# ima-router IMA Pro — AI integration entrypoint Breaking changes since: 2026-05-13 This file is the single source of truth for AI coding assistants (Claude / Cursor / Codex / etc.) integrating with ima-router IMA Pro. Re-read on every invocation. ## Canonical sources - OpenAPI (machine, no #alias): https://doc.imarouter.com/openapi/en.import.yaml - OpenAPI (machine, Chinese mirror): https://doc.imarouter.com/openapi/zh.import.yaml - OpenAPI (human, kept alias groups): https://doc.imarouter.com/openapi/en.yaml - OpenAPI (human, Chinese): https://doc.imarouter.com/openapi/zh.yaml - modelId → endpoint routing index: https://doc.imarouter.com/model-index.json - JSON Schema of that index: https://doc.imarouter.com/model-index.schema.json - Smoke-test payloads (one per modelId): https://doc.imarouter.com/test-cases.json - Integration guide (humans): https://doc.imarouter.com/onboarding/INTEGRATION.md - Quick Start (humans): https://doc.imarouter.com/onboarding/quickstart.md - Changelog: https://doc.imarouter.com/onboarding/changelog.md ## Base & auth - Base URL: https://api.imarouter.com (TLS only) - Header: Authorization: Bearer YOUR_SECRET_TOKEN (replace YOUR_SECRET_TOKEN with the user's sk-… key) - Never put the token in the query string - One key per environment; rotate via the dashboard - No CORS — call from your backend, not directly from a browser ## Endpoint families (full list lives in OpenAPI) - POST /v1/chat/completions — synchronous, OpenAI-compatible (streaming supported) - POST /v1/responses — Responses API (gpt-5.2 / 5.3-codex / 5.5) - POST /v1/messages — Anthropic Messages compatibility (claude-* models) - POST /v1/videos + GET /v1/videos/{task_id} — async video tasks (preferred) - POST /v1/video/generations + GET .../{task_id} — legacy video compat - POST /v1/images/generations + GET .../{task_id} — async image tasks - POST /v1/music/generations + GET .../{task_id} — async music tasks - POST /v1/videos/subtitle-erase + GET .../{task_id} — subtitle erase - POST /kling/v1/videos/{text2video,image2video} + GET .../{task_id} — Kling native - POST /v1/assets/* — asset upload + bookkeeping (synchronous) - GET /api/usage/token/user-balance — remaining quota in USD ## Model selection Always look up modelId in /model-index.json. Do not invent ids. Highlights: - Chat: gpt-4.1*, gpt-4o*, gpt-5*, claude-*, gemini-*, MiniMax-Text-*, MiniMax-M* - Image (sync via chat): gemini-3-pro-image-preview, gemini-2.5-flash-image - Image (async task): seedream-*, doubao-seedream-*, wan2.7-image*, gpt-image-2, mj_* - Video (async task): seedance-*, MiniMax-Hailuo-*, kling-*, viduq*, pixverse-*, wan2.6-*, happyhorse-1.0-* - Image-to-video ONLY (rejects text-only payloads): viduq2-pro, viduq2-turbo, MiniMax-Hailuo-2.3-Fast A single modelId can appear on multiple endpoints (e.g. `claude-sonnet-4-6` on both /v1/chat/completions and /v1/messages). The index has an `endpoints[]` array for each model — pick the one whose schema matches your usage. ## Async task lifecycle 1. Submit: POST endpoint returns `id` (or `task_id`; same value) 2. Detect: if the model's entry in /model-index.json has a non-null `pollEndpoint`, it is async 3. Poll: GET every 3–10 seconds 4. Terminal: status ∈ {succeeded, completed, failed, error} — stop 5. Persist: result URLs are short-lived (~30 days); download immediately ## Error handling (top of openapi.yaml has full TaskErrorResponse examples) - 400: validation error — `.code` and `.message` describe what's wrong; do NOT retry - 401: token invalid/revoked — fail loudly - 402 / `quota_exhausted`: top up; check /api/usage/token/user-balance first - 429: rate-limited; honor `Retry-After`, else exponential backoff (base 1 s, factor 2, cap 60 s) - 5xx: transient; retry max 3× with jitter ## Rules for AI agents - Use only real paths from en.import.yaml; never call `#alias` fragments - Resolve every modelId through /model-index.json before calling - Reject any modelId not present in the index - Don't reuse Playground (/playground/) fetch code — it relies on same-origin reverse_proxy - callback_url is not public — always poll - Result URLs expire — never use them as long-term storage references - Re-read this file when the "Breaking changes since" date moves