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).
Subscribing
Section titled “Subscribing”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 }'urlmust behttps://. Plain HTTP is rejected.typeselects which event family is delivered. See the catalogue.triggeris currently alwaysPUSH.keyis 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.
Delivery
Section titled “Delivery”- Quiddly POSTs JSON to your URL synchronously when the source event fires.
- Responses with status
< 400count as success. >=500responses trigger one automatic retry (~10 seconds later) via Celery.4xxresponses do NOT retry automatically - they are markedFAILEDin theWebhookRequestLogand surfaced via the request-log API.
Delivery guarantees
Section titled “Delivery guarantees”- At-least-once in practice. Implement idempotency keyed on the
X-Webhook-Idheader. - No ordering guarantee across events.
- Retries reuse the same
delivery_id. Two POSTs with the sameX-Webhook-Idrepresent the same logical event.
Inspecting deliveries
Section titled “Inspecting deliveries”# Search delivery logscurl -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.