GIFQ can send webhooks so your systems learn about payout progress without polling. This reference covers the events, how to configure them, how to verify signatures, and how delivery and retries behave.
Scope: webhooks currently fire for crypto payouts only. There is no webhook for gift-card order completion today — to track gift-card orders, poll GET /api/orders/:id until it reaches a terminal state.
Configuring webhooks
Webhooks are configured per payout order, not globally and not in a dashboard. Pass a callback_url (HTTPS, validated) when you call POST /api/payout-orders. Omit it and that order sends no webhooks.
Events
payout.status_changed— a recipient transitions into a non-terminal status (e.g.in_progress,processing).payout.terminal_state— a recipient transitions into a terminal status (completed,failed,expired,canceled). This replacesstatus_changedfor that transition — the two are mutually exclusive.payout.quote_created— the recipient creates a crypto quote.payout.quote_confirmed— the recipient confirms a quote (fires only on a real cross-currency confirmation).payout.quote_canceled— the recipient cancels a quote.
One event equals one POST per recipient transition. A payout order with N recipients produces up to N events as each recipient progresses.
Payload
Each delivery is a POST to your callback_url with these headers and a JSON body:
X-Gifq-Event— the event name (e.g.payout.terminal_state).X-Gifq-Signature—sha256=<hex>signature (see below).X-Gifq-Delivery— a fresh UUID per delivery attempt.X-Gifq-Timestamp— unix epoch seconds when the delivery attempt was sent.
Example terminal-state body:
{ "event": "payout.terminal_state", "payout_order_uuid": "...", "recipient_email": "[email protected]", "external_send_id": "cg-send-42", "status": "completed", "updated_at": "2026-05-14T15:01:23Z", "payout_type": "crypto", "tx_hash": "0xabc123...", "data": { }}
Verifying the signature
The signature is an HMAC-SHA256 over the raw request body, keyed with your company webhook secret, and should be compared in constant time. The secret is per-company, shared with you out-of-band during onboarding, and is not exposed via the API. Always verify the signature before trusting a payload.
Delivery, retries, and dedupe
Retries: up to 8 attempts with increasing backoff. GIFQ retries on transport errors and on merchant
5xxresponses.Permanent failure: a merchant
4xxis treated as non-retryable and discarded immediately (it will never succeed on retry).Timeouts: 5s to open the connection, 10s to read.
At-least-once delivery: a sweeper re-enqueues any delivery that was lost in transit, so the same event can arrive more than once. Deduplicate on
X-Gifq-Delivery(and/or the payout identifier + status) on your side.Respond
2xxquickly to acknowledge; do heavy processing asynchronously.
Endpoint requirements
Must be HTTPS and publicly reachable.
Should return
2xxon success; return5xxif you want GIFQ to retry.Should verify the HMAC signature on every request.
