Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.augustus.com/llms.txt

Use this file to discover all available pages before exploring further.

Overview

Webhooks deliver event notifications to your server as HTTP POST requests whenever something happens in your account, for example when a payout is created or a deposit is received. You can manage webhook subscriptions, inspect delivered events, and replay failed deliveries via the Augustus Dashboard, the REST API, or the SDK. See the Webhook Subscriptions, Webhook Deliveries, and Events resources in the API Reference for the full set of endpoints.

Events

Events follow the resource.action naming convention (e.g. payout.paid, deposit.received). The payload field in each delivery contains a full snapshot of the resource at the time of the event, matching the shape returned by the corresponding API endpoint. Augustus emits events for:
  • Payouts: when a payout is created, initiated, paid, or fails
  • Returns: when a return is initiated, paid, fails, or arrives back in your account
  • Deposits: when a deposit is received
  • Conversions: when a currency conversion is created, completes, or fails
See the Webhook Events section in the API Reference for the complete list of events and their payload schemas. A special ping.test event is only emitted by the test endpoint and does not reflect any real business activity; handlers should ignore it or use it to confirm their integration is wired up correctly.

Managing subscriptions

Webhook subscriptions are managed via the Augustus Dashboard or programmatically through the API. Each subscription has an HTTPS URL and a list of event types it receives.
curl -X POST https://api.augustus.com/v1/webhook_subscriptions \
  -H "Authorization: Bearer $AUGUSTUS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/webhooks/augustus",
    "events": ["payout.paid", "payout.failed", "deposit.received"]
  }'
Subscribe to ["*"] if you want to receive every event type, including any added in the future, without having to update your subscription. See the Webhook Subscriptions resource in the API Reference for the full set of endpoints.

Payload shape

All webhook deliveries use a consistent envelope. The example below shows a payout.paid delivery; other event types carry the same envelope but the payload shape matches the underlying resource.
{
  "id": "b7c8d9e0-f1a2-3b4c-5d6e-7f8a9b0c1d2e",
  "type": "payout.paid",
  "api_version": "2026-05-01",
  "payload": {
    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "type": "payout",
    "status": "paid",
    "amount": "100.00",
    "currency": "EUR",
    "reference": "INV-2026-001",
    "source_account_id": "01234567-89ab-cdef-0123-456789abcdef",
    "destination": {
      "type": "iban",
      "iban": "DE89370400440532013000",
      "bic": "COBADEFFXXX",
      "account_holder_name": "Jane Doe"
    },
    "failure": null,
    "metadata": {},
    "created_at": "2026-03-18T14:30:00Z",
    "updated_at": "2026-03-18T15:00:00Z"
  },
  "date": "2026-03-18T15:00:00.000Z"
}
id
string
required
Unique identifier for the event. Stable across retries of the same event. Use this to deduplicate.
type
string
required
Event type in resource.action format (e.g. payout.paid, deposit.received).
api_version
string
required
API version the payload was serialised at. Fixed when the event is created; stable across retries and redeliveries, even if your account’s pinned version changes in between. See Webhook versioning.
payload
object
required
Full resource snapshot at the time of the event. The shape matches what the API returns for the same resource.
date
string
required
ISO 8601 UTC timestamp when the event was created.
During an API version cut-over, branch on api_version to handle older and newer payload shapes side-by-side until all in-flight events drain:
switch (event.api_version) {
  case '2026-05-01':
    await handleCurrentVersion(event)
    break
  case '2026-08-01':
    await handleNextVersion(event)
    break
  default:
    await reportUnexpectedVersion(event)
}

Signature verification

Augustus signs webhooks using the Standard Webhooks specification. Every delivery includes three headers for replay protection and integrity verification:
HeaderDescription
webhook-idStable delivery identifier. Same as the envelope id. Use this to deduplicate retries.
webhook-timestampUnix timestamp (seconds) of the delivery attempt.
webhook-signatureOne or more v1,<base64_digest> HMAC-SHA256 signatures, space-separated. Two signatures appear during secret rotation.
The Augustus SDK handles signature verification and returns a typed event object. The unwrap method verifies the signature, then parses and returns the event. It throws an error if verification fails.
The body argument must be the raw request body string, not a parsed object. If you use a framework like Express with express.json(), you need to preserve the raw body for webhook routes. See the example below.
Express
import Augustus from '@augustusbank/typescript-sdk'
import express from 'express'

const client = new Augustus()
const app = express()

app.post('/webhooks', express.raw({ type: 'application/json' }), async (req, res) => {
  let event
  try {
    event = client.webhooks.unwrap(req.body.toString('utf-8'), { headers: req.headers })
  } catch (err) {
    return res.sendStatus(400)
  }

  switch (event.type) {
    case 'payout.paid':
      await fulfilPayout(event.payload.id)
      break
    case 'payout.failed':
      await markPayoutFailed(event.payload.id, event.payload.failure)
      break
    case 'ping.test':
      break
  }

  res.sendStatus(200)
})
The SDK reads the signing secret from the AUGUSTUS_WEBHOOK_KEY environment variable by default. You can also pass it explicitly via the key option on unwrap:
client.webhooks.unwrap(rawBody, {
  headers: req.headers,
  key: 'whsec_your_signing_secret',
})

Manual verification

If you are not using the SDK, verify signatures manually:
  1. Extract the webhook-id, webhook-timestamp, and webhook-signature headers
  2. Construct the signed content: {webhook-id}.{webhook-timestamp}.{raw_request_body}
  3. Compute HMAC-SHA256 using the base64-decoded key material from your signing secret (strip the whsec_ prefix, then base64-decode)
  4. Base64-encode the digest and compare with the v1, value(s) in the webhook-signature header
  5. Reject deliveries where the timestamp is older than 5 minutes
import { createHmac, timingSafeEqual } from 'crypto'

function verifyWebhook(
  body: string,
  headers: Record<string, string>,
  secret: string,
  toleranceSeconds = 300,
): boolean {
  const webhookId = headers['webhook-id']
  const timestamp = headers['webhook-timestamp']
  const signatures = headers['webhook-signature']

  if (!webhookId || !timestamp || !signatures) return false
  if (Math.abs(Date.now() / 1000 - Number(timestamp)) > toleranceSeconds) return false

  const keyMaterial = Buffer.from(secret.replace('whsec_', ''), 'base64')
  const toSign = `${webhookId}.${timestamp}.${body}`
  const expected = createHmac('sha256', keyMaterial).update(toSign, 'utf8').digest('base64')

  return signatures.split(' ').some((sig) => {
    const digest = sig.replace('v1,', '')
    return timingSafeEqual(Buffer.from(expected), Buffer.from(digest))
  })
}

Signing secrets

Your webhook signing secret is available in the Augustus Dashboard. Secrets follow the Standard Webhooks format with a whsec_ prefix followed by base64-encoded key material (e.g. whsec_dGhpcyBpcyBhbiBleGFtcGxl).
Treat the signing secret like a password. Do not expose it in client-side code or commit it to version control.

Secret rotation

You can rotate your webhook signing secret without downtime. During rotation, both the old and new secrets are active for 24 hours. The webhook-signature header includes signatures for both secrets during this window (space-separated), so your verification code should accept if any signature matches. At most two secrets are active at any time. If you use the SDK’s unwrap method, rotation is handled automatically.

Testing a subscription

To verify that your receiver is reachable and signature verification is correctly wired up, trigger a synthetic delivery to any subscription. Augustus dispatches a signed ping.test event through the real pipeline, using the same signing, headers, and retry schedule as a production event.
curl -X POST https://api.augustus.com/v1/webhook_subscriptions/b7c8d9e0-f1a2-3b4c-5d6e-7f8a9b0c1d2e/send_test_event \
  -H "Authorization: Bearer $AUGUSTUS_API_KEY"
Test deliveries behave like any other event with one exception: failures do not increment the subscription’s health counters or trigger failure-notification emails, so you can safely test against intentionally broken endpoints. The endpoint is rate-limited per merchant.

Inspecting events and deliveries

Every event Augustus sends you is recorded and queryable for 30 days via the API.
  • Events (GET /v1/events, GET /v1/events/:id) represent the facts that happened on your account. Each event has a stable id (the same id you receive in the webhook envelope) and the full payload snapshot.
curl "https://api.augustus.com/v1/events?event_type=payout.failed&created_at.gte=2026-03-01T00:00:00Z" \
  -H "Authorization: Bearer $AUGUSTUS_API_KEY"
  • Webhook Deliveries (GET /v1/webhook_deliveries, GET /v1/webhook_deliveries/:id) represent the individual delivery attempts against your subscriptions. One event can fan out to multiple deliveries if you have multiple matching subscriptions. Each delivery carries an attempts[] log with per-attempt status and HTTP status code returned by your receiver.
curl "https://api.augustus.com/v1/webhook_deliveries?status=failed&created_at.gte=2026-03-01T00:00:00Z" \
  -H "Authorization: Bearer $AUGUSTUS_API_KEY"
If a delivery failed or you want to replay it, trigger a fresh attempt with:
curl -X POST https://api.augustus.com/v1/webhook_deliveries/7e1d4f28-3b2a-4c5d-9e8f-1a2b3c4d5e6f/redeliver \
  -H "Authorization: Bearer $AUGUSTUS_API_KEY"
Redelivery creates a new delivery attempt against the same subscription using the same event payload and signing headers, so your receiver can treat it exactly like any other delivery and deduplicate via webhook-id.

Retry policy

Failed deliveries are retried with exponential backoff for up to 15 attempts total, spanning approximately 54 hours. Deliveries that fail all attempts are marked as permanently failed and can be inspected and replayed via the Webhook Deliveries API. Your endpoint should return a 2xx status code within 25 seconds to acknowledge receipt.

Event ordering

Event delivery order is not guaranteed. Your endpoint should handle out-of-order delivery gracefully and use the webhook-id header (or the envelope id field) to deduplicate retries.