Skip to content
/api/v1/billing/invoices

Fetch Stripe invoices for the authenticated user (PDF download links + amounts + status).

Fetch Stripe invoices for the authenticated user (PDF download links + amounts + status). EXEMPT (`cost: 0`). Returns an empty array for users without a `stripe_customer_id` (free-tier users who never upgraded).

Why use this

Live Stripe invoice list for the authenticated user — calls `stripe.Invoice.list(customer=...)` server-side and returns the relevant fields. EXEMPT (`cost: 0`). Returns empty array (NOT 400) for users without `stripe_customer_id` so the dashboard 'Invoices' table can render the empty state without special-casing free-tier users. Amounts are in CENTS (Stripe's native unit) — divide by 100 for USD display. The `invoice_pdf` URL is a short-lived Stripe-hosted PDF download — passes through Stripe's auth on click, no need to authenticate the request server-side.

Common use case

Dashboard 'Wallet → Invoices' table: GET this on page load → render rows of `created` (date) / `amount_paid` / `status` / 'Download PDF' link. For an inline transaction history (charges + grants + refunds) use [GET /api/v1/billing/history](/docs/account/billing-and-subscription/get-billing-history); for the Stripe Customer Portal where the user can download invoices and update billing info use [POST /api/v1/account/billing-portal](/docs/account/token-pricing/post-account-billing-portal).

Live Stripe invoice list for the authenticated user — wraps stripe.Invoice.list(customer=...) server-side and returns the canonical fields the dashboard needs. EXEMPT (cost: 0). AMOUNTS ARE IN CENTS (Stripe-native) — divide by 100 for USD display. Free-tier users without stripe_customer_id get an empty array (NOT 400) so the dashboard 'Invoices' table renders an empty state cleanly. The invoice_pdf URL is short-lived but Stripe-authenticated — pass directly to <a href> without auth. For an inline mixed transaction history (charges + admin grants + refunds, NOT just Stripe charges) use GET /api/v1/billing/history; for full subscription self-service (cancel, update card, view full invoice history beyond the most recent N) use POST /api/v1/account/billing-portal. To check the user's current subscription state use GET /api/v1/billing/subscription.

Parameters

NameInRequiredDefaultAllowedDescriptionExample
limitqueryoptional10Max invoices to return per page. Default 10. Stripe enforces an upper bound of 100 server-side — values above are silently truncated by Stripe. For a user's full invoice history, paginate via Stripe's `starting_after` cursor (NOT exposed by this endpoint — use POST /api/v1/account/billing-portal for full history).20

Response schema

FieldTypeNullableDescription
statusstringnoApiResponse envelope status — `success` on 200.
request_idstringyesPer-request correlation ID.
timestampstringnoISO-8601 UTC timestamp.
dataarraynoArray of Stripe invoice rows, sorted by Stripe (newest first by default). Empty array on free-tier users without `stripe_customer_id` AND on Stripe API errors (server logs the error and returns empty rather than 5xx — graceful degradation). Cap at the requested `limit` (default 10, max 100 enforced by Stripe).
data[].idstringnoStripe invoice ID in `in_XXXXXX` format. Stable for the lifetime of the invoice. Use as deduplication key when caching client-side.
data[].amount_dueintegernoAmount still owed on the invoice in CENTS (Stripe-native unit). 0 for paid invoices; positive for `open` / `past_due` invoices. Divide by 100 for USD display.
data[].amount_paidintegernoAmount already paid on the invoice in CENTS. For monthly subscriptions on the Paid plan: 2900 (= $29.00). Sum across all paid invoices = lifetime customer revenue.
data[].statusstringnoStripe invoice status — `paid` (most common), `open` (awaiting payment), `void` (admin-cancelled), `uncollectible` (Stripe gave up after retries), `draft` (rare, mostly admin-created). Drives UI badges.
data[].invoice_pdfstringyesShort-lived Stripe-hosted PDF URL for the invoice receipt. Passes through Stripe's auth — no server-side auth needed; just `<a href={invoice_pdf} target="_blank">Download</a>`. Null for invoices in `draft` or `void` status.
data[].createdintegernoUnix epoch timestamp (seconds) the invoice was created in Stripe. Multiply by 1000 for JS Date constructor: `new Date(invoice.created * 1000)`. Use for chronological display.
data[].currencystringnoISO-4217 currency code (lowercase per Stripe convention — e.g. `usd`, `eur`). Use to render currency symbol.

Sample response

·
  • "status": "success"
  • "request_id": "req_3OqK2jK9L8pQ4xZ7"
  • "timestamp": "2026-05-02T15:51:00.000Z"
  • "data":
    ]
}

Errors

StatusLabelDescription
200OKRequest succeeded.
400Bad RequestInvalid query, body, or path parameter.
401UnauthorizedMissing or invalid Authorization header / api_Token.
402Payment RequiredInsufficient token balance for this call. Top up
429Too Many RequestsRate limit exceeded for your tier (see /pricing for tier limits). Tier limits
500Server ErrorUnexpected server-side failure. Retry with backoff; report if persistent.

Code samples

curl "https://api.finradar.ai/api/v1/billing/invoices" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

Generate an API key in /account/credentials to run live queries (literal YOUR_API_KEY placeholder shown until then).