Webhook endpoints
Register and manage webhook endpoints programmatically — create configs, inspect deliveries, and rotate the signing secret used to verify events.
A webhook endpoint is a URL Tokeflow delivers signed events to, plus the configuration that governs it: which event types it subscribes to, whether it is active, and the signing secret used to prove each delivery came from Tokeflow.
These endpoints let you manage that configuration from your backend instead of the Dashboard — useful when you provision merchants programmatically or need to rotate secrets on a schedule. Every delivery Tokeflow sends is signed; always verify the signature before acting on an event. See Verifying webhook signatures.
The signing secret (whsec_…) is returned only when you create the endpoint or rotate the secret. Store it in a secrets manager at that moment — it cannot be retrieved later. Rotating invalidates the previous secret, so deploy the new one before rotating, or accept a short window of failed verifications.
The webhook endpoint object
A webhook configuration as returned by the create, list, and retrieve endpoints.
| Field | Type | Description |
|---|---|---|
id | string | Unique identifier for the webhook configuration. |
merchant_id | string | Merchant ID that owns this webhook configuration. |
url | string | The URL where webhook events will be sent. |
description | string | null | Description for this webhook configuration. |
event_filter | array | null | List of event types subscribed to. Null means all events. |
is_active | boolean | Whether this webhook configuration is active. |
created_at | string | When the webhook configuration was created. (ISO 8601 UTC). |
updated_at | string | When the webhook configuration was last updated. (ISO 8601 UTC). |
last_triggered_at | string | null | When the webhook was last triggered (most recent delivery). (ISO 8601 UTC). |
Endpoints
GET/api/v1/merchants/:merchant_id/webhook-configs
Auth: Organization key (with merchant_id) or Merchant key.
List webhook configurations.
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
merchant_id | string | Yes | — |
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
page | number | No | Page number (1-indexed). Default 1, min 1. |
limit | number | No | Number of items per page. Default 20, min 1, max 100. |
Example request
curl -G https://api.tokeflow.com/api/v1/merchants/mrc_8a3f12d9/webhook-configs \
-H "Authorization: Bearer sk_live_mer_…" \
--data-urlencode "page=1" \
--data-urlencode "limit=20"Example response — 200
{
"data": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"merchant_id": "550e8400-e29b-41d4-a716-446655440001",
"url": "https://api.example.com/webhooks/payments",
"description": "Production payment notifications",
"event_filter": [
"transaction.authorized",
"transaction.failed",
"transaction.refunded"
],
"is_active": true,
"created_at": "2024-01-15T10:30:00.000Z",
"updated_at": "2024-01-15T10:30:00.000Z",
"last_triggered_at": "2024-01-15T10:30:00.000Z"
}
],
"meta": {
"page": 1,
"limit": 20,
"total": 42,
"total_pages": 3,
"has_next": true,
"has_prev": false
}
}POST/api/v1/merchants/:merchant_id/webhook-configs
Auth: Organization key (with merchant_id) or Merchant key.
Create a webhook configuration.
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
merchant_id | string | Yes | — |
Request fields
| Field | Type | Required | Description |
|---|---|---|---|
url | string | Yes | The URL where webhook events will be sent. |
description | string | No | Optional description for this webhook configuration. |
event_filter | array | No | List of event types to subscribe to. If not provided, all events will be sent. |
Example request
curl -X POST https://api.tokeflow.com/api/v1/merchants/mrc_8a3f12d9/webhook-configs \
-H "Authorization: Bearer sk_live_mer_…" \
-H "Content-Type: application/json" \
-d '{
"url": "https://api.example.com/webhooks/payments",
"description": "Production payment notifications",
"event_filter": [
"transaction.authorized",
"transaction.failed",
"transaction.refunded"
]
}'Example response — 201
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"merchant_id": "550e8400-e29b-41d4-a716-446655440001",
"url": "https://api.example.com/webhooks/payments",
"description": "Production payment notifications",
"event_filter": [
"transaction.authorized",
"transaction.failed",
"transaction.refunded"
],
"is_active": true,
"created_at": "2024-01-15T10:30:00.000Z",
"updated_at": "2024-01-15T10:30:00.000Z",
"last_triggered_at": "2024-01-15T10:30:00.000Z",
"secret": "whsec_abc123def456..."
}DELETE/api/v1/merchants/:merchant_id/webhook-configs/:webhook_id
Auth: Organization key (with merchant_id) or Merchant key.
Delete a webhook configuration.
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
merchant_id | string | Yes | — |
webhook_id | string | Yes | — |
Example request
curl -X DELETE https://api.tokeflow.com/api/v1/merchants/mrc_8a3f12d9/webhook-configs/whk_3e9d1f42 \
-H "Authorization: Bearer sk_live_mer_…"Example response — 204 No Content
An empty body is returned on success.
GET/api/v1/merchants/:merchant_id/webhook-configs/:webhook_id
Auth: Organization key (with merchant_id) or Merchant key.
Get a webhook configuration.
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
merchant_id | string | Yes | — |
webhook_id | string | Yes | — |
Example request
curl https://api.tokeflow.com/api/v1/merchants/mrc_8a3f12d9/webhook-configs/whk_3e9d1f42 \
-H "Authorization: Bearer sk_live_mer_…"Example response — 200
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"merchant_id": "550e8400-e29b-41d4-a716-446655440001",
"url": "https://api.example.com/webhooks/payments",
"description": "Production payment notifications",
"event_filter": [
"transaction.authorized",
"transaction.failed",
"transaction.refunded"
],
"is_active": true,
"created_at": "2024-01-15T10:30:00.000Z",
"updated_at": "2024-01-15T10:30:00.000Z",
"last_triggered_at": "2024-01-15T10:30:00.000Z"
}PATCH/api/v1/merchants/:merchant_id/webhook-configs/:webhook_id
Auth: Organization key (with merchant_id) or Merchant key.
Update a webhook configuration.
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
merchant_id | string | Yes | — |
webhook_id | string | Yes | — |
Request fields
| Field | Type | Required | Description |
|---|---|---|---|
url | string | No | The URL where webhook events will be sent. |
description | string | No | Optional description for this webhook configuration. |
event_filter | array | No | List of event types to subscribe to. |
is_active | boolean | No | Whether this webhook configuration is active. |
Example request
curl -X PATCH https://api.tokeflow.com/api/v1/merchants/mrc_8a3f12d9/webhook-configs/whk_3e9d1f42 \
-H "Authorization: Bearer sk_live_mer_…" \
-H "Content-Type: application/json" \
-d '{
"url": "https://api.example.com/webhooks/payments",
"description": "Production payment notifications",
"event_filter": [
"transaction.authorized",
"transaction.failed",
"transaction.refunded"
],
"is_active": true
}'Example response — 200
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"merchant_id": "550e8400-e29b-41d4-a716-446655440001",
"url": "https://api.example.com/webhooks/payments",
"description": "Production payment notifications",
"event_filter": [
"transaction.authorized",
"transaction.failed",
"transaction.refunded"
],
"is_active": true,
"created_at": "2024-01-15T10:30:00.000Z",
"updated_at": "2024-01-15T10:30:00.000Z",
"last_triggered_at": "2024-01-15T10:30:00.000Z"
}GET/api/v1/merchants/:merchant_id/webhook-deliveries
Auth: Organization key (with merchant_id) or Merchant key.
List webhook delivery history.
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
merchant_id | string | Yes | — |
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
page | number | No | Page number (1-indexed). Default 1, min 1. |
limit | number | No | Number of items per page. Default 20, min 1, max 100. |
status | string | No | Filter by delivery status |
from | string | No | From timestamp (ISO 8601 format) - filter deliveries after this time |
to | string | No | To timestamp (ISO 8601 format) - filter deliveries before this time |
Example request
curl -G https://api.tokeflow.com/api/v1/merchants/mrc_8a3f12d9/webhook-deliveries \
-H "Authorization: Bearer sk_live_mer_…" \
--data-urlencode "page=1" \
--data-urlencode "limit=20" \
--data-urlencode "status=failed" \
--data-urlencode "from=2024-01-01T00:00:00Z"Example response — 200
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"merchant_id": "550e8400-e29b-41d4-a716-446655440001",
"merchant_webhook_config_id": "550e8400-e29b-41d4-a716-446655440002",
"payment_transaction_id": "550e8400-e29b-41d4-a716-446655440003",
"order_id": "550e8400-e29b-41d4-a716-446655440004",
"event_type": "transaction.authorized",
"payload": {
"event": "transaction.authorized",
"data": {
"transaction_id": "..."
}
},
"target_url": "https://api.example.com/webhooks/payments",
"attempt_number": 1,
"http_status_code": 200,
"response_body": "{\"received\": true}",
"status": "success",
"next_retry_at": "2024-01-15T10:35:00.000Z",
"created_at": "2024-01-15T10:30:00.000Z",
"sent_at": "2024-01-15T10:30:01.000Z"
}POST/api/v1/merchants/:merchant_id/webhooks/:webhook_id/rotate-secret
Auth: Organization key (with merchant_id) or Merchant key.
Rotate the webhook secret.
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
merchant_id | string | Yes | — |
webhook_id | string | Yes | — |
Example request
curl -X POST https://api.tokeflow.com/api/v1/merchants/mrc_8a3f12d9/webhooks/whk_3e9d1f42/rotate-secret \
-H "Authorization: Bearer sk_live_mer_…"Example response — 200
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"merchant_id": "550e8400-e29b-41d4-a716-446655440001",
"url": "https://api.example.com/webhooks/payments",
"description": "Production payment notifications",
"event_filter": [
"transaction.authorized",
"transaction.failed",
"transaction.refunded"
],
"is_active": true,
"created_at": "2024-01-15T10:30:00.000Z",
"updated_at": "2024-01-15T10:30:00.000Z",
"last_triggered_at": "2024-01-15T10:30:00.000Z",
"secret": "whsec_abc123def456..."
}Errors
Errors use the standard envelope. The most common cases here:
| HTTP | type | Typical cause |
|---|---|---|
400 | validation_error | Missing required field, or an operation the current state does not allow. |
401 | authentication_error | Missing or invalid API key. |
403 | authorization_error | The key lacks the required scope. |
404 | not_found_error | The resource does not exist or is not owned by this entity. |
429 | rate_limit_error | Rate limit exceeded — back off exponentially. |
See Errors for the full catalog.