Power your product's own recurring plans on the same engine that runs your cart, checkout, and vault. Trials with fraud protection, automatic dunning, a full lifecycle state machine, and a webhook for every transition — native to the engine, not a $500/mo bolt-on hiding the real cost of your business.
A subscription is a state machine, not a row you poll. Throttle owns the transitions: trial conversion, renewals, pause and resume, dunning, and cancellation. You react to events; the engine keeps the state.
Cancel from any state — immediately, or scheduled for period end.
When a renewal fails, Throttle retries automatically — on day 1, day 3, and day 7. If all three fail, the subscription cancels cleanly with reason dunning_exhausted. No silent leak. No recovery flow for you to build. No third-party rental.
Every attempt emits an event, so your backend — and your customer — always knows where things stand.
Trials start in trialing with no charge — but the card is vaulted at checkout. When the trial ends, the first invoice bills automatically. No "add a card to continue" friction, no dunning on day one.
Because the card is on file before the trial starts, repeat-trial abuse gets caught — a blocked attempt emits subscription.trial_blocked instead of silently minting free access.
Drive every transition from your backend with a typed client — or call the same operations directly over the REST API. Same engine either way.
import { createSubscriptionsClient } from '@usethrottle/subscriptions/server'
const subs = createSubscriptionsClient({
apiKey: process.env.THROTTLE_SECRET_KEY,
})
// Full lifecycle — typed, server-side
await subs.pause(id)
await subs.resume(id)
await subs.changePlan({ id, planReference: 'pro_annual' })
await subs.cancel(id, { atPeriodEnd: true }) /api/v1/subscriptions/api/v1/subscriptions/:id/api/v1/subscriptions/:id/api/v1/subscriptions/:id/pause/api/v1/subscriptions/:id/resume/api/v1/subscriptions/:id/change-plan/api/v1/subscriptions/:id/cancelThirteen subscription events, delivered to your endpoint with retries. Your backend stays in sync without polling.
subscription.created A subscription was created. subscription.activated Trial ended or signup cleared — billing begins. subscription.renewed A new period was charged successfully. subscription.updated Subscription fields changed. subscription.plan_changed Plan swapped — next renewal bills the new amount. subscription.plan_change_scheduled A plan change is queued for period end. subscription.paused Billing paused. subscription.resumed Billing resumed. subscription.past_due A renewal failed — dunning has started. subscription.payment_failed A renewal attempt failed. subscription.cancelled Cancelled — immediately or at period end. subscription.create_failed Subscription creation failed. subscription.trial_blocked A trial was blocked by fraud protection. We'd rather tell you the boundary than have you find it in production.
Flat or simply-recurring plans — consumer or SaaS — fit today, native to your commerce stack. Pricing on usage, seats, or sales bands, or a Stripe-style self-serve customer portal? Those aren't here yet — talk to us first and we'll tell you straight whether the fit is there.
Recurring billing belongs in the engine — next to cart, checkout, and the vault — not bolted on for $500/mo. See it on your stack.