Skip to main content
These endpoints read billing back: what a customer pays, what they owe, and what is coming. Invoices and subscriptions are read live from the workspace’s Stripe account, so they match what Stripe shows. The reads need the billing:read scope. The rest open a customer’s billing page (billing:portal) and set billing up (billing:admin). No endpoint here charges a card. Money moves only when a customer acts on their billing page or a quote. customer is your app’s own customer id (the customer key picked in Settings → Payments) or a Custral record id (rec_…). See Naming the customer. Every amount is in minor units (cents), the way Stripe returns them. Totals are per currency and never summed across currencies. If the workspace has not connected Stripe, each response has stripeConnected: false and empty invoice and subscription lists, rather than an error.

A customer’s billing

GET /v1/customers/{customer}/billing
quotes are Quote objects. upcomingInstalments are the dated parts of accepted quotes’ one-time totals that have not been billed yet.

Invoices

GET /v1/invoices
string
One customer’s invoices. Without it, the whole workspace’s for period.
string
30d, 90d, 365d or all. Defaults to 90d. Ignored with customer.
string
true for only invoices past their due date. The SDK takes a boolean.
With customer the response is {stripeConnected, invoices}:
Without it you get the workspace’s receivables for the period, with totals per currency:
truncated is true when the period holds more invoices than one read returns. Narrow period to see them all. With overdue=true, invoices is filtered but totals still covers the whole period. usageNotBilled counts metered usage events Custral could not send to Stripe because the customer had no Stripe customer yet, usually usage from before they accepted a quote. It is a running count, not limited to period.

Invoice attributes

string | null
Stripe’s invoice number. null on a draft.
string
draft, open, paid, void or uncollectible.
boolean
Open and past its due date. daysOverdue says by how much.
integer
Minor units, like amountDue and amountPaid.
string | null
Stripe’s hosted page where the customer pays. Send it to a customer who owes.

Subscriptions

GET /v1/subscriptions
string
required
Your app’s customer id, or a record id.

Subscription attributes

string
Stripe’s status: active, trialing, past_due, canceled and so on.
integer
Monthly recurring revenue after today’s discounts, in minor units.
string
autopay (charges the saved method) or invoice (sends a pay link).
string | null
Such as Visa ···· 4242. null for invoice collection or when none is saved.
boolean
Cancels when currentPeriodEnd is reached.
name, interval, currency, discountLabel, paymentTermsDays, trialEnd and currentPeriodEnd are what they say. To be told when a subscription starts, changes or ends, rather than polling, listen for subscription.started, subscription.updated, subscription.canceled, payment.succeeded, payment.failed and invoice.overdue webhooks.

Revenue metrics

GET /v1/revenue/metrics The workspace’s recurring revenue, read live from Stripe. The key’s creator must be a workspace admin, as in the app.
object[]
One entry per currency, the largest MRR first. mrr is monthly recurring revenue after today’s discounts (metered usage is not included); arr is mrr × 12; activeSubscriptions counts the subscriptions that bill.
number | null
Net revenue retention, trailing 12 months: what the customers who paid a year before the last complete month paid in that month, divided by what they paid then. 1.08 is 108%. Customers who joined since do not count; one who left counts as zero. null when nobody paid a year ago.
object[]
Invoiced per month (YYYY-MM) for the last 12 months, the current month last. Drafts and voided invoices are left out.
object[]
Up to five customers with the most MRR, by name.
truncated is true when Stripe holds more subscriptions or invoices than one read covers, so the figures undercount.

Billing sessions

POST /v1/customers/{customer}/billing-sessions Opens one customer’s billing page for 15 minutes. Call it from your server each time the customer opens Billing, then redirect to url, or pass token to CustralBilling.mount (@custral/js). The key’s creator needs Edit on the customer.
string
Where the page’s Back link and Stripe’s pages return. https only (http for localhost), on a host in allowedReturnDomains.
The token is a bearer credential for that one customer’s page. Send it to their browser only, and open a fresh session rather than storing one.

Cancel and resume

POST /v1/customers/{customer}/subscriptions/cancel Sets the customer’s plan to end at the period end. Nothing is charged or refunded. Unlike the billing page, this does not check the page’s settings: your server is acting, not the customer.
string
One of too_expensive, missing_features, switched_service, unused, other. Recorded in Stripe’s cancellation details.
string
Free text, recorded beside the reason.
POST /v1/customers/{customer}/subscriptions/resume keeps a plan that was set to end, and returns {resumed: true}.

Billing setup

GET /v1/billing/setup says whether billing from your product works yet. It needs billing:admin, and the key’s creator must be a workspace admin, as in Settings → Payments.
stripe.mode is test or live, read from the connected account. missing lists what is left, in the order to do it. Stripe can’t be connected through the API, because Stripe asks a person for consent. POST /v1/billing/setup/connect-link returns the settings page an admin opens to press Connect Stripe.

Payment settings

GET /v1/billing/settings and PATCH /v1/billing/settings read and change what Settings → Payments holds. Objects and properties are named by their key (account, account_id), never by id. Omitted fields stay as they are, and "" clears one.
string
The property on the customers object holding your app’s own customer id.
string
The email property on the customers object naming who gets invoices.
object[]
Other objects a quote can start from, each {object, link}, where link is its relation to the customers object (a deal that bills its account).
string
The relation on the customers object to a parent that sees its billing.
object
Which billing fields Custral keeps on which object, by object key: {"account": ["billing_status", "mrr"]}.
string[]
The ways to pay offered on Stripe’s pages.
string
autopay or invoice, for a quote that names neither.
integer
Days to pay an invoice, 0 to 365.
string[]
Hosts a returnUrl may point at. Anything else is refused with return_url_not_allowed.
string
The Stripe customer metadata key that holds your customer id, for matching existing Stripe customers to records.
The customers object itself is picked in Settings → Payments, because it carries a field mapping. The response names it as customersObject.

Billing page settings

GET /v1/billing/page and PATCH /v1/billing/page read and change what a customer’s billing page shows. Omitted fields stay as they are.
object
paymentMethod, usage, invoices, billingContact: each true to show it.
object
updateCard, changePlan, cancel: each true to offer it.
string
period_end (the default) or immediately. An upgrade is always charged now.
boolean
Ask why when a customer cancels.
The plans a customer can switch between are Plans.

Errors

See Errors for the HTTP status each code maps to.