QuickstartAPI ReferenceBilling IntegrationTutorials

Public docs for evaluation and integration.

Billing Integration API v1

Pricing, usage, and balance

Use three read-only, buyer-scoped endpoints to read the prices that apply to your account, reconcile finalized charges, and check current service-credit headroom.

Availability

Enabled per customer account

Credential

Dedicated bi_v1_ credential

Scope

Authenticated buyer only

Currency

USD decimal strings

Before you call

Billing Integration is separate from model inference. Your account must be enabled and you must use the dedicated reporting credential supplied during onboarding.

Environment
API_ORIGIN="https://api.elss.ai"
BILLING_CREDENTIAL="replace-with-your-bi_v1-credential"
  • Send the credential in Authorization: Bearer. A normal sk-* inference key is rejected.
  • Keep the credential on a trusted server. Do not place it in browser code, mobile apps, repositories, URLs, or logs.
  • The credential is fixed to your buyer account and billing.read scope. The API does not accept account_id or another customer selector.
  • All successful responses are JSON and include Cache-Control: private, no-store. Monetary values are exact decimal strings, never binary floating-point numbers.

Recommended polling flow

Each endpoint answers a different accounting question. Keep their responsibilities separate in your integration.

  1. 1. Cache the price contract

    Read /pricing and retain catalog_revision with ETag.

  2. 2. Import finalized usage

    Poll a closed UTC settlement window and store its immutable revision references.

  3. 3. Monitor headroom

    Read /balance for the amount currently available to spend.

GET

/v1/billing/pricing

Returns the active customer-visible catalog, or one exact historical catalog revision, for the authenticated buyer.

Use this to configure internal cost controls or explain which price contract applies. Do not use the public models page as an invoice authority.

Request contract

FieldType / locationRequirementMeaning
Authorizationheader · stringRequiredBearer followed by the dedicated bi_v1_ credential.
modelquery · stringOptionalReturn one exact canonical model. An unknown model returns billing_catalog_not_found.
catalog_revisionquery · stringOptionalRead one immutable historical catalog. Omit it for the active catalog.
If-None-Matchheader · stringOptionalSend the ETag from a prior response. An exact match returns 304 with no body.

Example request

cURL
curl --get "$API_ORIGIN/v1/billing/pricing" \
  --data-urlencode "model=gpt-5.4" \
  --header "Authorization: Bearer $BILLING_CREDENTIAL"

Example response

JSON
{
  "catalog_revision": "9e0d...5b7a",
  "effective_at": "2026-08-18T00:00:00Z",
  "settlement_profile_revision": "5c81...b210",
  "currency": "USD",
  "items": [
    {
      "model": "gpt-5.4",
      "catalog_item_revision": "861a...0d4c",
      "commitment_label": "Standard service",
      "rates": [
        {
          "component": "input",
          "unit": "token",
          "variant": "standard",
          "min_input_tokens": 0,
          "state": "priced",
          "amount": "2.500000000",
          "unit_scale": 1000000
        }
      ]
    }
  ]
}

Response contract

FieldType / locationRequirementMeaning
catalog_revisionstringAlwaysOpaque revision for the complete customer-visible catalog.
effective_atRFC3339 UTCAlwaysTime this catalog revision became active.
settlement_profile_revisionstringAlwaysImmutable revision used to convert internal quota into public USD amounts.
currencystringAlwaysUSD in Billing Integration v1.
items[].modelstringAlwaysCanonical model ID callable by this buyer.
items[].catalog_item_revisionstringAlwaysOpaque price revision for this model item.
items[].commitment_labelstringWhen presentCustomer-visible service commitment label.
items[].rates[]arrayAlwaysComponent rates keyed by component, unit, variant, and minimum input-token band.
rates[].amountdecimal stringAlwaysUSD price for the entire rates[].unit_scale quantity, not for one unit.
rates[].statepriced | freeAlwaysWhether this component has a positive price or is explicitly free.

How to use the result

  • Persist catalog_revision and catalog_item_revision beside any downstream cost rule derived from this response.
  • Treat each rate as amount per unit_scale. Use a decimal library and preserve every returned fractional digit.
  • Use the greatest applicable min_input_tokens band for the returned variant; do not average multiple bands.
  • Cache by ETag, but refetch the active catalog before changing production pricing assumptions.
GET

/v1/billing/usage

Returns a complete aggregate of finalized billing records for one closed UTC settlement window.

Use this for daily reconciliation and downstream cost allocation. A successful empty items array means the complete window contains no settled usage.

Request contract

FieldType / locationRequirementMeaning
Authorizationheader · stringRequiredBearer followed by the dedicated bi_v1_ credential.
start_timequery · RFC3339 UTCRequiredInclusive start, whole-second timestamp ending in Z.
end_timequery · RFC3339 UTCRequiredExclusive end, whole-second timestamp ending in Z. It cannot be in the future.
group_byquery · stringRequiredMust be exactly model in v1.

Example request

cURL
curl --get "$API_ORIGIN/v1/billing/usage" \
  --data-urlencode "start_time=2026-08-17T00:00:00Z" \
  --data-urlencode "end_time=2026-08-18T00:00:00Z" \
  --data-urlencode "group_by=model" \
  --header "Authorization: Bearer $BILLING_CREDENTIAL"

Example response

JSON
{
  "start_time": "2026-08-17T00:00:00Z",
  "end_time": "2026-08-18T00:00:00Z",
  "as_of": "2026-08-18T00:05:00Z",
  "data_complete_through": "2026-08-18T00:00:00Z",
  "items": [
    {
      "model": "gpt-5.4",
      "catalog_revision": "9e0d...5b7a",
      "catalog_item_revision": "861a...0d4c",
      "settlement_profile_revision": "5c81...b210",
      "currency": "USD",
      "meters": [
        {
          "code": "input",
          "quantity": "4200000",
          "unit": "token",
          "coverage": "complete",
          "evidence_state": "final"
        }
      ],
      "request_count": 128,
      "gross_amount": "12.000000000",
      "waiver_amount": "2.000000000",
      "net_billed_amount": "10.000000000",
      "charge_state": "waived",
      "coverage": "complete",
      "data_complete_through": "2026-08-18T00:00:00Z",
      "as_of": "2026-08-18T00:05:00Z"
    }
  ]
}

Response contract

FieldType / locationRequirementMeaning
start_time / end_timeRFC3339 UTCAlwaysEchoed half-open settlement window [start_time, end_time).
as_ofRFC3339 UTCAlwaysServer snapshot time for this report.
data_complete_throughRFC3339 UTCAlwaysCompleteness boundary. On success it matches the requested end_time.
items[].modelstringAlwaysCanonical model ID.
items[].catalog_revisionstringAlwaysCatalog revision active for these settled records.
items[].catalog_item_revisionstringAlwaysExact model-price revision used for these records.
items[].settlement_profile_revisionstringAlwaysUSD conversion revision used for all amounts in this row.
items[].meters[]arrayAlwaysFinal measured quantities. Each entry includes code, quantity, unit, coverage, and evidence_state.
items[].request_countintegerAlwaysLogical customer requests, not provider attempts or retries.
gross_amountdecimal stringAlwaysCharge before waivers.
waiver_amountdecimal stringAlwaysWaived amount, including exact display-rounding conservation where applicable.
net_billed_amountdecimal stringAlwaysAuthoritative customer charge. gross_amount - waiver_amount equals this value exactly.
charge_statecharged | waived | no_chargeAlwaysWhy this aggregate has its reported net amount.
coveragecompleteAlwaysEvidence completeness for this aggregate. Incomplete reports fail instead of returning partial rows.

How to use the result

  • The window is based on billing_settled_at, not request creation time. Query a closed UTC period such as the previous day.
  • The maximum window is 31 days and the maximum result is 1,000 aggregate rows. Split large reconciliation jobs into smaller windows.
  • Rows are separated when model, catalog revision, item revision, settlement profile, or charge state differs. Do not merge them without preserving those dimensions.
  • Only ingest a 200 response. A billing_report_not_ready error means the entire window is unavailable; no partial result was returned.
  • Parse quantities and money as decimal strings. Do not use IEEE-754 float arithmetic for reconciliation.
GET

/v1/billing/balance

Returns the authenticated buyer's current service-credit and admission-credit headroom.

Use available_to_spend for alerts and admission decisions. This is a current snapshot, not a reservation or a cash-wallet statement.

Request contract

This endpoint accepts no query parameters.

FieldType / locationRequirementMeaning
Authorizationheader · stringRequiredBearer followed by the dedicated bi_v1_ credential.

Example request

cURL
curl "$API_ORIGIN/v1/billing/balance" \
  --header "Authorization: Bearer $BILLING_CREDENTIAL"

Example response

JSON
{
  "currency": "USD",
  "balance_kind": "service_credit",
  "available_service_credit": "4820.150000000",
  "admission_credit": "500.000000000",
  "available_to_spend": "5320.150000000",
  "settlement_profile_revision": "5c81...b210",
  "as_of": "2026-08-18T09:00:00Z"
}

Response contract

FieldType / locationRequirementMeaning
currencystringAlwaysUSD in Billing Integration v1.
balance_kindservice_creditAlwaysConfirms that the response is service capacity, not cash or a refundable wallet.
available_service_creditdecimal stringAlwaysNon-negative prepaid or account service-credit component.
admission_creditdecimal stringAlwaysNon-negative credit-line component used for request admission.
available_to_spenddecimal stringAlwaysAuthoritative current spendable headroom after account deficit rules.
settlement_profile_revisionstringAlwaysUSD conversion revision used by this snapshot.
as_ofRFC3339 UTCAlwaysServer time at which the balance was read.

How to use the result

  • Use available_to_spend as the alert and admission value. It may differ from adding the two displayed components when the account carries a deficit.
  • Do not present these values as cash, funds on deposit, refundable balance, or an accounting ledger balance.
  • A successful read does not reserve capacity. Recheck close to any consequential operation and tolerate concurrent spending.

Errors and recovery

Billing endpoint errors use a stable JSON envelope with code, message, and request_id. Branch on error.code; preserve request_id for support.

HTTPError codeMeaningClient action
400billing_request_invalidUnknown field, invalid timestamp, unsupported grouping, or invalid window.Correct the request; do not retry unchanged.
400billing_result_limit_exceededThe report would exceed the bounded aggregate result limit.Split the time range into smaller windows.
401billing_credential_invalidCredential is missing, malformed, expired, revoked, or no longer valid for the active account profile.Replace or rotate the credential; do not use an sk-* key.
404billing_integration_unavailableThe optional Billing Integration capability is not ready on this deployment.Verify service availability or contact support; avoid rapid retries.
404billing_catalog_not_foundThe requested model or historical catalog revision is unavailable.Fetch the active catalog or correct the selector.
409billing_report_not_readyOne or more required settlement or evidence facts are not complete for the requested window.Do not ingest partial data; retry the same window with backoff.
503billing_query_timed_outThe bounded reporting query exceeded its server deadline.Retry with backoff; use a smaller window if it repeats.
500billing_query_failedAn unexpected reporting failure occurred.Retry with backoff and provide request_id if it persists.

Billing error envelope

JSON
{
  "error": {
    "code": "billing_report_not_ready",
    "message": "Billing report is not ready.",
    "request_id": "req_01J..."
  }
}

Retry policy

  • GET requests are idempotent. Retry 409, 429, 500, and 503 with exponential backoff and jitter; cap attempts and surface persistent failures.
  • Do not automatically retry 400 or 401 without changing the request or credential. Treat 404 as a configuration or selector issue first.
  • A gateway rate limit can return HTTP 429 using the standard API error envelope instead of the billing-specific code envelope.
  • Log status, error.code, and request_id. Never log the Authorization header or raw credential.

Go-live checklist

Complete these checks before relying on the API for customer-facing accounting or automated controls.

  • Store the bi_v1_ credential in a server-side secret manager and verify that sk-* keys are not used on billing routes.
  • Use an exact decimal library for every amount and meter quantity.
  • Persist catalog, catalog-item, and settlement-profile revisions with imported usage.
  • Poll closed UTC windows, preserve [start_time, end_time), and make imports idempotent by window plus returned revisions.
  • Treat 409 as no report, not zero usage, and alert after bounded retries.
  • Use available_to_spend for headroom monitoring while treating the response as a non-reserving snapshot.