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
/v1/account/creditsReturns 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"
}
}creditsis the available account balance used by admission checks.outstandinghas already been deducted from it; do not subtractoutstandingagain.outstandingis the sum of unsettled LLM usage, unsettled image usage, and in-flight media reservations.key_limitisnullfor an unlimited key. When present,remainingislimit − spent − reserved(the same bucket admission uses). The example above is500 − 120.25 − 20reserved. Check bothcreditsandkey_limit.remainingbefore starting a costly request.- All monetary fields are decimal strings. Amounts use six fractional digits;
credits_per_usdis derived from the current credit price. updated_atis 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 status | error.type | Meaning |
|---|---|---|
401 | authentication_error | The key is missing, invalid, inactive, or no longer usable. |
503 | internal_error | The 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
/v1/models/pricingReturns 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 forstandard(Official API Relay) andflex(Subscription Direct). datais an array of groups, not an object with fixedllmandmediaproperties. Group and row fields differ bykind; skip an unknownkindinstead 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
listand may includeempty_reason: "no_authorization". - LLM prices are credits per 1M tokens.
cache_read_pricefalls 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 returnnull. - Media
reference_priceis informational. Parameterized media tasks use the price locked when the task is created, so the final charge is not guaranteed to equalreference_price. A media row can also exposetoken_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-idand the price snapshot recorded for that call, rather than relying oncatalog_versionas 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.