Webhooks are how Anton tells your system that something happened without you having to ask. A payout settles, a beneficiary is blocked, an RFI is raised — Anton signs a JSON event and POSTs it to an HTTPS URL you control. This guide covers the integrator’s end-to-end: how to subscribe, how to verify signatures, how to handle retries, and what patterns your receiver should follow.Documentation Index
Fetch the complete documentation index at: https://docs.antonpayments.com/llms.txt
Use this file to discover all available pages before exploring further.
When to use webhooks (vs polling)
Always use webhooks in production. Polling has three problems:- Wastes rate-limit budget —
GET /v1/payouts/{id}in a loop quickly hits the 1,000 req/min per-merchant ceiling. - Introduces latency — you learn about state changes on your polling interval, not when they happen.
- Misses intermediate transitions — by the time you poll, a payout may have already moved through two states.
Creating a subscription
- HTTPS —
http://is rejected in all non-development environments. - Publicly reachable — private IP ranges, loopback, and cloud metadata endpoints (e.g.
169.254.169.254) are rejected server-side.
id (wbh_...) and a one-time secret (whsec_...). Store the secret in your secrets manager immediately — Anton doesn’t retain the plaintext, and you cannot retrieve it later without calling GET /v1/webhooks/{id}/secret (which you can, but rotating is cleaner).
Use ["*"] as the events array to subscribe to everything.
Signing and verification
Every delivery carries HMAC-SHA256 headers:X-Webhook-Signature: v1={hex-hmac}X-Webhook-Timestamp: {unix-seconds}X-Webhook-ID: {event-id}— use for deduplicationX-Webhook-Event: {event-type}User-Agent: AntonPayments-Webhook/1.0
{timestamp}.{raw-body}. Verify every delivery in constant time.
See Webhook Signing for copy-paste verification code in bash, JavaScript, PHP, and Go. Treat unverified deliveries as untrusted HTTP requests — do not act on the payload until the signature checks out.
Delivery semantics
- At-least-once. Subscribers may occasionally receive the same event twice. Deduplicate on the envelope
id. - Ordering — events for the same resource dispatch in the order they occur, but network retries can re-order arrivals at your endpoint. Don’t assume order; reconcile state from the payload.
- Retries — failed deliveries retry with exponential backoff: 30s, 2m, 8m, 32m, hourly. Up to 5 total attempts. After 5 failures, the delivery is abandoned.
- Timeout — Anton waits up to 30 seconds for your
2xxresponse. Return 2xx fast and do heavy work asynchronously (enqueue, then respond). - Redirects — not followed. Your URL must respond directly.
2xx status code. Non-2xx responses (including 3xx) count as failure and trigger retries.
The events you probably want
Core payout lifecycle:payout.completed— funds deliveredpayout.failed— rail rejected or failed settlementpayout.returned— funds returned after sendpayout.screening_failed— sanctions or compliance blockpayout.velocity_blocked— velocity rule rejected
beneficiary.createdbeneficiary.updated— edit, PII update, archive, or restorebeneficiary.blocked— compliance action
rfi.created— Anton raised a Request for Informationscreening.hit— payout held pending screening review
fx.exchange.completed,fx.exchange.failed
funding.credit— deposit landed in your balance
Receiver patterns
A production-ready webhook receiver does four things in order:Enqueue fast
Read the raw body, enqueue it for async processing, return
200 immediately. Don’t block on database writes or downstream API calls inside the request handler — Anton’s 30-second timeout is generous but chains of dependent work can exceed it.Verify the signature
Before the enqueued worker trusts the payload, verify the signature using the stored secret. Reject anything older than 5 minutes (replay protection).
Deduplicate
Check the envelope
id against a recent-events store (Redis SET with TTL works). Skip if already seen. At-least-once delivery means this IS going to happen.Debugging delivery failures
GET /v1/webhooks/events/{id}/deliveries returns every delivery attempt Anton made for a given event — the exact request headers sent, your response status, response body (truncated), transport errors, duration, and retry schedule.
When a delivery is failing, this is where you look:
- Signature mismatch (400 from your endpoint) — you’re verifying against a parsed body instead of the raw bytes, or the secret rotated and you didn’t update.
- Connection timeout — your endpoint took longer than 30s to respond. Move work off the request path.
- 5xx from your endpoint — application error; look at your own logs.
- Certificate errors — your HTTPS cert is expired, self-signed, or mismatched to the hostname.
Testing without waiting for real events
Fire a synthetic delivery viaPOST /v1/webhooks/{id}/test:
test event to your subscription. Use it to validate connectivity, signature verification, and response handling before depending on real events in sandbox tests.
Secret rotation
When a secret might be compromised — or on a schedule — rotate it:Deactivation vs deletion
- Deactivate (
POST /v1/webhooks/{id}/deactivate) — stop delivering events. Subscription stays as a record; reactivation may be a supported future path. - Delete (
DELETE /v1/webhooks/{id}) — permanent. Event history remains for audit, but no new deliveries.
Next steps
Webhook event catalog
Every event type and its payload schema.
Webhook signing
Copy-paste HMAC verification in 4 languages.