Webhooks
Outbound: n8n webhook connector
The n8n_webhook connector type sends a JSON payload to a configured webhook URL. It's used to trigger external workflows (n8n, Zapier, Make.com — anything that accepts an HTTP POST) from inside an agent or recipe.
Configure a connector via POST /api/connectors:
{
"name": "Sales Slack Webhook",
"type": "n8n_webhook",
"config": {
"webhook_url": "https://n8n.your-domain.com/webhook/abc123"
}
}
The connector exposes a single action (send_message) that the agent runtime calls when an agent invokes the corresponding tool:
{
"tool": "send_to_n8n",
"arguments": {
"message": "Customer X just signed up",
"metadata": {"customer_id": 42}
}
}
The connector POSTs {message, metadata} to the configured webhook_url and returns the response body to the agent.
There is no retry logic — a failed webhook returns the HTTP status to the caller and the agent decides what to do. There is no signing — n8n is expected to authenticate via the URL's secret path component.
Outbound: Twilio messaging
A second outbound integration: the twilio_messaging connector sends WhatsApp messages via the Twilio API. Same fire-and-forget shape; configured per-org and invoked from the send_whatsapp agent tool.
Inbound: CSP reports
POST /api/csp-report receives Content Security Policy violation reports from browsers. The App (vertical SaaS) domain ships a CSP in report-only mode; violations land at this endpoint where they're logged for review.
The endpoint is unauthenticated (browsers cannot include a token on report POSTs). To prevent abuse, it's behind the same nginx rate limit as the rest of /api/.
Reports are not stored long-term — they're written to the application log only. To retain them, configure your log shipper to filter the csp_report logger and forward to your SIEM. See Audit Logging for the pattern.
What's planned
A future webhook subscription API will add:
| Capability | Planned shape |
|---|---|
| Subscribe to events | POST /api/webhooks with {event_type, target_url, secret}. |
| Event types | dataset.updated, recipe.run.failed, dashboard.published, audit.security_event, ... |
| Signed payloads | HMAC-SHA256 of the body using the subscription's secret, sent as X-Honeyframe-Signature. |
| Retry policy | Exponential backoff with jitter, give up after 24 hours. |
| Delivery log | Per-subscription log of delivery attempts visible in the UI. |
Until that lands, the workarounds are:
- Database-driven — set up a logical-replication slot on
dataintel.audit_logorpipeline_runsand have your downstream consumer reduce over the change stream. - Polling — periodically GET
/api/pipeline/runs?status=failed&since=...from your monitoring system. - Agent-tool fan-out — give your agent a webhook tool (
send_to_n8n) and let the agent itself decide when to fire.
Designing for the future webhook API
If you're building integrations that will eventually move to subscription webhooks, structure them so the swap is mechanical:
- Run your consumer at a stable HTTPS URL.
- Generate a 32-byte secret per integration; store it server-side.
- Verify body integrity with HMAC even today (the polling integration won't sign anything, but write the verifier first).
- Use a job queue between webhook receipt and your business logic so retries are idempotent.
When the subscription API ships, you'll register your existing consumer URL and turn off the polling — no consumer-side code changes needed.