Replay a delivery
BuildingIn development for the v1 API. The contract is set; the route is not served yet.
Queues a new delivery of the same event, byte for byte, to the same subscription. It goes out on the next pass with its own Heru-Delivery-Id and Heru-Attempt: 1; discard it by Heru-Event-Id if you already processed the event. Allowed for delivered, failed and expired deliveries whose event is still retained (30 days); a delivery in progress or of a deleted subscription answers 409. Retrying with the same Idempotency-Key returns the same new delivery.
Needs the webhooks:write scope.
oauth2 webhooks:writeAuthorizationBearer <token>OAuth 2.0 client credentials. Exchange your client_id and client_secret at /oauth/token of the environment for a bearer token valid for one hour. The playground of every operation asks for your own client and keeps it in your browser tab only.
Scope: webhooks:write
id*stringThe delivery id.
^dlv_[0-7][0-9a-hjkmnp-tv-z]{25}$Idempotency-Key*stringUnique per operation. Retrying with the same key returns the original result for 24 hours.
length <= 255The new delivery, pending if the subscription is active or held if it is paused or disabled. replay_of points at the original.
application/json- response
id*string^dlv_[0-7][0-9a-hjkmnp-tv-z]{25}$event_id*string^evt_[0-7][0-9a-hjkmnp-tv-z]{25}$event_type*stringsubscription_id*string^whk_[0-7][0-9a-hjkmnp-tv-z]{25}$status*stringpending waits for the next pass; delivering is in flight; retrying failed and waits for next_retry_at; failed exhausted its retries; held waits for the subscription to be active again; expired will not be sent.
"pending""delivering""delivered""retrying""failed""held""expired"attempt_count*integerattempts*array<>Oldest first. Attempts are kept for 30 days; the delivery and its counters stay.
next_retry_at*|nulllast_status_code*integer|nulllast_error*string|nulldelivered_at*|nullreplay_of*|nullcreated_at*stringdate-timeupdated_at*stringdate-timecurl -X POST 'https://api.dev.b2b.heru.app/v1/deliveries/dlv_01m53g5zw414zt6vg08fqbacgm/replay' \ -H 'Idempotency-Key: try-it-0001'{ "id": "dlv_01m53h2c7fe8pq4x0n6yt9r1kv", "event_id": "evt_01m53g5zw414zt6vg08fqbacgm", "event_type": "invoice.stamped", "subscription_id": "whk_01m53g5zw414zt6vg08fqbacgm", "status": "pending", "attempt_count": 0, "attempts": [], "next_retry_at": "2026-10-26T15:04:41.000Z", "last_status_code": null, "last_error": null, "delivered_at": null, "replay_of": "dlv_01m53g5zw414zt6vg08fqbacgm", "created_at": "2026-10-26T15:04:41.000Z", "updated_at": "2026-10-26T15:04:41.000Z"}Send a test event nowPOST
Posts a signed `webhook.test` event (`data: {webhook_id, message}`) to the URL right away, with the secrets and extra headers in force, and answers what the endpoint replied. One attempt, no retries; it works on a `paused` or `disabled` subscription and does not count towards `consecutive_failures`. The delivery shows in the log like any other. At most 10 per minute per subscription. Needs the `webhooks:write` scope.
Update a webhook subscriptionPATCH
Changes only the fields sent. `status: paused` holds the deliveries that are waiting; `status: active` resumes them and releases the held ones, also when heru disabled the subscription. A validation that fails changes nothing. Needs the `webhooks:write` scope.