Skip to main content
The Webhook Endpoints API lets you register URLs to receive event notifications when payment sessions change state. When a relevant event fires — such as session.paid or session.expired — Crypto Checkout sends an HTTP POST request to each of your registered endpoints with the event payload. Each endpoint is secured with a shared HMAC signing secret. You should always verify the X-Signature header on incoming requests before processing the payload.
The signing secret is returned only once at endpoint creation time. Store it immediately in a secrets manager. If you lose it, you must delete the endpoint and create a new one.

The WebhookEndpoint object

id
string
Unique identifier for the webhook endpoint. Format: UUID.
object
string
Always "webhook_endpoint".
url
string
The HTTPS URL Crypto Checkout sends event payloads to.
events
string[]
The list of event types this endpoint is subscribed to. ["*"] means all events.
active
boolean
When false, deliveries to this endpoint are suspended.
secretPrefix
string
The first few characters of the signing secret, e.g. "whsec_abc123". Use this to identify which secret to use when verifying signatures without exposing the full secret.
createdAt
string
ISO 8601 timestamp of when the endpoint was registered.

POST /webhook_endpoints

Registers a new webhook endpoint. Returns the endpoint object plus the one-time secret field with a 201 status. Required scope: webhooks:write

Request body

url
string
required
A valid HTTPS URL that Crypto Checkout will POST event payloads to. HTTP (non-TLS) URLs are rejected.
events
string[]
required
An array of event type strings to subscribe to. Pass ["*"] to receive all events. Must contain at least one entry.Available event types:
  • session.pending
  • session.detected
  • session.paid
  • session.underpaid
  • session.overpaid
  • session.expired
  • session.paid_late
  • session.failed

Example request

curl -X POST https://your-domain.com/api/v1/webhook_endpoints \
  -H "Authorization: Bearer ck_test_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-site.com/webhooks",
    "events": ["session.paid", "session.expired"]
  }'
const endpoint = await client.webhookEndpoints.create({
  url: "https://your-site.com/webhooks",
  events: ["session.paid", "session.expired"],
});

// Save endpoint.secret to your secrets manager — it won't be shown again
console.log(endpoint.secret);

Example response 201

{
  "id": "we_01HXYZ",
  "object": "webhook_endpoint",
  "url": "https://your-site.com/webhooks",
  "events": ["session.paid", "session.expired"],
  "active": true,
  "secretPrefix": "whsec_abc123",
  "secret": "whsec_abc123def456ghijklmnopqrstuvwxyz",
  "createdAt": "2024-01-15T10:00:00.000Z"
}
The secret field is only present in this creation response. It is never returned again. Treat it like a password and store it securely.

GET /webhook_endpoints

Returns a cursor-paginated list of your registered webhook endpoints. Required scope: webhooks:read

Query parameters

limit
integer
Number of results to return. Between 1 and 100. Defaults to 25.
starting_after
string
An endpoint id used as a pagination cursor. Returns endpoints created before this one.

Example request

curl "https://your-domain.com/api/v1/webhook_endpoints" \
  -H "Authorization: Bearer ck_test_YOUR_KEY"
const { data, hasMore, nextCursor } = await client.webhookEndpoints.list();

Example response 200

{
  "data": [
    {
      "id": "we_01HXYZ",
      "object": "webhook_endpoint",
      "url": "https://your-site.com/webhooks",
      "events": ["session.paid", "session.expired"],
      "active": true,
      "secretPrefix": "whsec_abc123",
      "createdAt": "2024-01-15T10:00:00.000Z"
    }
  ],
  "hasMore": false,
  "nextCursor": null
}

GET /webhook_endpoints/{id}

Retrieves a single webhook endpoint by its ID. The signing secret is not returned in this response. Required scope: webhooks:read

Path parameters

id
string
required
The ID of the webhook endpoint to retrieve.

Example request

curl https://your-domain.com/api/v1/webhook_endpoints/we_01HXYZ \
  -H "Authorization: Bearer ck_test_YOUR_KEY"
const endpoint = await client.webhookEndpoints.retrieve("we_01HXYZ");

DELETE /webhook_endpoints/{id}

Permanently deletes a webhook endpoint. No further events will be delivered to the registered URL. Required scope: webhooks:write

Path parameters

id
string
required
The ID of the webhook endpoint to delete.

Example request

curl -X DELETE https://your-domain.com/api/v1/webhook_endpoints/we_01HXYZ \
  -H "Authorization: Bearer ck_test_YOUR_KEY"
const result = await client.webhookEndpoints.del("we_01HXYZ");
// { id: "we_01HXYZ", deleted: true }

Example response 200

{
  "id": "we_01HXYZ",
  "deleted": true
}

POST /webhook_endpoints/{id}/test

Sends a synthetic session.paid event to the endpoint’s registered URL. Use this to verify that your handler is reachable and correctly processes the payload without waiting for a real payment. Required scope: webhooks:write

Path parameters

id
string
required
The ID of the webhook endpoint to test.

Example request

curl -X POST https://your-domain.com/api/v1/webhook_endpoints/we_01HXYZ/test \
  -H "Authorization: Bearer ck_test_YOUR_KEY"
const { deliveryId } = await client.webhookEndpoints.test("we_01HXYZ");
console.log("Test delivery ID:", deliveryId);

Example response 200

{
  "deliveryId": "dlv_01HABC"
}
After running a test delivery, check your server logs and verify that the X-Signature header matches the HMAC-SHA256 of the raw request body signed with your endpoint secret. If signature verification fails, double-check that you are using the raw body bytes — not a parsed JSON object — when computing the hash.