Trang này chưa được dịch sang Tiếng Việt. Đang hiển thị bản gốc tiếng Anh.

Unsupported endpoints

What returns 404, and why

MyIP OpenRouter implements the chat, completion, models, keys and credits surface of the openrouter API. The other product families are not implemented, and most of them are not planned. This page gathers that boundary in one place.

A silent 404 leaves an SDK user with nothing to go on. So an unimplemented path comes back with a body that says what is missing and where.

The 404 response

json
{
  "error": {
    "code": 404,
    "message": "Endpoint not supported on MyIP OpenRouter",
    "metadata": {
      "error_type": "not_supported",
      "path": "/api/v1/embeddings"
    }
  }
}

metadata.path contains the path you requested, verbatim. That one field is usually enough to find out which endpoint a library is calling behind your back. Like every other /api/v1 response, it carries the X-MyIP-Currency: KRW header.

Paths that return 404

These are the paths that code ported from openrouter reaches for most often. Anything else under /api/v1 that we have not implemented gets the same 404, whether or not it is listed here.

PathFamily
/embeddingsEmbeddings
/images*, /videos*, /audio/*Image, video and audio generation and transcription
/responsesResponses API
/messagesAnthropic-style messages API
/rerankReranking
/files*File upload and management
/guardrails*Guardrails and moderation
/byok*BYOK (bring your own provider key)
/presets*Presets
/workspaces*, /scim/*Organisations, workspaces, user provisioning
/oauth/*OAuth PKCE key issuance
/observability/*Third-party observability integrations
/containers/*Code execution containers
/analytics/*, /activityAnalytics and activity APIs
/classifications/*Classifiers

What to use instead

For each family: the substitute we do have, or a plain statement that there is none.

Embeddings (/embeddings)

No substitute. We serve generative models only. If you need embeddings, use a separate embedding service and combine the results in your application.

Images, video and audio (/images*, /videos*, /audio/*)

No substitute, for either generation or transcription. There is no endpoint that creates an image, turns speech into text, or turns text into speech.

Input is a different matter. Where the catalogue declares that a model accepts image input, you can attach images to messages on /chat/completions — see Multimodal input. Check what a given model accepts via architecture.input_modalities in the GET /models response.

Responses API (/responses)

Use /chat/completions. openrouter's Responses API tracks OpenAI's newer surface; we maintain one request shape. Streaming, tool calling and structured outputs all work on chat completions.

Anthropic-style messages (/messages)

Use /chat/completions. We support exactly one request shape, the OpenAI-compatible one. You cannot point an Anthropic SDK at us; point an OpenAI SDK at us by changing its base_url. See OpenAI SDK.

Reranking (/rerank)

No substitute.

Files (/files*)

No substitute. There is no way to upload a file once and reference it later. Put the content you need directly into the messages of each request. That raises the prompt tokens on every call, so for a long context you repeat often, prompt caching is what brings the cost back down.

Guardrails and moderation (/guardrails*)

No substitute. Input and output screening belongs in your application. The gateway does not moderate content.

BYOK (/byok*)

No substitute. You cannot register your own provider key and route it through us. We buy the upstream capacity; you pay us in won-denominated credits. That is why the byok_usage family in GET /key is always 0 and is_byok in GET /generation is always false.

Presets (/presets*)

No substitute. There is no server-side bundle of parameters you can call by name. Keep settings such as model, temperature and system prompt in your own configuration and send them on each request.

Organisations, workspaces, SCIM (/workspaces*, /scim/*)

No substitute. An account is a single person; there are no organisation accounts, seat management or automated user provisioning. The closest thing available to a team today is one account issuing several keys, one per purpose, each with its own limit — see GET and POST /keys.

OAuth PKCE (/oauth/*)

No substitute. There is no flow by which a third-party app obtains a key on a user's behalf. Keys are created by a person in the dashboard, or by calling POST /keys with a management key.

Observability integrations (/observability/*)

No substitute as an integration. We do not push logs to external observability tools. What we do give you is per-call cost, tokens, latency and the provider that actually answered, through GET /generation, plus the X-MyIP-Generation-Id response header that hands you that id immediately. Those two are what you build your own logging on today.

Code execution containers (/containers/*)

No substitute. We do not run code a model produces.

Analytics and activity APIs (/analytics/*, /activity)

No API. Usage history is visible on the dashboard's activity screen, and individual calls are readable through GET /generation. Per-key rollups come from usage_daily, usage_weekly and usage_monthly in GET /key; account-wide totals come from GET /credits.

Classifiers (/classifications/*)

No substitute.

Batch API

No substitute. There is no path that queues requests for discounted later processing. Send concurrent requests instead; see Rate limits.

When it is the model name, not the path

The following two produce 400 model_not_found, not a 404. The symptoms look similar enough to be worth listing here.

Model variant suffixes (:free, :nitro, :exacto, …)

Not supported. A model id must match the catalogue string exactly.

json
{ "model": "lgai/exaone-4.0-32b" }

Something like lgai/exaone-4.0-32b:nitro is not an id in the catalogue, so it returns 400 model_not_found. If you want to select on speed or price, use provider.sort rather than a suffix — see Provider routing.

Auto-router ids (openrouter/auto and similar)

Not supported. No model id with an openrouter/ prefix exists in our catalogue. To try several models in order, use the models array in the request body — see Model fallbacks.

json
{
  "models": ["google/gemma-4-26b-a4b", "lgai/exaone-4.0-32b"],
  "messages": [{ "role": "user", "content": "Hello" }]
}

What we do implement

The other side of the boundary. All of these work.

PathAuth
POST /chat/completionsInference key
POST /completionsInference key
GET /models, /models/count, /models/{author}/{slug}/endpointsNone
GET /models/userInference key
GET /generation?id=Inference key
GET /key, /auth/keyInference or management key
GET /creditsInference or management key
GET/POST /keys, GET/PATCH/DELETE /keys/{hash}Management key
GET /providersNone
GET /datasets/rankings-dailyInference or management key
GET /datasets/app-rankingsInference or management key
GET /benchmarksInference or management key

The other place not_supported appears

The same error_type is used in one more spot. On GET, PATCH and DELETE /keys/{hash}, a hash that does not exist — or belongs to another user — returns 404 not_supported. To tell the two apart, look for metadata.path: an unimplemented path has it, the key 404 does not.

Cập nhật lần cuối 5 thg 9, 2026