Skip to content

FAQ

Answers to the questions we hear most often about billing, keys, errors, and limits.

No. MirAPI is prepaid — top up any amount and pay per request. There is no monthly fee and no minimum spend.

It depends on the protocol your tool speaks:

Protocol Base URL
OpenAI-compatible https://api.mirapi.ai/v1
Anthropic https://api.mirapi.ai
Gemini https://api.mirapi.ai or https://api.mirapi.ai/v1beta

Rule of thumb: if a tool appends paths like /chat/completions to the base URL itself, enter https://api.mirapi.ai/v1. Anthropic tools expect the bare origin https://api.mirapi.ai (no /v1).

In the console catalogue or via GET /v1/models. Each entry reports the model id/name (use the exact name in requests), context_length, pricing (USD per 1M tokens), supported_parameters, and output_modalities.

Catalogue entries are either Available (real channel pricing, callable now) or Coming soon (vendor list price, not callable yet). A discount badge compares MirAPI’s combined input+output price against the vendor’s official price — it is a price comparison, not a quality claim.

Prepaid USD balance, no subscription. Top-ups are converted to USD at the exchange rate on the day you pay, and that rate is locked in.

  • Text and multimodal chat: per token — input, output, and cache read are billed separately.
  • Image generation: per image.
  • Video generation: per second of output.

Reasoning/thinking tokens are billed as output. Cache reads are cheaper than ordinary input. All prices are shown in the catalogue and console before you call.

No. Prepaid balance never expires — it stays until you use it.

Requests fail with 403 and a message that the balance is insufficient. Top up and the same key works again immediately.

Three places show the same data: the console billing log, GET /api/usage/token (account-level summary), and GET /api/log/token (per-request detail).

Note that a non-streaming response’s usage field reports token counts only — it never includes a dollar amount. Money values come from the console and /api/log/token.

A request failed but was charged. What do I do?

Section titled “A request failed but was charged. What do I do?”

Open a ticket with the request ID from the error or response. Support looks up the exact request and its billing entry. Every error message ends with the request ID, so paste the whole message when filing a ticket.

Use prompt caching: automatic on OpenAI-compatible models, cache_control on Anthropic-protocol requests. Keep your system prompt and shared context as a stable prefix, and cache reads are billed at the model’s cache-read price. See Prompt caching.

Revoke it in the console and create a new one. Key changes take effect immediately — there is no propagation delay.

Yes. Set a model whitelist when creating the key. Calls outside the whitelist return 403.

Each key can carry four kinds of limits:

  • Model whitelist — models outside the whitelist return 403.
  • Validity period — the key stops working after it expires.
  • Quota — an upper bound on usage.
  • IP allowlist — requests from other addresses are rejected.

MirAPI also accepts an OpenAI-Organization header but ignores it (there is no organization isolation).

  • 401 — the key is missing, unknown, or invalid. Check that MIRAPI_API_KEY is set, that the key has no trailing newline or spaces, and that you send it in the right header for your protocol.
  • 403 — the key is valid but the request was rejected (insufficient balance, model whitelist, quota, or IP allowlist).

See Authentication for the headers each protocol expects.

Retry with exponential backoff. The gateway does not retry for you, and responses carry no Retry-After header. A jittered schedule such as 1s → 2s → 4s (capped around 30s) works well.

  • 413 — the request body is too large; shrink it (fewer tokens, smaller attachment) and retry.
  • 500 — a server-side failure. Idempotent requests are safe to retry.

If a model has several healthy channels the gateway routes around a failing channel automatically, so a transient 500 does not always mean the model is down. It never silently swaps in a different model — if no channel for the requested model is available, the request fails.

OpenAI-protocol errors use an envelope with these fields:

Field Meaning
message Human-readable error text; it ends with the request ID.
type new_api_error (gateway side) or upstream_error (upstream failure, message redacted).
param The parameter that caused the error, when applicable.
code A machine-readable error code.

Anthropic-protocol errors use:

{
"type": "error",
"error": {
"type": "permission_error",
"message": "..."
}
}

Every error message ends with a request ID — include it in any support ticket.

Requests are forwarded to the model vendor to be processed — the vendor sees what their model needs. MirAPI does not train on your traffic and does not use your prompts for anything other than serving the request.

Only the request metadata needed for billing (timestamp, model, token counts, cost) is retained in the log. When you send sensitive data, assume the upstream vendor can see your prompts.

Yes. MCP servers run unchanged — they are tools your agent (Claude Code, Cursor, Cline, …) invokes, and only the model API goes through MirAPI. Configure the agent with the MirAPI base URL and key as usual; its MCP tools keep working. See Claude Code or Cursor for the setup.

Enter it under Billing → Redeem in the console. The code’s value is added to your USD balance.

Per second of generated video output, billed when the job completes. A failed or cancelled job is not charged.

The catalogue shows deepseek/deepseek-chat but my call fails. Why?

Section titled “The catalogue shows deepseek/deepseek-chat but my call fails. Why?”

The vendor/ prefix is a catalogue-browsing ID. API calls use the bare name — for example deepseek-chat — exactly as returned by GET /v1/models.