Webhooks

Ante POSTs JSON to your HTTPS URL when a group's state changes. Verify Ante-Signature on the raw body before you mark an order paid or ship goods.

Copy this page as a setup prompt for your coding assistant.

Two ways to receive events

SourceSecret for verificationTypical use
Dashboard endpointwhsec_… (shown once when you register the URL)One stable URL, event filters, delivery log in portal
Per-session webhook_urlMerchant signing secret (ante_sign_…, same as cart signing)Different URL per order; set on session create from SDK or REST

Register dashboard URLs at Merchants → Webhooks. Pass webhook_url on session create for per-order delivery. Both can fire for the same event if URLs overlap.

Envelope

Every delivery uses this shape. Parse type and act on data.

JSON
{
  "id": "evt_1719234567890",
  "type": "group.funded",
  "created_at": "2025-06-24T14:30:00.000Z",
  "data": { }
}

Event types and payloads

group.created

Session exists; organizer opened the group. Useful for analytics or holding inventory lightly.

data
{
  "session_id": "j57…",
  "group_id": "j57…",
  "order_ref": "ORD-1042",
  "expiry_at": "2025-06-25T14:30:00.000Z"
}

group.funded

Every share is paid. Ante started merchant payout. Use this to fulfill. transfer_id is the Stripe transfer when available (none in sandbox). When checkout currency differs from your preferred payout currency, FX fields are included — see Currencies & payouts → Important limitations and webhook fields.

data
{
  "session_id": "j57…",
  "group_id": "j57…",
  "transfer_id": "tr_…",
  "total": 12000,
  "merchant_fee": 241,
  "order_ref": "ORD-1042",
  "checkout_currency": "eur",
  "payout_currency_preference": "usd",
  "fx_fee_cents": 196,
  "merchant_transfer_cents": 9603
}

group.expired

Funding window closed with balance outstanding. Paid shares are refunded.

data
{
  "session_id": "j57…",
  "group_id": "j57…",
  "order_ref": "ORD-1042",
  "refunded": true,
  "reason": "expired"
}

group.cancelled

Merchant cancelled via API or dashboard flow. Refunds when shares were already paid.

data
{
  "session_id": "j57…",
  "group_id": "j57…",
  "refunded": true,
  "cancelled_by": "merchant"
}

Verify Ante-Signature

Header example: Ante-Signature: t=1719234567,v1=abc123…. t is Unix seconds. v1 is HMAC-SHA256 hex of {t}.{rawRequestBody} using your endpoint secret. Reject if timestamp is more than 300 seconds from your server clock.

Node.js
import { verifyWebhookSignature } from "@splitante/sdk/signing";

export async function POST(req: Request) {
  const rawBody = await req.text();
  const header = req.headers.get("ante-signature") ?? "";
  const secret = process.env.ANTE_WEBHOOK_SECRET!; // whsec_… or signing secret

  if (!verifyWebhookSignature(rawBody, secret, header)) {
    return new Response("Invalid signature", { status: 401 });
  }

  const event = JSON.parse(rawBody);
  if (event.type === "group.funded") {
    await fulfillOrder(event.data.order_ref, event.data.session_id);
  }
  return Response.json({ received: true });
}

Handler timing

Return 2xx within 30 seconds. Queue heavy work after the response. Non-2xx and timeouts trigger retries.

Retries

Up to 12 attempts. Delays after failure (approximate):

AttemptWait before retry
1immediate
230s
31m
42m
55m
610m
730m
81h
92h
103h
114h
125h

Status per delivery: Webhooks → Recent deliveries.

Test

Use "Send test" on a registered endpoint, or complete a sandbox checkout and pay every share. Local dev needs a public HTTPS URL (tunnel). Ante does not call localhost directly.

Register via API: REST API. Keys: Security.