Quick Start
Create a webhook
Go to Dashboard > Webhooks, click Add Webhook, enter your HTTPS endpoint URL, and select the events you want to receive.You can also create one via the API:
Save your signing secret
After creation you’ll see a signing secret (starts with
whsec_). Copy it immediately — it won’t be shown again. You’ll use this to verify that incoming requests actually came from Danube.Build your endpoint
Your server needs to do three things:
- Read the raw request body and parse the signature header
- Verify the HMAC signature (which includes a timestamp for replay protection)
- Return a
2xxstatus code within 10 seconds
Test it
Trigger an event (e.g. execute a tool) and check the delivery status in Dashboard > Webhooks. Expand your webhook to see recent deliveries, including HTTP status codes and response bodies.
Event Types
| Event | Fires when |
|---|---|
tool.execution.completed | A tool ran successfully |
tool.execution.failed | A tool execution errored |
workflow.completed | All workflow steps finished |
workflow.failed | Any workflow step errored |
agent.spend.limit_approaching | Daily spend reached 80% of an API key’s limit |
Payload Format
Every delivery uses this envelope:tool.execution.completed / tool.execution.failed
tool.execution.completed / tool.execution.failed
workflow.completed / workflow.failed
workflow.completed / workflow.failed
agent.spend.limit_approaching
agent.spend.limit_approaching
Signature Verification
Every delivery includes a signedX-Danube-Signature header with a timestamp for replay protection. Always verify it before processing.
How it works
The signature header has the format:- Danube computes
HMAC-SHA256("{timestamp}.{raw_body}", your_secret)and sends the result along with the timestamp - Your server reconstructs the same signed content (
{timestamp}.{raw_body}) and computes the HMAC using the secret you saved at creation - Compare the two digests using a constant-time comparison to prevent timing attacks
- Reject deliveries where the timestamp is too old (e.g. more than 5 minutes) to prevent replay attacks
Request Headers
| Header | Value |
|---|---|
X-Danube-Signature | t={unix_ts},sha256={hex_digest} — timestamped HMAC-SHA256 |
X-Danube-Event | Event type, e.g. tool.execution.completed |
X-Danube-Delivery | Unique delivery UUID (use to deduplicate) |
Content-Type | application/json |
User-Agent | DanubeAI-Webhooks/1.0 |
Retries and Failures
If your endpoint doesn’t return a2xx or the request times out, Danube retries with exponential backoff:
| Attempt | Delay before retry |
|---|---|
| 1st retry | ~1 second |
| 2nd retry | ~4 seconds |
Best Practices
Respond fast
Return
200 immediately, then process the event asynchronously. The delivery times out after 10 seconds.Verify signatures
Always validate
X-Danube-Signature before trusting the payload. Never skip this in production.Check the timestamp
Reject signatures where
t is more than 5 minutes old to prevent replay attacks.Handle duplicates
Use the
X-Danube-Delivery UUID to deduplicate. Network retries may deliver the same event more than once.Use HTTPS
Webhook URLs must use
https://. Danube will not deliver to plain HTTP or internal/private endpoints.