Developers · API endpoints

Webhook endpoints

Register, update, pause and test webhook endpoints, rotate their secrets, and read and resend deliveries over the API.

Version
v1.0.0
Base URL
https://dppapi-production.up.railway.app/v1
Format
JSON · OpenAPI 3.1
FeedbackLast updated

Dieser Artikel liegt noch nicht auf Deutsch vor und wird unten auf Englisch angezeigt.

Register where events are delivered, inspect what was sent and resend it. The Webhooks guide covers the payload, the signature and retries. Endpoints can also be managed in the app under Organisation → API → Webhooks.

Webhooks are part of API access (erp_api), included on every plan. Over the API an endpoint is paused with enabled: false, never deleted, so its delivery history survives.

Personalise the samples. Paste a test key and every snippet uses it — and your own model and passport ids.

GET/v1/webhooks
read scope

List webhook endpoints

Your endpoints, newest first, each with its last delivery and how many deliveries have failed — a broken receiver shows at a glance. Signing secrets are never listed.

Responses

  • 200OK — The endpoints.

Errors1

Response fields · 200

object
GET /v1/webhooks
curl "https://dppapi-production.up.railway.app/v1/webhooks" \-H "Authorization: Bearer $DPP_API_KEY"
200 OK · The endpoints.
{"data": [{"id": "cm1qb7h2c0020l70fd3e4f5g6","url": "https://erp.example.com/hooks/dpp","description": "ERP status sync","events": ["passport.published", "passport.recycled"],"enabled": true,"createdAt": "2027-01-10T08:00:00.000Z","lastDelivery": {"status": "succeeded","responseStatus": 200,"createdAt": "2027-01-15T10:02:11.300Z","eventType": "passport.published"},"failedDeliveries": 0}]}
POST/v1/webhooks
write scope

Register a webhook endpoint

The URL must use https and resolve to a public address. An endpoint with an empty events list receives every event type. The response carries the signing secret (whsec_…) — the only time it is shown; store it straight away.

Request body3

  • urlhttps URL, ≤ 2000required

    Where deliveries are POSTed.

  • eventsstring[]optional

    Event types to receive. Empty or omitted: all. See event types.

  • descriptionstring, ≤ 200optional

    What this endpoint is for.

Headers2

  • Idempotency-Keystringheaderoptional

    Optional. A unique string per logical operation (a UUID is ideal). The first response is stored for 24 hours and replayed for retries; see Idempotency.

  • X-DPP-Dry-Run"true"headeroptional

    Optional, live keys. Validate the write in full and store nothing. Test keys always dry-run; see Test keys.

Responses

  • 201Created — The endpoint, with its secret.

Errors4

Response fields · 201

object
  • idstring
  • urlstring · uri
  • descriptionstring | null
  • eventsarray of string

    Empty = every event.

    One ofmodel.createdmodel.updateddocument.uploadedpassport.createdpassport.publishedpassport.status_changedpassport.recycledpassport.event_recordedsupplier.submitted

  • enabledboolean
  • createdAtstring · date-time
  • lastDeliveryobject | null
  • failedDeliveriesinteger
  • secretstring
POST /v1/webhooks
curl -X POST "https://dppapi-production.up.railway.app/v1/webhooks" \-H "Authorization: Bearer $DPP_API_KEY" \-H "Content-Type: application/json" \-H "Idempotency-Key: 7b3e0c52-1f7d-4b8a-9a52-2f0e6d1c9a44" \-d '{"url": "https://erp.example.com/hooks/dpp","description": "ERP status sync","events": ["passport.published","passport.recycled"]}'
201 Created · The endpoint, with its secret.
{"id": "cm1qb7h2c0020l70fd3e4f5g6","url": "https://erp.example.com/hooks/dpp","description": "ERP status sync","events": ["passport.published", "passport.recycled"],"enabled": true,"createdAt": "2027-01-10T08:00:00.000Z","secret": "whsec_4f1a9c2e7d5b8361f4a0c9e2d7b5a8361f4a0c9e2d7b5a83"}
GET/v1/webhooks/event-types
read scope

Event types

Every event type you can subscribe to. Read it at start-up instead of hard-coding the list: new types are additive.

Responses

  • 200OK — The event types.

Response fields · 200

object
  • dataarray of string
GET /v1/webhooks/event-types
curl "https://dppapi-production.up.railway.app/v1/webhooks/event-types" \-H "Authorization: Bearer $DPP_API_KEY"
200 OK · The event types.
{"data": ["model.created","model.updated","document.uploaded","passport.created","passport.published","passport.status_changed","passport.recycled","passport.event_recorded","supplier.submitted"]}
GET/v1/webhooks/{id}
read scope

Get an endpoint

One endpoint, without its secret.

Parameters1

  • idstringpathrequired

    The webhook endpoint id.

Responses

  • 200OK — The endpoint.

Errors2

  • 401unauthorized The key is missing, unknown or revoked.
  • 404Not found No webhook endpoint with this id in your organisation.

Response fields · 200

object
  • idstring
  • urlstring · uri
  • descriptionstring | null
  • eventsarray of string

    Empty = every event.

    One ofmodel.createdmodel.updateddocument.uploadedpassport.createdpassport.publishedpassport.status_changedpassport.recycledpassport.event_recordedsupplier.submitted

  • enabledboolean
  • createdAtstring · date-time
  • lastDeliveryobject | null
  • failedDeliveriesinteger
GET /v1/webhooks/{id}
curl "https://dppapi-production.up.railway.app/v1/webhooks/cm1qb7h2c0020l70fd3e4f5g6" \-H "Authorization: Bearer $DPP_API_KEY"
200The endpoint.
PATCH/v1/webhooks/{id}
write scope

Update or pause an endpoint

Change the URL, description or events, or pause deliveries with enabled: false and resume with true.

Parameters1

  • idstringpathrequired

    The webhook endpoint id.

Request body4

  • urlhttps URL, ≤ 2000optional

    New URL; checked like on creation.

  • descriptionstring | nulloptional

    New description.

  • eventsstring[]optional

    Replaces the subscribed events.

  • enabledbooleanoptional

    false pauses deliveries.

Headers2

  • Idempotency-Keystringheaderoptional

    Optional. A unique string per logical operation (a UUID is ideal). The first response is stored for 24 hours and replayed for retries; see Idempotency.

  • X-DPP-Dry-Run"true"headeroptional

    Optional, live keys. Validate the write in full and store nothing. Test keys always dry-run; see Test keys.

Responses

  • 200OK — The updated endpoint.

Errors5

Response fields · 200

object
  • idstring
  • urlstring · uri
  • descriptionstring | null
  • eventsarray of string

    Empty = every event.

    One ofmodel.createdmodel.updateddocument.uploadedpassport.createdpassport.publishedpassport.status_changedpassport.recycledpassport.event_recordedsupplier.submitted

  • enabledboolean
  • createdAtstring · date-time
  • lastDeliveryobject | null
  • failedDeliveriesinteger
PATCH /v1/webhooks/{id}
curl -X PATCH "https://dppapi-production.up.railway.app/v1/webhooks/cm1qb7h2c0020l70fd3e4f5g6" \-H "Authorization: Bearer $DPP_API_KEY" \-H "Content-Type: application/json" \-d '{"enabled": false}'
200The updated endpoint.
POST/v1/webhooks/{id}/rotate-secret
write scope

Rotate the signing secret

Issues a new secret, shown once. The old secret stops verifying immediately, so deploy the new one to your receiver first-thing: deliveries that fail verification meanwhile are retried on the normal schedule.

Parameters1

  • idstringpathrequired

    The webhook endpoint id.

Headers2

  • Idempotency-Keystringheaderoptional

    Optional. A unique string per logical operation (a UUID is ideal). The first response is stored for 24 hours and replayed for retries; see Idempotency.

  • X-DPP-Dry-Run"true"headeroptional

    Optional, live keys. Validate the write in full and store nothing. Test keys always dry-run; see Test keys.

Responses

  • 200OK — The new secret.

Errors3

Response fields · 200

object
  • idstring
  • secretstring
POST /v1/webhooks/{id}/rotate-secret
curl -X POST "https://dppapi-production.up.railway.app/v1/webhooks/cm1qb7h2c0020l70fd3e4f5g6/rotate-secret" \-H "Authorization: Bearer $DPP_API_KEY"
200 OK · The new secret.
{"id": "cm1qb7h2c0020l70fd3e4f5g6","secret": "whsec_9b2e0c7a5d3f1e8c6a4b2d0f9e7c5a3b1d8f6e4c2a0b9d7f"}
POST/v1/webhooks/{id}/test
write scope

Send a test event

Sends a signed ping event now and answers with what your endpoint said — the quickest end-to-end check of a receiver and its signature verification. Takes no body.

Parameters1

  • idstringpathrequired

    The webhook endpoint id.

Responses

  • 200OK — The delivery outcome.

Errors3

Response fields · 200

object
  • idstring
  • eventIdstring
  • eventTypestring
  • statusstring

    One ofpendingsucceededfailed

  • attemptsinteger
  • responseStatusinteger | null
  • responseBodystring | null

    First 2,000 characters of what your endpoint answered.

  • lastErrorstring | null
  • nextAttemptAtstring · date-time | null
  • createdAtstring · date-time
  • deliveredAtstring · date-time | null
POST /v1/webhooks/{id}/test
curl -X POST "https://dppapi-production.up.railway.app/v1/webhooks/cm1qb7h2c0020l70fd3e4f5g6/test" \-H "Authorization: Bearer $DPP_API_KEY"
200 OK · The delivery outcome.
{"id": "cm1qf3g4h0060l70fm5n6b7v8","status": "succeeded","responseStatus": 200,"responseBody": "ok","lastError": null,"attempts": 1}
GET/v1/webhooks/{id}/deliveries
read scope

Delivery log

Every delivery to the endpoint, newest first: the event, each attempt’s outcome, the first 2,000 characters your endpoint answered, and when the next retry is due.

Parameters4

  • idstringpathrequired

    The webhook endpoint id.

  • limitintegerqueryoptional

    Page size, 1–200. Default 50.

  • cursorstringqueryoptional

    The next_cursor of the previous page. Omit for the first page.

  • status"pending" | "succeeded" | "failed"queryoptional

    Only one outcome.

Responses

  • 200OK — A page of deliveries (payload abridged).

Errors3

Response fields · 200

object
  • has_morebooleanrequired
  • next_cursorstring | nullrequired

    Pass as cursor to get the next page.

GET /v1/webhooks/{id}/deliveries
curl "https://dppapi-production.up.railway.app/v1/webhooks/cm1qb7h2c0020l70fd3e4f5g6/deliveries?status=failed" \-H "Authorization: Bearer $DPP_API_KEY"
200 OK · A page of deliveries (payload abridged).
{"data": [{"id": "cm1qf3g4h0060l70fm5n6b7v8","eventId": "evt_5f0c1d2e3a4b4c6d8e9f0a1b2c3d4e5f","eventType": "passport.published","status": "failed","attempts": 6,"responseStatus": 503,"responseBody": "Service Unavailable","lastError": "HTTP 503","nextAttemptAt": null,"createdAt": "2027-01-15T10:02:11.300Z","deliveredAt": null,"payload": { "id": "evt_5f0c1d2e3a4b4c6d8e9f0a1b2c3d4e5f", "type": "passport.published" }}],"has_more": true,"next_cursor": "eyJpZCI6ImNtMXE4eTBicTAwMDZsNzBmeDl5OHo3dzYifQ"}
POST/v1/webhooks/deliveries/{deliveryId}/resend
write scope

Resend a delivery

Sends a delivery again now — after you fixed a receiver, for example — and answers with the new outcome. The event id is unchanged, so an idempotent receiver ignores it if it already processed the event.

Parameters1

  • deliveryIdstringpathrequired

    The delivery id from the log.

Responses

  • 200OK — The delivery with its new outcome.

Errors3

Response fields · 200

object
  • idstring
  • eventIdstring
  • eventTypestring
  • statusstring

    One ofpendingsucceededfailed

  • attemptsinteger
  • responseStatusinteger | null
  • responseBodystring | null

    First 2,000 characters of what your endpoint answered.

  • lastErrorstring | null
  • nextAttemptAtstring · date-time | null
  • createdAtstring · date-time
  • deliveredAtstring · date-time | null
POST /v1/webhooks/deliveries/{deliveryId}/resend
curl -X POST "https://dppapi-production.up.railway.app/v1/webhooks/deliveries/cm1qf3g4h0060l70fm5n6b7v8/resend" \-H "Authorization: Bearer $DPP_API_KEY"
200The delivery with its new outcome.

Cookie-Einstellungen

Sie entscheiden, welche Cookies verwendet werden. Ihre Wahl können Sie jederzeit über „Cookie-Einstellungen“ im Footer ändern. Datenschutzerklärung

Notwendig

Immer aktiv

Für den Betrieb der Website erforderlich: Ihr Hell-/Dunkel-Design und diese Cookie-Auswahl werden in Ihrem Browser gespeichert. Sie dienen nicht dem Tracking.

Analyse

Google Analytics 4 misst über Statistiken, wie Seiten genutzt werden, und hilft uns, die Website zu verbessern. Wenn Sie zustimmen, setzt es Cookies und erfasst Ihren Besuch vollständig. Wenn Sie ablehnen, setzt es keine Cookies, doch Google kann weiterhin technische Daten erhalten, etwa die aufgerufene Seite, Ihren Browsertyp und Ihre IP-Adresse.

_ga, _ga_* · bis zu 2 Jahre · Google