/api/v1/billing/invoicesFetch 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
Common use case
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
| Name | In | Required | Default | Allowed | Description | Example |
|---|---|---|---|---|---|---|
| limit | query | optional | 10 | — | Max 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
| Field | Type | Nullable | Description |
|---|---|---|---|
| status | string | no | ApiResponse envelope status — `success` on 200. |
| request_id | string | yes | Per-request correlation ID. |
| timestamp | string | no | ISO-8601 UTC timestamp. |
| data | array | no | Array 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[].id | string | no | Stripe invoice ID in `in_XXXXXX` format. Stable for the lifetime of the invoice. Use as deduplication key when caching client-side. |
| data[].amount_due | integer | no | Amount 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_paid | integer | no | Amount 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[].status | string | no | Stripe 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_pdf | string | yes | Short-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[].created | integer | no | Unix 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[].currency | string | no | ISO-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
| Status | Label | Description |
|---|---|---|
| 200 | OK | Request succeeded. |
| 400 | Bad Request | Invalid query, body, or path parameter. |
| 401 | Unauthorized | Missing or invalid Authorization header / api_Token. |
| 402 | Payment Required | Insufficient token balance for this call. Top up |
| 429 | Too Many Requests | Rate limit exceeded for your tier (see /pricing for tier limits). Tier limits |
| 500 | Server Error | Unexpected 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).