Skip to main content
Webhooks let you receive HTTP POST notifications when a job finishes. Instead of polling the Get Job Status endpoint, configure a webhook URL on your portal and get notified automatically.

Setup

1. Generate a signing key

Go to API Keys > Webhook Key in the dashboard and click Generate Webhook Key. Copy the secret — it’s only shown once. You can also rotate or revoke the key from the same page.

2. Set a webhook URL on your portal

Add a webhook_url when creating or updating a portal:
curl -X PATCH https://agent.usedari.com/portals/my-org/insurance_quote \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"webhook_url": "https://example.com/webhooks/dari"}'
Or set it in the dashboard under Automations > Settings > Webhook URL.

Payload

When a job completes or fails, a POST request is sent to the webhook URL. The payload matches the Get Job Status response with two additional fields:
{
  "job_id": "550e8400-e29b-41d4-a716-446655440000",
  "portal_id": "my-org/insurance_quote",
  "status": "completed",
  "event_type": "completed",
  "result": null,
  "final_result": {"quoteId": "Q-123", "premium": 89.50},
  "error": null,
  "total_cost_usd": 0.12,
  "downloads_link": "https://storage.example.com/downloads/...",
  "video_recording_url": "https://storage.example.com/recordings/...",
  "log_url": "logs/550e8400.log",
  "created_at": "2025-01-15T10:30:00+00:00",
  "updated_at": "2025-01-15T10:31:45+00:00",
  "timestamp": "2025-01-15T10:31:45.123456+00:00"
}
FieldDescription
event_typeEither completed or error
timestampISO 8601 timestamp of when the webhook was sent
All other fields are identical to the job status response.

Signature verification

Every webhook request includes an X-Webhook-Signature header containing an HMAC-SHA256 signature. Verify it to ensure the payload was sent by Dari and hasn’t been tampered with. The signature is computed over the JSON body using your webhook signing key:
import hashlib
import hmac
import json

def verify_signature(body: bytes, signature: str, secret: str) -> bool:
    """Verify the X-Webhook-Signature header."""
    # The payload is serialized with compact separators and sorted keys
    payload = json.loads(body)
    canonical = json.dumps(payload, separators=(",", ":"), sort_keys=True)
    expected = hmac.new(
        secret.encode(), canonical.encode(), hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, signature)
Node.js
const crypto = require("crypto");

function verifySignature(body, signature, secret) {
  const payload = JSON.parse(body);
  const canonical = JSON.stringify(payload, Object.keys(payload).sort());
  // For exact match, use compact JSON with sorted keys:
  const sorted = JSON.stringify(
    JSON.parse(body),
    Object.keys(JSON.parse(body)).sort()
  );
  const expected = crypto
    .createHmac("sha256", secret)
    .update(canonical)
    .digest("hex");
  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(signature)
  );
}
Always verify the signature before processing the payload. Reject requests with missing or invalid signatures.

Retry behavior

If your endpoint returns a non-2xx status code or times out (10s), the webhook is retried up to 3 times with exponential backoff (1s, 3s, 9s delays).

Requirements

  • Your endpoint must return a 2xx status code within 10 seconds
  • Both a webhook signing key (org-level) and a webhook URL (portal-level) must be configured for webhooks to fire
  • Webhooks are only sent for terminal events (completed and error)