Browse documentation

Customer webhooks

Current release · Updated October 2, 2026

DryKraft Customer webhooks reference: methods, permissions, request fields, response shapes, examples and current limits. Read authentication and error handling first.

GET/api/developer/webhooks/events

Read event catalogue

Access: Owner or admin · Success: 200

Current built-in/custom CRM record events and supported Finance, team, Outreach and billing lifecycle events. Credentials and security events are excluded. Refresh before registering if schemas changed.

No request body is required.

Response

FieldTypeRequiredDetails
eventsstring[]No
Request shape (illustrative)
curl --request GET \
  --url 'https://app.drykraft.com/api/developer/webhooks/events' \
  --cookie 'drykraft_session=<YOUR_SESSION_TOKEN>'
GET/api/developer/webhooks/

List customer webhooks

Access: Owner or admin · Success: 200

25 endpoints per cursor page, including disabled endpoints. No signing secret or ciphertext is returned. Browser session administrator access only.

Query parameters

ParameterTypeRequiredDetails
cursoruuidNo

No request body is required.

Response

FieldTypeRequiredDetails
itemsCustomerWebhook[]No
next_cursorstring or nullNo
Request shape (illustrative)
curl --request GET \
  --url 'https://app.drykraft.com/api/developer/webhooks/' \
  --cookie 'drykraft_session=<YOUR_SESSION_TOKEN>'
POST/api/developer/webhooks/

Register customer webhook

Access: Owner or admin · Success: 201

Current password and active plan required; shared approval limit 30/15 min. Up to 50 retained endpoints/workspace and 100 unique subscribed event types. Public DNS and HTTPS:443 are validated. Same UUID/normalized original settings returns 200/secret=null. Events committed after registration enqueue immutable signed notification envelopes atomically; historical events are not backfilled.

JSON request

FieldTypeRequiredDetails
iduuidYes
namestringYesWebhook name Max 100 characters.
urlstringYesPublic HTTPS URL; no credentials/query/fragment; port 443 Max 2048 characters.
eventsstring[]Yes Min 1 items. Max 100 items.
passwordstringYes Max 128 characters.

Response

FieldTypeRequiredDetails
webhookCustomerWebhookNo
secretstring or nullNoOne-time signing secret, only in first 201 response. Store privately.
Request shape (illustrative)
curl --request POST \
  --url 'https://app.drykraft.com/api/developer/webhooks/' \
  --cookie 'drykraft_session=<YOUR_SESSION_TOKEN>' \
  --header 'Content-Type: application/json' \
  --data '{
  "id": "00000000-0000-4000-8000-000000000001",
  "name": "<Webhook name>",
  "url": "<Public HTTPS URL; no credentials/query/fragment; port 443>",
  "events": [
    "<Unique supported event type>"
  ],
  "password": "<value>"
}'
PUT/api/developer/webhooks/{id}

Update or disable webhook

Access: Owner or admin · Success: 200

Current version required. New destination, expanded subscriptions or reactivation requires current password. Enabled changes require active billing; disabling is allowed after expiry. Pending deliveries to changed destinations/removed events or disabled endpoints cancel. An accepted in-flight request can finish before this update. No queued historical event is forwarded to a new destination.

JSON request

FieldTypeRequiredDetails
namestringYesWebhook name Max 100 characters.
urlstringYesPublic HTTPS URL; no credentials/query/fragment; port 443 Max 2048 characters.
eventsstring[]Yes Min 1 items. Max 100 items.
enabledbooleanYesEnable future event delivery
versionintegerYesPositive optimistic version returned by the latest read. Refresh on 409; do not overwrite stale changes. Min 1.
passwordstringNo Max 128 characters.

Response

Use CustomerWebhook.

Request shape (illustrative)
curl --request PUT \
  --url 'https://app.drykraft.com/api/developer/webhooks/00000000-0000-4000-8000-000000000001' \
  --cookie 'drykraft_session=<YOUR_SESSION_TOKEN>' \
  --header 'Content-Type: application/json' \
  --data '{
  "name": "<Webhook name>",
  "url": "<Public HTTPS URL; no credentials/query/fragment; port 443>",
  "events": [
    "<Unique supported event type>"
  ],
  "enabled": false,
  "version": 1
}'
POST/api/developer/webhooks/{id}/rotate

Rotate webhook signing secret

Access: Owner or admin · Success: 201

Current password/version and active plan required. Replace encrypted signing secret immediately; subsequent attempts, including retries, use the new secret. In-flight request can finish. New operation UUID returns 201/one-time secret; identical completed retry 200/secret=null. No automatic grace period for the former secret.

JSON request

FieldTypeRequiredDetails
iduuidYes
versionintegerYesPositive optimistic version returned by the latest read. Refresh on 409; do not overwrite stale changes. Min 1.
passwordstringYes Max 128 characters.

Response

FieldTypeRequiredDetails
webhookCustomerWebhookNo
secretstring or nullNoOne-time signing secret, only in first 201 response. Store privately.
Request shape (illustrative)
curl --request POST \
  --url 'https://app.drykraft.com/api/developer/webhooks/00000000-0000-4000-8000-000000000001/rotate' \
  --cookie 'drykraft_session=<YOUR_SESSION_TOKEN>' \
  --header 'Content-Type: application/json' \
  --data '{
  "id": "00000000-0000-4000-8000-000000000001",
  "version": 1,
  "password": "<value>"
}'
GET/api/developer/webhooks/{id}/deliveries

Read delivery history

Access: Owner or admin · Success: 200

25 tenant-scoped delivery summaries per cursor page. Automatic retry delays after failure are 60, 300, 1800 and 7200 seconds, at most 5 attempts/cycle. Fifth failure disables the endpoint and cancels its other pending deliveries. Billing expiry defers sends 15 minutes without using an attempt. History has sanitized errors/statuses, never receiver response bodies.

Query parameters

ParameterTypeRequiredDetails
cursoruuidNo

No request body is required.

Response

FieldTypeRequiredDetails
webhookCustomerWebhookNo
itemsWebhookDelivery[]No
next_cursorstring or nullNo
Request shape (illustrative)
curl --request GET \
  --url 'https://app.drykraft.com/api/developer/webhooks/00000000-0000-4000-8000-000000000001/deliveries' \
  --cookie 'drykraft_session=<YOUR_SESSION_TOKEN>'
GET/api/developer/webhooks/{id}/deliveries/{deliveryId}

Inspect delivered envelope and attempts

Access: Owner or admin · Success: 200

Immutable exact envelope plus latest 50 append-only completed attempt rows, newest first. Each row records attempt, secret_version, HTTP status/sanitized error and start/completion time. A process loss after acceptance can leave no completed attempt; receiver must deduplicate the delivery ID.

No request body is required.

Response

FieldTypeRequiredDetails
iduuidNo
endpoint_iduuidNo
event_iduuidNo
event_typestringNoBusiness event type
statequeued | retrying | succeeded | failed | cancelledNoDelivery state
attemptsintegerNoTotal completed attempts
cycle_attemptsintegerNoAttempts since creation or latest replay
versionintegerNoPositive optimistic version returned by the latest read. Refresh on 409; do not overwrite stale changes. Min 1.
next_attempt_atstringNoTimestamp
last_statusinteger or nullNo
last_errorstring or nullNo
created_atstringNoTimestamp
completed_atstring or nullNo
payloadWebhookEnvelopeNo
attempt_historyobject[]No
Request shape (illustrative)
curl --request GET \
  --url 'https://app.drykraft.com/api/developer/webhooks/00000000-0000-4000-8000-000000000001/deliveries/00000000-0000-4000-8000-000000000001' \
  --cookie 'drykraft_session=<YOUR_SESSION_TOKEN>'
POST/api/developer/webhooks/{id}/deliveries/{deliveryId}/replay

Replay failed delivery

Access: Owner or admin · Success: 200

Current failed-delivery version and acknowledge_duplicate=true required. Restore/reapprove the original destination/event and enable endpoint first. Active billing required. Stable operation UUID resets the retry cycle once; exact retries recover the recorded result. Original body, event ID and delivery ID remain; new timestamp/signature and current secret are used. Delivery is at-least-once and can repeat external effects.

JSON request

FieldTypeRequiredDetails
iduuidYes
versionintegerYesPositive optimistic version returned by the latest read. Refresh on 409; do not overwrite stale changes. Min 1.
acknowledge_duplicatetrueYes

Response

Use WebhookDelivery.

Request shape (illustrative)
curl --request POST \
  --url 'https://app.drykraft.com/api/developer/webhooks/00000000-0000-4000-8000-000000000001/deliveries/00000000-0000-4000-8000-000000000001/replay' \
  --cookie 'drykraft_session=<YOUR_SESSION_TOKEN>' \
  --header 'Content-Type: application/json' \
  --data '{
  "id": "00000000-0000-4000-8000-000000000001",
  "version": 1,
  "acknowledge_duplicate": true
}'