Skip to main content

Overview

Webhooks push event notifications to your server in real time. Instead of polling the API to check payout status, you register a URL and Anton sends HTTP POST requests when events occur.

How webhooks work

1

Subscribe

Register a webhook URL and choose which events you want to receive.
2

Event occurs

When something happens (e.g., a payout completes), Anton creates an event.
3

Delivery

Anton sends an HTTP POST to your URL with the event payload as JSON. The request includes an X-Anton-Signature header for verification.
4

Acknowledge

Your server responds with a 2xx status code. If delivery fails, Anton retries with exponential backoff.

Event types

EventDescription
payout.createdA payout was created
payout.screeningPayout entered screening
payout.approvedPayout approved (maker-checker)
payout.processingPayout submitted to rail
payout.sentRail confirmed dispatch
payout.completedPayout delivered successfully
payout.failedPayout delivery failed
payout.returnedFunds returned
payout.cancelledPayout cancelled
payee.createdA payee was created
payee.updatedA payee was updated
payee.deletedA payee was deleted
batch.completedA batch finished processing
batch.failedA batch processing failed

Webhook payload

Every webhook delivery contains:
{
  "id": "evt_cng3q8s6ek9kc5qg1h3g",
  "type": "payout.completed",
  "created_at": "2026-02-14T10:30:00Z",
  "data": {
    "id": "pay_cng3q8s6ek9kc5qg1h2g",
    "status": "completed",
    "amount": "1000.00",
    "currency": "USD",
    "payee_id": "pye_cng3q8s6ek9kc5qg1h1g",
    "completed_at": "2026-02-14T10:30:00Z"
  }
}

Signature verification

Every webhook request includes an X-Anton-Signature header containing an HMAC-SHA256 signature of the raw request body. Always verify this signature before processing the payload to confirm the request came from Anton.

Obtaining your signing secret

Retrieve the signing secret for a webhook subscription:
curl https://api.antonpayments.dev/v1/webhooks/wh_abc123/secret \
  -H "Authorization: Bearer ak_test_..."
Response
{
  "data": {
    "secret": "whsec_a1b2c3d4e5f6..."
  }
}
Store the secret securely. You will use it to compute the expected signature for each incoming webhook request.

Verifying signatures

Compute the HMAC-SHA256 of the raw request body using your signing secret, then compare it to the value in the X-Anton-Signature header.
import crypto from 'crypto';
import express from 'express';

const app = express();

// Use raw body for signature verification
app.post('/webhooks/anton', express.raw({ type: 'application/json' }), (req, res) => {
  const signature = req.headers['x-anton-signature'];
  const secret = process.env.ANTON_WEBHOOK_SECRET;

  const expected = crypto
    .createHmac('sha256', secret)
    .update(req.body)
    .digest('hex');

  if (!crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) {
    return res.status(401).send('Invalid signature');
  }

  const event = JSON.parse(req.body);

  switch (event.type) {
    case 'payout.completed':
      // Handle completed payout
      break;
    case 'payout.failed':
      // Handle failed payout
      break;
  }

  res.status(200).send('OK');
});
Always use constant-time comparison when verifying signatures. Functions like crypto.timingSafeEqual (Node.js), hmac.compare_digest (Python), and hmac.Equal (Go) prevent timing attacks. Never use == or === for signature comparison.

Retry policy

If your endpoint doesn’t return a 2xx response, Anton retries with exponential backoff:
AttemptDelay
1Immediately
21 minute
35 minutes
430 minutes
52 hours
68 hours
After all retries are exhausted, the delivery is marked as failed. You can view failed deliveries and manually retry them through the dashboard.

Best practices

Process webhook payloads asynchronously. Return a 200 response immediately, then handle the event in a background job. This prevents timeouts and ensures reliable delivery.
Use the event id field to deduplicate. In rare cases, Anton may deliver the same event more than once. Your handler should be idempotent.
Always verify the X-Anton-Signature header before acting on a webhook payload. Never trust unverified requests.