Webhooks
Webhooks Overview
Emofy delivers HTTP webhooks to subscribed URLs when domain events fire. At-least-once delivery, Stripe-compatible signing, idempotency via delivery ID.
Webhooks
Emofy delivers HTTP POST notifications to your URL whenever a subscribed
event fires in an organization that installed your app.
Delivery semantics
- At-least-once. Your receiver must be idempotent. Deduplicate on
X-Emofy-Delivery-Id— never on the payload alone. - 5-attempt exponential retry for 5xx / timeout responses (AC-6). After
the final attempt, the delivery is marked
dead_lettered. - 10-second request timeout. Return
2xxfast. Offload slow work to your own job queue. - Per-URL concurrency cap. Emofy sends at most 3 deliveries in flight per receiver URL so one slow integration can't starve the platform's worker pool.
- Auto-pause kicks in after 20 consecutive 5xx / timeout failures (checked against the last 50 deliveries within 15 min). You re-enable from the developer portal once your receiver is healthy again.
Envelope
Request body is always JSON:
{
"event": "app.installed",
"timestamp": 1740000000000,
"deliveryId": "whd_...",
"eventId": "wob_...",
"apiVersion": "v1",
"data": {
"orgId": "org_...",
"appId": "app_...",
"installedBy": "usr_...",
"installedAt": "2026-04-21T10:00:00.000Z"
}
}Request headers
| Header | Meaning |
|---|---|
Content-Type | Always application/json |
Emofy-Signature | HMAC-SHA256 envelope — see Signature Verification |
X-Emofy-Delivery-Id | whd_* — use this as your idempotency key |
X-Emofy-Event-Type | e.g. app.installed |
X-Emofy-Webhook-Id | The subscription id, apw_* or whk_* |
X-Webhook-Signature | Legacy signature (T+0→T+30d only). See Signature Verification |
X-Webhook-Timestamp | Legacy timestamp pair for the legacy signature |
Quick checklist for your receiver
- Return
2xxonly after you've durably recorded the delivery id. - Verify
Emofy-Signature— reject requests with invalid or expired signatures (see Signature Verification). - Check
Math.abs(Date.now() - t) < 5 * 60 * 1000to reject replays. - Use
X-Emofy-Delivery-Idas the primary key in your ingest log — duplicate deliveries are part of the contract, not a bug.
Related
- Signature Verification — Node / Python / curl snippets
- Retries & Replay — dead-letter handling + manual replay
- Event Reference — the curated 10 events developer apps can subscribe to