Skip to main content

Webhooks

Subscribe to real-time events like incoming emails, delivery failures, and completed calls.

Configuration

Configure webhooks in the dashboard, via the API, the CLI, the webhook_set MCP tool, or any SDK. Each delivery is a JSON POST to your endpoint:

Event Types

Event NameDescription
message.receivedTriggered when an agent receives a new email or SMS.
message.sentTriggered when a message is successfully sent.
message.failedTriggered when a message fails to send or bounces.
agent.createdTriggered when a new agent mailbox is created.
call.endedTriggered when a voice call completes.
The full, current list is available from GET /webhooks/event-types.

Signing secret

When you create a webhook, the API returns a secret once, in the create response. Store it securely — read endpoints (GET /webhooks and GET /webhooks/{id}) never return it again. If you lose it, rotate it:
Rotating immediately invalidates the previous secret.

Verifying deliveries

Every delivery carries a signature and a timestamp so you can confirm it came from Anima and reject replays:
HeaderDescription
X-Anima-Signaturev1=<hex> — HMAC-SHA256 of {timestamp}.{rawBody}, keyed by your signing secret.
X-Anima-TimestampISO-8601 time the delivery was signed; bound into the signature.
X-Anima-EventThe event name (e.g. message.received).
X-Anima-Delivery-IdStable id for this delivery, unchanged across retries.
Recompute the HMAC over {timestamp}.{rawBody}, compare it in constant time, and reject deliveries whose timestamp falls outside a tolerance window (for example, 5 minutes). The timestamp is part of the signed content specifically so you can stop replays.
Verify against the raw request body, before any JSON parse or re-serialize — re-encoding can change bytes and break the signature.

Advanced settings

The X-Anima-Signature HMAC already proves a delivery came from Anima. On top of it, you can have Anima present a credential your endpoint checks, and control how fast it delivers.

Endpoint authentication

Handy when your gateway expects a header rather than a signature. This is in addition to the HMAC.
TypeWhat Anima sends
bearerAuthorization: Bearer <token>
basicAuthorization: Basic <base64(username:password)>
custom_headerA header you name, e.g. X-My-Secret: <value>
The credential is write-only — set on create or update, never returned by a read, encrypted at rest.

Delivery throttling and retries

  • rateLimitPerMinute — cap deliveries per minute to a single endpoint. Over-limit deliveries defer to the next window rather than dropping.
  • maxAttempts — max delivery attempts before dead-lettering (default 3). Retries use exponential backoff, and an endpoint that keeps failing is auto-disabled.
Set these when you create or update a webhook — via the API, the webhook_set MCP tool, the CLI, or any SDK:
The other schemes work the same way: basic (username + password) and custom_header (a header name + value) — in the SDKs, WebhookAuthBasic / WebhookAuthCustomHeader (Python), the matching { type: "basic", … } union member (TypeScript), or anima.NewBasicAuth / anima.NewCustomHeaderAuth (Go). Pass {"type":"none"} on update to remove authentication.