Webhooks: Send Cogny Events to Slack, Zapier or Your Own Server
Configure an outbound webhook, pick from eight events, verify the X-Cogny-Signature header and handle retries. Included on Cogny Cloud and AppSumo Tier 3 and Tier 4.
Cogny pushes events to an https URL you choose, the moment they happen. Use it to post loop results and alerts into Slack, start a Zapier or Make flow, or feed your own systems — without polling and without asking the AI for an update.
Which plans include webhooks
| Plan | Webhooks |
|---|---|
| Cogny Cloud | Included |
| AppSumo Tier 3 and Tier 4 | Included |
| Free, Solo, Cogny AI, Cogny Pro, AppSumo Tier 1 and Tier 2 | Not included |
On plans without webhooks the Settings tab is hidden and the API returns 403 with the plan that would include them. If a workspace moves to a plan without webhooks, its endpoints are kept but nothing is sent until it moves back.
Events
| Event | Fires when |
|---|---|
report.completed | A scheduled report or audit finishes. |
alert.triggered | A budget-pacing or metric-target alert crosses its threshold. |
alert.resolved | That alert returns to normal. |
ticket.created | Cogny files a new recommendation. |
ticket.status_changed | A recommendation moves on the board. |
campaign.updated | An agent writes a change to a connected platform — one event per write. |
loop_run.completed | A loop run has been evaluated: outcome, summary, measured metrics and estimated USD impact. |
task.shipped | An agent published something on a connected platform: a campaign, ad, post, page or site. |
Subscribe to specific events, or to * for every event including ones added later. The full machine-readable contract — every event's data schema, the signature scheme and the retry schedule — is at /api/webhook-events with no authentication.
The envelope
{
"id": "5f8b1c2e-…",
"event": "loop_run.completed",
"created_at": "2026-10-02T08:14:22.104Z",
"warehouse_id": "9c1e…",
"text": "🟢 Loop \"Pause losing ads\" run: success (est. impact $420). → https://app.cogny.com/warehouse/9c1e…/tickets?ticket=…",
"data": {
"loop": { "id": "…", "name": "Pause losing ads", "url": "https://app.cogny.com/warehouse/9c1e…/scheduled-prompts/…" },
"run": { "id": "…", "ticket_id": "…", "run_at": "…", "outcome": "success", "summary": "…", "url": "…" },
"impact": { "usd": 420, "metrics": { "cpa_change_pct": -12 } },
"workspace": { "id": "9c1e…", "url": "https://app.cogny.com/warehouse/9c1e…" }
}
}
textis a one-line summary with a link. A Slack incoming webhook posts it as the message, so Slack needs no relay.datais event-specific. Every variant has aworkspaceobject and a deep link to the thing that happened.
Verifying the signature
Each request carries:
X-Cogny-Signature: t=1800000000,v1=<hex hmac-sha256>
X-Cogny-Event: loop_run.completed
X-Cogny-Delivery: 5f8b1c2e-…
X-Cogny-Webhook-Id: 7a3d…
The signed message is ${t}.${rawBody}, keyed with the endpoint's signing secret. Verify against the raw body before parsing JSON, compare in constant time, and reject a t more than 300 seconds from now.
import { createHmac, timingSafeEqual } from 'crypto';
export function verifyCogny(rawBody, header, secret) {
const parts = Object.fromEntries(header.split(',').map((p) => p.split('=', 2)));
const t = Number(parts.t);
if (!Number.isFinite(t) || Math.abs(Date.now() / 1000 - t) > 300) return false;
const expected = Buffer.from(createHmac('sha256', secret).update(`${t}.${rawBody}`).digest('hex'));
const given = Buffer.from(parts.v1 ?? '');
return expected.length === given.length && timingSafeEqual(expected, given);
}
Responses and retries
- Any
2xxis success. Respond quickly and do your work afterwards. 410 Gonedisables the endpoint.- Anything else, or no response within 10 seconds, is retried after about 1 minute, 5 minutes, 30 minutes, 2 hours, 6 hours and 12 hours — seven attempts over roughly 20 hours.
- After 20 consecutive failed deliveries the endpoint is disabled, with the reason shown in Settings. Re-enabling it clears the count.
Every attempt is listed in the endpoint's delivery log with the status code your server returned.
Endpoint requirements
Targets must be public https URLs. Plain http, credentials in the URL, private and reserved addresses and internal hostnames are rejected, and redirects are not followed. If your receiver is on a private network, put a public relay in front of it.
Not covered in this version
- No built-in email or CRM connectors. For HubSpot, Salesforce, Klaviyo or email, point the endpoint at a Zapier or Make catch hook and map the fields there.
- No per-event payload customisation. Every subscriber of an event receives the same body.
task.shippeddoesn't include impact yet. Impact is measured days later and shows on the workspace's Tasks board;loop_run.completedis where measured impact arrives for loops.
Managing endpoints over the API
/api/warehouse/{warehouseId}/webhooks (GET, POST), /{webhookId} (PATCH, DELETE) and /{webhookId}/test (POST). Bearer auth with a workspace owner or admin session.
Reading this with an AI agent? Fetch the raw markdown at /docs/webhooks/index.md or see llms.txt.