Developer docs v0.1.0

Webhooks

Endpoints that receive events.

Concepts, behaviour and examples: Webhooks guide.

GET /v1/webhooks

List webhooks

Cursor-paginated (limit, starting_after).

Authentication
Merchant API key
Effect
Read-only.

Query parameters

NameTypeRequiredDescription
limitintegernoPage size (1–100). · ≥ 1, ≤ 100, default 20
starting_afterstringnoObject ID; return objects after it (ascending ID order). · 26 chars

Responses

StatusMeaningBody / error codes
200Success.object
401Missing or invalid API key.authentication_error
429Rate limited; honor retry-after.rate_limit_exceeded too_many_auth_failures
500Server error.api_error
Example response
{
  "object": "list",
  "url": "string",
  "has_more": false,
  "data": [
    {
      "object": "webhook",
      "id": "01JB9XK3M2R7TQ8N4V6Y0ZPA1C",
      "merchant_id": "01JB9XK3M2R7TQ8N4V6Y0ZPA1C",
      "url": "https://example.com/hooks/payware",
      "enabled_events": [
        "customer.created"
      ],
      "is_active": false,
      "created_at": "2026-10-25T18:00:00.000Z",
      "updated_at": "2026-10-25T18:00:00.000Z"
    }
  ]
}

POST /v1/webhooks

Create a webhook

Registers a URL to receive events. The signing secret is returned once.

Authentication
Merchant API key
Effect
Creates an active webhook.

Headers

NameTypeRequiredDescription
Idempotency-KeystringnoMakes retries safe: same key + body replays the stored response (idempotency-replayed: true); a different body returns 409 idempotency_key_in_use. · ≤ 96 chars

Request body

FieldTypeRequiredDescription
urlstring (uri)yeshttp/https, no credentials. In production: https, no localhost/*.local/*.internal/private addresses (unless WEBHOOK_ALLOW_PRIVATE_HOSTS=true). · ≤ 2048 chars
enabled_eventsEventType[]noOmit or leave empty to receive all events.
is_activebooleannofalse pauses delivery.
Example request
{
  "url": "https://example.com/hooks/payware",
  "enabled_events": [
    "customer.created"
  ],
  "is_active": false
}

Responses

StatusMeaningBody / error codes
201Webhook created.WebhookWithSecret
400Invalid body or URL.invalid_webhook_url validation_failed invalid_json
401Missing or invalid API key.authentication_error
429Rate limited; honor retry-after.rate_limit_exceeded too_many_auth_failures
500Server error.api_error
Example response
{
  "object": "webhook",
  "id": "01JB9XK3M2R7TQ8N4V6Y0ZPA1C",
  "merchant_id": "01JB9XK3M2R7TQ8N4V6Y0ZPA1C",
  "url": "https://example.com/hooks/payware",
  "enabled_events": [
    "customer.created"
  ],
  "is_active": false,
  "created_at": "2026-10-25T18:00:00.000Z",
  "updated_at": "2026-10-25T18:00:00.000Z",
  "secret": "string"
}

GET /v1/webhooks/:id

Retrieve a webhook

The secret is omitted.

Authentication
Merchant API key
Effect
Read-only.

Path parameters

NameTypeRequiredDescription
idstringyesObject ID (ULID). · 26 chars

Responses

StatusMeaningBody / error codes
200Success.Webhook
401Missing or invalid API key.authentication_error
404Not found, or not yours.resource_missing
429Rate limited; honor retry-after.rate_limit_exceeded too_many_auth_failures
500Server error.api_error
Example response
{
  "object": "webhook",
  "id": "01JB9XK3M2R7TQ8N4V6Y0ZPA1C",
  "merchant_id": "01JB9XK3M2R7TQ8N4V6Y0ZPA1C",
  "url": "https://example.com/hooks/payware",
  "enabled_events": [
    "customer.created"
  ],
  "is_active": false,
  "created_at": "2026-10-25T18:00:00.000Z",
  "updated_at": "2026-10-25T18:00:00.000Z"
}

POST /v1/webhooks/:id

Update a webhook

Partial update.

Authentication
Merchant API key
Effect
Updates the webhook.

Path parameters

NameTypeRequiredDescription
idstringyesObject ID (ULID). · 26 chars

Headers

NameTypeRequiredDescription
Idempotency-KeystringnoMakes retries safe: same key + body replays the stored response (idempotency-replayed: true); a different body returns 409 idempotency_key_in_use. · ≤ 96 chars

Request body

FieldTypeRequiredDescription
urlstring (uri)nohttp/https, no credentials. In production: https, no localhost/*.local/*.internal/private addresses (unless WEBHOOK_ALLOW_PRIVATE_HOSTS=true). · ≤ 2048 chars
enabled_eventsEventType[]noOmit or leave empty to receive all events.
is_activebooleannofalse pauses delivery.
Example request
{
  "url": "https://example.com/hooks/payware",
  "enabled_events": [
    "customer.created"
  ],
  "is_active": false
}

Responses

StatusMeaningBody / error codes
200Success.Webhook
400Invalid request.empty_update
401Missing or invalid API key.authentication_error
404Not found, or not yours.resource_missing
429Rate limited; honor retry-after.rate_limit_exceeded too_many_auth_failures
500Server error.api_error
Example response
{
  "object": "webhook",
  "id": "01JB9XK3M2R7TQ8N4V6Y0ZPA1C",
  "merchant_id": "01JB9XK3M2R7TQ8N4V6Y0ZPA1C",
  "url": "https://example.com/hooks/payware",
  "enabled_events": [
    "customer.created"
  ],
  "is_active": false,
  "created_at": "2026-10-25T18:00:00.000Z",
  "updated_at": "2026-10-25T18:00:00.000Z"
}

DELETE /v1/webhooks/:id

Delete a webhook

Removes the webhook and its delivery history.

Authentication
Merchant API key
Effect
Deletes the webhook and its events.

Path parameters

NameTypeRequiredDescription
idstringyesObject ID (ULID). · 26 chars

Headers

NameTypeRequiredDescription
Idempotency-KeystringnoMakes retries safe: same key + body replays the stored response (idempotency-replayed: true); a different body returns 409 idempotency_key_in_use. · ≤ 96 chars

Responses

StatusMeaningBody / error codes
200Success.DeletedObject
401Missing or invalid API key.authentication_error
404Not found, or not yours.resource_missing
429Rate limited; honor retry-after.rate_limit_exceeded too_many_auth_failures
500Server error.api_error
Example response
{
  "object": "string",
  "id": "01JB9XK3M2R7TQ8N4V6Y0ZPA1C",
  "deleted": true
}

POST /v1/webhooks/:id/rotate-secret

Rotate the signing secret

The old secret stops working immediately; failed deliveries are retried and re-signed with the new one.

Authentication
Merchant API key
Effect
Replaces the signing secret.

Path parameters

NameTypeRequiredDescription
idstringyesObject ID (ULID). · 26 chars

Headers

NameTypeRequiredDescription
Idempotency-KeystringnoMakes retries safe: same key + body replays the stored response (idempotency-replayed: true); a different body returns 409 idempotency_key_in_use. · ≤ 96 chars

Responses

StatusMeaningBody / error codes
200Success.WebhookWithSecret
401Missing or invalid API key.authentication_error
404Not found, or not yours.resource_missing
429Rate limited; honor retry-after.rate_limit_exceeded too_many_auth_failures
500Server error.api_error
Example response
{
  "object": "webhook",
  "id": "01JB9XK3M2R7TQ8N4V6Y0ZPA1C",
  "merchant_id": "01JB9XK3M2R7TQ8N4V6Y0ZPA1C",
  "url": "https://example.com/hooks/payware",
  "enabled_events": [
    "customer.created"
  ],
  "is_active": false,
  "created_at": "2026-10-25T18:00:00.000Z",
  "updated_at": "2026-10-25T18:00:00.000Z",
  "secret": "string"
}

POST webhook: event

Event delivery

Payware POSTs one JSON envelope per event to each matching webhook. Headers: x-signature: t=<unix>,v1=<hex HMAC-SHA256 of <t>.<raw body>, x-event-type, x-webhook-id (unique per delivery, stable across retries). Respond with any 2xx within WEBHOOK_TIMEOUT_MS (default 10 s); redirects are never followed. Delivery is at-least-once, retried after 1 min, 5 min, 30 min, 2 h and 24 h (then failed); dedupe on id and expect out-of-order arrival.

Authentication
None
Effect
Your endpoint receives one signed envelope per event.

Request body

FieldTypeRequiredDescription
idstringyesLogical event ID; the same for every webhook that receives it. · 26 chars
object"event"yes
typeEventTypeyes
createdstring (date-time)yes
dataobjectyes
data.objectobjectnoThe full API object (subscription, customer, payment, instrument or enrollment); deletions carry {object, id, deleted: true}.
data.retry_atstring (date-time) | nullnopayment.failed only: next attempt, null when exhausted or standalone.
data.replacement_instrument_idstring | nullnoinstrument.detached only. · 26 chars
Example request
{
  "id": "01JB9XK3M2R7TQ8N4V6Y0ZPA1C",
  "object": "event",
  "type": "customer.created",
  "created": "2026-10-25T18:00:00.000Z",
  "data": {
    "object": {},
    "retry_at": "2026-10-25T18:00:00.000Z",
    "replacement_instrument_id": "01JB9XK3M2R7TQ8N4V6Y0ZPA1C"
  }
}

Responses

StatusMeaningBody / error codes
2XXAcknowledged.