{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-guides/sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":[]},"type":"markdown"},"seo":{"title":"Webhooks","description":"Start today using our public API to power your next project."},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"webhooks"},"children":["Webhooks"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["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."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"when-to-use-webhooks"},"children":["When to use webhooks"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Update your ledger or accounting system the instant a card is used"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Run fraud, velocity, or budget checks on approved authorizations"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Notify cardholders or finance teams of activity in near real time"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Reconcile settled transactions against your internal records"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If you only need batch reporting, polling ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST /v1/cards/transactions"]}," with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["\"source\": \"cards\""]}," may be simpler."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"what-you-will-build"},"children":["What you will build"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["A complete Jeeves webhook integration has five moving parts:"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["An ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["HTTPS receiver endpoint"]}," on your infrastructure that accepts ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST"]}," requests with a JSON body and returns ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["2xx"]}," within 10 seconds."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["A ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["signature verifier"]}," that recomputes the HMAC-SHA256 of the raw request body and compares it against the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["X-Webhook-Signature"]}," header."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["An ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["idempotency layer"]}," that deduplicates events by ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["X-Webhook-Event-Id"]},". Delivery is at-least-once — the same event will occasionally arrive more than once."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["An ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["asynchronous worker"]}," that performs business logic in the background so your endpoint can acknowledge fast."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["One or more ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["webhook subscriptions"]}," created via the API, each pointing at your endpoint and listing the event types it cares about."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"architecture-at-a-glance"},"children":["Architecture at a glance"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"Jeeves event → Webhook Delivery Service → POST your endpoint\n                                                ↓\n                          [1] verify HMAC-SHA256 signature\n                                                ↓\n                          [2] enqueue (SQS / Kafka / Pub/Sub)\n                                                ↓\n                          [3] respond 200 OK\n                                                ↓\n                              ── background worker ──\n                                                ↓\n                          [4] dedupe by event_id (unique index)\n                                                ↓\n                          [5] apply business logic\n"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"quick-start"},"children":["Quick start"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"1.-expose-an-https-endpoint"},"children":["1. Expose an HTTPS endpoint"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Your endpoint must be publicly reachable over HTTPS with a CA-signed certificate, accept ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST application/json"]},", and respond ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["2xx"]}," within the configured timeout (default 10 s, max 30 s)."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"2.-create-a-subscription"},"children":["2. Create a subscription"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"POST /v1/webhooks/subscriptions\n{\n  \"url\":            \"https://your-app.com/webhooks/jeeves\",\n  \"eventTypes\":     [\"transaction.auth.approved\", \"transaction.auth.declined\"],\n  \"developerEmail\": \"dev@your-company.com\"\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"blockquote","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Warning — Store the secret immediately"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The response includes a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["secret"]}," field starting with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["whsec_"]},". ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["This is the only time it is returned in plaintext."]}," Store it immediately in a secrets manager."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"3.-verify-the-signature-and-handle-the-event"},"children":["3. Verify the signature and handle the event"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Recompute the HMAC-SHA256 of the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["raw"]}," request body using your subscription secret, then compare it (constant-time) with the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["X-Webhook-Signature"]}," header. See ",{"$$mdtype":"Tag","name":"a","attributes":{"href":"/guides/integration-guides/webhooks/signatures"},"children":["Verifying signatures"]},"."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"4.-send-a-test-delivery"},"children":["4. Send a test delivery"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"POST /v1/webhooks/subscriptions/{id}/test\n"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The synchronous response includes the HTTP status and latency from your endpoint. Iterate until your endpoint reliably returns ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["2xx"]},"."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"event-types"},"children":["Event types"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Event type"},"children":["Event type"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"When it fires"},"children":["When it fires"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["transaction.auth.approved"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["A card authorization was approved"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["transaction.auth.declined"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["A card authorization was declined"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["transaction.settled"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["A card transaction was settled (posted to account)"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["transaction.failed"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["A card transaction failed after the authorization stage"]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"typical-event-sequences"},"children":["Typical event sequences"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Scenario"},"children":["Scenario"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Events in order"},"children":["Events in order"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Normal purchase"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["transaction.auth.approved"]}," → ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["transaction.settled"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Declined purchase"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["transaction.auth.declined"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Reversed / voided"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["transaction.auth.approved"]}," → ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["transaction.failed"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Force post (no prior auth)"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["transaction.settled"]}," only"]}]}]}]}]},{"$$mdtype":"Tag","name":"blockquote","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Note"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["A single purchase may emit several events over hours or days. Key off both the event type and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["relatedTransactionId"]}," — never assume a one-to-one mapping between authorizations and settlements."]}]}]},"headings":[{"value":"Webhooks","id":"webhooks","depth":1},{"value":"When to use webhooks","id":"when-to-use-webhooks","depth":2},{"value":"What you will build","id":"what-you-will-build","depth":2},{"value":"Architecture at a glance","id":"architecture-at-a-glance","depth":2},{"value":"Quick start","id":"quick-start","depth":2},{"value":"1. Expose an HTTPS endpoint","id":"1.-expose-an-https-endpoint","depth":3},{"value":"2. Create a subscription","id":"2.-create-a-subscription","depth":3},{"value":"3. Verify the signature and handle the event","id":"3.-verify-the-signature-and-handle-the-event","depth":3},{"value":"4. Send a test delivery","id":"4.-send-a-test-delivery","depth":3},{"value":"Event types","id":"event-types","depth":2},{"value":"Typical event sequences","id":"typical-event-sequences","depth":2}],"frontmatter":{"seo":{"title":"Webhooks"}},"lastModified":"2026-06-15T18:50:49.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/guides/integration-guides/webhooks","userData":{"isAuthenticated":false,"teams":["anonymous"]}}