{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-contents/api/sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":[]},"type":"markdown"},"seo":{"title":"Webhooks","description":"Explore our documentation and API and start integrating Kustom Checkout","llmstxt":{"hide":false,"sections":[{"title":"Table of contents","includeFiles":["**/*"],"excludeFiles":[]}],"excludeFiles":[]}},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"webhooks","__idx":0},"children":["Webhooks"]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"overview","__idx":1},"children":["Overview"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Kustoms Webhooks allow you to receive real-time notifications when events occur in our system. Instead of polling the API, you configure an endpoint and Kustom will send an HTTP ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST"]}," request to that URL whenever a subscribed event occurs. We're planning to add additional delivery mechanisms as well at a later point."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Webhook payloads are intentionally slim. They contain just enough information to identify that something has happened. To get the most up to date information, use the included identifiers to fetch the full object from the relevant API endpoint."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"getting-started","__idx":2},"children":["Getting Started"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"1-set-up-your-endpoint","__idx":3},"children":["1. Set up your endpoint"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Create an HTTPS endpoint on your server that:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Accepts ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST"]}," requests"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Returns a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["2xx"]}," HTTP status code to acknowledge receipt"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Responds within a reasonable timeout"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If your endpoint does not return a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["2xx"]}," response, Kustom will retry delivery (see Retries)."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"2-register-your-endpoint","__idx":4},"children":["2. Register your endpoint"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Configure your webhook destination in the Kustom Portal under Settings → Webhooks. There you can decide what HTTPS endpoint to use and which events to listen to."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"3-verify-the-webhook-signature","__idx":5},"children":["3. Verify the webhook signature"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Every webhook request includes signature headers so you can verify the payload originated from Kustom. See Security & Signature Verification below."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"event-types","__idx":6},"children":["Event Types"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The following event types are supported:"]},{"$$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":"Description"},"children":["Description"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["dispute.created"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["A new dispute has been opened on an order."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["dispute.updated"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["An existing dispute has been updated (e.g. status change)."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["order.created"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["A new order has been created."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["capture.created"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["A capture has been made on an order."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["refund.created"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["A refund has been issued on an order."]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"payload-format","__idx":7},"children":["Payload Format"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["All webhook payloads follow a consistent structure:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n    \"id\": \"kevt_1YcaJdWrmlw9yp1GiiVgad\",\n    \"merchant_id\": \"DM11917000\",\n    \"timestamp\": \"2026-04-10T08:27:07.248645321Z\",\n    \"type\": \"capture.created\",\n    \"data\": {\n        \"order_id\": \"25ed76ed-6477-46bb-8444-63945789ccfb\",\n        \"capture_id\": \"070ddfa9-f7a8-4fb0-8291-b5b31a300a23\",\n        \"created_at\": \"2026-04-10T08:27:02.648627Z\"\n    }\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Fields:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["id"]}," — A unique ID for this event. Stable across retries — use this for idempotency."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["merchant_id"]}," — Your Kustom Merchant ID (MID)."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["type"]}," — The type of event that occurred."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["timestamp"]}," — ISO 8601 timestamp of when the event was generated."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Additional fields vary by event type (e.g. ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["order_id"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["dispute_id"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["status"]},")."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["To retrieve the full object, use the relevant API endpoint with the provided identifier."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"security--signature-verification","__idx":8},"children":["Security & Signature Verification"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Kustom signs every webhook payload so you can confirm it was sent by Kustom and has not been tampered with. We follow the ",{"$$mdtype":"Tag","name":"a","attributes":{"href":"https://www.standardwebhooks.com/"},"children":["Standard Webhooks"]}," specification."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"signature-headers","__idx":9},"children":["Signature headers"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Every webhook request includes three headers:"]},{"$$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":"Header"},"children":["Header"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Description"},"children":["Description"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["webhook-id"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["A unique message ID. Identical across retry attempts — use for deduplication."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["webhook-timestamp"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Unix timestamp (seconds) of when the message was sent."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["webhook-signature"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["One or more HMAC-SHA256 signatures, space-delimited (for key rotation support)."]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"your-signing-secret","__idx":10},"children":["Your signing secret"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["When you configure a webhook destination, Kustom generates a shared signing secret in the format:"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["whsec_<base64-encoded-secret>"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["You can retrieve and rotate this secret via the Portal."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["More information and best practices on verifying the signature can be found in ",{"$$mdtype":"Tag","name":"a","attributes":{"href":"https://github.com/standard-webhooks/standard-webhooks/blob/main/spec/standard-webhooks.md"},"children":["Standard Webhooks documentation."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"rotating-your-signing-secret","__idx":11},"children":["Rotating your signing secret"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["You can rotate your signing secret at any time via the Portal. The rotation can take up to 10 mins to as it's reliant on caching. During a rotation period, Kustom will sign with both the old and new secrets (space-delimited in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["webhook-signature"]},"). Once you have updated your code to use the new secret, you can retire the old one."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"retries","__idx":12},"children":["Retries"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If your endpoint does not respond with a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["2xx"]}," status code, or times out, Kustom will retry delivery automatically using an exponential backoff strategy. Retries continue for up to 3 days."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Because events may be delivered more than once (e.g. during retries), your endpoint should be idempotent. Use the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["id"]}," (or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["webhook-id"]}," header) to detect and safely discard duplicate deliveries."]}]},"headings":[{"value":"Webhooks","id":"webhooks","depth":1},{"value":"Overview","id":"overview","depth":2},{"value":"Getting Started","id":"getting-started","depth":3},{"value":"1. Set up your endpoint","id":"1-set-up-your-endpoint","depth":4},{"value":"2. Register your endpoint","id":"2-register-your-endpoint","depth":4},{"value":"3. Verify the webhook signature","id":"3-verify-the-webhook-signature","depth":4},{"value":"Event Types","id":"event-types","depth":3},{"value":"Payload Format","id":"payload-format","depth":3},{"value":"Security & Signature Verification","id":"security--signature-verification","depth":3},{"value":"Signature headers","id":"signature-headers","depth":4},{"value":"Your signing secret","id":"your-signing-secret","depth":4},{"value":"Rotating your signing secret","id":"rotating-your-signing-secret","depth":4},{"value":"Retries","id":"retries","depth":3}],"frontmatter":{"seo":{"title":"Webhooks"}},"lastModified":"2026-04-20T12:41:47.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/contents/api/api-basics/webhooks","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}