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

Cet article n'est pas encore disponible en français ; il est affiché ci-dessous en anglais.

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.

Préférences en matière de cookies

Vous choisissez les cookies utilisés. Vous pouvez modifier votre choix à tout moment via « Paramètres des cookies » en bas de page. Politique de confidentialité

Nécessaires

Toujours actifs

Indispensables au fonctionnement du site : votre thème clair/sombre et ce choix de cookies sont enregistrés dans votre navigateur. Ils ne servent pas à vous suivre.

Analyse

Google Analytics 4 mesure l’utilisation des pages au moyen de statistiques, ce qui nous aide à améliorer le site. Si vous acceptez, il dépose des cookies et mesure votre visite en détail. Si vous refusez, il ne dépose aucun cookie, mais Google peut tout de même recevoir des données techniques, comme la page consultée, le type de navigateur et l’adresse IP.

_ga, _ga_* · jusqu’à 2 ans · Google