Skip to content

Test clocks

Move time forward in test mode to watch trials end, subscriptions renew and cancellations take effect in seconds, exactly as they will in live mode.

A test clock is a time of its own, in test mode. Customers created on a clock live at the clock's time: their subscriptions start then, and their trials, renewals and cancellations happen when you move the clock forward, not when real time passes. Use clocks to test your billing end to end, in seconds, before you go live.

Create a clock and attach a customer

HTTP
POST /api/v1/test_clocks

{ "name": "Monthly plan renewal", "frozenTime": "2026-10-01T08:00:00Z" }

frozenTime is where the clock starts (now by default, or up to a year back and five years ahead). Attach customers when you create them:

HTTP
POST /api/v1/customers

{ "email": "lena@example.com", "testClockId": "clk_01m4…" }

Everything you then do for that customer happens at the clock's time: a subscription created now starts at frozenTime, a pause or a plan change is dated at the clock's time, and usage events are checked against it. A clock holds up to 10 customers.

The same goes for a subscription the customer buys on the hosted checkout (a session for that customer, or one where they enter their email): it's on the clock and starts at the clock's time, with its trial, first period, first invoice and included credits dated then, and it renews when you advance the clock. The payment itself is recorded when it happens.

Advance the clock

HTTP
POST /api/v1/test_clocks/{id}/advance

{ "frozenTime": "2026-11-02T00:00:00Z" }

The clock becomes advancing and, in the background, every step its customers' subscriptions are due by then runs in time order, each at its own time: trial notices and trial ends, invoice.upcoming, renewal drafts an hour before each period end, renewals with their invoices, changes scheduled for the period end, price changes, cancellations at the period end, resumptions of paused subscriptions, the expiry of unpaid first invoices, and collection: dunning retries and their final action, reminders and overdue of bank-transfer invoices, and card-expiry reminders; and the expiry of its customers' wallet credits, each at its expiresAt. Then the clock is ready at its new time, and test_clock.ready goes to your webhooks.

Read the clock with GET /api/v1/test_clocks/{id} until it's ready. Invoices that are charged go to your test processor as soon as their step is done, as they would in live mode, and the payment's webhook settles them at the clock's time. Wallet auto-reloads of the clock's customers are quoted and recorded at the clock's time the same way. One advance moves a clock at most 732 days; advance again to go further.

Entitlements follow the clock too: a clock's customers' entitlements are resolved at the clock's time, and when an advance finishes they're recomputed at the clock's new time, so a past-due grace period or an override that ended on the way is applied within one job cycle, with customer.entitlements.updated when a value changes. Real time passing changes nothing for them.

If a step can't run (for example, a renewal that can't be taxed), the clock stops at the last step that ran with status: internal_failure, and advance.error says which subscription and step failed and why. Fix the cause and advance again: it continues from there.

While a clock advances, its customers' subscriptions can't be changed (test_clock_advancing).

Delete a clock

DELETE /api/v1/test_clocks/{id} ends what the clock simulated: its customers' subscriptions are canceled at once (nothing more is billed), its customers are deleted, and the clock is removed. Invoices and ledger entries made on the way stay as test-mode records.

Clocks need subscriptions:write to create, advance and delete, and subscriptions:read to read. They exist in test mode only; the same requests in live mode are refused with mode_not_supported.