Wallet
Wallet
Four read-only endpoints, scoped to the key’s owner. A developer billing their own
customers needs the same figures the dashboard shows; reading them by hand does not scale
past a demo.
Every amount is reported twice, *_usd and *_micro_usd. Match on the micro integer when
reconciling.
Rows use one sign convention throughout, matching the wallet: a charge is negative, a grant
or top-up is positive. You never have to learn a per-type rule, and a sum across rows is
meaningful without filtering first.
Balance
GET /api/v1/balance
curl https://hisoka.ai/api/v1/balance -H "Authorization: Bearer $HISOKA_API_KEY"
{
"object": "balance",
"currency": "USD",
"balance_usd": 4.819965,
"balance_micro_usd": 4819965,
"credits": "4819",
"credit_value_usd": 0.001
}
credits and credit_value_usd are returned together so the two can be reconciled rather
than guessed at. New integrations should read balance_micro_usd.
Transactions
GET /api/v1/transactions
| Query | Notes |
|---|---|
limit |
1-100, default 25. Capped, not refused. |
page |
default 1 |
type |
usage, grant, topup, adjustment, purchase. An unknown value is ignored rather than refused, so a stale client still gets data. |
model |
exact model id |
since / until |
ISO timestamps |
curl "https://hisoka.ai/api/v1/transactions?limit=2&type=usage" \
-H "Authorization: Bearer $HISOKA_API_KEY"
{
"object": "list",
"currency": "USD",
"data": [
{
"id": "01M73N2HP4HDDZH803J1C120HT",
"type": "usage",
"product": "api",
"amount_usd": -0.002759,
"amount_micro_usd": -2759,
"balance_after_usd": 4.819965,
"balance_after_micro_usd": 4819965,
"created_at": "2026-11-09T23:47:13+00:00",
"model": "glm-5.3-flash",
"provider": "Hisoka",
"input_tokens": 55097,
"output_tokens": 24,
"cached_tokens": 0
}
],
"total": 1284,
"page": 1,
"limit": 2,
"has_more": true
}
total counts rows matching the filter, not rows on the page. A page of 2 with
total: 1284 is the response working correctly, not a truncation.
provider is always our own brand. The upstream pool is operator information and is
scrubbed here the same way it is scrubbed in error messages.
One transaction
GET /api/v1/transactions/{publicId}
Accepts the public id or the numeric id. Scoped to your ledger: another account’s id
answers 404 transaction_not_found rather than 403, so the endpoint cannot be used to
probe for ids.
Usage summary
GET /api/v1/usage/summary?period=30d
period |
Window |
|---|---|
24h, 7d, 30d, 90d |
that window |
| anything else | all time, reported as "period": "all" |
{
"object": "usage_summary",
"currency": "USD",
"period": "30d",
"requests": 1284,
"tokens_in": 48210093,
"tokens_out": 912342,
"tokens": 49122435,
"usd": 2.418,
"micro_usd": 2418000,
"usd_per_1k_tokens": 0.0000492,
"models": [
{
"model": "glm-5.3-flash",
"requests": 1102,
"tokens_in": 44210000,
"tokens_out": 812000,
"usd": 1.994,
"micro_usd": 1994000
}
]
}
usd_per_1k_tokens is null when nothing was billed, because a rate over zero tokens is a
division by zero dressed up as a price.
models is sorted by spend, highest first, so the report leads with what actually costs
you money.
Errors
| Code | HTTP | Means |
|---|---|---|
invalid_api_key |
401 | missing, revoked or expired key |
transaction_not_found |
404 | that id is not in your ledger |