Subscriptions
Read what your invoices and events add up to — and why a subscription is or is not counted.
Subscriptions
GET https://api.faurya.com/api/v1/billing/subscriptions/{external_id}Requires Bearer Token authentication with your Faurya API key.
This endpoint is read-only and exists for one reason: to answer "why is this subscription not showing up?"
You never create a subscription directly. It comes into being from an invoice line or a subscription_start event, and its history is the sum of every line and event that touched it. This endpoint shows you that history, the one state that governs right now, and — if the subscription is not counted as a subscriber — which rule says so.
const response = await fetch(
"https://api.faurya.com/api/v1/billing/subscriptions/sub_900",
{ headers: { Authorization: `Bearer ${process.env.FAURYA_API_KEY}` } },
);Response
{
"object": "subscription",
"external_id": "sub_900",
"data": {
"external_id": "sub_900",
"customer_external_id": "cus_42",
"started_at": "2026-01-01T00:00:00.000Z",
"status": "ACTIVE",
"plan_external_id": "plan_pro_monthly",
"recurring_amount": 49,
"currency": "USD",
"quantity": 1,
"monthly_recurring_amount": 49,
"counts_as_subscriber": true,
"not_counted_reason": null,
"states": [
{
"source": "line:inv_1042/li_1",
"change_type": "CREATED",
"status": "ACTIVE",
"plan_external_id": "plan_pro_monthly",
"recurring_amount": 49,
"currency": "USD",
"quantity": 1,
"event_order": null,
"occurred_at": "2026-03-01T00:00:00.000Z",
"effective_at": "2026-03-01T00:00:00.000Z",
"retracted_at": null
}
]
},
"request_id": "req_01JQ8Z0Y5N6W3K2M4P7R9T1V3X"
}The summary
started_at— when asubscription_startevent said it began. Never guessed;nullif no start event was ever sent.status— the lifecycle status of the state in force right now.plan_external_id,recurring_amount,currency,quantity— what that governing state says the subscription costs.recurring_amountis per billing cycle, with tax removed.monthly_recurring_amount— the same amount normalised to one month using the plan's cadence: a499yearly plan reads back as roughly41.58monthly. It isnullrather than0when the amount or the cadence is unknown, because a zero would read as "no revenue".counts_as_subscriber— whether this subscription is in your subscriber count.not_counted_reason— why not, when it is not.
These figures are the subscription's own, in its own currency, with none of your site's policies applied — no churn-recognition window, no past-due auto-churn, no conversion into your reporting currency. Your reports are the authority on those. This endpoint tells you what the subscription itself states, which is what you need when the two disagree.
Why a subscription is not counted
not_counted_reason | What it means | What to do |
|---|---|---|
NO_STATES | Nothing has been recorded for it at all. | Check the invoice line or start event actually landed. |
NOT_IN_FORCE_YET | Everything recorded takes effect in the future, or has been retracted. | Expected for a scheduled start. Otherwise check your effective_dates. |
NOT_COMMENCED | It was billed, but nothing proves service started. | Record the transaction that paid the first invoice, or send a subscription_start event. |
CANCELLED | A cancellation is in force. | Expected after churn. |
EXPIRED | The subscription ran out. | Expected. |
COMPLETED | It finished its term. | Expected. |
INSUFFICIENT_LIFECYCLE_EVIDENCE | The state in force has a status no membership rule covers. | Send a lifecycle event that states the subscription's status plainly. |
NOT_COMMENCED is by far the most common surprise, and it is deliberate: an unpaid first invoice is a checkout that may never complete, so Faurya does not count it as a subscriber until a collected payment, a trial line, a free period or a start event proves service began. Renewals after that stay active whether or not they are paid — that is dunning, not a subscription that never started.
The state history
states is every state ever derived for the subscription, in order, including retracted ones. It is the audit trail behind the summary.
source— where the state came from.line:<invoice id>/<line id>for an invoice line,event:<event id>for a subscription event.change_type—CREATED,RENEWED,UPDATED,PLAN_CHANGED,CANCELLED,SCHEDULED_CANCELLATION,PAUSEDorRESUMED. Faurya derives this by comparing each period against the one before it; you never send it.status— what the subscription was in that state.occurred_at— when it was decided, or when the invoice was issued.effective_at— when it took, or takes, hold. This is what "in force at T" is measured on.retracted_at— set when a retraction withdrew this state, or a line was removed from an open invoice. A retracted state is kept, not deleted, so the history stays readable.
Because change_type is relational, sending a back-dated invoice can change the change_type of a state another invoice produced — a CREATED becomes a RENEWED once the period before it arrives. That is correct, and it is why you can upload a history in any order.
Response codes
200 OK— the subscription exists.401 Unauthorized— missing or invalid API key.404 Not Found— no subscription with that id. Nothing has named it yet.429 Too Many Requests— over the rate limit.