Webhook events
The decision.completed event of the OpenAPI document — the request sent to webhook destinations, its headers, every field of the event and the answers Dcision expects.
POST <your webhook URL>Dcision sends a decision.completed event to every webhook destination that fires. The event is part of the OpenAPI document, served without authentication at https://api.dcision.io/openapi.json, under webhooks → decision.completed.
Request headers
| Header | Required | Description |
|---|---|---|
Dcision-Signature | Yes | t=<unix seconds>,v1=<hex> — the HMAC-SHA256 of <t>.<raw body> with your signing secret; two v1 entries during the 24 hours after a rotation. See Verify the signature. |
Dcision-Delivery | Yes | The delivery ID, dlv_… — the same on every attempt. |
Dcision-Attempt | Yes | 1 to 6. |
Dcision-Event | Yes | decision.completed. |
Content-Type | Yes | application/json. |
User-Agent | Yes | Dcision-Destinations/1.0 (+https://docs.dcision.io/destinations). |
Body
{
"id": "dlv_8kJx2mQp4LzN7vR1tY6w",
"type": "decision.completed",
"created": 1759658400,
"livemode": true,
"destination": "notify_sales",
"data": {
"decision": "lead-qualification",
"decision_id": "dec_3fKq9ZtW1mXcV7bN2pLa",
"version": 4,
"execution_id": "exec_8HsT2kQw9ZyR4vMn1cXe",
"result": { "purchase_intent": 0.9412, "priority": "high", "route": "sales" },
"confidence": { "purchase_intent": 0.8824, "priority": 0.69, "route": 0.85 },
"scores": { "priority": 2.81 },
"composites": { "lead_score": 0.8414 },
"action": "continue",
"action_reason": { "type": "default" },
"params": { "message": "We need pricing for 500 users and want to start next month.", "team": "inbound" }
}
}| Field | Type | Description |
|---|---|---|
id | string | The delivery ID, dlv_…, the same on every attempt — deduplicate on it. |
type | string | decision.completed. Check it: more event types may be added. |
created | integer | When the decision ran, in Unix seconds. |
livemode | boolean | false for runs with a test key (dcs_test_…) and from the Playground. |
destination | string | The key of the destination that sent the event. |
data.decision | string | The decision's slug. |
data.decision_id | string | The decision's ID, dec_…. |
data.version | integer or null | The version that answered; null from the Playground, which runs the draft. |
data.execution_id | string | The run's ID, exec_… — the execution_id of the API response. |
data.result | object | The answers, keyed by question. Empty after an engine-error fallback. |
data.confidence | object | The confidence of each answer, from 0 to 1. |
data.scores | object | The weighted level of each score question; {} when there are none. |
data.composites | object | The value of each composite; {} when there are none. |
data.action | string | continue, block, escalate or fallback. |
data.action_reason | object | Why the action was chosen — see action_reason. |
data.params | object | The params mapped in the destination. The state itself is never sent. |
Responses
| Your answer | What Dcision does |
|---|---|
Any 2xx within 10 seconds | The delivery succeeded. |
408, 425, 429, 5xx, a timeout or a network error | Retries — six attempts over about seven hours, honoring Retry-After on 429 and 503. |
Any other 4xx, or a redirect | The delivery fails at once; it can be resent from the app. |
See Delivery and retries.
Other destinations
API requests, workflows and agents carry the same Dcision-* headers and signature — Dcision-Event is decision.completed for them too — plus an Idempotency-Key equal to the delivery ID. Their bodies are different: verify them with verifySignature / verify_signature, which don't expect an event.
Webhook trigger
POST /v1/hooks/{token} — run a deployed decision from a secret URL without an API key, from forms, CRMs, Zapier, n8n, Make or any backend, optionally signed with a whsec_ secret.
Errors
The error format and every error code with its HTTP status, what it means and what to do about it — plus which errors are safe to retry.