OpenCode
OpenCode is an open-source terminal coding agent — also available as a desktop app and IDE extensions — driven by opencode.json. Register MirAPI once as a provider and you can pick any MirAPI model per session, paying from your existing prepaid balance.
What you need
Section titled “What you need”| Element | Value |
|---|---|
| Base URL | https://api.mirapi.ai/v1 |
| API key | Your MirAPI key, referenced as {env:MIRAPI_API_KEY} |
| Model | deepseek-chat under provider mirapi |
| Protocol | OpenAI-compatible (/v1) |
If you do not have a key yet, create one in the console at https://console.mirapi.ai. The key is shown only once, so copy it immediately.
Configure
Section titled “Configure”- Install OpenCode if it is not already installed:
curl -fsSL https://opencode.ai/install | bashOther installers include npm install -g opencode-ai and brew install anomalyco/tap/opencode.
- Add a provider block to
opencode.jsonat your project root (or~/.config/opencode/opencode.jsonfor user-wide settings; JSONC is accepted):
{ "provider": { "mirapi": { "npm": "@ai-sdk/openai-compatible", "name": "MirAPI", "options": { "baseURL": "https://api.mirapi.ai/v1", "apiKey": "{env:MIRAPI_API_KEY}" }, "models": { "deepseek-chat": { "name": "DeepSeek Chat" } } } }}- Export the key in your shell:
export MIRAPI_API_KEY=sk-...Set a default model
Section titled “Set a default model”To skip the model picker on startup, add a top-level model key. OpenCode composes ids as provider_id/model_id, so a MirAPI model is prefixed with mirapi/:
{ "model": "mirapi/deepseek-chat"}You can still override it per invocation with --model.
Verify with a message
Section titled “Verify with a message”opencode run "Reply with exactly: connected to MirAPI" --model mirapi/deepseek-chatThe reply should contain connected to MirAPI. In an interactive session, run /models and select mirapi/deepseek-chat.
How it works
Section titled “How it works”OpenCode runs custom providers on the Vercel AI SDK. @ai-sdk/openai-compatible speaks the OpenAI Chat Completions protocol, so MirAPI receives POST /v1/chat/completions at https://api.mirapi.ai/v1. Responses stream as standard SSE (data: lines, ending with data: [DONE]), which the AI SDK parses for you.
Protocol variants
Section titled “Protocol variants”MirAPI serves the same models over three protocols. The provider above is OpenAI-compatible; if you prefer another SDK’s behaviour, point the AI SDK’s @ai-sdk/anthropic provider at https://api.mirapi.ai (auth x-api-key) or @ai-sdk/google at https://api.mirapi.ai (auth x-goog-api-key). Whether a given model is available on a given protocol depends on its capability flags in the catalogue.
Errors and billing
Section titled “Errors and billing”| Status | Meaning | What to do |
|---|---|---|
| 401 | Key missing, invalid, or unknown | Check {env:MIRAPI_API_KEY} and the exported variable |
| 403 | Key valid but rejected — balance exhausted, model not whitelisted, quota reached, or IP not allowed | Resolve the cause, then retry |
| 413 | Request too large | Reduce the payload |
| 429 | Rate limited (no Retry-After header) |
Retry with exponential backoff |
| 500 | Server error | Idempotent requests can be retried safely |
Every error message ends with a request ID — include it in any support ticket.
Chat usage bills per token: input, output, and cache read, per 1M tokens. Reasoning tokens bill as output. Prompt caching is automatic on OpenAI-compatible models; confirm hits via usage.prompt_tokens_details.cached_tokens. The balance is prepaid USD and never expires — when it runs out you get 403, and the same key resumes immediately after a top-up. Reconcile spending in the console billing log or via GET /api/usage/token (summary) and GET /api/log/token (per-request detail).
Tool-specific pitfalls
Section titled “Tool-specific pitfalls”@ai-sdk/openai-compatibleis the right npm package for OpenAI-compatible gateways; the plainopenaipackage also works but keeps the SDK’s default behaviours.- The model list is manual. OpenCode does not auto-discover MirAPI models; add each one you want by its exact
GET /v1/modelsname. Thevendor/prefix is console-only and never part of the request name. - The provider prefix is
mirapi/—mirapi/deepseek-chatmeans thedeepseek-chatmodel under themirapiprovider, not a model namespace. - 403 with a valid key usually means the model is not whitelisted for that key or the balance is exhausted. Top up or adjust the whitelist, then retry.
- Auth errors — check that
{env:MIRAPI_API_KEY}matches the exported variable name exactly. - Config changes need a restart — OpenCode reads
opencode.jsonat startup, so restart it after editing the provider block.