Subscriptions
A subscription (sub_…) binds a customer to a
price and drives recurring billing from the customer’s
wallet.
Create a subscription
Section titled “Create a subscription”curl -s "$TRILE_API/v1/subscriptions" \ -H "x-api-key: $TRILE_KEY" -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{ "customerId": "cus_01ARZ3NDEKTSV4RRFFQ69G5FAW", "priceId": "price_01ARZ3NDEKTSV4RRFFQ69G5FAY" }'What happens on create:
- No trial → the first cycle is charged immediately from the wallet. If the balance is
short, you get
400 insufficient_fundsand no subscription is created. - Trial price → status starts
trialing; the first charge is deferred to the trial’s end. - Subscribing a customer to a price they already hold returns
409 subscription_already_exists.
Subscription status
Section titled “Subscription status”| Status | Meaning |
|---|---|
trialing | In a free trial; not yet charged. |
active | Current cycle paid; billing normally. |
past_due | A renewal couldn’t be covered by the wallet. Recoverable — customer tops up, Trile retries. |
canceled | Ended. No further billing. |
Each subscription carries currentPeriodStart / currentPeriodEnd so you know when the next
charge is due.
Update
Section titled “Update”curl -X PATCH "$TRILE_API/v1/subscriptions/sub_01ARZ3..." \ -H "x-api-key: $TRILE_KEY" -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{ "cancelAtPeriodEnd": true, "metadata": { "plan_note": "downgrade pending" } }'Use cancelAtPeriodEnd to schedule a cancellation without cutting off access immediately.
Cancel
Section titled “Cancel”# Cancel at end of current period (customer keeps access until then)curl -X POST "$TRILE_API/v1/subscriptions/sub_01ARZ3.../cancel" \ -H "x-api-key: $TRILE_KEY" \ -H "Content-Type: application/json" \ -d '{ "atPeriodEnd": true }'
# Cancel immediatelycurl -X POST "$TRILE_API/v1/subscriptions/sub_01ARZ3.../cancel" \ -H "x-api-key: $TRILE_KEY" \ -H "Content-Type: application/json" \ -d '{ "atPeriodEnd": false }'React to billing
Section titled “React to billing”Don’t poll for renewals. Subscribe to webhooks:
subscription.created/subscription.updated/subscription.canceledinvoice.paid— a cycle was charged successfullyinvoice.payment_failed— wallet couldn’t cover the cycle; subscription is nowpast_due
See The wallet model for how past_due recovers when the customer
tops up.