Account credits & pricing

Read the available credits for an API key and fetch its current model price catalog.

Authentication

Both endpoints are server-to-server endpoints. Authenticate with Authorization: Bearer <API_KEY>. Keep the key on your backend; do not expose it in browser code.

Available credits

GET/v1/account/credits

Returns the account-level credits available to the current API key and the limit remaining for that key.

curl https://hopsapi.com/v1/account/credits \\
  -H "Authorization: Bearer sk-YOUR_KEY"
{
  "data": {
    "credits": "1250.500000",
    "outstanding": "12.300000",
    "currency": "credits",
    "credits_per_usd": "100",
    "key_limit": {
      "limit": "500.000000",
      "spent": "120.250000",
      "remaining": "359.750000"
    },
    "updated_at": "2026-09-18T09:00:00.000Z"
  }
}
  • credits is the available account balance used by admission checks. outstanding has already been deducted from it; do not subtract outstanding again.
  • outstanding is the sum of unsettled LLM usage, unsettled image usage, and in-flight media reservations.
  • key_limit is null for an unlimited key. When present, remaining is limit − spent − reserved (the same bucket admission uses). The example above is 500 − 120.25 − 20 reserved. Check both credits and key_limit.remaining before starting a costly request.
  • All monetary fields are decimal strings. Amounts use six fractional digits; credits_per_usd is derived from the current credit price.
  • updated_at is the timestamp of the balance read. A cached provider balance keeps its cache timestamp.
  • This response does not expose credit-line or other lending fields.

Errors

HTTP statuserror.typeMeaning
401authentication_errorThe key is missing, invalid, inactive, or no longer usable.
503internal_errorThe account balance could not be read. The response includes error.code and error.request_id.

A 503 means that the balance is unavailable, not that the account has zero credits. Do not replace it with a zero balance.

Model price catalog

GET/v1/models/pricing

Returns one current, key-scoped catalog for every model and channel that the API key can call.

curl https://hopsapi.com/v1/models/pricing \\
  -H "Authorization: Bearer sk-YOUR_KEY"

The response has one catalog version and a forward-compatible data array:

{
  "catalog_version": "c1f0a9e2",
  "generated_at": "2026-09-18T09:00:00.000Z",
  "currency": "credits",
  "credits_per_usd": "100",
  "data": [
    {
      "kind": "llm",
      "price_unit": "1M_tokens",
      "list": [
        {
          "model": "claude-sonnet-5",
          "display_name": "Claude Sonnet 5",
          "channel": "flex",
          "channel_name": "Subscription Direct",
          "official_input": "200.000000",
          "official_output": "1000.000000",
          "input_price": "70.000000",
          "output_price": "350.000000",
          "cache_read_price": "7.000000",
          "cache_write_price": "87.500000",
          "cache_write_1h_price": "140.000000"
        }
      ]
    },
    {
      "kind": "media",
      "price_unit": "per_call",
      "list": [
        {
          "model": "gpt-image-2",
          "display_name": "GPT Image 2",
          "channel": "standard",
          "channel_name": "Official API Relay",
          "reference_price": "5.000000",
          "reference_note": "Per image; quality and resolution determine the locked task price",
          "call_price": "3.350000",
          "token_prices": [{ "meter": "text_input", "price": "3.350000" }]
        }
      ]
    }
  ]
}

Reading the catalog

  • Use (model, channel) as the price key. The same model can have different prices for standard (Official API Relay) and flex (Subscription Direct).
  • data is an array of groups, not an object with fixed llm and media properties. Group and row fields differ by kind; skip an unknown kind instead of failing. New product categories can be added without changing existing groups.
  • The platform includes each currently available product group even when this key has no authorization for it; that group then has an empty list and may include empty_reason: "no_authorization".
  • LLM prices are credits per 1M tokens. cache_read_price falls back to the model input price when no separate cached-input price is configured. Cache-write prices are populated only for Anthropic-compatible channels; other rows return null.
  • Media reference_price is informational. Parameterized media tasks use the price locked when the task is created, so the final charge is not guaranteed to equal reference_price. A media row can also expose token_prices; reconcile that part from actual usage.
  • The catalog has no advance-price notice period and no historical catalog versions. Reconcile each call using its x-aitoken-request-id and the price snapshot recorded for that call, rather than relying on catalog_version as an accounting record.

ETag polling

Cache the response body and its ETag, then send If-None-Match on the next request:

curl -i https://hopsapi.com/v1/models/pricing \\
  -H "Authorization: Bearer sk-YOUR_KEY" \\
  -H 'If-None-Match: "c1f0a9e2"'

An unchanged catalog returns 304 Not Modified with no response body. A changed price, authorization scope, or model catalog produces a new catalog_version and ETag.

These account and catalog endpoints do not use the LLM account limits or the retired shared per-key/per-IP allowance. Every response includes x-aitoken-request-id; retain it for support and reconciliation. The pricing endpoint returns 503 with pricing_unavailable if its source data cannot be read; do not treat an empty catalog as a read failure response.

On this page

On this page