Last verified: 15 October 2026. OpenRouter’s catalog, provider availability, pricing, limits, privacy controls, and beta features change. This guide deliberately avoids fixed model counts and static model prices.
The OpenRouter API is a practical way to connect one application to models from multiple AI providers without writing a separate integration for each provider. That convenience is real, but it is not magic: your request still reaches an upstream provider, provider policies still matter, and routing can change the model, price, latency, and behavior you receive. This guide starts with the first API call and ends with the controls that matter in production.
Quick answer: choose an eligible model from the live catalog, create a capped OpenRouter key, send an OpenAI-compatible request to https://openrouter.ai/api/v1, and inspect the response’s actual model, provider details, usage, and finish reason. Use default routing until you have a reason to control providers. Add model fallbacks for availability, provider restrictions for privacy or price, local validation for tools and JSON, and server-side budgets before you put the integration in front of users.
In one sentence: OpenRouter is a multi-provider gateway and routing layer, not a single model company and not a guarantee that all upstream models behave the same.
What is the OpenRouter API?
OpenRouter presents one API for calling a changing catalog of third-party language, vision, embedding, image, and related models. Its documentation describes a unified API, aggregated billing and analytics, routing across providers, and fallbacks. Your application talks to OpenRouter; OpenRouter selects or forwards to an eligible upstream provider; the response comes back in a normalized API shape.
That makes OpenRouter useful when you want to compare models, keep a common application interface, or improve resilience without maintaining five provider SDKs. The OpenAI-compatible surface is particularly helpful: many applications can reuse familiar chat-completions code by changing the base URL and key.
OpenRouter is not the model itself. It does not make an open model identical to a proprietary model, and it cannot erase differences in tokenizers, context windows, safety behavior, tool calling, structured output support, latency, or provider-side retention. The API reference also warns that unsupported parameters may be ignored. Treat compatibility as an interface convenience, not as a promise of identical semantics. See the plain-language companion: what is OpenRouter?
How the architecture works
A useful mental model has five layers:
- Your application: authenticates with an OpenRouter key, constructs a request, executes tools, validates output, and decides what to show the user.
- OpenRouter’s API layer: authenticates, applies account and key limits, normalizes request and response formats, and records usage metadata.
- Model selection: you can name one model, provide an ordered fallback list, or use a router such as the free-model router. A model may have multiple eligible providers.
- Provider routing: OpenRouter chooses a provider according to current availability, price, capability, and your
providerpreferences. You can prefer price, throughput, or latency, restrict data collection, require a provider, or set a maximum price. - Upstream execution: the provider runs the model and returns output, an error, usage, and sometimes provider-specific metadata.
This design explains both the appeal and the trade-off. A request can survive a provider outage, but a fallback may produce a different style of answer or support a different tool schema. The response’s model field and generation details are therefore more useful than assumptions based on the request alone.
Who should use it—and who should not?
OpenRouter is a strong fit for prototypes, AI products that compare or switch models, teams that want one billing and observability surface, applications that need a fallback path, and developers who already use OpenAI-style SDKs. It is also convenient for experiments involving text, vision, PDFs, tools, structured JSON, embeddings, or model-specific capabilities.
It is a weaker fit when your central requirement is one vendor’s exact semantics, a contractual service-level agreement from a single provider, deterministic model-version behavior, or a residency and retention guarantee that you cannot demonstrate for every eligible endpoint. A router cannot give you a provider contract it does not have. For regulated, safety-critical, medical, financial, legal, employment, or high-impact customer-facing work, review the current OpenRouter Terms, model terms, provider policies, and any required DPA instead of relying on a dashboard label.
A practical approach: use OpenRouter to reduce integration friction, not to outsource engineering judgment. Keep your application’s quality tests, security boundary, privacy review, and failure handling independent of the gateway.
Sign up, create a key, and make the first request
The beginner flow is account creation, credits, API Keys, and a server-side environment variable. OpenRouter credits are prepaid and deducted as requests run. Create separate keys for development, staging, and production, and give each a useful limit. The authentication documentation recommends key limits because a leaked key or runaway agent can consume the whole balance, including auto-top-ups.
Inference keys are Bearer tokens. Management API keys are different: they are intended for administrative key-management endpoints and cannot be used to make model-completion requests. Never place either kind of secret in browser JavaScript, a mobile bundle, a public repository, or a client-side WordPress plugin.
- Open an OpenRouter account and add credits if your chosen model requires them.
- Create an inference key in the Keys area. Use a small cap while developing.
- Store it as
OPENROUTER_API_KEYin your server or local secret store. - Choose a current model slug from the live model catalog or query
GET /api/v1/models. - Make a small request and record the model, usage, cost, and finish reason.
For a step-by-step version, see OpenRouter API key setup.
Minimal cURL, Python, and JavaScript examples
Use a model ID that exists in the live catalog when you run these examples. The IDs below are examples of syntax, not a recommendation or a permanent inventory. Do not copy an example model blindly into production.
cURL
curl https://openrouter.ai/api/v1/chat/completions \
-H "Authorization: Bearer $OPENROUTER_API_KEY" \
-H "Content-Type: application/json" \
-H "HTTP-Referer: https://example.com" \
-H "X-OpenRouter-Title: Example app" \
-d '{
"model": "YOUR_CURRENT_MODEL_ID",
"messages": [
{"role": "user", "content": "Explain API gateways in two sentences."}
]
}'
HTTP-Referer and X-OpenRouter-Title are optional identification headers. They are useful for an app identity, not a substitute for authentication.
Python with the OpenAI SDK
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["OPENROUTER_API_KEY"],
base_url="https://openrouter.ai/api/v1",
default_headers={
"HTTP-Referer": "https://example.com",
"X-OpenRouter-Title": "Example app",
},
)
response = client.chat.completions.create(
model="YOUR_CURRENT_MODEL_ID",
messages=[
{"role": "user", "content": "Explain API gateways in two sentences."}
],
)
print(response.choices[0].message.content)
print("actual model:", response.model)
print("usage:", response.usage)
The official community guide documents this OpenAI-compatible pattern. The OpenRouter Python tutorial and OpenRouter OpenAI SDK guide can cover installation, environment setup, and a fuller application.
JavaScript
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.OPENROUTER_API_KEY,
baseURL: "https://openrouter.ai/api/v1",
defaultHeaders: {
"HTTP-Referer": "https://example.com",
"X-OpenRouter-Title": "Example app"
}
});
const response = await client.chat.completions.create({
model: "YOUR_CURRENT_MODEL_ID",
messages: [
{ role: "user", content: "Explain API gateways in two sentences." }
]
});
console.log(response.choices[0].message.content);
console.log(response.model, response.usage);
The important differences from a direct OpenAI integration are the base URL and OpenRouter key. The rest of your code still needs to account for model-specific behavior.
Live model selection: choose capability before brand
Do not begin by asking, “Which provider is best?” Begin by writing down the task: text generation, vision, PDF understanding, JSON extraction, tools, embeddings, image generation, long context, low latency, or low cost. Then inspect the live model metadata. The models API exposes architecture, pricing, context information, modality, and supported parameters. Filter for what you actually need instead of discovering incompatibility after deployment.
For production, pin a specific model ID when reproducibility matters. For exploration, a router or fallback list may be more useful. In both cases, log the actual response model and provider. A request that starts with one logical model can be served by a particular provider or, after a failure, a different model in your fallback list.
A good selection record contains:
- the model ID and date selected;
- required input and output modalities;
- context and maximum output needs;
- whether tools or structured outputs are required;
- privacy and regional constraints;
- maximum acceptable latency and price;
- quality tests and fallback compatibility.
Pricing, credits, fees, and the math
OpenRouter credits are USD-denominated prepaid balance. Model and provider charges are commonly expressed per million tokens, but a request can also involve input, output, reasoning, image, request, search, OCR, or other metered units. The only safe price is the current model/provider page plus the usage actually returned for your request.
The current official pricing page says inference is billed at the provider list price without an additional per-request inference markup. It also lists plan-specific platform fees on credit purchases: the page retrieved on 15 October 2026 showed Standard at 5.5% and Business at 8%, with Enterprise contract pricing. Verify payment-specific terms at checkout before funding an account. The companion article, OpenRouter pricing, fees, and credits, explains the calculation and keeps these figures dated.
Model cost math is straightforward once you have current rates:
input_cost = input_tokens / 1_000_000 * current_input_rate
output_cost = output_tokens / 1_000_000 * current_output_rate
request_cost = input_cost + output_cost + applicable_tool_or_media_costs
For example, if a live model page says input is R_in dollars per million tokens and output is R_out, use your response usage rather than character counts. Do not insert made-up numbers into a timeless article. Also remember that a fallback’s successful model determines the model inference charge. OpenRouter says failed provider attempts are not charged for model tokens, although an auxiliary service that already ran can have its own charge.
BYOK pricing
Bring Your Own Key lets OpenRouter route to a provider using your provider credential. The current BYOK documentation and pricing page describe a plan-dependent allowance: Standard and Business include $25,000 per month of list-price inference with no BYOK fee; above that, the current policy says OpenRouter charges 5% of the comparable list-price request from OpenRouter credits. Enterprise terms are custom. The allowance is based on list-price inference cost, not request count.
This supersedes older promotional language about a one-million-request allowance. The historical announcement itself directs readers to the current policy. Treat BYOK as a credential and routing option, not as a universal privacy bypass or an automatic way to eliminate all costs.
Free models: useful laboratory, poor SLA
Free models are excellent for learning the request format, testing a UI, and running low-volume experiments. They are not a quality, availability, or latency contract. The free-model router can choose an available free model after filtering for request capabilities; a specific :free variant gives more control, but not every model has every suffix.
As of the date above, the official pricing FAQ described free-model limits of 20 requests per minute and 50 requests per day, with a possible increase to 1,000 daily requests after at least $10 in credits have been purchased. Failed attempts can count toward the daily cap, and a negative balance can block free models. Another official FAQ summary presents the rule more briefly, so check the current pricing and limits pages rather than treating these figures as permanent. Read OpenRouter free models for current quota checks and practical uses.
Provider routing, fallbacks, and BYOK in practice
Default provider routing
For a selected model, current documentation says default routing considers recent availability and price, with lower-cost providers favored while unreliable providers are deprioritized. That is useful as a default, but it is an implementation behavior, not a promised provider order or SLA. Price, capacity, and outages can change while your code stays the same.
The provider object lets you make that choice more explicit. Depending on the endpoint and current support, controls include order, allow_fallbacks, require_parameters, data_collection, zdr, only, ignore, quantizations, sort, performance preferences, and max_price.
const response = await client.chat.completions.create({
model: "YOUR_CURRENT_MODEL_ID",
messages,
provider: {
sort: "latency",
require_parameters: true,
allow_fallbacks: true,
max_price: {
prompt: 10,
completion: 30
}
}
});
In this illustrative request, max_price.prompt: 10 and completion: 30 mean dollars per million tokens, not dollars per token. Replace them with your approved ceilings. Use a hard max_price when exceeding a ceiling is unacceptable. Use performance thresholds as preferences, not guarantees. Pinning one provider may improve reproducibility or satisfy a policy, but it also removes part of the resilience that brought you to a router.
See OpenRouter model routing for the decision tree and OpenRouter model fallbacks for failure behavior.
Model fallbacks
The models array provides model IDs in priority order. When the first model cannot complete the request, OpenRouter can try the next. Current documentation lists triggers such as downtime, rate limits, moderation, context validation, and refusal. This can make a product more available, but it changes the output contract. The next model may not support the same tool, schema, context length, or tone.
const response = await client.chat.completions.create({
model: "PRIMARY_MODEL_ID",
models: [
"PRIMARY_MODEL_ID",
"SECONDARY_MODEL_ID",
"TERTIARY_MODEL_ID"
],
messages
});
console.log({
actualModel: response.model,
usage: response.usage,
finishReason: response.choices?.[0]?.finish_reason
});
Test every fallback with the same acceptance checks. A fallback is not successful merely because it returned HTTP 200.
BYOK routing
BYOK keys can be prioritized, used as a fallback, filtered per key, and combined with shared OpenRouter capacity depending on settings. Provider-side rate limits and costs still apply. If your organization uses BYOK, note the budget caveat: BYOK spend does not count toward workspace guardrails by default; enable the current “include BYOK spend” option if comparable usage must count.
Privacy, ZDR, and provider data collection
Privacy is the section most likely to be oversimplified. OpenRouter documentation says prompt and response logging is opt-in, while request metadata such as token counts and latency is retained. Product-use logging is also described as an opt-in exchange for a 1% usage discount. “No prompt retention by default” therefore does not mean “nothing is processed,” “no metadata exists,” or “every upstream provider has the same policy.”
Provider routing can be constrained using data-collection preferences and ZDR-related controls, but eligibility is endpoint-specific. A provider’s policy, a plugin’s behavior, a server-side web search, file parsing, and regional routing can create different data paths. ZDR should be read as a filter or routing requirement documented for eligible providers—not as a claim that no system can retain anything for security, abuse prevention, billing, or law.
OpenRouter’s privacy policy describes account, usage, device, transaction, and submitted-file data. Persistent Files API uploads may remain until deletion or account closure, subject to legal, security, and backup exceptions. Transient media may be retained for abuse, security, billing, or legal purposes. Read the policy at publication time and obtain contractual advice where necessary.
Regional routing is a separate control. A regional entry point can help with locality requirements, but it is not a substitute for verifying each eligible provider, model, tool, and data path. Do not claim that a region URL automatically makes a workflow compliant.
Structured outputs: JSON is not validation
For simple machine-readable responses, request json_object. For a defined contract, use json_schema and provide the schema. Current structured-output support is model- and endpoint-specific, and strict compliance can vary by provider. Even with strict: true, validate locally. A schema request is an instruction and a routing constraint; it is not a replacement for application validation.
const response = await client.chat.completions.create({
model: "A_MODEL_THAT_SUPPORTS_STRUCTURED_OUTPUTS",
messages: [
{ role: "user", content: "Extract the person's name and email." }
],
response_format: {
type: "json_schema",
json_schema: {
name: "contact",
strict: true,
schema: {
type: "object",
properties: {
name: { type: "string" },
email: { type: "string" }
},
required: ["name", "email"],
additionalProperties: false
}
}
}
});
const data = JSON.parse(response.choices[0].message.content);
// Validate data again with your language's schema validator.
Filter the live catalog for supported parameters, use require_parameters when a provider must honor the request, and decide what to do when a fallback lacks support. Our dedicated tutorial is OpenRouter structured outputs and JSON Schema.
Tool calling: the model suggests, your code decides
Tool calling is a three-step loop:
- Send a tool definition with a JSON schema.
- Inspect the model’s requested tool call, authorize and execute it in your application.
- Send the assistant’s tool call and your tool result back to the model, including the tools again where required.
OpenRouter may pass native tool formats through or transform them for a provider. Tool support is still model- and endpoint-dependent. The application—not the model—owns authorization. Treat arguments as untrusted input, validate against a schema, restrict allowed actions, enforce timeouts, and keep side effects auditable.
const tools = [{
type: "function",
function: {
name: "get_weather",
description: "Get weather for a city",
parameters: {
type: "object",
properties: { city: { type: "string" } },
required: ["city"],
additionalProperties: false
}
}
}];
const first = await client.chat.completions.create({
model: "A_MODEL_THAT_SUPPORTS_TOOLS",
messages: [{ role: "user", content: "Weather in London?" }],
tools
});
const call = first.choices[0].message.tool_calls?.[0];
if (call?.function.name !== "get_weather") throw new Error("Unexpected tool");
const args = JSON.parse(call.function.arguments);
// Validate args, authorize the user, call a safe local function, and set a timeout.
const result = await safeWeatherLookup(args.city);
const second = await client.chat.completions.create({
model: first.model,
messages: [
{ role: "user", content: "Weather in London?" },
first.choices[0].message,
{ role: "tool", tool_call_id: call.id, content: JSON.stringify(result) }
],
tools
});
Use OpenRouter function calling and tools for a longer implementation. Never allow a model to invent a shell command, SQL mutation, refund, email, or network request and then execute it without an authorization boundary.
Images and PDFs
Vision-capable models can accept image content parts using a public URL or a base64 data URL. Limits, supported formats, image counts, tokenization, and cost vary by model and provider. For private assets, avoid publicly accessible URLs unless that exposure is intentional; send base64 from a controlled server or use an approved file path.
const response = await client.chat.completions.create({
model: "A_CURRENT_VISION_MODEL_ID",
messages: [{
role: "user",
content: [
{ type: "text", text: "Describe the chart and list its three largest values." },
{
type: "image_url",
image_url: { url: "data:image/png;base64,BASE64_IMAGE_DATA" }
}
]
}]
});
PDFs use file content parts and can be provided as a URL or base64. A native file-capable model may receive the file directly; otherwise OpenRouter may use a document parser. Parsing engines and per-page or model charges are changeable, so disclose them in your cost model. Test page limits, tables, scans, and context usage—not just a clean one-page PDF.
See OpenRouter vision, images, and PDFs. Image generation is a different workflow and model capability; see OpenRouter image generation API. For embeddings and retrieval-augmented generation, see OpenRouter embeddings and RAG.
Web search: useful, extra, and beta
The current openrouter:web_search server tool is documented as beta. The model decides when to search; OpenRouter uses native provider search where available or can fall back to Exa, then returns results for synthesis. It incurs extra cost even when the selected model is free. The older :online path is deprecated in favor of the server tool.
That beta label matters. The tool shape, backend, pricing, citations, and availability can change. Treat search output as evidence to inspect, not an automatic truth oracle. Keep a source list, show citations to users where appropriate, and test what happens when search is unavailable.
const response = await client.chat.completions.create({
model: "A_CURRENT_MODEL_ID",
messages: [{ role: "user", content: "Summarize today's official release notes." }],
tools: [{ type: "openrouter:web_search" }]
});
Do not describe web search as a free add-on or assume that ZDR rules for the model automatically cover the search provider. Review the current server-tools policy for that exact workflow.
Prompt caching
Prompt caching is provider- and model-dependent. OpenRouter documentation describes implicit and explicit caching, sticky provider routing, session or prompt-cache keys, cache metrics, and provider-specific cache-write, cache-read, and time-to-live rules. Keep reusable instructions and long reference material at the front of the prompt, and keep changing user data later where the provider’s cache scheme rewards that layout.
Measure rather than assume. Inspect usage fields such as cached tokens and cache-write tokens, compare latency and cost across realistic traffic, and verify whether a provider’s cache persists longer than the request. A cache hit can reduce cost, but it can also create data-governance questions if sensitive prefixes are reused too broadly.
Observability, activity, and cost controls
OpenRouter’s Activity view aggregates spend, requests, token volume, blended cost, and cache hit rate. Logs provide request-level detail such as generation, provider, attempts, latency, cost, fallback waterfall, and optional content. The API response and generation lookup are valuable for your own ledger: store the generation ID, actual model, usage, finish reason, latency, and application request ID.
Broadcast can send traces to configured observability platforms without adding instrumentation to every application. That is convenient, but those destinations become additional data processors. Scrub prompts, tool arguments, secrets, and personal data before exporting, and check retention at the receiving service.
Input and Output Logging is documented as a beta, opt-in feature. The current docs describe administrator control, a minimum three-month content-retention period, and limitations for EU/US regional requests. Treat this as a deliberate data policy decision, not a debugging toggle.
For teams, use layered controls:
- a workspace budget for shared spend;
- per-key or per-member limits;
- model and provider guardrails;
- privacy and region restrictions;
- notifications and an application-level budget;
- an audit trail that reconciles provider usage with your customer or job ID.
Organizations and workspaces can centralize credits, keys, routing, BYOK, guardrails, observability, members, and budgets. Enterprise documentation also describes SSO/SAML, SCIM mappings, and workload identity features; availability depends on plan. Use separate development, staging, and production workspaces instead of sharing one unlimited secret.
Production security
Keep keys on the server. Use a secret manager, repository scanning, per-environment keys, small limits, rotation, and alerts. If a key leaks, revoke or rotate it immediately and review recent activity. A management key should never be shipped with application code.
Build an explicit trust boundary around model output. Escape generated HTML, parameterize database queries, validate URLs, limit tool arguments, and require human approval for consequential actions. The model can be persuasive and wrong even when the transport succeeded.
For reproducibility, pin model IDs and intentional providers. For resilience, use fallbacks. You can have both by separating workloads: pin an extraction job to a tested endpoint while allowing a conversational assistant a fallback path. Record which policy applied at runtime.
Rate limits, budgets, and request discipline
OpenRouter distinguishes several limits that are easy to confuse. A credit limit concerns available prepaid balance and is associated with a 402-style failure. A configured key or workspace budget can produce a 403-style rejection. A request rate limit is a 429 condition. Check the key endpoint and response headers when debugging instead of trying to infer the cause from a vague message.
Paid-model throughput is not the same thing as an unlimited SLA. Current documentation says OpenRouter does not impose a plan-based rate limit on paid models, while upstream provider limits normally apply and global abuse or DDoS protection can still reject bursts. Adding keys or accounts is not a responsible concurrency strategy. Bound your own concurrency, queue work, and make backoff part of the client.
A sound retry policy has four parts. First, classify the error rather than retrying every non-200 response. Second, honor Retry-After when supplied. Third, use exponential backoff with jitter and a maximum attempt count. Fourth, make the operation idempotent or assign a job ID so a timeout does not create duplicate side effects. For generation, a retry may be acceptable; for a tool that sends an email, charges a card, or changes a database row, the action needs its own idempotency key and authorization.
Rate limits also affect free models. The current pricing documentation describes daily and per-minute free limits, and says failed attempts can count toward a daily allowance. Because the exact figures and eligibility rules can change, expose a friendly “try again later or select a paid model” state rather than baking a number into your product copy. Check remaining key and budget information through the documented endpoint when you need an operational dashboard.
Streaming needs its own timeout policy. Set a connection timeout and an overall job deadline. A model can produce tokens slowly enough to keep a socket technically open while the user waits too long. If you cancel a stream, record the partial response and whether the provider or your client ended it. Partial text is not necessarily safe to display as a complete answer, particularly for JSON, code, or a transaction proposal.
What OpenRouter normalizes—and what it leaves to you
Normalization is most valuable at the transport layer: familiar messages, authentication, tool and response conventions, usage fields, and a common place to select models. It does not normalize the underlying model’s personality, training data, instruction hierarchy, tokenizer, refusal style, reasoning behavior, or factual reliability. Even a parameter with a familiar name may be unsupported by a specific endpoint, ignored, transformed, or interpreted differently.
That is why a production test should be capability-based rather than brand-based. Create a small test suite for your real prompts. Include a valid case, an ambiguous case, a long-context case, a tool argument case, malformed or adversarial input, and a provider failure simulation. Assert the things your application actually needs: valid schema, citations when required, no unauthorized tool call, acceptable latency, and a safe failure message. Do not assert that two different models will use the same wording.
There is also a product limitation: routing can hide upstream change until it reaches your users. A provider can change capacity, a model can be removed, a free variant can become unavailable, and a fallback can become the model that answers most often. Pin or constrain the routes that require repeatability. For flexible workloads, make the variability visible in logs and quality monitoring.
Finally, remember that an API gateway does not solve prompt design, retrieval quality, evaluation, human review, or application security. OpenRouter can make it easier to call a model; it cannot tell whether the model’s answer is true or whether your application should act on it. Keep a human approval path for consequential decisions and a rollback switch for model, prompt, provider, and tool changes.
Error handling: status code is only the beginning
OpenRouter documents a normalized error envelope and these broad categories:
| Status | Meaning | Typical action |
|---|---|---|
| 400 | Invalid parameters or request | Fix the request; do not blindly retry. |
| 401 | Authentication failure | Check the key and environment; rotate if exposed. |
| 402 | Insufficient credits or budget | Check balance and key/workspace limits. Retry only where metadata indicates an in-flight budget condition. |
| 403 | Permission, guardrail, moderation, or policy rejection | Explain or route deliberately; do not hammer retries. |
| 408 | Timeout | Use bounded retry with an idempotency strategy where applicable. |
| 429 | Rate limit | Honor Retry-After, back off with jitter, and reduce concurrency. |
| 502 | Provider or model failure | Use a compatible fallback, then record the provider error. |
| 503 | No provider meets routing requirements | Relax an unnecessary constraint or fail clearly. |
Streaming adds a trap: a stream can return HTTP 200 and then fail in a later server-sent event. Parse error events, preserve partial output, and do not mark a job complete until the stream ends with an acceptable finish reason. The official error reference documents provider error metadata and retry behavior.
For practical debugging, see OpenRouter 429 errors and OpenRouter invalid API key 401 errors.
Integrations and when an SDK is enough
Use the OpenAI-compatible SDK when your application already expects chat completions and you need normal control over retries, validation, tools, and logging. Use direct HTTP when you need a feature the SDK does not expose cleanly or want a very small dependency surface.
For automation, an integration platform can be sensible for low-risk workflows, but keep secrets and budgets scoped. Review OpenRouter with n8n and OpenRouter with Zapier. For vendor decisions, compare the trade-offs in OpenRouter vs OpenAI and OpenRouter vs LiteLLM; neither comparison should be reduced to model count or a static price table.
Decision checklist
- Have you named the task and required capabilities before selecting a model?
- Did you verify the current model and provider support for tools, JSON schema, vision, PDFs, or search?
- Is the API key server-side, capped, scoped, rotated, and monitored?
- Have you separated inference cost, credit-purchase fees, media/search charges, and BYOK policy?
- Did you choose default routing intentionally, rather than assuming it is a fixed provider?
- Does every fallback pass the same output, safety, schema, and latency tests?
- Are privacy, ZDR, provider collection, regional routing, plugins, files, and logging reviewed as separate paths?
- Do you record actual model, provider, usage, generation ID, finish reason, and error details?
- Do retries honor status codes, Retry-After, backoff, idempotency, and stream errors?
- Can you disable a model, provider, key, workspace, or tool without redeploying the whole product?
- For regulated or high-risk use, do you have current contractual and provider assurances?
12 OpenRouter API FAQs
1. Is OpenRouter the same as OpenAI?
No. OpenRouter offers an OpenAI-compatible interface, but it routes to multiple third-party models and providers. Compatibility covers request conventions, not identical output, privacy, pricing, or operational guarantees.
2. Do I need an OpenAI API key?
No. You need an OpenRouter inference key. You can use the OpenAI SDK by setting its base URL to OpenRouter and its API key to your OpenRouter key.
3. Is the OpenRouter API free?
Some models have free variants, subject to changing availability and limits. Paid inference, credits, platform fees, media, search, and other services follow current policies. Free does not mean unlimited or production-grade.
4. Does OpenRouter add a markup to every token?
The current pricing page says inference uses provider list pricing without a per-request inference markup. Credit-purchase plan fees, BYOK policy, and auxiliary service charges are separate and can change.
5. Does routing always use the cheapest provider?
No guarantee. Current documentation describes price-aware default routing that also considers availability and capability. You can set provider preferences, but the result remains subject to eligible endpoints and current conditions.
6. Can I force a specific provider?
Often, yes, using provider ordering or allow/ignore controls where the endpoint supports them. Turning off provider fallbacks improves control but can reduce resilience. Test the exact request and model.
7. Are fallbacks automatic?
Provider fallback is generally enabled by default, and a models array can define model fallback order. Fallbacks can alter capability, quality, cost, and privacy path, so log and validate the actual result.
8. Is my prompt stored?
OpenRouter docs describe prompt and response logging as opt-in, while metadata is retained. Upstream providers and features such as search, files, parsing, and external observability can have their own policies. Read the current privacy and provider documentation for your route.
9. Does ZDR guarantee zero data retention everywhere?
No. ZDR is a routing and eligibility control for supported paths, not a blanket statement about every provider, plugin, tool, security log, billing record, or uploaded file. Verify the entire workflow.
10. Can OpenRouter return strict JSON?
It can request JSON object or JSON Schema output where the selected model and provider support it. Validate locally regardless, and design a fallback for unsupported structured output.
11. Can models call my functions automatically?
No function should run merely because a model requested it. Your application receives a tool call, validates and authorizes it, executes a safe function, and sends the result back. The model suggests; your code decides.
12. When should I integrate directly with a provider?
Choose a direct integration when one provider’s exact API, contract, residency, support, SLA, or version control is the requirement. Choose OpenRouter when multi-provider access, common billing, experimentation, or routing resilience provides more value than that direct relationship.
Conclusion
The OpenRouter API is best understood as an integration and routing layer: one practical front door to a changing ecosystem of models and providers. Its value is not that it makes every model interchangeable. Its value is that it lets you compare, route, fail over, observe, and govern those choices through a common surface.
Start small: one capped key, one explicitly tested model, one server-side request, and one usage log. Then add only the controls your workload needs—provider preferences, fallbacks, structured output validation, tools, privacy filters, regional routing, budgets, and observability. Keep the live catalog and official policies beside your deployment checklist. That is how OpenRouter becomes useful infrastructure rather than another abstraction you have to debug.
Sources and last verified
This article was fact-checked against official OpenRouter documentation and product pages retrieved on 15 October 2026 UTC. Volatile statements—fees, free limits, model/provider inventory, routing behavior, BYOK allowances, privacy settings, regional availability, beta labels, and support matrices—must be rechecked before publication and whenever the integration changes.
- OpenRouter FAQ
- OpenRouter pricing
- Quickstart and live model catalog
- Authentication, limits, and errors
- Models API and API overview
- Provider selection, model fallbacks, and free router
- BYOK and data collection
- structured outputs, tool calling, image understanding, and PDFs
- web search, prompt caching, Activity, Broadcast, and Input & Output Logging
- guardrails, workspaces, Privacy Policy, and Terms
- OpenAI SDK guide and status
