Webhooks
Webhooks let Infinite Audience tell your application when asynchronous work is ready. Your workflow moves on immediately—no polling loop required.
| Event | Use it when |
|---|---|
segment.ready |
A file match or segment build completed |
segment.failed |
A file match or segment build needs attention |
delivery.completed |
An export or destination delivery completed |
delivery.failed |
A delivery needs attention |
Choose where events go
Section titled “Choose where events go”- Add
webhook_urlto one request for a one-off callback. - Set an organization URL with
PUT /v1/settings/webhookfor a shared default. - Create a durable subscription when an app should receive selected event types across the account.
Create a subscription
Section titled “Create a subscription”curl -X POST https://api.infiniteaudience.ai/v1/webhook-subscriptions \ -H "Authorization: Bearer $ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "target_url":"https://your-app.example.com/webhooks/infinite-audience", "events":["segment.ready","segment.failed","delivery.completed","delivery.failed"] }'Copy the returned secret into your secret manager when it appears. Like an API key, its plaintext is shown once.
Receive the event
Section titled “Receive the event”Every event uses a consistent envelope:
{ "id": "evt_1a2b3c", "type": "segment.ready", "created_at": "2026-08-26T18:04:12.000Z", "api_version": "2026-08-06", "org_id": "org_xyz", "subject": {"kind":"segment","id":"seg_abc123","name":"Spring customers"}, "data": {"status":"completed","match_count":1200000}, "links": {}}Use type to route the event, subject to identify the work, and data for the event-specific result. Treat additional fields as compatible additions.
Verify the signature
Section titled “Verify the signature”Each request includes X-IA-Timestamp and X-IA-Signature. Compute HMAC-SHA256(secret, "{timestamp}.{raw_body}"), prefix the hex digest with v1=, compare in constant time, and reject timestamps older than five minutes.
import { createHmac, timingSafeEqual } from 'crypto';
export function verify(rawBody: Buffer, timestamp: string, signature: string, secret: string) { const age = Math.abs(Math.floor(Date.now() / 1000) - Number(timestamp)); if (!Number.isFinite(age) || age > 300) return false; const expected = Buffer.from(`v1=${createHmac('sha256', secret).update(`${timestamp}.${rawBody}`).digest('hex')}`); const received = Buffer.from(signature); return expected.length === received.length && timingSafeEqual(expected, received);}Check your implementation
Section titled “Check your implementation”Use this fixed test vector to confirm that your HMAC code produces the same signature before you connect a live endpoint:
Secret: whsec_testTimestamp: 1700000000Raw body: {"id":"evt_test","type":"segment.ready"}Expected signature: v1=665cf5f9d7444181e6ea95771d98ec6865abff200494207281ce9e3041e7b35bThe timestamp is intentionally fixed for repeatable testing, so test the signature calculation separately from your five-minute freshness check.
Return a 2xx response quickly, then queue slower work. Infinite Audience retries timeouts, 408, 429, and 5xx responses up to 10 total attempts; 410 Gone ends delivery for that endpoint.
