Skip to content

Webhooks

Register endpoints in the merchant dashboard under Settings → Webhooks, and subscribe each one to the events it cares about. Endpoints belong to a mode: a sandbox endpoint hears nothing about live orders, so a test receiver can be pointed at a laptop without any risk of it seeing real ones.

Every delivery is a POST with this body:

{
  "id": "evt_9Xk2mQpR7vLzT4hB1nWsY6dF3jCg",
  "type": "contract.paid",
  "created": 1786512000,
  "livemode": false,
  "data": { "object": { "…": "…" } }
}

id identifies the event, not the delivery: it is the same across retries and across every endpoint subscribed to it, so it is what to deduplicate on. livemode says which half of the account produced the event — false for everything that happened in sandbox.

Header Meaning
ShotPay-Event-Id Matches id in the body.
ShotPay-Event-Type Matches type in the body.
ShotPay-Delivery-Attempt 1 on the first try, higher on a retry.
ShotPay-Signature t={unix},v1={hex} — see Signatures.

Answer 2xx as soon as the event is stored. Anything else is retried with backoff, up to five attempts, so slow processing should happen after the response rather than before it.

What data.object holds depends on the event — see Event Types for the map and the fields of each payload.