Skip to content

Claude Code advanced

Claude Code is Anthropic’s terminal coding agent, and it talks to MirAPI over the Anthropic Messages API (POST /v1/messages). This page covers what to configure once the connection works: pinning the model, restricting permissions, wiring lifecycle hooks, and capping spend. There is no OpenAI or Gemini variant to set up — Claude Code only speaks the Anthropic protocol.

Prerequisites: Claude Code configured with ANTHROPIC_BASE_URL="https://api.mirapi.ai" (the bare origin, no /v1) and ANTHROPIC_AUTH_TOKEN — see Claude Code.

Project settings live in .claude/settings.json in the project root. The keys you are most likely to touch:

Key What it does
model Pins the MirAPI model for the project, e.g. deepseek-chat
max_turns Caps the tool-use turns per task, bounding runaway loops
permissions.allow Tools and patterns Claude Code may run without asking
permissions.deny Tools and patterns to block or flag
hooks Commands that run on lifecycle events (Stop, Notification, PostToolUse, …)
env Per-project environment variables (an alternative to shell exports)
statusLine A custom command for the statusline
{
"model": "deepseek-chat",
"max_turns": 40,
"permissions": {
"allow": [
"Read",
"Edit",
"Bash(git:*)"
],
"deny": [
"Bash(rm:*)",
"Bash(curl:*)"
]
},
"hooks": {
"Notification": [
{
"hooks": [
{
"type": "command",
"command": "terminal-notifier -message 'Claude Code finished' 2>/dev/null || true"
}
]
}
],
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "echo 'paused for input'"
}
]
}
]
}
}
  • permissions is the whitelist of what Claude Code may do without confirmation; anything else triggers an interactive prompt.
  • hooks fire on lifecycle events and are the place for notifications, formatting, or guards.

Change model in settings.json, or pass ANTHROPIC_MODEL at launch:

Terminal window
ANTHROPIC_MODEL="deepseek-chat" claude

The model name must match an entry from GET /v1/models exactly. A model outside the key’s whitelist returns 403. Claude Code is optimized for Anthropic-style clients, so pick a model that supports tool calling for the best experience.

The quota is enforced on the gateway side, so even a runaway session cannot exceed it:

  1. In https://console.mirapi.ai → API Keys, set a quota limit (spend cap) on the key. Once the cap is reached, requests are rejected with 403 until you raise it.
  2. Check usage at any time:
Terminal window
curl https://api.mirapi.ai/api/usage/token -H "Authorization: Bearer $MIRAPI_API_KEY"
curl https://api.mirapi.ai/api/log/token -H "Authorization: Bearer $MIRAPI_API_KEY"

GET /api/usage/token returns account-level totals; GET /api/log/token returns per-request detail.

  • Conversations are billed per token — input, output, and cache read are three separate prices per 1M tokens. Reasoning and thinking tokens count as output.
  • Cache reads are cheaper than ordinary input.
  • MirAPI draws from a prepaid balance: no subscription, no minimum, and the balance never expires.
  • When the balance runs out, requests fail with 403; topping up restores the same key immediately.
  • 404 on /v1/messages/count_tokens — that endpoint is not implemented; Claude Code may call it at startup, and the error is harmless.
  • 401 — the key is missing, malformed, or unknown. Fix ANTHROPIC_AUTH_TOKEN.
  • 403 — the key is valid but the request was refused: balance exhausted, model not whitelisted, quota reached, or IP not allowed. Check the error message for the reason.
  • 429 — rate limited. Retry with jittered exponential backoff (1s → 2s → 4s, capped around 30s). There is no Retry-After header, and the gateway does not retry for you.
  • 500 — safe to retry idempotent requests.
  • Every error message ends with a request ID — include it when you open a support ticket.
  • Hook commands that print a lot of output slow the session down; keep them quiet.
  • permissions.deny blocks matching commands but is not a hard security boundary — review the interactive prompts before approving anything risky.
  • The Anthropic base URL stays bare (https://api.mirapi.ai); do not append /v1.