Skip to content

Webhooks overview

Quiddly delivers webhook events for the resource changes most integrations care about. Subscriptions live on the Webhook resource and are scoped to a single client (or the whole tenant for system-managed hooks).

Terminal window
curl -X POST "https://$HOST/webhook" \
-H "Authorization: Bearer $JWT" \
-H "Content-Type: application/json" \
-d '{
"title": "Invoice sync to ERP",
"url": "https://your.app/quiddly-webhooks",
"type": "INVOICE",
"trigger": "PUSH",
"method": "POST",
"key": "<hmac-shared-secret>",
"clientId": "C.100100",
"enabled": true
}'
  • url must be https://. Plain HTTP is rejected.
  • type selects which event family is delivered. See the catalogue.
  • trigger is currently always PUSH.
  • key is the shared HMAC secret used to sign deliveries (see Verifying webhooks). It is encrypted at rest.
  • customHeaders (optional) is a flat object of extra headers Quiddly attaches to each delivery - useful for routing on your side.

Required rights: CreateWebhook, ReadWebhook, UpdateWebhook, DeleteWebhook.

  • Quiddly POSTs JSON to your URL synchronously when the source event fires.
  • Responses with status < 400 count as success.
  • >=500 responses trigger one automatic retry (~10 seconds later) via Celery.
  • 4xx responses do NOT retry automatically - they are marked FAILED in the WebhookRequestLog and surfaced via the request-log API.
  • At-least-once in practice. Implement idempotency keyed on the X-Webhook-Id header.
  • No ordering guarantee across events.
  • Retries reuse the same delivery_id. Two POSTs with the same X-Webhook-Id represent the same logical event.
Terminal window
# Search delivery logs
curl -X POST "https://$HOST/webhook/log/search" \
-H "Authorization: Bearer $JWT" \
-H "Content-Type: application/json" \
-d '{ "clientId": "C.100100", "status": "FAILED" }'
# Detail (includes the payload Quiddly sent)
curl "https://$HOST/webhook/log/$WHRL_ID" \
-H "Authorization: Bearer $JWT"
# Manual retry (after the auto-retry window or for 4xx failures)
curl -X PUT "https://$HOST/webhook/log/retry/$WHRL_ID" \
-H "Authorization: Bearer $JWT"

/webhook/log/retry/<id> requires RetryWebhookEvents and only retries logs in FAILED status. There is a 5-minute per-log lock to prevent stampeding, and a 30-minute cool-off after the original delivery attempt.