API ReferenceBilling

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 a subscription_start event said it began. Never guessed; null if 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_amount is per billing cycle, with tax removed.
  • monthly_recurring_amount — the same amount normalised to one month using the plan's cadence: a 499 yearly plan reads back as roughly 41.58 monthly. It is null rather than 0 when 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_reasonWhat it meansWhat to do
NO_STATESNothing has been recorded for it at all.Check the invoice line or start event actually landed.
NOT_IN_FORCE_YETEverything recorded takes effect in the future, or has been retracted.Expected for a scheduled start. Otherwise check your effective_dates.
NOT_COMMENCEDIt was billed, but nothing proves service started.Record the transaction that paid the first invoice, or send a subscription_start event.
CANCELLEDA cancellation is in force.Expected after churn.
EXPIREDThe subscription ran out.Expected.
COMPLETEDIt finished its term.Expected.
INSUFFICIENT_LIFECYCLE_EVIDENCEThe 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, PAUSED or RESUMED. 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.