Webhooks
Receive real-time HTTP notifications the moment a card transaction is approved, declined, settled, or fails. Webhooks let your systems react to events as they happen — no polling required.
When to use webhooks
- Update your ledger or accounting system the instant a card is used
- Run fraud, velocity, or budget checks on approved authorizations
- Notify cardholders or finance teams of activity in near real time
- Reconcile settled transactions against your internal records
If you only need batch reporting, polling POST /v1/cards/transactions with "source": "cards" may be simpler.
What you will build
A complete Jeeves webhook integration has five moving parts:
- An HTTPS receiver endpoint on your infrastructure that accepts
POSTrequests with a JSON body and returns2xxwithin 10 seconds. - A signature verifier that recomputes the HMAC-SHA256 of the raw request body and compares it against the
X-Webhook-Signatureheader. - An idempotency layer that deduplicates events by
X-Webhook-Event-Id. Delivery is at-least-once — the same event will occasionally arrive more than once. - An asynchronous worker that performs business logic in the background so your endpoint can acknowledge fast.
- One or more webhook subscriptions created via the API, each pointing at your endpoint and listing the event types it cares about.
Architecture at a glance
Jeeves event → Webhook Delivery Service → POST your endpoint
↓
[1] verify HMAC-SHA256 signature
↓
[2] enqueue (SQS / Kafka / Pub/Sub)
↓
[3] respond 200 OK
↓
── background worker ──
↓
[4] dedupe by event_id (unique index)
↓
[5] apply business logicQuick start
1. Expose an HTTPS endpoint
Your endpoint must be publicly reachable over HTTPS with a CA-signed certificate, accept POST application/json, and respond 2xx within the configured timeout (default 10 s, max 30 s).
2. Create a subscription
POST /v1/webhooks/subscriptions
{
"url": "https://your-app.com/webhooks/jeeves",
"eventTypes": ["transaction.auth.approved", "transaction.auth.declined"],
"developerEmail": "dev@your-company.com"
}Warning — Store the secret immediately
The response includes a
secretfield starting withwhsec_. This is the only time it is returned in plaintext. Store it immediately in a secrets manager.
3. Verify the signature and handle the event
Recompute the HMAC-SHA256 of the raw request body using your subscription secret, then compare it (constant-time) with the X-Webhook-Signature header. See Verifying signatures.
4. Send a test delivery
POST /v1/webhooks/subscriptions/{id}/testThe synchronous response includes the HTTP status and latency from your endpoint. Iterate until your endpoint reliably returns 2xx.
Event types
| Event type | When it fires |
|---|---|
transaction.auth.approved | A card authorization was approved |
transaction.auth.declined | A card authorization was declined |
transaction.settled | A card transaction was settled (posted to account) |
transaction.failed | A card transaction failed after the authorization stage |
Typical event sequences
| Scenario | Events in order |
|---|---|
| Normal purchase | transaction.auth.approved → transaction.settled |
| Declined purchase | transaction.auth.declined |
| Reversed / voided | transaction.auth.approved → transaction.failed |
| Force post (no prior auth) | transaction.settled only |
Note
A single purchase may emit several events over hours or days. Key off both the event type and
relatedTransactionId— never assume a one-to-one mapping between authorizations and settlements.