Receive real-time notifications when subscription states change - and know which changes to poll for instead.
Webhook events push subscription state changes to your server as they happen, so you can provision access, trigger dunning flows, and keep your records in sync without polling.
The setup flow - registering the webhook URL, subscribing to events, verifying payload signatures - is shared with the rest of the Merchant API. The rest of this guide covers what's specific to subscriptions.
How it works
Revolut sends each event as an HTTP POST request to the url you registered with Create a webhook. The following events are sent for subscriptions:
| Event | Fires when | Typical reaction |
|---|---|---|
SUBSCRIPTION_INITIATED | The subscription is created | Mark the customer's account as provisioning - access starts once the subscription activates |
SUBSCRIPTION_FINISHED | The subscription completes its last cycle naturally | End access gracefully - the customer completed their commitment |
SUBSCRIPTION_CANCELLED | The subscription is cancelled - by you or the customer | Stop provisioning immediately, record the cancellation |
SUBSCRIPTION_OVERDUE | A renewal or settlement payment fails | Trigger your dunning flow - notify the customer, consider restricting access |
The payload is minimal by design - the Webhook event API reference documents the exact shape you'll receive:
POST /your-webhook-endpoint HTTP/1.1
Host: your-server.example.com
Content-Type: application/json
Revolut-Request-Timestamp: 1721050064
Revolut-Signature: v1=4fce70bda66b2e713be09fbb7ab1b31b0c8976ea4eeb01b2
{
"event": "SUBSCRIPTION_OVERDUE",
"subscription_id": "550e8400-e29b-41d4-a716-446655440000",
"external_reference": "cus_8f3a91"
}| Parameter | Description |
|---|---|
event | The event type - one of the subscription events above. |
subscription_id | The affected subscription - use it to Retrieve a subscription for the full current state. |
external_reference | Your identifier, echoed from creation. Optional - match it to your records instead of the UUID if you prefer. |
The payload tells you that something changed, not the full subscription state.
Always retrieve the subscription before acting on an event - the state may have moved on since the event was generated.
Before you begin
Before you start, make sure you have the following:
- Your subscription model implemented - you've built the subscription you want to monitor with webhooks - see Get started with the Subscriptions API
- A registered webhook URL - subscribe it to the
SUBSCRIPTION_*events - see Use webhooks - Signature verification ready - see Verify the payload signature
Handle subscription events
Respond and retry
- Acknowledge fast - respond with any
200-399code within the timeout (204is recommended) and do heavy processing off the request thread. - Retries - if delivery times out or your endpoint responds
4XX, Revolut retries the event 3 more times, each with a 10-minute delay. Make your handler idempotent - the same event can arrive more than once. - Ordering isn't guaranteed - handle events based on the subscription's current retrieved state rather than assuming events arrive in lifecycle order.
- IP allowlisting - events originate from these addresses:
| Environment | Webhook IP addresses |
|---|---|
| Production | 35.246.21.235, 34.89.70.170 |
| Sandbox | 35.242.130.242, 35.242.162.241 |
Poll what webhooks don't tell you
Subscription webhooks cover a small set of state changes. Several lifecycle moments emit no event - track those by polling Retrieve a subscription or the cycle list:
| Change | Event | How to track |
|---|---|---|
| Subscription created | SUBSCRIPTION_INITIATED | Webhook |
| Activation - first payment collected or payment method attached | None | Retrieve the subscription, check state: "active" |
| Plan change scheduled or applied | None | Retrieve the subscription |
| Cycle created or completed | None | Retrieve a subscription cycle list |
| Usage settlement charged | None | Retrieve the cycle - the post_billing_order_id appears after the cutoff |
| Renewal or settlement payment failed | SUBSCRIPTION_OVERDUE | Webhook - see Failed payments and retries |
| Cancellation | SUBSCRIPTION_CANCELLED | Webhook |
| Natural completion | SUBSCRIPTION_FINISHED | Webhook |
For activation specifically, a practical pattern is to poll the subscription after the customer completes the setup order - there's no activation event to wait for.
Implementation checklist
Confirm your webhook integration handles subscription events correctly:
- Webhook registered and subscribed to the
SUBSCRIPTION_*events - see Use webhooks - Every payload's signature is verified before processing - see Verify the payload signature
- Handler responds
200-399quickly and processes asynchronously - Handler is idempotent - the 3 retries with 10-minute delays can deliver duplicates
- Events are matched to your records via
external_referenceorsubscription_id -
SUBSCRIPTION_OVERDUEtriggers your dunning flow;SUBSCRIPTION_CANCELLEDandSUBSCRIPTION_FINISHEDstop provisioning - Activation, plan changes, and cycle completions are covered by polling - no events exist for them