Overview
Webhooks let you receive real-time order events —order.pending, order.paid,
order.failed — as HTTP POST requests to your own URLs. Every delivery is signed
with Anyway’s platform Ed25519 key so you can verify it came from us.
There is no per-endpoint secret. Anyway signs all webhook payloads with a
single platform key; you verify them with the public key published at
GET /v1/webhooks/signing-key. The public key
is safe to cache and is the same for every endpoint.x-org-id header.
Events
| Event | Fires when | data.order.status |
|---|---|---|
order.pending | A payment was submitted and is being verified | PENDING |
order.paid | The order settled successfully — fulfill here | PAID |
order.failed | The order failed | FAILED |
events array subscribes the endpoint to all events.
GET /v1/webhook
List the org’s webhook endpoints (paginated).Request
Optional filter on name / URL.
Response
POST /v1/webhook
Create a webhook endpoint.Request
Request Body
A label for the endpoint (1–255 chars).
The HTTPS URL to deliver events to.
Events to subscribe to. Omit or pass
[] to receive all events.
One of order.pending, order.paid, order.failed.Response
The response does not contain a secret — payloads are signed with the platform key (see Verifying signatures).PATCH /v1/webhook/{webhookId}
Update an endpoint. All fields are optional; only those present are changed.Enable or disable delivery without deleting the endpoint.
DELETE /v1/webhook/{webhookId}
Delete an endpoint.204 No Content.
GET /v1/webhooks/signing-key
Public endpoint (no auth) that publishes the Ed25519 verification key. Fetch it once and cache it — it is shared across all your endpoints.publicKey (whpk_-prefixed) is consumable directly by the
Standard Webhooks verifier libraries. The
keys array is the equivalent JWKS (RFC 7517/8037) for generic JOSE tooling.
Payload
Anyway uses the Standard Webhooks envelope. The event id and timestamp are authoritative in the headers (webhook-id, webhook-timestamp); the body carries the typed event.
Envelope fields
| Field | Type | Notes |
|---|---|---|
type | string | order.pending · order.paid · order.failed. Route on this. |
timestamp | string | RFC 3339, when the event fired. |
apiVersion | string | Payload schema version (e.g. 2026-06-01). |
data.order | object | The order resource (below). |
order object
| Field | Type | Nullable | Notes |
|---|---|---|---|
orderId | string | no | Anyway order id. |
orgId | string | no | Your org id. |
merchantReference | string | yes | Your own reference, echoed back unchanged. Use as your idempotency / correlation key. |
status | enum | no | PENDING · PAID · FAILED — mirrors the event type. |
provider | enum | no | CRYPTO · X402 · CREDITS. |
amountCents | integer | no | Amount in minor units of currency. |
currency | string | no | Lowercase ISO 4217 / token symbol (e.g. usdc). |
crypto | object | yes | On-chain provenance; null for off-chain (CREDITS) orders. |
crypto.chainId | string | — | CAIP-2 chain id (e.g. eip155:8453). |
crypto.asset | string | — | CAIP-19 asset id. |
crypto.assetSymbol | string | — | Human-readable symbol (e.g. USDC). |
crypto.txHash | string | — | On-chain transaction hash. |
crypto.payer | string | yes | Buyer account, CAIP-10. |
crypto.recipient | string | yes | Your receiving account, CAIP-10. |
product | object | yes | { id, name } or null. |
paymentLinkId | string | yes | Originating payment link id. |
createdAt / updatedAt | string | no | RFC 3339 UTC. |
Verifying signatures
Each delivery carries three Standard-Webhooks headers:| Header | Example | Meaning |
|---|---|---|
webhook-id | msg_2abc... | Unique delivery id — use to de-duplicate. |
webhook-timestamp | 1717400180 | Unix seconds; reject if too old. |
webhook-signature | v1a,<base64(ed25519 signature)> | Space-separated list; one or more schemes. |
{webhook-id}.{webhook-timestamp}.{raw-body}. Verify it with the published
public key — easiest via a Standard Webhooks library:
Delivery & retries
- Transport:
POSTwithContent-Type: application/json; the envelope is the body. - Acknowledge: return any
2xx. Non-2xxresponses and timeouts count as failed. - Timeout: 10 seconds per attempt.
- Retries: up to 12 attempts with exponential backoff (capped at 1 hour); a
Retry-Afterresponse header is honored. After the final attempt the event is dropped. - De-duplication: the same
webhook-idmay be delivered more than once — make your handler idempotent. - Ordering is not guaranteed: events may arrive out of order (e.g.
paidbeforepending). Drive your state offstatus/type, not arrival order.