Create a webhook endpoint
The response is the only time the signing secret is returned. Deliveries carry Ctpeway-Signature: t=<unix>,v1=<hex hmac_sha256(secret, "<t>.<body>")>.
Authorization
Section titled “Authorization”Send your API key as a bearer token in the Authorization header. Secret API key: Authorization: Bearer ctp_live_sk_…. A publishable key (ctp_…_pk_…) is accepted by these operations only, which serve reference data: getRate, listAssets, listNetworks (each marked x-publishable-key: true). Every other operation refuses it with 403 publishable_key_not_allowed, whatever Origin the request carries: that header binds browsers, not other clients, and nothing on this API relies on it.
Headers
Section titled “Headers”| Name | Type | Description |
|---|---|---|
Idempotency-Key |
string | Makes the request safe to retry: the same key with the same request replays the first response (Idempotent-Replayed: true) for 24 hours; the same key with a different request is 422 idempotency_key_reused; while the first request is still running, 409 idempotency_request_in_progress with Retry-After. Only POST honours it. At most 255 characters. Pattern ^[!-~]+$. |
Request body
Section titled “Request body”| Field | Type | Description |
|---|---|---|
url required |
string | Where events are POSTed. Live mode: https on a verified domain. At least 8 characters, at most 2048 characters. |
events required |
array of strings | Event types to receive, or ["*"] for every event. At least 1 item, at most 64 items. |
description |
string | At most 200 characters. |
Example request
Section titled “Example request”curl -X POST "https://api.ctpeway.com/v1/webhook_endpoints" \ -H "Authorization: Bearer $CTPEWAY_API_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: <a-unique-key>" \ -d '{ "url": "https://shop.example/webhooks/ctpeway", "events": [ "invoice.paid", "settlement.held", "settlement.released" ]}'import { CtpeWay } from '@ctpeway/sdk';
const ctpeway = new CtpeWay(process.env.CTPEWAY_API_KEY);
const result = await ctpeway.webhookEndpoints.create({ url: 'https://shop.example/webhooks/ctpeway', events: [ 'invoice.paid', 'settlement.held', 'settlement.released', ],});Response
Section titled “Response”201 Created
Section titled “201 Created”| Field | Type | Description |
|---|---|---|
id |
string | 24 hexadecimal characters. |
url |
string | |
description optional |
string | |
events |
array of strings | Event types this endpoint receives, or ["*"] for all. |
status |
string | failing: a delivery ran out of retries; deliveries continue. disabled: nothing is sent. One of enabled, disabled, failing. |
secret_last4 |
string | Last four characters of the signing secret. |
previous_secret_expires_at optional |
string (date-time) | After a rotation: until then deliveries are also signed with the previous secret. |
failing_since optional |
string (date-time) | |
last_success_at optional |
string (date-time) | |
livemode |
boolean | |
created_at |
string (date-time) | |
updated_at |
string (date-time) | |
secret |
string | The signing secret (whsec_…). Returned only now; store it, it cannot be read again. |
{ "id": "0123456789abcdef01234567", "url": "string", "description": "string", "events": [ "string" ], "status": "enabled", "secret_last4": "string", "previous_secret_expires_at": "2026-01-01T00:00:00.000Z", "failing_since": "2026-01-01T00:00:00.000Z", "last_success_at": "2026-01-01T00:00:00.000Z", "livemode": true, "created_at": "2026-01-01T00:00:00.000Z", "updated_at": "2026-01-01T00:00:00.000Z", "secret": "string"}The values are placeholders generated from the schema. They show the shape, not real data.
Errors
Section titled “Errors”A failed request answers with the error format described under Errors.
Besides the codes any endpoint can return, this endpoint can answer with these code values:

