Webhooks
Trigger Sophon from external systems, and subscribe external systems to Sophon events — with HMAC signatures and retry.
Webhooks are how Sophon talks to the outside world asynchronously. They come in two flavors:
- Inbound — external systems POST to Sophon; an agent or workflow runs in response.
- Outbound — Sophon POSTs to external systems when events happen (task completed, approval requested, cron fired, …).
Both flavors support HMAC-SHA256 signing, retries with exponential backoff, and per-webhook filters.
Inbound webhooks
An inbound webhook is a URL Sophon exposes. Anything POSTed to it triggers an agent or workflow.
Creating one
Dashboard → Settings → Webhooks → Add Inbound. Configure:
- Name — internal label
- Path —
/api/webhooks/receive/<your-slug>(auto-generated or custom) - Action — Agent (send the POST body as a message), Workflow (trigger with the POST body as
$trigger.body), or Custom handler - Secret — generated; used for HMAC signature verification (optional but recommended)
- Filters — optional rules on headers or body that must match before the webhook fires (e.g.,
X-GitHub-Event: push)
Once saved, you get the full URL and secret. Paste them into the external system.
Verifying the signature
On every POST, Sophon computes HMAC_SHA256(secret, body) and compares against the X-Sophon-Signature header. Mismatches are rejected with 401.
import hmac, hashlib, base64
signature = hmac.new(secret.encode(), body, hashlib.sha256).hexdigest()
# send with header "X-Sophon-Signature: sha256=<signature>"Many external systems (GitHub, Stripe, Slack) sign their webhooks with their own scheme. Sophon supports the common ones automatically — pick the scheme when you create the webhook.
Example — GitHub push to agent
Create inbound webhook:
Path: /api/webhooks/receive/github-push
Action: agent "sophon"
Message: "A push happened: {{$trigger.body.head_commit.message}} on {{$trigger.body.ref}}"
Scheme: GitHub (uses X-Hub-Signature-256)
Secret: (paste GitHub's secret)
Filter: X-GitHub-Event == "push"
In GitHub: add this URL as a webhook with Content-Type: application/json.Every push to the repo now sends a chat message to Sophon, which processes it and (likely) runs a CI summary or updates memory.
Outbound webhooks
An outbound webhook is a URL Sophon posts to when specific events occur.
Creating one
Dashboard → Settings → Webhooks → Add Outbound. Configure:
- Name
- Target URL — where to POST
- Secret — used to HMAC-sign outbound payloads (recipient verifies)
- Events — which events to subscribe to (see table below)
- Filters — optional rules on event payload (e.g., only
workflow.completedfor workflowmorning-briefing) - Headers — custom headers added to every POST
- Retry policy — max attempts, backoff curve
Events
| Event | Fires when | Payload includes |
|---|---|---|
task.queued / .started / .completed / .failed | Any task transitions | Task ID, session, agent, status, duration |
approval.requested / .approved / .rejected / .timed_out | Approval lifecycle | Approval ID, tool, params, risk level, outcome |
workflow.created / .updated / .deleted / .run.started / .run.completed / .run.failed | Workflow lifecycle | Workflow ID, run ID, duration, error |
cron.fired / .failed | Cron execution | Job ID, fire time, duration, outcome |
document.uploaded / .deleted | Document lifecycle | Document ID, title, size, tags |
memory.written / .forgotten | Memory changes | Entry ID, content excerpt, scope |
discussion.started / .completed / .failed | Discussion lifecycle | Run ID, topic, verdict |
node.online / .offline / .command.executed | Sophon Node events | Node ID, command, result |
Retries
Failed outbound POSTs (non-2xx, or no response within timeout) retry with exponential backoff: 1 min, 5 min, 15 min, 1 h, then give up. After giving up, the delivery failure is logged and (optionally) the webhook auto-disables.
You can force a retry from the Dashboard delivery log, or disable auto-disable in per-webhook settings.
Outbound payload format
{
"event": "task.completed",
"timestamp": "2026-04-22T10:15:23.000Z",
"webhookId": "wh_abc123",
"deliveryId": "del_xyz789",
"data": {
"taskId": "task_def456",
"sessionId": "sess_...",
"agentId": "sophon",
"duration": 4321,
"tokensUsed": 1847,
"outcome": "completed"
}
}The deliveryId is unique per POST attempt; use it for deduplication on your end if you receive retries.
Testing
Dashboard → Settings → Webhooks → <webhook> → Test. Sends a synthetic event with sample data. Your receiver should respond 200 OK; Sophon shows the response status, headers, and body.
For inbound webhooks, the Test button shows the URL to POST to, a sample curl, and live logs of the last 20 incoming requests.
Delivery log
Every delivery attempt is logged:
- Delivery ID, event, attempt number
- Request URL, headers, body
- Response status, headers, body (truncated to 2 KB)
- Latency, error message if any
Dashboard → Settings → Webhooks → <webhook> → Deliveries. Filter by status (delivered / failed / pending). Retry failed deliveries one at a time or in bulk.
Retention: 30 days on Personal/Pro, configurable on Enterprise.
Security
- HMAC signing — always use secrets for inbound webhooks. Unsigned webhooks should be reserved for test-only slugs.
- TLS only — outbound webhooks require HTTPS except for
localhost(for dev). - SSRF guard — outbound URL targets are checked against the SSRF guard (blocks private networks, cloud metadata).
- Secret rotation — rotating a secret invalidates the old one immediately; update the external system to avoid failed signature checks.
CLI
sophon webhooks list
sophon webhooks show <id>
sophon webhooks test <id>
sophon webhooks deliveries <id>
sophon webhooks retry <delivery-id>
sophon webhooks rotate-secret <id>Limits and gotchas
- Outbound rate limit — max 100 deliveries/minute per Gateway. Over the limit, events queue and eventually drop (24 h buffer).
- Inbound body size — 5 MB max. Larger payloads return 413.
- Response timeout — outbound webhooks time out after 10 seconds waiting for response. Long-running handlers should ack immediately and process async.
- Filter regexes must be safe — no catastrophic backtracking. Sophon pre-validates.
Where to go next
- Workflows — webhook triggers in workflows
- Cron & Scheduled Jobs — cron-driven outbound webhooks
- Webhooks API Reference — full payload schemas per event