Two read-only endpoints help you track spend: GET / reads the balance of the key’s workspace, and GET / reads what a specific request cost. Neither one is billed.
Read the balanceLink to the Read the balance section
GET https://api.realmoon.ai/v1/creditsReturns the balance of the API wallet of the workspace the key belongs to.
- Authentication: an
sk-moon-…key with theinferencescope (see Authentication). - Parameters: none.
- Response: a
creditsobject.
ExampleLink to the Example section
curl https://api.realmoon.ai/v1/credits \
-H "Authorization: Bearer $MOONAI_API_KEY"import os
import httpx
from openai import OpenAI
client = OpenAI(base_url="https://api.realmoon.ai/v1", api_key=os.environ["MOONAI_API_KEY"])
credits = client.get("/credits", cast_to=httpx.Response).json()
print(credits["balance"])import OpenAI from 'openai';
const client = new OpenAI({ baseURL: 'https://api.realmoon.ai/v1', apiKey: process.env.MOONAI_API_KEY });
const credits = await client.get('/credits');
console.log(credits.balance);ResponseLink to the Response section
{ "object": "credits", "balance": 1250000, "currency": "credits" }| Field | Type | Description |
|---|---|---|
object | string | Always credits. |
balance | integer | Balance in credits: paid credits, free credits and the API credit included in the plan, with the hold of in-flight requests already deducted. It can be negative. |
currency | string | Always credits. |
The balance goes back up when in-flight requests are settled at their actual cost (see Hold, then actual cost). A negative balance blocks new requests until the next top-up (402 ).
ErrorsLink to the Errors section
Only the errors common to the whole API apply: 401 , 403 , 403 , 429 , 503 . See Errors.
Read the cost of a requestLink to the Read the cost of a request section
GET https://api.realmoon.ai/v1/generation?id=gen-…Returns the final cost and the tokens counted for a request made in the key’s workspace.
- Authentication: an
sk-moon-…key with theinferencescope, from the same workspace as the request. - Parameter:
id, in the query string. - Response: a
generationobject.
ParameterLink to the Parameter section
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | yes | The request ID: gen- followed by 32 characters. |
Where to find the ID:
| Endpoint | ID |
|---|---|
/ | The id field of the response (or of each stream chunk), and the X-Moon-Request-Id header. |
| Images, speech, transcription, embeddings, OCR | The X-Moon-Request-Id header of the response. |
POST / | The X-Moon-Request-Id header of the response that starts the video. The video’s id (video_…) is not accepted here. |
ExampleLink to the Example section
curl "https://api.realmoon.ai/v1/generation?id=gen-0123456789abcdef0123456789abcdef" \
-H "Authorization: Bearer $MOONAI_API_KEY"import os
import httpx
from openai import OpenAI
client = OpenAI(base_url="https://api.realmoon.ai/v1", api_key=os.environ["MOONAI_API_KEY"])
raw = client.chat.completions.with_raw_response.create(
model="anthropic/claude-haiku-4.5",
messages=[{"role": "user", "content": "Hello"}],
)
request_id = raw.headers.get("x-moon-request-id")
cost = client.get(
"/generation",
cast_to=httpx.Response,
options={"params": {"id": request_id}},
).json()
print(cost["credits_charged"])import OpenAI from 'openai';
const client = new OpenAI({ baseURL: 'https://api.realmoon.ai/v1', apiKey: process.env.MOONAI_API_KEY });
const { response } = await client.chat.completions
.create({ model: 'anthropic/claude-haiku-4.5', messages: [{ role: 'user', content: 'Hello' }] })
.withResponse();
const requestId = response.headers.get('x-moon-request-id');
const cost = await client.get('/generation', { query: { id: requestId } });
console.log(cost.credits_charged);ResponseLink to the Response section
{
"object": "generation",
"id": "gen-0123456789abcdef0123456789abcdef",
"model": "anthropic/claude-haiku-4.5",
"tokens_prompt": 12,
"tokens_completion": 41,
"credits_charged": 0,
"created_at": 1793836800
}The credits_charged value is made up.
| Field | Type | Description |
|---|---|---|
object | string | Always generation. |
id | string | The ID you requested. |
model | string | The model called, under the ID you sent. |
tokens_prompt | integer or null | Input tokens counted. null for an image, a video, speech, a transcription or OCR. |
tokens_completion | integer or null | Output tokens counted, reasoning included. null for all media, embeddings included. |
credits_charged | integer | Final cost in credits: hold, settlement and refunds added together. Never negative. |
created_at | integer | The request’s timestamp, in Unix seconds. |
When to read the cost againLink to the When to read the cost again section
- A request settled right away (complete response with its token count, finished media) has its final cost as soon as it responds.
- A response that was interrupted, or that had no token count, can still be settled at the actual cost reported by the provider for about twenty minutes: read
/again later.v1/ generation - A video is settled when its job ends: its cost is also available in
usage.creditsof the video object (see Videos). - A request’s details can be deleted after 90 days:
/then returnsv1/ generation 404. Daily totals remain in the “Usage” tab of the portal.
ErrorsLink to the Errors section
| HTTP | code | Meaning |
|---|---|---|
| 400 | missing_required_parameter | id is missing (param: "id"). |
| 404 | null | generation : unknown ID, an ID from another workspace, or one whose details were deleted. |
Common errors (key, rate) are in Errors.
See alsoLink to the See also section
- Costs and wallet: holds, settlement, top-ups and invoices.
- Limits: workspace and key spend caps.
- Authentication: the response headers, including
X-Moon-Request-Id.