Billing

Read your balance, credit grants, and invoices. Reads only — no money moves through this API.

What your organization has, what it owes, and what it bought. Reads only.

EndpointScopeToken owner's role
GET /billing/balancebilling:readAdmin
GET /billing/grantsbilling:readAdmin
GET /billing/invoicesbilling:readAdmin
GET /billing/invoices/{id}billing:readAdmin

Billing is admin-only: the token owner must currently be an organization Admin (403 insufficient_scope otherwise). Payments, payment methods, credit purchases and billing-mode changes are handled in the portal.

Credit amounts are integer nano-USD (*_nanousd, 10⁻⁹ USD — exact), with a convenience *_usd number alongside; invoices carry integer cents in their own currency. Balances and invoices are views of the same record as Usage; if an API response and an issued invoice ever disagree, the invoice governs.

Python examples share this setup:

import os
import requests

BASE = "https://portal.<domain>/api/v1/mgmt"
s = requests.Session()
s.headers["Authorization"] = f"Bearer {os.environ['TF_PAT']}"

Retrieve the balance

GET /api/v1/mgmt/billing/balance

The organization's prepaid credit wallet — the balance every inference request is checked against.

FieldTypeNotes
available_nanousdintegerCredit available, in nano-USD.
available_usdnumberThe same amount in USD, for display.
currencystringAlways USD.
wallet_presentbooleanfalse when the organization has never been granted credit.
curl https://portal.<domain>/api/v1/mgmt/billing/balance \
  -H "Authorization: Bearer $TF_PAT"
{
  "available_nanousd": 1835617883000,
  "available_usd": 1835.617883,
  "currency": "USD",
  "wallet_present": true
}

If billing data is temporarily unavailable the call is 502 upstream_unavailable — retry.

List credit grants

GET /api/v1/mgmt/billing/grants

Every credit movement on the organization — grants, top-ups, refunds — newest first. Paginated.

FieldTypeNotes
idstringA stable id for the row (grant_…).
created_atstring
sourcestringWhere the credit came from, e.g. stripe (a top-up), signup, promo, admin_grant, refund. Treat it as an open set.
memostringHuman description.
amount_nanousdintegerNegative for refunds and reversals.
amount_usdnumberThe same amount in USD.
referencestring | nullThe payment reference for a top-up, when there is one.
curl https://portal.<domain>/api/v1/mgmt/billing/grants \
  -H "Authorization: Bearer $TF_PAT"
{
  "data": [
    {
      "id": "grant_9f2c41d07a5b3e18",
      "created_at": "2026-09-01T12:00:00Z",
      "source": "stripe",
      "memo": "Credit top-up",
      "amount_nanousd": 2000000000000,
      "amount_usd": 2000,
      "reference": "pi_3P…"
    },
    {
      "id": "grant_1ab07c3de4f59260",
      "created_at": "2026-03-02T09:41:17Z",
      "source": "signup",
      "memo": "Starter credit",
      "amount_nanousd": 25000000000,
      "amount_usd": 25,
      "reference": null
    }
  ],
  "has_more": false,
  "next_cursor": null
}

List invoices

GET /api/v1/mgmt/billing/invoices

Paginated, newest first.

FieldTypeNotes
idstringOpaque id.
stripe_invoice_idstringThe payment provider's invoice id.
amount_centsintegerInvoice total in cents of currency.
currencystring
statusstringThe invoice status reported by the payment provider, e.g. open or paid.
period_start, period_endstring | nullThe billed period.
pdf_urlstring | nullThe provider-hosted PDF, once issued.
created_atstring
curl https://portal.<domain>/api/v1/mgmt/billing/invoices \
  -H "Authorization: Bearer $TF_PAT"
{
  "data": [
    {
      "id": "f0e1d2c3-b4a5-4968-8776-5a4b3c2d1e0f",
      "stripe_invoice_id": "in_1Q…",
      "amount_cents": 421193,
      "currency": "usd",
      "status": "paid",
      "period_start": "2026-08-01T00:00:00Z",
      "period_end": "2026-09-01T00:00:00Z",
      "pdf_url": "https://…/invoice.pdf",
      "created_at": "2026-09-01T02:00:00Z"
    }
  ],
  "has_more": false,
  "next_cursor": null
}

Retrieve an invoice

GET /api/v1/mgmt/billing/invoices/{id}

Returns one invoice — the same object as a list row. An id that is not one of your organization's invoices returns 404.

curl https://portal.<domain>/api/v1/mgmt/billing/invoices/f0e1d2c3-b4a5-4968-8776-5a4b3c2d1e0f \
  -H "Authorization: Bearer $TF_PAT"

Reconcile usage with billing

  1. Pull the period from GET /usage with from/to set to the invoice's period_start/period_end.
  2. When the invoice's currency is usd, compare the usage totals.cost_nanousd with the invoice's amount_cents directly (1 cent = 10,000,000 nano-USD).
  3. Between invoices, watch GET /billing/balance fall as usage accrues.

Both sides are the same record, so this is a check, not a fix-up — if they disagree, contact support. Quote the X-Request-Id of both responses.

Errors specific to billing

StatusCodeWhen
403insufficient_scopeToken lacks billing:read, or the owner is not currently an Admin.
404not_foundInvoice absent or in another organization.
422unsupported_filterAny query parameter other than limit/cursor on the lists.
502upstream_unavailableBilling data (balance, grants) is temporarily unavailable. Retry.