OpenRouter Release Notes
131 release notes curated from 138 sources by the Releasebot Team. Last updated: Aug 22, 2026
- Aug 21, 2026
- Date parsed from source:Aug 21, 2026
- First seen by Releasebot:Aug 22, 2026
Image Benchmarks: See the Capabilities of Every Model
OpenRouter launches Visual Image Benchmarks to help users compare image models with challenging prompts, grid-based results, and sorting by price and generation time. The update focuses on clearer visual evaluation and hints at more modalities coming soon.
Unlike choosing a text model, where we have a vast array of LLM benchmarks, picking an image model can feel arbitrary. Output samples tend to be curated eye candy and LLM-as-a-judge evals can’t yet capture the details a human would notice instantly. While arena scores help, they evaluate which outputs people prefer rather than what a model can actually do.
Today we’re launching Visual Image Benchmarks to help you quickly evaluate the capabilities of all the image models we offer (39 as of August ‘26). We’ve selected a set of challenging prompts designed to differentiate the capabilities of models, and show every result in a grid with sorting for both price and generation time.
Prompts designed to test the boundaries of image model capabilities
Each challenge is designed to differentiate the capabilities of image models. We’ve initially grouped them into seven families:
- Improbable scenes. A wine glass filled level with the rim, umbrellas that are closed. Training data is full of the ordinary version of both.
- Counting. Three fingers, specific numbers of cards and dice.
- Text. One long exact string on a poster, and several languages in the same frame.
- Spatial relations. Occlusion and mirror reflections.
- Negation. A zebra with no stripes, a Times Square with no advertising.
- Editing. Minimal diffs, object removal, person removal, all from a reference image.
- Consistency. Holding a product or four reference subjects steady across a new scene.
The prompts are written so you can instantly evaluate them visually. For example, can a model follow the instruction to fully fill a wine glass?
More visual evals and additional modalities coming soon
It’s similarly challenging to evaluate video and audio models to understand their quality and capabilities. We intend to expand this tool out across modalities as well as keep it up to date with all the new image models we add.
Check out our image benchmarks today! If you have any prompts that could challenge the next round of models, share it with us in #feedback on our Discord.
Generating images via the OpenRouter API and Chat
Once you’ve evaluated models via these benchmarks, try them on your own prompts through the image generation API or Chat to see how they perform on your own content.
Original source - Aug 17, 2026
- Date parsed from source:Aug 17, 2026
- First seen by Releasebot:Aug 18, 2026
Understand your AI usage: every agent, model, and request
OpenRouter adds Activity, Explore, Guardrails, and a beta Analytics API to help teams track spend, usage, and request-level costs per agent, model, and workspace. It also brings drill-down logs, custom views, exports, and terminal-friendly analytics for deeper cost control.
Start with the big picture
Every company that spent the last two years deploying agents is now asking the same question: what are they costing us, and which ones are worth it? OpenRouter’s Activity dashboard and beta Analytics API answer that question per agent, per model, per request.
Open Activity to see how spend breaks down across agents, apps, and team members. Find out which models and tasks drive costs, and where caching cuts your bill. Create and save custom views, then drill from any chart down to the individual requests.
All of the data is available through the beta Analytics API. Point your agent at the openrouter-analytics skill to dig into your usage, get a quick answer in your terminal, or pull the numbers into your own dashboards.
Overview is your usage at a glance. Five metrics at the top: total spend, requests, token volume, cache hit rate, and blended cost per million tokens, each with a sparkline and a comparison against the previous period. On the same screen, your top users and apps, spend by model, OpenRouter credits versus BYOK spend, request volume by model, prompt and completion token breakdown, and prompt caching.
Trends takes the same data and sorts by movement instead of size, with a panel showing what’s rising and falling. See your trends across models, users, API keys, and apps. Use it to spot a runaway agent, a new model gaining traction, or a tool spreading across your org.
Explore any question
Every card on Overview and Trends links into Explore, where you assemble the view yourself:
- Metric: spend, request count, tokens (prompt, completion, reasoning, or cached), cache hit rate, blended cost per million tokens, BYOK versus credit spend, or latency and throughput down to P50/P90/P99
- Group by (up to two dimensions): model, variant, provider, API key, app, user, workspace, origin, country, data region, finish reason, context length, session, generation, custom user IDs, or any classifier dimension you’ve defined
- Rollup: minute, hour, day, week, or month, or drop the time axis for a ranked table
- Chart type: bar, line, or dot plot
Use it to see which apps are driving usage in each workspace, which models your agents are using for each task type, or how your provider latency is trending over time.
Save your go-to views. Open the options menu, choose Save current chart, and name it. In an organization you also choose who sees it: Only me, or Everyone in my organization.
Download CSV or Download PDF to send any chart’s data straight into a spreadsheet or report.
Guardrails shows what your prompt injection and sensitive-information rules blocked, redacted, or flagged, and which rules are doing the work. Use it to monitor the rate of sensitive data entering your prompts, and which rules and data types are catching it. Filter by workspace or classifier to narrow in on where it’s coming from.
Expand a card to get the full breakdown, including which combinations of detected patterns drove each block, redaction, and flag.
Click a chart, land in the logs
Aggregates show you that something got expensive. The next question is which requests.
Every chart and ranked table in Activity links through to the logs behind it. Click Tuesday’s bar, one model’s slice of a stacked chart, or a row in a ranked table, and you land in your logs filtered to those requests.
Open any row in logs for the Generation detail view. It shows:
- Cost: upstream inference, caching, web search, and file processing, plus the discounts and cache savings applied
- Performance: provider latency, throughput, and time to first token
- Routing: which provider served the request, whether it fell back to another one, and the finish reason
- Attribution: the app, API key, and workspace behind it, plus session and request IDs and data region
- Context: any guardrail events, classifier tags, and the raw metadata
The Prompt detail view renders the full messages array and a flamegraph of estimated tokens per message colored by role: system, user, assistant, and tool. A conversation that costs three times what you expected usually shows it here as a wide band of tool calls or a heavy system prompt. The cached prefix is shaded, so you can see how far into the prompt the cache held and which message broke it.
Per-message token counts are estimates derived from message size; the totals on the generation itself are recorded usage. Prompts and completions detail only exist if private input/output logging was enabled when the request ran, which you can enable in your workspace observability.
Same data as Explore, via API
Everything in Explore is also available through the beta Analytics API: let your agent run the analysis, get a quick answer in your terminal, or pull the numbers into your own dashboards. Analytics queries require a management key. Two endpoints:
- GET /api/v1/analytics/meta returns the currently supported metrics, dimensions, filter operators, and granularities. Call the metadata endpoint first to see what’s available; we’re always adding new metrics and dimensions.
- POST /api/v1/analytics/query runs the query and returns the same aggregates the Explore charts are drawn from.
For agents
The cost control cookbook puts your agent in charge of spend analysis. Give your coding agent a management key and the openrouter-analytics skill and have it run a cost review on your OpenRouter account. It finds the models costing a multiple of your blended rate per million tokens, traces them back to the keys and pipelines responsible, and returns ranked recommendations.
We ran this internally and found a preview model burning ~$6.2K/month at roughly 25x the org’s blended rate. One drill-down query later, 98% of it traced to a single batch-pipeline key running a task that never needed a frontier model. The fix was a one-line model swap. See the query recipes and agent prompts we used in the cookbook.
Get started
Open Activity, or start in Explore if you already know the question you want answered. To work from your terminal instead, grab a management key and hit the beta Analytics API.
Tell us what you’d like to see next in #feedback on Discord.
Original source All of your release notes in one feed
Join Releasebot and get updates from OpenRouter and hundreds of other software products.
- Aug 17, 2026
- Date parsed from source:Aug 17, 2026
- First seen by Releasebot:Aug 18, 2026
OpenRouter Image Generation: A Code-First API Tutorial
OpenRouter adds a dedicated Image generation API that lets developers reach supported image models with one request format and one key. The guide covers generating images, decoding base64 output, saving files locally, and using reference images for variations.
Adding image generation to an app gets harder when you need to support more than one provider. Dozens of image models across many providers use different endpoints, data formats, controls, and billing models, with charges calculated per image, megapixel, or token.
We address this integration problem with a dedicated Image generation API that uses one request format and one key across supported models.
Tl;dr
- One API and one key reach supported image models through POST /api/v1/images.
- Buffered responses place the generated image in data[0].b64_json, which you decode and save locally.
- Compatible models accept an optional reference image through input_references.
In this guide, you’ll build runnable Python and JavaScript flows that send a prompt, decode and save the returned image, then pass a reference image to the endpoint and save the generated variation.
Prerequisites
Before you start, have the following ready:
- An OpenRouter account. You’ll create the API key in Step 1.
- Python 3 with the requests package, or Node 18+ with built-in fetch.
Step 1: Get a key and choose an image model
Create a key on the keys page, then export it in the same terminal you’ll use to run the script.
Choose a model from the image models collection. Let’s start with bytedance-seed/seedream-4.5 for the first run.
You can switch between image-capable models by changing the model string. Optional controls such as resolution, multiple outputs, and reference inputs vary by model, so check the capability record before adding them.
For runtime discovery, GET /api/v1/images/models returns image-capable slugs and supported parameters. Each model also has endpoint records with provider-specific capabilities and pricing. You don’t need those endpoints for this tutorial, but they’re useful once this script becomes a product feature.
Step 2: Send your first image request
Send a POST request to https://openrouter.ai/api/v1/images. The Image API requires two body fields. model selects an image-capable model, while prompt describes the image you want. Authenticate with your OpenRouter key in the Bearer header.
Python example code and JavaScript example code are provided to send the request, check response.ok, and parse the JSON result.
Where is the image in the response?
A successful buffered response follows this shortened shape:
{ "data": [ { "b64_json": "iVBORw0KGgoAAA...", "media_type": "image/png" } ], "usage": { "cost": 0.0123 } }The example cost only demonstrates the field shape. It’s not a current price.
The data is an array because one request can return multiple results. The first image sits at data[0].b64_json. That value contains base64-encoded bytes, not a hosted URL.
media_type appears when we can identify the output format. The optional usage.cost value reports the completed request cost when available.
For now, a nonempty b64_json value confirms that generation succeeded. The next step turns those bytes into a local image file.
Step 3: Decode and save output.png
The response shows that generation worked, but the image is still base64 text inside JSON. The next step is to decode b64_json into bytes and write those bytes to disk. Both scripts below repeat the request so you can run either file independently.
Python and JavaScript example scripts are provided to decode the base64 image data and save it as output.png, printing "Saved output.png" and optionally the request cost.
Run either version from the directory containing the file:
python3 generate.pyFor JavaScript use:
node generate.mjsA successful run prints Saved output.png. The cost line appears only when the response includes usage.cost.
The output format varies by model. Some models return JPEG or WebP bytes instead of PNG. If the format matters for your use, read media_type from the response and pick the file extension to match.
Step 4: Add a reference image
A reference image gives the model visual material to work from instead of relying on the prompt alone. It’s added through input_references.
For a local file, read the bytes, encode them as base64, and prepend the correct media type to create a data URL.
Place the image file product.jpg in the same project folder as the script, then create the file reference.py:
Python example code is provided to read product.jpg, encode it as base64, create a data URL, and send a POST request with input_references containing the reference image.
Run it from the same directory:
python3 reference.pyThis pattern works well for product-photo variations because the source image can preserve the recognizable object while the prompt changes the setting, lighting, or presentation.
Reference-image support and accepted reference counts vary by model endpoint. Before you depend on this feature, inspect the endpoint record and confirm that input_references appears in supported_parameters.
Step 5: Make the request reusable
Once the request works reliably, move the settings that rarely change into a local configuration file. Keep the model slug, provider routing, timeout, and output directory together. Leave the prompt, reference image, and user controls in the request so they can change with each image.
Troubleshooting and cost notes
Most failures become obvious when you log the HTTP status and full response body before reading any image fields.
- Missing data[0].b64_json. Check the response body first. Confirm that you sent a POST request to /api/v1/images and selected an image-capable model.
- A 401 response. Make sure the process can read OPENROUTER_API_KEY. Check that the variable exists without printing its value, then export it from the terminal running the script.
- A reference request fails. Confirm that the model supports input_references and check the image URL. A local JPEG must use a valid data URL starting with data:image/jpeg;base64,.
- Unexpected cost. Check the endpoint’s pricing before running a batch. If available, record usage.cost with the model slug and output filename during your test runs.
Frequently asked questions
Can I use OpenRouter to generate images?
Yes. Send a POST request to /api/v1/images with an image-capable model, a prompt, and your OpenRouter API key. The response contains base64 image data that you decode and save locally.
How do I use the API to generate images?
Authorize the request with a Bearer header, then send the model and prompt. Check the response status, decode data[0].b64_json, and write the resulting bytes to an image file.
How do I generate AI images through prompts?
Describe the prompt subject, setting, composition, lighting, and style. Use input_references only when a compatible model should edit or vary an existing image.
Which API is best for image generation?
Compare image quality, controls, reference-image support, latency, and pricing. OpenRouter is the best fit when you want one API key and a common request format for multiple image models.
References
- Image generation docs, the canonical reference for POST /api/v1/images and input_references.
- Image models collection, curated image-capable models.
- Live image models API, runtime discovery of slugs and supported parameters.
- Aug 12, 2026
- Date parsed from source:Aug 12, 2026
- First seen by Releasebot:Aug 13, 2026
Live Web Search Benchmarks: Pick the Right Engine, Depth, and Model for Your Agent
OpenRouter launches live web search benchmarks and a new Benchmarks page to help users choose the best search setup. It compares models, engines, search methods, and budgets across multiple suites, highlighting tradeoffs in quality, cost, and speed.
Web search is table stakes for most LLM requests in order to overcome knowledge cutoffs.
Labs and search providers are evolving fast to make search more effective and efficient, leaving all of us with a set of tricky decisions: take the native search some labs build in, or wire up a third-party engine like Exa, Parallel, or Perplexity? Is one search enough, and if not how long do I let the agent keep searching? Are more search turns worth the quality they buy?
We built live leaderboards to help you decide the best search configuration with data. See the data on our new Benchmarks page.
We benchmark all the combinations to find strengths and weaknesses
When setting up a search request, you have four decisions:
- Model. Writes the exact query that gets submitted to the search engine and processes the results.
- Engine. You can choose a specific engine or rely on the bundled engines offered by some labs. On OpenRouter, we offer Exa, Parallel, and Perplexity, alongside the native engines from labs like OpenAI, Anthropic, and Google.
- Search method. Either you can perform the search before calling the model and pass the results in as context, or you can equip the model with a web search tool that it calls at its discretion.
- Search budget. If you choose the search tool method, you can also give the model a budget for how many searches it’s allowed to do. This enables models to adjust the query if it doesn’t like the results or to do follow-up searches. Our runs use 1, 5, or 25 turns.
To comprehensively understand web search performance, we regularly run four benchmarks across multiple models, engines, and search configurations:
- BrowseComp: hard fact-finding that takes real browsing
- DeepSearchQA: multi-hop research questions
- WideSearch: broad “fill in the whole table” collection
- HLE: expert exam questions with search
Each page ranks configurations by quality, value, and speed, so you can make decisions on the factor most important to your workload. The leaderboards are live, so the numbers move as new runs land and new models and engines are added. Today’s leader is not guaranteed to be tomorrow’s. We won’t spend much time on today’s leaders in this post as we expect that to change over time. Instead, let’s look into what the data tells us about how to make a decision for your workload.
Search budget matters more than any other factor
Increasing the engine budget up from one turn improves quality more than any other single change you can make. To illustrate, here was our initial run of BrowseComp on Perplexity across three different budgets:
Model, with Perplexity | 1 turn | 5 turns | 25 turns Claude Opus 5, high | 35.8% ($0.14) | 66.5% ($0.51) | 89.0% ($0.99) GPT-5.6 Sol, high | 46.3% ($0.20) | 65.2% ($0.29) | 82.4% ($0.50) GPT-5.6 Luna, extra-high | 33.7% ($0.02) | 57.0% ($0.04) | 74.0% ($0.10)This pattern holds up across all providers we measured:
These runs cover BrowseComp only, using the server tool with ten results per search, no page fetching or code execution, and the latest qualifying run per configuration.
Increasing search depth is the cheapest way we’ve found to increase quality. Increasing from 1 turn to 25 roughly doubles the score while costing only 2.5-7 times more per question.
You may assume this universally slows down response time, but that’s not always the case. For example, Luna took 140 seconds per question at 1 turn and 111 seconds at 25. Of the 35 configurations we ran at both 1 and 5 turns, over a third were slower with fewer turns. All were OpenAI models. These models deal with the constrained search budgets with extra reasoning.
On the other hand, search depth can be detrimental to costs on easier tasks. For example, on HLE, GPT-5.6 Sol with Perplexity scored similarly between 1 turn and 25 turns, for triple the cost. If your searches tend to be simple, it may still be worth keeping your budget limited.
Your worst-case cost scenario is driven by your failure rate
The other situation where an expanded budget is detrimental is when the model is failing to find an answer. We found that models would exhaust their budget attempting to find an answer even though they would eventually fail.
Suite (25-turn budget) | Avg searches when correct | Avg searches when incorrect BrowseComp | 10.3 | 19.7 DeepSearchQA | 11.7 | 20.1 HLE | 5.2 | 7.5 WideSearch | 17.6 | 23.4The deepest attempt we recorded, 81 searches on a WideSearch table, was still graded incorrect. If your workload has a high failure rate, then reducing search depth is likely an efficient path for reducing costs.
While the engine matters, the model matters more
Once the budget is set, the next most important question is which model to use.
Model | Perplexity | Exa | Parallel Claude Opus 5, high | 89.0% ($0.99) | 82.2% ($1.29) | 88.8% ($2.42) GPT-5.6 Sol, high | 82.4% ($0.50) | 77.8% ($0.54) | 76.6% ($1.26) DeepSeek V4 Flash, high | 77.0% ($0.08) | 67.4% ($0.12) | 64.6% ($0.10) GPT-5.6 Luna, extra-high | 74.0% ($0.10) | 68.4% ($0.14) | 58.0% ($0.11)The table above shows the BrowseComp results at 25 turns, comparing frontier models versus budget models across search engines.
Varying the engine while holding the model constant changed the score by an average of 10 points while the average gap between frontier and cost-efficient models was larger at 15 points. Across engines, cost varied most for frontier models, where the priciest engine cost 2.5x the cheapest, versus 1.5x for cost-efficient models.
The reason a comparison like this is possible at all is that the server tool sits above the provider. Change the model in your request and the search behavior stays consistent, including for models whose provider ships no search of its own.
Of course, benchmarks are only a reference for possible performance. They tell you which configurations are worth trying and roughly what they cost. The cost and quality of these choices for your own real tasks will differ, so the highest-value thing you can do with these pages is treat them as a shortlist and then run your own questions through the top few.
Try it on your own workload
Everything above is a request parameter you can set today on OpenRouter.
- Web plugin. The web plugin runs a single search before the model starts writing, which is the fast, cheap option for questions that just need fresh facts.
- Server tool. The server tool hands the model the search tool and lets it decide what to look up next, which is what you want when the answer takes several steps to find.
- Engine. On OpenRouter, you set engine to exa, parallel, perplexity, or native; auto tries native first before falling back to a third party.
- Search budget. The top-level max_tool_calls request field caps how many agent turns it gets, meaning how many rounds of searching it may take before it has to answer, and max_results sets how many results come back each time.
A reasonable starting point: pick the suite closest to your task, take the cheapest configuration within a few points of the top score, then re-run your own evaluation set against the two or three rows above it to see whether the extra spend shows up in your results.
Benchmarking methodology
Every run goes through the public OpenRouter API against production endpoints, using our open source benchmark harness.
- Isolated to search performance. To ensure we are comparing only the search configuration, we standardized on ten results per search, no page fetching, and no code execution. Reasoning is fixed per model, as reflected in the tables.
- Scores are strict. Each evaluated answer is right or wrong against the official answer key, using an LLM judge where semantic comparison is needed. WideSearch also reports answer-item accuracy separately.
- Cost and speed are per question. Cost is total spend, including grading, divided by evaluated questions. Speed is candidate generation time per evaluated question.
- Each page shows the latest qualifying run for every configuration. A run qualifies once it completes a minimum number of questions, and new runs supersede old ones.
FAQ
How do these scores compare with published vendor agent leaderboards?
They are not directly comparable. Most published tables for these benchmarks are measuring full agent products that combine search, full page fetching, and code tools. These leaderboards isolate search configurations: the model reads search result excerpts only, with page fetching and code tools off. This allows direct comparisons between configurations, but won’t maximize benchmark scores.
Which search engine should I pick?
It depends on the model and the task, which is why the pages exist. The gap between engines is large for some models and negligible for others, and a provider’s own native search is not automatically its best option. Check the live leaderboard for the suite closest to your workload, read cost and latency alongside the score, and re-check it over time, because the ordering changes as new runs land.
How current are the numbers?
The leaderboards always show the latest qualifying run for each configuration, executed on OpenRouter’s benchmark harness against production endpoints. New runs supersede old ones on the page.
Tell us which engines or models we should benchmark next in #feedback on Discord.
Original source - Aug 10, 2026
- Date parsed from source:Aug 10, 2026
- First seen by Releasebot:Aug 10, 2026
Model Routing Powered by Wisdom of the Market
OpenRouter launches a major update to its Auto router, using recent community spend data to route prompts with fresher model choices, cost tiers, sticky multi-turn behavior, and privacy-aware fallback handling. A new auto-beta also gives early access to upcoming improvements.
The beauty in markets is the pattern of large, diverse groups of independent individuals collectively making better judgments and decisions than any single expert. OpenRouter sees trillions of tokens every day, and we’ve been working on a new way to share the collective wisdom of these millions of people making model decisions.
Today we’re launching a major update to our Auto router (openrouter/auto) that’s informed by the over 55T in weekly token spend on OpenRouter. We’ve found that model selection driven by market spend outperforms the choices of our old Auto router across a wide spectrum of tasks and cost levels. By referencing the past 7 days of OpenRouter usage, it always stays up to date with new model releases.
We’ve been testing this approach in beta with thousands of people over the past few weeks and today we deployed it for everyone using the Auto router. Try it now by sending "model": "openrouter/auto" to any of our inference endpoints, or read the docs for details.
To power this router, we transformed the task classifications we run on a representative sampling of prompts into a pareto-optimal routing curve. This is the same underlying data that’s shown on our model rankings by task spend. You can specify your desired cost level by sending a cost_tier parameter and it will respect any guardrails/privacy settings from your account when selecting a model.
We used benchmarks across domains to verify the new Auto router’s performance
We designed the router for versatility, so we evaluated it against a deliberately diverse set of benchmarks: MMLU Pro (Knowledge), τ³-bench Banking (Agents), WideSearch (Search), DSQA (Research), and SWE-Atlas QnA (Coding).
To be confident in the new router’s selections at the default cost level, we needed to see it achieve the same level of performance as the old router while reducing costs. We saw this in most domains, with a few exceptions where the old Auto router was underperforming modern budget models. At the max cost level, our bar was frontier performance even if it ended up costing more than the old router.
Default on the new router is cost_tier=low and cost_quality_tradeoff=7 on the old router. Max compares cost_tier=max to cost_quality_tradeoff=0.
These results capture a moment in time and will shift as community preferences change over time. We’re using benchmarking to understand relative performance between routing strategies to build confidence that the wisdom of the crowd truly is getting you improved results. Our hypothesis is that efficient model selection will improve with time as more people adopt OpenRouter.
Cost comparison
The new router’s default cost tier will be cost-efficient across a range of workloads, while max allows a broader range of high-cost models for when performance matters more than spend.
Any routing strategy that switches between multiple models will incur some increased costs when input cache is rebuilt. Often this cost is worthwhile in order to move to a model better suited to a new task, but can be wasteful if the model switches too frequently. The Auto router implements “sticky” behaviors to keep multi-turn conversations on one model until the model being used is no longer a leading choice for your task.
How the new Auto router works
The new Auto router makes decisions based on what the people using OpenRouter, in aggregate, are using for exactly the kind of task your prompt represents. Think of it like a market index that always stays up to date and gets more efficient the more people use OpenRouter.
The model mixture below shows how the new Auto router’s routing curve maps each task type to the cost_tier settings: low, medium, high, xhigh, and max. It is a point-in-time view: the routing curve shifts as new models launch and the OpenRouter community’s usage patterns change.
This snapshot is current as of August 10. See the rankings page for the latest.
The rankings it uses are computed from aggregate anonymized spend statistics, protecting the privacy and data policies of all of our customers. Your prompts are classified in-flight without requiring retention. Here’s how it works:
- Classify the task. A fast, lightweight classifier assigns each prompt one of ~30 fine-grained task types, such as code debugging, multi-step agent planning, knowledge Q&A, math, customer support, or research reports.
- Rank by real-world spend share. For that task type, the new Auto router looks up which models the OpenRouter community actually spends on over the past 7 days, similar to the “Share of Spend” view from our rankings page. This is a live signal: when people migrate a workload to a new model, the router follows within days.
- Apply your cost tier. The cost_tier setting (low, medium, high, xhigh, or max) sets how much you’re willing to spend and selects the matching cost band of candidates. At low, routing stays with the cheapest capable models for each task; at max, it picks from the most capable, priciest models.
- Route with fallbacks. The selected models become the primary pick plus fallbacks, ordered by their share of usage. Routing respects the model and provider restrictions on your request and account, like allowed models, guardrails, and ZDR policies. If classification or rankings are ever unavailable, the router falls back to a default model set, so a request never fails because of a routing problem.
Across turns, the router remembers the model a conversation landed on and prefers it on later turns. It identifies a conversation from an explicit session_id when provided, or from a fingerprint of the messages otherwise. Candidates are still ranked from scratch each turn, and the remembered model is reused only while it remains among the top candidates, so a better-suited model can take over when the task changes.
Try the new Auto router now
The Auto router works wherever you’d normally put a model string:
{ "model": "openrouter/auto", "messages": [ { "role": "user", "content": "Explain quantum entanglement in simple terms" } ] }Or set your cost tier and restrict the candidate set:
{ "model": "openrouter/auto", "messages": [{ "role": "user", "content": "..." }], "plugins": [{ "id": "auto-router", "cost_tier": "max", "allowed_models": [ "anthropic/*", "openai/*" ] }] }The cost_tier parameter accepts low, medium, high, xhigh, or max, and sets how much you’re willing to spend: low routes to the cheapest capable models, max always picks from the most capable ones. The old Auto router exposes a numeric cost_quality_tradeoff setting where 0 is the high-quality setting and higher values are more cost-sensitive, defaulting to 7. The cost_quality_tradeoff parameter is still accepted for backwards compatibility and keeps its original cost-ceiling behavior, and it takes precedence if you send both.
The response’s model field tells you which model was selected, and there’s no additional fee; you pay the standard rate for whichever model runs. See the new Auto router docs for details, including session stickiness for multi-turn conversations.
Use openrouter/auto-beta to be the first to get new improvements
Use openrouter/auto-beta to be the first to get new improvements
We’ll continue improving this router to optimize model selection and cache performance over time. Anyone who wants to try the newest routing behaviors first can use openrouter/auto-beta, where those changes land before they reach openrouter/auto. The new router has been running here for a couple of weeks, with thousands of people using it for real workloads. Tell us what you see in our Discord or through your account representative.
Original source Similar to OpenRouter with recent updates:
- Anthropic release notes796 release notes · Latest Sep 2, 2026
- Obsidian release notes107 release notes · Latest Aug 20, 2026
- OpenAI release notes974 release notes · Latest Sep 1, 2026
- Perplexity release notes30 release notes · Latest Aug 24, 2026
- OpenClaw release notes292 release notes · Latest Sep 1, 2026
- Cursor release notes128 release notes · Latest Aug 27, 2026
- Aug 6, 2026
- Date parsed from source:Aug 6, 2026
- First seen by Releasebot:Aug 7, 2026
Governing AI Spend Across a Team on OpenRouter
OpenRouter adds six spend controls for teams, including per-key limits, guardrails, workspace budgets, presets, organizations, and an Activity dashboard. It helps teams cap costs, govern models and providers, and track usage with clearer control across shared AI spend.
What’s the fastest way to govern team AI spend on OpenRouter?
Your team’s AI bill is the total of every key each engineer holds. One developer creates a key for a side experiment. Another wires a few keys into a CI pipeline. Someone else pastes a token into a notebook, gets the prototype working, and forgets the key is still active.
None of that is careless on its own, but add it up and the bill gets hard to explain. OpenRouter has 6 controls that bring order to it, and this article walks through each one, the team it suits, and the plan it needs.
The controls layer on top of each other. So start with the cheapest one that covers your risk, and only add more when you need them. When two controls overlap, the stricter one applies. Allowlists intersect and the lower budget blocks first.
Pick the cheapest control that fits your team’s risk, then layer up. A small team often only needs per-key limits plus the Activity dashboard on day 1.
Each control does one of three jobs. Budgets and per-key limits decide how much can be spent. Model and provider allowlists decide what it can be spent on. The Activity dashboard shows who spent it. The 6 controls split across those three jobs and work together, so you rarely need all 6 at once.
The control comparison table
Read down from the top. The controls that block spend come first, and the ones that track it come last. All of them are available on free and pay-as-you-go plans except workspace budgets, which need Enterprise.
Control What it caps or restricts Where it’s set Who can set it Plan tier Blocks or tracks Per-key credit limit Total credits one API key can spend Dashboard or Management API Key owner Free / PAYG Blocks (rejects over limit) Guardrails Budget + model/provider allowlist + privacy, per member or key Settings › Privacy Account owner (org admin in an organization) Free / PAYG Blocks (403 at budget cap) Workspace budgets Total spend for a whole workspace Workspace settings or Management API Organization admin Enterprise Blocks (403 at limit) Presets The model, routing, and config a request uses Presets settings Organization member (admin to share org-wide) Free / PAYG Tracks (a default, not a hard cap) Organizations and roles Who holds spending authority; shared credit pool Organization settings Org admin Free / PAYG Tracks (structure, not a cap) Activity dashboard Nothing; it reports Activity page All organization members (visibility) Free / PAYG Tracks (usage + export)A practical setup usually pairs at least one blocking control with one reporting control. For example, a production service key gets a monthly limit, and the Activity dashboard tells you whether that service is actually where the spend is going. If one developer needs a tighter model allowlist or budget than everyone else, add a guardrail for that member.
What are you actually paying for?
Before you set up any controls, it helps to know what the spend actually is. We don’t mark up provider pricing, so the price in the model catalog is what inference costs. The platform fee is charged when you buy credits (5.5% on card top-ups for standard pay-as-you-go, minimum $0.80), not on each request. A request that fails doesn’t bill at all.
So there’s no hidden markup to police. The job of these controls is simply to cap how much real inference your team runs.
The model catalog lists the per-model rates you’ll be capping.
Bring-your-own-key (BYOK) spend behaves differently
BYOK spend doesn’t always count where you’d expect, so you’ll want to check this before you build controls around it. When you route through your own provider keys, we charge a 5% fee on the model cost, waived for the first 1 million BYOK requests per month.
Both workspace budgets and guardrail budgets count only OpenRouter credit spend by default, so if your team runs mostly on its own provider keys, a budget covers less of the bill than it looks like it does. Each has an Include BYOK spend setting (include_byok_in_budgets) you can turn on so BYOK inference counts toward the limit too.
Making each request cheaper is a separate topic from capping your team’s spend. For that, see provider routing for cost and prompt caching.
How do you cap spend on a single API key?
A per-key limit is the simplest hard cap. It limits one API key, and you don’t need an organization to use it.
Use it when you want to cap one engineer, service, environment, prototype, or contractor key. A staging key might get a small daily limit. A production service key might get a larger monthly one. A temporary evaluation key might reset weekly, so the experiment stops spending after the review ends.
You can set limits in the dashboard or through the Management API, which can create, rotate, update, and disable keys. That means an internal provisioning flow can issue every key with a limit from day one instead of relying on someone to add one later.
The weakness is that a per-key limit caps the key, not the person. If one person owns 5 keys, each with its own daily limit, they can spend the sum of all 5. The key doesn’t know about the others. Per-key limits also say nothing about which models or providers a caller can use.
Start with per-key limits. When you need a rule that follows a person, or one that combines a budget with model, provider, or privacy restrictions, move on to guardrails.
How do guardrails control budgets, models, and privacy?
A guardrail is a policy that follows a person or a key.
One guardrail can contain a budget limit, a model allowlist, a provider allowlist, Zero Data Retention rules, prompt-injection and jailbreak detection, sensitive-info handling, and custom regex filters. Assign it to an organization member and it becomes the baseline for all of that member’s keys. Or assign a guardrail directly to a single API key for tight control.
Use a guardrail when “cap this key” isn’t enough and the rule you actually want is “this person can only use these models, within this budget, under these privacy rules.”
Platform teams usually reach this point because different groups need different things. One group at your organization uses frontier models in production, where reasoning accuracy matters more than price; another runs batch jobs that depend on high volume and can work with cheaper models; a third team needs to handle inputs that may contain sensitive information and needs ZDR. Guardrails let you set those rules once instead of asking every application team to write policy into their code.
We follow one simple layering rule: stricter always wins. In the diagram, the layers included in a request are your account’s settings, your workspace’s defaults, the guardrail assigned to a member’s account, and the guardrail assigned directly to an API key. All layers combine into one effective request policy.
When more than one guardrail applies to a request, its access is limited by the strictest rules. Model and provider allowlists work on the same basis. For example, if the account baseline allows for 10 models but the API-key guardrail allows only three of those models, the key gets three models, not ten. The same applies for provider allowlists. For ZDR, if any layer turns it on for a model group, it’s on.
When multiple layers set a sensitive-info filter, they all apply, and if one of those filters blocks a request while another redacts it, the blocking rule wins. Budgets are checked separately too. If a team sets a member-level budget and a key-level budget, they don’t merge into one pool, which means a request has to pass both budgets.
For guardrails that control budgets, enforcement is per-user and per-key, and not shared. That means a guardrail budget applies independently to each member and key that you assign it to. If you give the same daily budget guardrail to three members, each of those members gets that budget separately; they don’t share one big pool. When a key makes a request to OpenRouter, usage counts toward both the key’s budget and the budget of the member who owns the key.
This is the main reason to use guardrails instead of only per-key limits. With guardrails, you can very easily cap the spending of a person across all their keys, while still having the ability to tighten a limit on one key if a particular application needs a smaller cap.
A few things to know. In an organization, only admins manage guardrails (a personal account can create guardrails for its own keys too). Keep in mind that your allowlists need some upkeep as your model policy changes. And when a budget runs out, the caller gets a 403, not a warning beforehand.
When should you use a workspace budget?
Use a workspace budget when you need a hard cap on an entire workspace, no matter how many keys live inside it. Set a USD limit for a daily, weekly, monthly, or lifetime window, and OpenRouter blocks requests with a 403 at the limit. This caps the whole environment at once, so you don’t have to police every key inside it.
Plan tier restrictions
Workspace budgets are an Enterprise feature, and they are created and managed by your organization’s admins. Per-key limits and guardrails work on both free and PAYG plans, but workspace budgets don’t. If you’re not on Enterprise, a per-member guardrail budget is how you cap your team’s spend instead.
How workspaces fit
A workspace keeps one team’s setup separate from another’s. Each workspace has its own keys, guardrails, BYOK, routing, presets, plugins, observability, members, and budgets. However, billing, management keys, and privacy settings live at the account level, and Activity and Logs are account-level views that you can filter by workspace. Because of this, a workspace budget effectively caps everything routed through that workspace at once, and only an admin can create or delete a workspace.
A few limits to know about:
- Each shorter window must have a smaller budget. A lifetime budget must be bigger than a monthly one, which must be bigger than a weekly one, which must be bigger than a daily one.
- BYOK requests. Requests that use your own provider key (BYOK), and thus don’t spend any OpenRouter credits, don’t count toward the budget by default. Enable the workspace’s Include BYOK spend setting to count them.
- Requests already in flight. Requests that are already in flight when a budget is hit will be allowed to finish. So actual spend can run slightly over before the next request is blocked.
- No email or webhook alerts yet. Callers will get a 403 when a request is blocked, and you can check the state of your budget by navigating to your workspace settings.
For the full set of rules and implementation details, see the workspace budgets documentation and the enterprise quickstart.
Can a preset control what a team spends?
Not directly. Presets set the defaults for what a request does, but don’t automatically put a cap on what it costs. That’s why they sit below the three hard caps above them: per-key limits, guardrail budgets, and workspace budgets.
A preset is a named configuration, referenced as @preset/slug, that can hold a model choice, fallback models, provider routing, a system prompt, and generation parameters. Instead of hard-coding those choices in every service, teams point requests at a shared preset and change the configuration in one place.
A lot of wasted AI spend starts with stale configuration. One service pins an expensive model for a task that no longer needs it. Another forgets to sort providers by price. A third keeps an old prompt that burns tokens on context nobody uses. Presets give platform teams one place to fix the default.
For example, a team could create a “support-triage” preset that uses a cost-appropriate model, sets provider: { "sort": "price" }, and keeps the system prompt consistent across apps. When the team needs to change the model or routing policy, it can update the preset instead of shipping code across multiple services.
The limit is that presets guide behavior rather than enforce it. A request can override any preset value by sending its own parameters. So presets are good for standardizing well-behaved applications, not for stopping a caller who sends different parameters.
How do organizations and roles control who can spend?
An organization puts everyone’s spend into one shared credit pool and decides who controls it. All members draw from central billing. Only admins can buy credits and set billing, provider, and privacy configuration. Members create their own keys and see only their own.
Create an organization when more than one or two people share AI spend and you want one bill and one set of admins.
There are two roles, Admin and Member. Admins hold the spending authority, and members work within it. There are no finer-grained permissions for sub-teams. Org-wide presets and guardrails let admins set defaults that apply to the whole organization.
Organizations have some limitations you should know about:
- An organization caps at 10 members - contact support to push the limits higher.
- Transferring personal credits into an organization is self-serve from the credits page, with eligibility rules (account and membership age, recently purchased credits, and cooldowns). Organizations billed by invoice can’t receive transfers.
- You can’t convert a personal account into an organization.
- Isolation inside an organization comes from workspaces, not roles. Each workspace gets its own keys, guardrails, and budgets while the org keeps one bill.
What can the Activity dashboard show about team spend?
The Activity dashboard is the reporting layer under every other control. Every API response includes a usage object with token counts and cost, plus each key exposes daily, weekly, and monthly usage totals. And in an organization, the Activity dashboard shows usage across members, with exports grouped by Model, API Key, or Creator (the org member). That’s where you find out who spent what on which model.
One thing to know: in organization context, the activity feed shows every member’s usage metadata to every member. That covers model, cost, and timing, but never prompts or responses. Members can’t scope the feed to just their own activity, which is good for shared accountability but can surprise teams expecting privacy inside a shared org.
One aside: adding more keys or accounts doesn’t raise your rate limits. Rate limits are a separate topic from spend limits; see the rate-limits reference.
Which controls fit your team?
Here’s a decision heuristic to match the controls below to your situation. Default to the cheapest one that fully covers the risk, unless there’s a reason not to. Only reach for Enterprise workspace budgets when you truly need a hard cap on a whole environment. Each line below is one decision:
- Solo or side project. A per-key credit limit with a monthly reset is all you need.
- Small team, one bill (under 10 people). An organization for the shared pool, per-key limits, and the Activity dashboard to see who’s spending what. Add a guardrail when one person’s access or budget needs to differ.
- Multiple teams, or staging-versus-prod. Workspaces to keep them separate, a guardrail per member or key for budgets, a model allowlist, and presets to standardize configuration. Add workspace budgets if you’re on Enterprise.
- Regulated or sensitive data. Guardrails with ZDR per model group, PII filters, and a provider allowlist. We’re SOC 2 Type 2 compliant but don’t offer a HIPAA business associate agreement (BAA), so a health-data workload that needs a BAA isn’t a fit for that specific requirement today.
Whatever your team looks like today, start simple. Set per-key limits now, and add guardrails and workspace budgets when team size or compliance actually calls for them.
Frequently asked questions
Can I set a spending limit per API key on OpenRouter?
Yes. Every API key can have a limit in credits and a limit_reset of daily, weekly, or monthly on any plan, free or paid. Requests past the limit get rejected, and you can read the remaining balance through GET /api/v1/key.
How do I cap spend for a whole team?
It depends on your plan. On free and pay-as-you-go plans, assign a guardrail with a budget to each member or key. Each member and key gets its own budget, and requests past it get a 403. On Enterprise, a workspace budget caps an entire workspace at once.
Can I restrict which models my team can use?
Yes, through a guardrail’s model allowlist (and a provider allowlist alongside it). An empty allowlist means all models are permitted. When multiple guardrails apply, the allowlists intersect, so the strictest one wins.
Can organization members see each other’s spend?
In an organization, the Activity feed shows all members’ usage metadata (model, cost, and timing) to all members. We don’t store prompts or responses, so the content of requests is never visible. The feed can’t be scoped to just your own activity in org context.
How many people can be in an OpenRouter organization?
Organizations are capped at 10 members. If you need more than that, let us know!
Does OpenRouter have per-team cost attribution?
At the moment, yes, but only at the member level. The Activity dashboard exports usage grouped by Creator (the org member), and each key reports daily, weekly, and monthly totals. There is no per-sub-team attribution.
Does OpenRouter alert me before I hit a budget?
Not yet. When you hit a cap, requests get a 403, and there’s no email or webhook warning beforehand. You can check current status in the dashboard. This applies to per-key limits, guardrail budgets, and workspace budgets alike.
Is OpenRouter HIPAA compliant for a healthcare team?
We don’t offer a HIPAA business associate agreement (BAA) today. We are SOC 2 Type 2 compliant, so for a health-data workload that requires a BAA, you’ll need a different path for that specific workload.
Original source - Aug 4, 2026
- Date parsed from source:Aug 4, 2026
- First seen by Releasebot:Aug 5, 2026
Ori Harness: The Best Way to Use OpenRouter with Any Harness
OpenRouter adds ori CLI support that logs users in and auto-configures popular harnesses for the best OpenRouter setup out of the box. It starts with Claude Code, Codex, OpenCode, and Hermes, with smarter model-aware defaults and more harness support planned.
We often see folks trying to use OpenRouter with their favorite harnesses resort to writing ad-hoc scripts or complex config to tweak them to fit just right. Some harnesses require minimal configuration, maybe just one environment variable, but others like Claude Code require many more.
You can now install the ori CLI, log in with OpenRouter, and immediately have an optimized configuration right out of the box that works with all your favorite harnesses:
Install ori cli
curl -fsSL https://openrouter.ai/labs/ori/install.sh | bash ori loginLog in to OpenRouter
Set up and optimized for OpenRouter
ori claude ori codex ori opencode ori hermes... more to come
Why do I need this if I can just change a few settings?
When using a gateway like OpenRouter, to get the same out-of-the-box experience with Claude Code as you get using Anthropic’s first-party harness, there’s a lot of environment variables you need to set…
ANTHROPIC_BASE_URL=https://openrouter.ai/api ANTHROPIC_AUTH_TOKEN=<openrouter-api-key> ANTHROPIC_API_KEY= OPENROUTER_API_KEY=<openrouter-api-key> CLAUDE_CODE_SKIP_FAST_MODE_ORG_CHECK=1 CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1 ENABLE_TOOL_SEARCH=true CLAUDE_CODE_SIMPLE_SYSTEM_PROMPT=1 ANTHROPIC_DEFAULT_HAIKU_MODEL=~anthropic/claude-haiku-latest ANTHROPIC_DEFAULT_SONNET_MODEL=~anthropic/claude-sonnet-latest ANTHROPIC_DEFAULT_OPUS_MODEL=~anthropic/claude-opus-latest ANTHROPIC_DEFAULT_FABLE_MODEL=~anthropic/claude-fable-latest[1m] ANTHROPIC_DEFAULT_FABLE_MODEL_NAME=FableFor Anthropic models, enabling ENABLE_TOOL_SEARCH will save you almost half the system prompt in tokens, and is the default setting on modern Claude models… when Claude Code detects the first-party harness.
Tool search meaningfully changes the agent’s behavior as well: when tool search is disabled, Claude uses more tokens, more turns to accomplish the same task, and uses the Todo tool more!
However, most open models today do not support tool search at all. In ori claude, we detect your --model flag and switch the settings to be most optimal for the model you’re using. In the future, we plan to take this further and optimize tool settings, system prompt verbosity, and more depending on the model.
That’s it
Claude Code is a particularly tricky example, but we’ll be optimizing ori harness for many harnesses. Today we support:
- Claude Code
- Codex
- OpenCode
- Hermes
Please give it a try!
Some future plans and ideas:
- Better support desktop apps
- A toolbar widget to track your usage, and toggle global switching to OpenRouter
- Including WebSearch plugins out of the box for harnesses like OpenCode and Pi
If any of those sound appealing, or if you have feedback on a harness you’d like us to support, please join the Discord and leave us a note in the #ori-feedback channel.
Original source - Aug 3, 2026
- Date parsed from source:Aug 3, 2026
- First seen by Releasebot:Aug 4, 2026
Ori Eval: Find the Best Model for What You're Building
OpenRouter launches Ori Eval, an agentic model evaluation tool that tests your app on real prompts, writes eval files for you, and compares models on cost, speed, tool calls, and answer quality. It routes through OpenRouter, supports CI, and helps teams pick the best model with proof.
As more and more apps add AI functionality, the choice of which model to use for what you’re building remains just as hard, if not harder, with over 500 models you can choose from.
In practice, that choice is often made without a systematic method: a recommendation from social media, a benchmark leaderboard, or a general sense that one model is currently the strongest.
These resources are genuinely useful, but each has the same limit. A benchmark measures a fixed task set, and a recommendation reflects someone else’s application. Neither can tell you how a model behaves in your app, on your harness, on your data, and on your prompts.
Meanwhile new models ship every week, and the cost of re-evaluating them by hand is high enough that many teams delay the decision, or keep a model that no longer fits.
At OpenRouter, we know a thing or two about models.
What we’ve learned is that there is no definitive best model - only the best model for what you’re building.
Ori Eval helps you find that single model, and prove it to you.
To get started, tell your agent:
run curl -fsSL https://openrouter.ai/skills/spawn-ori-eval and follow the instructions in its output to get started
Ori Eval will walk you through how to choose the best model for what you’re building like a friendly and experienced engineering friend - no eval experience needed.
Tl;dr
- Ori Eval runs your agent on your own prompts, asserts on the tools it called, and grades open-ended answers with an LLM judge.
- Ori pins the harness and the model during a run. The environment stays the same, so if an eval result changed, you know that the change can only be attributed to a change in the model.
- Ori Eval routes through OpenRouter, so model comparisons cover every model and lab.
- You don’t need to know how to write an eval. Ori Eval finds every place your code calls a model, asks what matters to you, and writes the eval files.
- An eval file is code. Run it in CI to block a regression, and re-run it when a new model comes out.
- To start, tell your coding agent:
run curl -fsSL https://openrouter.ai/skills/spawn-ori-eval and follow the instructions in its output to get started.
Ask a question, get an answer (with proof)
To use Ori Eval, you can simply tell your favorite coding agent:
run curl -fsSL https://openrouter.ai/skills/spawn-ori-eval and follow the instructions in its output
Your agent hands the request to Ori Eval. Ori Eval explores your codebase, and it comes back with questions. Before it runs any evaluations, it works with you to help figure out what’s important to you — is it cost, performance, latency, speed, tool call accuracy, etc. It then chooses the 5 latest models that fit your requirement, and confirms with you.
Once all these necessary requirements have been gathered, Ori Eval writes a review.eval.ts file, runs your agent against the candidate models in parallel, and returns a table:
model | catch | p50 | $/PR | result
anthropic/claude-opus-5 | 94% | 38s | $0.041 | pass
openai/gpt-5.6-sol | 92% | 44s | $0.038 | pass
moonshotai/kimi-k3 | 90% | 31s | $0.019 | pass
z-ai/glm-5.2 | 86% | 26s | $0.008 | pass
google/gemini-3-pro | 84% | 52s | $0.062 | fail (cost)The recommendation comes with the reason: let’s say, the top bug catch rate inside your model cost criteria, and the value pick if bug review volume grows.
Don’t worry if you’ve never written an eval before
Writing good evals is not easy, that’s why we handle the annoying part for you.
Ori Eval scans your codebase for every place a model runs, and shows you what it found: the use case surface, the exact file, and the model you use there right now. It then asks where you want the eval to cover, and what matters most to you: accuracy, speed, cost, or something else?
Once Ori Eval is done interviewing you, it writes the eval file from your answers, and runs it.
It’s that easy.
Consistent scores, run after run
Because Ori Eval is an agent, it can pin the harness, the model, and the effort for the duration of a run. It also comes pre-tuned: we’ve already chosen the harness and the model that work best for eval work, so you don’t have to.
An eval checks three things
An eval file is a *.eval.ts file that runs with bun test. It checks the tools the agent called, the tools it avoided, and the quality of the answer:
const run = await agent.run("dinner in Lisbon?"); run.tool("search").toBeCalled(); run.tool("delete_file").toNotBeCalled(); run.toComplete();For open-ended answers, an LLM-as-a-judge grades the output. Ori Eval helps you set the grading criteria and the minimum score, so even tricky open-ended questions can be evaluated.
Every bug becomes something you can test against
Tell Ori Eval about a bug in plain words: let’s say, a support agent is issuing refunds without even checking the order first — a pretty big problem.
Ori Eval writes an eval that asserts lookup_order gets called. The eval fails proving that the bug exists. You then fix the agent, and the eval passes. The assertion stays in your test suite, so you’ll always be able to catch it.
Block regressions, and re-run when the field moves
Add ori eval to a GitHub Actions workflow. It exits like bun test, so failed evals also fails the build, and a regression never reaches prod.
Since what Ori Eval writes is just code, you can also easily schedule them to run every so often. One of our early beta testers now runs model comparisons monthly. When a new model drops and it performs better than the existing model in your code base, a PR gets opened, and all you have to do is merge it and experience all the benefits without you even thinking about it.
Get started
Tell your coding agent:
run curl -fsSL https://openrouter.ai/skills/spawn-ori-eval and follow the instructions in its output to get started
That’s it.
The skill installs Ori (our pre-tuned coding agent), asks you to sign in, interviews you, and runs the eval. If you use the OpenRouter MCP server, run /spawn-ori-eval instead, and skip the URL.
To install Ori by hand:
curl -fsSL https://openrouter.ai/labs/ori/install.sh | bashThen run ori login. Running evals also needs Bun.
Read more on the Ori Eval page or the Ori Eval docs.
Original source - Jul 29, 2026
- Date parsed from source:Jul 29, 2026
- First seen by Releasebot:Jul 29, 2026
Using OpenRouter With LangChain: ChatOpenRouter Setup Guide
OpenRouter adds a dedicated LangChain integration with ChatOpenRouter for Python and TypeScript, making it easier to use 400+ models with built-in routing, failover, streaming, tools, structured output, and observability without rebuilding existing apps.
Quickstart: OpenRouter in a LangChain app in 5 minutes
Get a working model call in three steps: install, authenticate, invoke.
OpenRouter is a model router behind one OpenAI-compatible API: one endpoint, 400+ models, 70+ providers. ChatOpenRouter slots into any chain or agent like any other LangChain chat model. The model string is the only OpenRouter-specific piece.
Step 1: Install and authenticate
Install langchain-openrouter and put your key in the environment. Generate a key at openrouter.ai/settings/keys.
pip install -U langchain-openrouter export OPENROUTER_API_KEY="sk-or-..."Use the -U flag. The package is beta and moves fast; always pull the latest. ChatOpenRouter automatically reads OPENROUTER_API_KEY from the environment. You can also pass it explicitly as api_key if you manage secrets differently.
Step 2: Instantiate and invoke
from langchain_openrouter import ChatOpenRouter model = ChatOpenRouter( model="anthropic/claude-sonnet-4.5", temperature=0, max_tokens=1024, max_retries=2, ) response = model.invoke("Summarize this support ticket in one sentence.") print(response.content)temperature, max_tokens, and max_retries behave exactly as they do on any LangChain chat model. The model argument is our slug in provider/model format.
If you want to confirm your key works before wiring up LangChain, the endpoint speaks the OpenAI Chat format directly:
curl https://openrouter.ai/api/v1/chat/completions \ -H "Authorization: Bearer $OPENROUTER_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "anthropic/claude-sonnet-4.5", "messages": [{"role": "user", "content": "Summarize this support ticket in one sentence."}] }'Same key, same model string, same response shape. ChatOpenRouter is a typed LangChain wrapper over that endpoint.
Step 3: TypeScript
The TypeScript path is the same shape with @langchain/openrouter:
import { ChatOpenRouter } from '@langchain/openrouter'; const model = new ChatOpenRouter('anthropic/claude-sonnet-4.5', { temperature: 0.8, }); const response = await model.invoke('Summarize this support ticket in one sentence.'); console.log(response.content);Install with npm install @langchain/openrouter. The current version lives on npm.
Full setup details are on OpenRouter’s LangChain integration page and in LangChain’s ChatOpenRouter reference.
Pick a model: the provider/model string
The model parameter is OpenRouter’s slug in provider/model form, and swapping models is a one-string change. Nothing else in your chain moves: your prompts, tool definitions, and output stay as they are.
Set model="anthropic/claude-sonnet-4.5" today, change it to openai/gpt-5-mini or deepseek/deepseek-r1 tomorrow, and your chains stay exactly as they are.
Pull current provider/model strings from openrouter.ai/models. That page shows which models are available, which providers offer them, and how much each one costs per token. The slugs in this guide are illustrations; the catalog is the source of truth.
For LangChain agents, there’s a shorthand that skips the constructor entirely:
from langchain.agents import create_agent agent = create_agent(model="openrouter:anthropic/claude-sonnet-4.5")The openrouter:provider/model prefix tells create_agent to resolve through ChatOpenRouter. Same one-string swap, one layer up.
Streaming responses
Use stream_events to get tokens as the model produces them. The async variant, astream_events, does the same within an async chain.
Streaming costs the same per-token rate as a non-streaming call. You stream for the user experience, not the bill.
for event in model.stream_events("Explain provider routing in three sentences.", version="v3"): if event["event"] == "on_chat_model_stream": print(event["data"]["chunk"].text, end="", flush=True)Pass version="v3" to get the current event schema. The async form is the same with astream_events and an async for:
async for event in model.astream_events("Explain provider routing in three sentences.", version="v3"): if event["event"] == "on_chat_model_stream": print(event["data"]["chunk"].text, end="", flush=True)usage_metadata is available on the final aggregated message, so you can read token counts without making a second call.
Tool calling and structured output
Use bind_tools for tool calling and with_structured_output for typed responses. Both accept strict=True to force schema adherence.
strict works with the function_calling and json_schema methods, not with json_mode.
Bind tools with a Pydantic schema
from pydantic import BaseModel, Field class GetWeather(BaseModel): """Get the current weather for a city.""" city: str = Field(description="City name, e.g. 'Lisbon'") model_with_tools = model.bind_tools([GetWeather], strict=True) result = model_with_tools.invoke("What's the weather in Lisbon?") print(result.tool_calls)strict=True makes the model adhere to the tool schema rather than improvising arguments.
Get structured output
with_structured_output binds a schema to the whole response:
class TicketSummary(BaseModel): sentiment: str priority: int summary: str structured = model.with_structured_output(TicketSummary, method="json_schema") summary = structured.invoke("Customer is furious the export button is broken again.") print(summary.priority, summary.summary)The default method is function_calling. Passing method="json_schema" uses native JSON-schema enforcement where the model supports it.
Not every model supports every method; check the model catalog for per-model capabilities. Setting require_parameters: true in the provider object (covered next) keeps requests on providers that honor the parameters you sent.
Provider routing and fallbacks
ChatOpenRouter exposes our routing layer through openrouter_provider and route, so a single chain can survive a provider going down with no extra resilience code in your app.
Here’s what happens by default when you make a call. We price-load-balance across the providers serving your chosen model and route away from any provider that had an outage in the last 30 seconds, using the rest as live fallbacks. Your chain code never sees the retry. A request that ultimately can’t be completed isn’t billed.
Steer providers with openrouter_provider
model = ChatOpenRouter( model="anthropic/claude-sonnet-4.5", openrouter_provider={ "order": ["Anthropic", "Google"], "allow_fallbacks": True, "data_collection": "deny", "sort": "throughput", }, )order sets your provider preference.
allow_fallbacks: True lets us fall back past your preferred providers if they’re unavailable.
sort accepts "throughput" or "latency" when speed matters more than price.
data_collection: "deny" routes away from providers that train on your prompts.
only and ignore allow or exclude specific providers.
require_parameters: True keeps requests on providers that support the exact parameters you’re sending.The full provider object reference is at openrouter.ai/docs/guides/routing/provider-selection.
Fail over across models, not just providers
Provider failover is on by default; route="fallback" states it explicitly. To also fail over to different models, pass a models array through model_kwargs and we try each model in sequence:
model = ChatOpenRouter( model="anthropic/claude-sonnet-4.5", route="fallback", model_kwargs={ "models": [ "anthropic/claude-sonnet-4.5", "openai/gpt-5-mini", "google/gemini-3-flash-preview", ], }, )models isn’t a named constructor argument, so it rides in model_kwargs, which forwards extra parameters to the API unchanged. If the primary can’t serve the request, we try the next provider, then the next model in the array. Pair the array with sort: {by, partition: "none"} in openrouter_provider to rank endpoints globally across all listed models rather than per-model.
Your LangChain chain points at one ChatOpenRouter, we spread the request across providers, and you’re billed only for the run that succeeds.
Reasoning, multimodal, caching, and observability
Each of these is one constructor or request parameter.
Reasoning
Set a reasoning budget with the reasoning parameter:
model = ChatOpenRouter( model="anthropic/claude-sonnet-4.5", reasoning={ "effort": "high", "summary": "auto", }, )effort runs from xhigh down through high, medium, low, minimal, to none. Reasoning token counts appear in usage_metadata.output_token_details.reasoning, so you can see exactly what the thinking cost.
Multimodal inputs
Image, audio, video, and PDF inputs pass through HumanMessage content blocks, just as LangChain handles multimodal models. Which modalities are supported depends on the model; check the catalog for per-model capabilities.
Prompt caching
Drop a cache_control: {"type": "ephemeral"} breakpoint on a message content block to enable caching. Cache reads surface in usage_metadata.input_token_details.cache_read, so you can see the savings per call. The prompt caching guide covers the cost side.
Observability
Pass a session_id (up to 256 characters) to group related requests, and a trace object for per-request metadata. We forward both to your configured Broadcast destinations, so traces land in your existing stack without extra instrumentation.
None of these require changes to your chain structure; they’re constructor or request parameters that layer on top of whatever you’ve already built.
Common problems and how to fix them
Four problems come up often, and each has a fix.
Version compatibility on a beta package
langchain-openrouter is recent and in beta, so it requires a current LangChain. It’s not backward-compatible with older LangChain versions. Pin to the version on PyPI, upgrade LangChain alongside it, and don’t copy a version pin from an older tutorial.
The ChatOpenAI + base_url pattern
If you’re on an older LangChain version that predates the dedicated package, pointing ChatOpenAI’s base_url at https://openrouter.ai/api/v1 with your OpenRouter key still works. Use it when you can’t upgrade. With current LangChain, the dedicated ChatOpenRouter package provides cleaner access to provider routing, reasoning, and structured output, but there’s no urgency to migrate if your current setup is working.
The model returns the same answer every time
If a model keeps returning the same response, that’s almost always temperature or caching behavior, not a defect. Set a non-zero temperature and check whether prompt caching is active.
Per-model parameter support
Not every model supports every parameter you can pass. When in doubt, set require_parameters: true in openrouter_provider so we only route to providers that accept your parameters, or check the model page in the catalog first.
Standardize on the ChatOpenRouter package, pin it from PyPI or npm, and keep model strings current from openrouter.ai/models. Set openrouter_provider once and every call in your chain inherits cross-provider failover, billed only for the run that succeeds.
Frequently asked questions
Is OpenRouter the same as LangChain?
No. They compose rather than compete. OpenRouter is a model provider and router that sits behind one OpenAI-compatible API, giving you 400+ models from 70+ providers. LangChain is the orchestration framework you build chains and agents in. You use OpenRouter as a model inside LangChain through ChatOpenRouter.
How do I use OpenRouter with LangChain?
Install langchain-openrouter, set OPENROUTER_API_KEY, and instantiate ChatOpenRouter(model="provider/model"). Then call .invoke(...), .stream_events(...), .bind_tools(...), or .with_structured_output(...) like any LangChain chat model. The package is beta; pin the version from PyPI or npm. The TypeScript path uses @langchain/openrouter with the same shape.
Does LangChain support OpenRouter tool calling and structured output?
Yes. Use model.bind_tools([...]) for tools and model.with_structured_output(Schema, method="json_schema") for typed responses, both with strict=True to enforce the schema. These are first-class methods on the current ChatOpenRouter package and supersede the older JSON-schema workarounds on the legacy ChatOpenAI path.
Can I set provider routing or fallbacks from LangChain?
Yes. Pass openrouter_provider={...} to steer providers, and model_kwargs={"models": [...]} to fail over across models. Provider failover is on by default: OpenRouter price-load-balances and routes away from providers with an outage in the last 30 seconds. Failed requests aren’t billed; you pay only for the run that succeeds.
Do I still need the ChatOpenAI + base_url pattern?
Not on the current LangChain. The dedicated ChatOpenRouter package is the current path and gives cleaner access to provider routing, reasoning, and structured output. The ChatOpenAI override, pointing base_url at https://openrouter.ai/api/v1 with your OpenRouter key, still works as a fallback for older LangChain versions that predate the package.
Which models can I use?
Any of the 400+ models in the catalog, via the provider/model slug. Check openrouter.ai/models for current strings, per-model capabilities, and pricing. The available models and per-token rates change, so treat the catalog as the source of truth.
Original source - Jul 27, 2026
- Date parsed from source:Jul 27, 2026
- First seen by Releasebot:Jul 28, 2026
Image Generation Models on OpenRouter
OpenRouter adds unified image generation and image understanding through one API key and base URL, with a dedicated /images endpoint, vision support on /chat/completions, routing and failover for image calls, and a growing image model catalog.
Tl;dr
- Both image jobs run on one API key. Generate images with POST /api/v1/images (model plus prompt in, base64 images out), and analyze images by sending an image_url to a vision model on /chat/completions.
- The catalog includes Google, OpenAI, Black Forest Labs, xAI, ByteDance, Microsoft, Recraft, Krea, and Sourceful. Browse the image model catalog or filter by /models?output_modalities=image.
- Provider routing carries to image calls: /api/v1/images accepts order, only, ignore, sort, and allow_fallbacks, and vision calls on /chat/completions take the full chat provider object.
- OpenRouter does not add provider markup, and failed image requests are not billed (Zero Completion Insurance).
- If you get “no endpoints found that support image input”, you sent an image to a text-only model. Switch to a model whose input_modalities include image.
Can I generate and read images through one API?
Yes, through one base URL and one API key. To generate an image, POST a prompt to the dedicated Image API. To read one, send it to a vision model on the standard Chat Completions endpoint.
Which image models are available?
The catalog includes Google (the Gemini image family), OpenAI (GPT Image), Black Forest Labs (FLUX), xAI (Grok Imagine), ByteDance (Seedream), Microsoft (MAI-Image), Recraft, Krea, and Sourceful (Riverflow). Specific model names shift with every release, so for the current lineup, capabilities, and per-model pricing, use the image model catalog.
How do I generate an image?
Send a POST to /api/v1/images with a model and a prompt. The images come back in the data array as base64.
Each entry in data carries the image as base64 in b64_json, plus a media_type field (typically image/png; Recraft vector models can return image/svg+xml). The usage field reports token counts and the request’s cost. Request up to 10 images per call with n (not every provider supports n > 1), and iterate data rather than hardcoding index 0.
Controlling dimensions, quality, and format
The request body takes image-specific fields directly:
- resolution: Normalized tier: 512, 1K, 2K, 4K
- aspect_ratio: Ratio from 1:1 up to extended values like 21:9; providers clamp to their supported subset
- quality: auto, low, medium, or high
- output_format: png, jpeg, webp, or svg (vector models only)
- input_references: Reference images (URL or base64) for image-to-image work
Check the model’s supported_parameters in GET /api/v1/images/models for what each endpoint accepts. Providers can also take provider-specific options through provider.options, and models with supports_streaming: true can stream partial images over SSE with stream: true. The image generation doc covers the full request schema.
How do I analyze or read an image?
Send a messages array containing a text part and an image_url part to a vision model on /chat/completions. You get a text completion back. The image_url accepts either a public URL or a base64 data URL.
The response comes back as a standard text completion, with the model’s answer in choices[0].message.content.
Four behaviors to plan for:
- Supported types are image/png, image/jpeg, image/webp, and image/gif.
- Multiple images go in as separate content entries. How many a model accepts varies by provider and model.
- Order matters. Send the text part first, then images. Alternatively, put images in the system prompt if they need to come before the user turn.
- URLs vs. base64. URLs are more efficient over the wire. Base64 is the right choice for local or private files you don’t want to host publicly.
For PDFs, use the file content type rather than rendering pages to images first. OpenRouter also supports audio and video inputs through the same endpoint, using the same pattern of swapping the model and content type. The multimodal overview covers every input type.
Generation or understanding: which do I need?
Use generation when the output is a new visual asset: mockups, product shots, illustrations, marketing creative, anything that begins as a text prompt and ends as pixels.
Use understanding when you already have an image and need information from it: OCR on receipts and forms, accessibility alt-text, object or defect detection on a production line, classification, or plain description.
The endpoint you call tells us which job you’re doing. Generation posts to /api/v1/images; understanding posts to /chat/completions. Both use the same API key and land on the same bill.
There’s a third option for apps where the conversation itself should decide when an image is needed. The openrouter:image_generation server tool (beta) lets a chat model generate an image mid-conversation without your application code making that call explicitly. Add { "type": "openrouter:image_generation" } to the request’s tools array, and the model determines when to invoke it. It defaults to openai/gpt-5-image. The server-tool doc covers the available parameters.Do routing and failover work for image calls?
Yes. On /api/v1/images, the provider object accepts order, only, ignore, sort, and allow_fallbacks. An image model served by more than one provider can fail over between them if the first is unavailable or slow.
Vision calls on /chat/completions take the full chat provider object, including data_collection: "deny".
You pay the catalog rate with no markup from us. Under Zero Completion Insurance, an image call that fails over and never completes isn’t billed. For how the router picks a provider, see how OpenRouter model routing works.Is there a free way to generate images?
Not at the moment. The free tier covers models with the :free suffix at 50 requests/day and 20 RPM with no credit card (1,000 requests/day with $10 or more in credits), and no image generation model currently carries that suffix. The free pool changes as models come and go, so it’s worth re-checking.
Generation therefore draws on your credit balance, but testing costs little. Per-image pricing on low-cost models starts around a cent, and each response’s usage.cost reports what the request cost. The free models guide covers the free tier’s mechanics for text models.How do I fix “no endpoints found that support image input”?
This error means you sent an image_url to a model that doesn’t accept image input. We auto-filter available models by request content, so when the model you named has no available endpoint that supports images, the request fails with this error instead of silently dropping the image.
Fix it in three steps:- Confirm the model supports image input. Its input_modalities must include image. Text-only models never will.
- Find a vision-capable model. Run GET /api/v1/models?input_modalities=image, or use the input modality filter on the Models page.
- Update the model string in your request and resend.
Sibling errors like no endpoints found that support tool use and the data-policy variants work the same way. The error names the requirement that didn’t match; relax it or pick a model and provider combination that meets it.
What limits should I plan around?
- Base64 output: Generated images return in data[].b64_json as base64 bytes, not a hosted file URL. Decoding and storage are on you.
- Direction support varies by model: Generation models live on /api/v1/images; vision input needs a model whose input_modalities include image on /chat/completions. Mismatches surface as the “no endpoints found” error.
- Parameter support varies by endpoint: aspect_ratio values, n > 1, streaming, and provider-specific options differ per endpoint. Check supported_parameters in GET /api/v1/images/models.
- All-or-nothing billing: A generation is billed in full on completion or not at all on failure; there’s no partial-image billing.
Start with the image model catalog, test a prompt in the Chatroom, and wire the call with the snippets above.
Frequently asked questions
Can I generate and read images through one API?
Yes, through one base URL and one API key. To generate an image, POST a model and a prompt to https://openrouter.ai/api/v1/images. To read one, send it as an image_url to a vision model on /chat/completions. Both land on the same bill.
Which image generation models are available on OpenRouter?
The catalog includes Google (Gemini image family), OpenAI (GPT Image), Black Forest Labs (FLUX), xAI (Grok Imagine), ByteDance (Seedream), Microsoft (MAI-Image), Recraft, Krea, and Sourceful (Riverflow). Filter /models?output_modalities=image or browse the image model collection for the current lineup and pricing.
How do I fix “no endpoints found that support image input”?
You sent an image_url to a model that doesn’t accept image input. Confirm the model’s input_modalities include image, find a vision-capable model with GET /api/v1/models?input_modalities=image, and update the model string in your request.
Is there a free way to generate images on OpenRouter?
Not at the moment. The free tier (50 requests/day, 20 RPM, no credit card) covers models with the :free suffix, and no image generation model currently carries it, so generation draws on your credit balance. Low-cost models start around a cent per image.
Do routing and failover work for image calls?
Yes. The /api/v1/images endpoint accepts provider.order, only, ignore, sort, and allow_fallbacks, so ordering, cost/latency sort, and cross-provider failover work the same way as on chat. Vision calls on /chat/completions take the full chat provider object, including data_collection: "deny".
How are generated images returned?
In the response’s data array; each entry has b64_json with the base64-encoded image bytes and a media_type field (typically image/png). Request up to 10 images per call with the n parameter and iterate data rather than hardcoding index 0.
Original source - Jul 24, 2026
- Date parsed from source:Jul 24, 2026
- First seen by Releasebot:Jul 25, 2026
Classifiers: Track What Your Agents Do and What It Costs
OpenRouter adds beta classifiers for structured AI usage reporting, letting teams tag generations by taxonomy, model choice, department, task type, complexity, compliance needs, and cost center. It brings continuous visibility into logs and Activity Explorer without adding inference latency.
You can now automatically classify your OpenRouter generations with structured metadata for AI usage reporting.
Every request carries information: the type of work, the level of complexity, which department it came from, whether it contains internal data it shouldn’t. Classifiers, now available in beta, give you that visibility. Define your criteria (task type, agent complexity, compliance category, cost center). A model of your choice tags each generation, or a sampled subset, against your taxonomy and write the results to your logs. You get continuous visibility into what your agents and users are doing, which models they’re using for different tasks, and where the costs go.
Create a classifier in your workspace settings, or read the docs first.Pick a template or define your own taxonomy
A classifier is a small config with four parts: a taxonomy (up to eight dimensions, each with the values you choose), a classification prompt (instructions sent to the classifier model as a system message), a model to read each prompt and apply it, and a sampling rate. Classification runs asynchronously after each request completes, so it never adds latency to your inference path.
Choose from six preset templates, customize a template, or build your own from scratch.Templates and what they tag:
- Department: Which business function originated the request: engineering, sales, marketing, legal, and so on. Useful for seeing which parts of the org drive inference cost
- Audience: Who the output is for: internal use, client-facing, regulators, or the public. Feeds compliance workflows that depend on who reads a model’s output
- Task type: What the model is doing: coding, agent workflows, data processing, content writing. Useful to check whether the right tier of model is being used for each task
- Engineering work: Feature development, bug fixing, documentation, refactoring, code review. Good for tracking where AI is helping and which models are used for each type of work
- Agent complexity: Difficulty tier (from trivial tool calls to frontier-expert work) plus task family. For teams running agents, where “which model handled a hard task well” is the question that matters
- Capitalizable software expense: Whether AI-assisted engineering work is potentially capitalizable development versus maintenance, operations, or support
Select your classification model. We recommend Gemini 3.5 Flash Lite for the best value: cheap, strong accuracy on structured output, good enough for most taxonomies. You can change the model at any time.
At high throughput, the cost of classifying every request adds up. Use the sampling rate to keep costs down. Run a high-fidelity compliance classifier at 100% while a broader cost-attribution classifier samples 10% of the same traffic, keeping costs proportional to the oversight you need.Structured tags in your logs
Classifier outputs are coerced into structured formats, constrained to the dimensions and values you define. Every classified generation is tagged in your logs, so you can filter requests by classification. For example, you can pull every request tagged department: legal or agent_complexity_difficulty_tier: complex_multistep. Each tagged generation’s detail panel breaks down classified dimensions and values.
You can also run a classifier on demand against any past generation to sanity-check a new taxonomy. Open it in your logs, pick a classifier, and see how it gets tagged.Roll it up in Activity
Individual tags on generations answer “what was this request?” The Activity Explorer answers the aggregate questions: group your traffic by any classifier dimension to see which models are being used for each task type or level of agent complexity, and which departments or tasks drive the most spend.
Results are aggregated over time; watch patterns shift in your data and show stakeholders how your AI usage is governed. Classifier filters carry across the Activity tabs so you can see trends and guardrail enforcement by any classifier value.Get started
Classifiers are available now in beta. Create a classifier in your workspace or read the docs to learn more about taxonomy design, billing, and how classification works under the hood. Classifiers work even with input & output logging disabled.
Original source
Tell us what you think in #feedback on Discord. - Jul 22, 2026
- Date parsed from source:Jul 22, 2026
- First seen by Releasebot:Jul 23, 2026
Transcription on OpenRouter
OpenRouter adds audio transcription support with a new /api/v1/audio/transcriptions endpoint, using the same API key as chat. It brings Whisper-class and newer STT models, automatic multi-provider load balancing, usage-based cost reporting, and timestamp support on compatible providers.
You’ve got a 40-minute sales call recording, a folder of voice memos, or a user holding down a mic button, and you need a text transcript. The usual approach is to stand up a Whisper server or add a second provider SDK just for speech-to-text, on top of whatever already handles your chat traffic. On OpenRouter you can send the audio to
POST /api/v1/audio/transcriptionsinstead and get back JSON with the transcribed text and a usage object, using the same API key and auth as Chat Completions.You don’t need a new SDK or a separate service. Because transcription runs on the same platform as your chat traffic, a model hosted by several providers is load-balanced across them automatically instead of being pinned to a single vendor.
Tl;dr
- Transcribe by sending base64-encoded audio to
POST /api/v1/audio/transcriptionsand reading JSON text plus a usage object off the response. It takes the same Bearer key as Chat Completions. - Whisper-class models work here (the slug is
openai/whisper-1). Newer token-priced speech-to-text (STT) models exist too. Discover them with?output_modalities=transcription, not the default catalog. - When a transcription model is hosted by more than one provider, we load-balance across them automatically. The per-request routing controls you use on chat (
order,allow_fallbacks,data_collection,sort) are not applied on this endpoint today; the provider block here carries provider-specific options only. Bring-your-own-key (BYOK) routes to your own provider key for the platform fee only. - The real limits to design around are a 60-second upstream timeout, no audio URLs (send base64 JSON, or an OpenAI-style multipart file up to 25 MB), and no SRT/VTT output. Word and segment timestamps are available with
response_format: "verbose_json"on OpenAI-compatible providers. - Pricing is duration-based or token-based depending on the model, with no provider markup. The
usage.costfield returns the actual per-request cost so you can meter spend.
How do you transcribe audio on OpenRouter?
Send base64-encoded audio to
POST /api/v1/audio/transcriptionsand read thetextfield off the JSON response. You pass your OpenRouter API key as a Bearer token exactly as you do on a chat call, set a model, and hand it the audio.The response is JSON with a
textstring that holds the transcript and ausageobject that reports the audio duration in seconds, the token counts, and the dollar cost of the request. You make one request, and the transcript comes back in the response body, so there’s no polling and no job ID to track.The request body carries a model and an
input_audioobject. Insideinput_audioyou put the file as base64 data and a format string. Optionally, you add a language hint, a temperature, and a provider block.Which speech-to-text models are available?
You can pick from two families of models. Whisper-class models like
openai/whisper-1are priced by duration, per second of audio, while newer speech-to-text models are priced per token. Which one fits depends on your accuracy bar, your language mix, and your budget.STT model IDs don’t show up in the default
/api/v1/modelscatalog. That’s expected, because transcription is an output modality you filter for.The field-by-field request contract
The whole flow takes three steps. You base64-encode the file, POST it with a model and a format, and read text and usage off the response. The
datafield takes raw base64 bytes, not adata:URI, so don’t prefix it withdata:audio/mp3;base64,. Theformatfield is required, and it tells the upstream model how to decode those bytes.The response and its usage accounting
The response is JSON with a
textstring and ausageobject. Theusageobject is what lets you meter spend per request instead of estimating it.When to use transcription vs. audio input or text-to-speech?
Use
/audio/transcriptionswhen you want audio turned into text, and audio input on chat when you want a model to reason about the audio.The transcription endpoint fits meeting notes, voice commands, captioning, and searchable archives of calls or podcasts. If you want sentiment on a support call, a Q&A about what was said, or audio mixed with other modalities in one prompt, use the
input_audiocontent type on/chat/completions. Turning text into speech is a third, separate endpoint.How does provider routing work for transcription?
Transcription uses the same routing layer as chat. When a model is hosted by more than one provider, we distribute your requests across them, load-balanced by price, so you aren’t pinned to a single vendor. What transcription doesn’t expose today is per-request routing control. The
order,only,allow_fallbacks,data_collection, andsortfields you’d set on a chat call are not applied on/api/v1/audio/transcriptions. The provider block on this endpoint carries provider-specific options instead.What are the limits to plan around?
Four constraints shape how you structure a transcription call:
- 60-second upstream timeout: ~60 seconds of processing time, not a hard cap on audio length. Large or uncompressed recordings are the ones that time out. Split long audio into segments, transcribe each, and stitch the text.
- No audio URLs: Audio can’t be passed by URL on this endpoint. Send base64 JSON, or an OpenAI-style multipart file up to 25 MB. Compressed formats (
mp3,aac) make smaller, faster payloads. - No SRT/VTT output:
srt,vtt, andtextresponse formats are rejected with a 400. Timestamps are available viaverbose_jsonon OpenAI-compatible providers; build subtitle files from those yourself. - Format support varies by provider: The list (
wav/mp3/flac/m4a/ogg/webm/aac) is common, but a given model or provider may not accept all of them.wavis the safest default.
What does a transcription request cost?
You pay the model’s catalog rate with no markup from us, and the
usage.costfield tells you the exact figure per request. Whisper-class models charge per second of audio, and newer models charge per token.Rates change, so we keep the live figure on each model’s page in the catalog rather than printing one here. Reading
usage.costoff the response tells you what each request actually cost. STT models are paid, so API transcription draws on your credit balance.Frequently asked questions
How do I transcribe audio files with OpenRouter?
Send base64-encoded audio to
POST /api/v1/audio/transcriptionswith a model and aninput_audioobject (dataplusformat). The response is JSON with atextstring (the transcript) and ausageobject (seconds, tokens, and cost). It uses the same Bearer API key and auth as Chat Completions.Does OpenRouter support Whisper?
Yes. Whisper-class models are available for transcription, and
openai/whisper-1is the slug to use. STT model IDs aren’t in the default/api/v1/modelslist, so you discover them by filtering with?output_modalities=transcriptionor browsing the Speech-to-Text collection. Whisper is duration-priced, per second of audio; newer STT models price per token instead.What audio formats does OpenRouter transcription accept?
The common set is
wav,mp3,flac,m4a,ogg,webm, andaac, passed in the requiredinput_audio.formatfield. Support varies by model and provider, so not every model accepts every format.wavis the safest default for broad compatibility; compressed formats likemp3give smaller, faster payloads.Can OpenRouter return timestamps or SRT/VTT subtitles?
Timestamps, yes. Set
response_formattoverbose_jsonto get segment-level timestamps, and addtimestamp_granularities: ["word"]for word-level timestamps in awordsarray. That works on OpenAI-compatible providers (OpenAI, Groq, Together); other providers reject it with a 400. SRT/VTT output isn’t supported, so build subtitle files from the timestamps yourself.How long can the audio be?
The practical limit is the roughly 60-second upstream processing timeout, not a fixed audio-length cap. Short and medium clips return in one call. For long recordings, split the audio into segments, transcribe each, and stitch the text together.
How much does transcription cost on OpenRouter?
You pay the model’s catalog rate with no markup. Whisper-class models price per second of audio; newer STT models price per token. The
Original sourceusage.costfield in each response reports the exact dollar cost of that request. - Jul 16, 2026
- Date parsed from source:Jul 16, 2026
- First seen by Releasebot:Jul 17, 2026
Every Modality Through One API
OpenRouter adds a unified multimodal API for chat, images, video, audio, transcription, and embeddings through one OpenAI-compatible base URL. It highlights one key, one bill, provider routing and failover, plus dedicated endpoints for generation and transcription.
Tl;dr
- Set one base URL (https://openrouter.ai/api/v1) and call image, video, audio, embeddings, and transcription through it. Switch modality by changing the model string and the content type.
- Most input modalities ride the /chat/completions endpoint. Five have dedicated endpoints: /images, /videos, /audio/speech, /audio/transcriptions, and /embeddings.
- The same provider routing object (failover, data_collection: "deny", cost/latency sort) works on an embeddings call exactly as it does on a chat call.
- One API key, one bill, one OpenAI-shaped request format across all 5 modalities. We don’t mark up provider pricing, and failed requests aren’t billed.
- Real limits to plan around: embeddings don’t stream, audio input is base64 only, and video URL support is provider-specific.
Can one API handle image, video, audio, embeddings, and transcription?
Yes. One base URL serves every modality, and you switch between them by changing the model string and the request content type. Set https://openrouter.ai/api/v1 as your base URL, pass your API key as a Bearer token, and you reach the full catalog through one OpenAI-compatible interface.
Wiring up 4 provider SDKs means each provider brings its own auth refresh, retry and backoff semantics, rate-limit headers, streaming format, and error schema. You write that glue 4 times, maintain it 4 times, and a change from one provider only ever fixes its own corner.
We’re a drop-in replacement for the OpenAI Chat API, so the same request format carries across every modality that rides /chat/completions, and the TTS endpoint follows the OpenAI Audio API. The dedicated endpoints (image generation, video generation, transcription, and embeddings) each have their own request shape, but our official SDKs (@openrouter/sdk for TypeScript, openrouter for Python) wrap all of it behind one interface.
Which endpoint does each modality use?
Most input modalities ride /chat/completions and differ only by content type. Five modalities have dedicated endpoints. Here’s the full map, grounded in our multimodal overview and embeddings reference.
Modality Endpoint How you call it Text / chat POST /api/v1/chat/completions messages array Image input (vision) POST /api/v1/chat/completions image_url content type PDF POST /api/v1/chat/completions file content type Audio input POST /api/v1/chat/completions input_audio content type Video input POST /api/v1/chat/completions video_url content type Image generation POST /api/v1/images prompt in, base64 images out Video generation POST /api/v1/videos (async) submit prompt, get job ID, poll Text-to-speech POST /api/v1/audio/speech text in, MP3/PCM bytes out Transcription (STT) POST /api/v1/audio/transcriptions base64 audio in, JSON text + usage out Embeddings POST /api/v1/embeddings text or text+image, vectors outFive of these modalities run on /chat/completions and change only the content type in the message array. Five have their own endpoints because their call shape is different: image generation takes a prompt plus image-specific knobs (resolution, aspect ratio, output format) and returns base64 images, video generation is asynchronous (you poll a job), speech and transcription move raw audio bytes, and embeddings return vectors instead of completions. Single-provider docs rarely lay this out side by side, because no single provider serves all of them.
You can test multimodal inputs without paying. The free tier needs no credit card, and free models run under low daily rate limits that rise once you’ve added credits. That’s enough to send an image to a vision model or generate a batch of embeddings before you commit.
When should you use each modality?
Generation and understanding are different tasks even within the same media type, and the endpoint you reach for depends on which one you’re doing.
Image: generation vs. understanding.
Use image generation when you need a new image, and image input when you have one to analyze. Generation produces assets, mockups, and illustrations from a text prompt through a POST to the dedicated /api/v1/images endpoint, with optional reference images for image-to-image work. Vision input goes the other way: you send an image_url on /chat/completions, and the model does OCR, description, or detection. See the image generation docs for the full walkthrough.
Video: input vs. generation.
Use the async /videos endpoint to produce clips and video_url on chat to understand them. Video generation submits a prompt and returns a job ID you poll until the clip is ready, with configurable resolution, aspect ratio, and duration. Video understanding sends a video_url to a video-capable model for analysis, action recognition, or object detection. More in the video generation announcement.
Audio and speech: output vs. analysis.
Use /audio/speech for voice output and audio input on chat for analysis. Text-to-speech sends text to /api/v1/audio/speech and returns MP3 or PCM bytes through an OpenAI Audio-compatible endpoint, so OpenAI client libraries work against it. Audio input rides /chat/completions with the input_audio content type for tasks like sentiment or content analysis. Details in the audio APIs announcement.
Embeddings: retrieval and similarity.
Use embeddings when you need retrieval or similarity, not generation. The embeddings docs name 6 jobs: RAG, semantic search, recommendations, clustering, duplicate detection, and anomaly detection. You can batch many inputs in one request, and some models accept text and an image together to produce a single joint vector (nvidia/llama-nemotron-embed-vl-1b-v2 is one).
Transcription: speech to text.
Use /audio/transcriptions for speech-to-text. You send base64-encoded audio and get back JSON with the transcribed text plus usage statistics. It fits meeting notes, voice commands, and captioning.
Do routing and failover work for embeddings and image calls too?
Yes. The same provider object you use on a chat call works identically on an embeddings call: provider order, automatic failover, data-collection policy, and cost or latency sort. Here’s the exact shape from the embeddings docs:
{ "model": "openai/text-embedding-3-small", "input": "Your text here", "provider": { "order": ["openai", "azure"], "allow_fallbacks": true, "data_collection": "deny" } }The routing controls carry to the dedicated image endpoint too: /api/v1/images accepts provider.order, provider.allow_fallbacks, provider.only, provider.ignore, and provider.sort, so failover, ordering, and cost/latency sort work the same way on an image generation call as on a chat call.
An embedding model served by more than one provider can fall back from one to another when the first returns an error. The same cross-provider failover applies to embeddings, image, audio, and chat alike through the provider object.
We don’t mark up provider pricing: the rate in the model catalog is what you pay. Zero Completion Insurance means a failed run isn’t billed, so a request that fails over and never completes costs nothing. That holds across modalities.
What do you actually save by consolidating?
One API key, one bill, one request format across every modality.
The same Bearer token authorizes a vision call, a TTS call, and an embeddings call. There’s no separate key vault per provider and no per-modality onboarding. When you add a new capability, say you start doing RAG, you call /embeddings with the key you already have.
Consolidated billing means usage across modalities lands on a single OpenRouter statement at catalog rates. You can compare what image generation cost versus embeddings in one place, rather than exporting CSVs from 4 dashboards. That reconciliation friction is exactly what the r/ShowYourApp builder ran into when the all-in-one stack got harder than expected.
What are the limits to plan around?
Each modality has constraints worth knowing before you build. These are our own current limits, stated plainly so you can design around them rather than discover them in production.
Limit Modality What it means for you No streaming Embeddings Responses come back complete, not token by token. Plan synchronous handling. Deterministic output Embeddings Same input gives the same vector. Cache aggressively. Base64 only Audio input Audio can’t be passed by URL. Encode local files first. Provider-specific URLs Video input URL support varies. Gemini on AI Studio accepts only YouTube links. Model-by-model support All Not every model supports every modality. We auto-filter by content. Free-tier rate limits All Free models have low daily limits that rise once you add credits.The unified API earns its place when you need more than one media type, when swapping models is a one-string change, or when a provider outage shouldn’t take your feature down. If your entire app is a single chat feature against one general-purpose model from one provider, a direct integration is simpler and the consolidation upside is thinner.
Start with one call
Send a single embeddings request against the base URL.
Example Python code:
import requests response = requests.post( "https://openrouter.ai/api/v1/embeddings", headers = { "Authorization": "Bearer <OPENROUTER_API_KEY>", "Content-Type": "application/json", }, json = { "model": "openai/text-embedding-3-small", "input": "The quick brown fox jumps over the lazy dog", }, ) print(response.json()["data"][0]["embedding"][:5])Example TypeScript code:
import { OpenRouter } from '@openrouter/sdk'; const openRouter = new OpenRouter({ apiKey: process.env.OPENROUTER_API_KEY }); const response = await openRouter.embeddings.generate({ model: 'openai/text-embedding-3-small', input: 'The quick brown fox jumps over the lazy dog', }); console.log(response.data[0].embedding);Example curl:
curl https://openrouter.ai/api/v1/embeddings \ -H "Authorization: Bearer $OPENROUTER_API_KEY" \ -H "Content-Type: application/json" \ -d '{"model": "openai/text-embedding-3-small", "input": "The quick brown fox jumps over the lazy dog"}'From here, go deeper per modality with the multimodal overview, or browse models by output modality to find what fits each call.
Frequently asked questions
Can I use one API for image generation, embeddings, and transcription?
Yes. All three run through our base URL at https://openrouter.ai/api/v1, with one API key. Image generation uses the dedicated /images endpoint, embeddings use /embeddings, and transcription uses /audio/transcriptions. You change the endpoint and content type, not the integration, the auth, or the API key.
Does OpenRouter support embeddings?
Yes. Embeddings run through POST /api/v1/embeddings and return vectors for RAG, semantic search, recommendations, clustering, duplicate detection, and anomaly detection. You can batch multiple inputs in one request, and some models accept text and an image together for a joint vector.
Which modalities use the chat endpoint vs. a dedicated endpoint?
Text, image input, PDF, audio input, and video input all use /chat/completions and differ only by content type. Image generation (/images), video generation (/videos), text-to-speech (/audio/speech), transcription (/audio/transcriptions), and embeddings (/embeddings) use dedicated endpoints, because their call shapes differ: prompt-to-image requests, async jobs, raw audio bytes, or returned vectors instead of completions.
Are there free AI APIs that support multimodal inputs?
Yes. We have a free tier at OpenRouter, no credit card required. Free models run under low daily rate limits that rise once you’ve added credits, which is enough to send images, generate embeddings, or test other modalities before you commit.
Can I send text and an image in one embeddings request?
Yes, with multimodal embedding models. You wrap the input in a content array containing text and image_url objects, and the model returns a single joint vector that captures both. nvidia/llama-nemotron-embed-vl-1b-v2 is one model, useful when you want text and images to share a single retrieval space.
Do provider routing and failover work for embeddings and image calls too?
Yes. The same provider routing controls (order, allow_fallbacks, cost/latency sort) apply to embeddings, image, audio, and chat calls. If a provider errors, the call falls over to the next one serving that model, and a failed run is never billed.
Original source - Jun 25, 2026
- Date parsed from source:Jun 25, 2026
- First seen by Releasebot:Jun 26, 2026
The OpenRouter MCP Server
OpenRouter launches the MCP server, giving coding agents live model rankings, pricing, docs, benchmarks, and test inference so they can choose the best model with current data instead of stale guesses. It also adds OAuth-based setup, capped keys, and provider-aware model testing.
Your coding agent is incredible at writing code.
But when it comes to choosing the right model for, say, coding without blowing through your monthly budget in one day, or the best model for designing a landing page, it really struggles.
Your agent can make an approximate guess of the “best” model, but it’s guessing from training data that is months stale, with no knowledge of how much it costs, how well it performs for a given task, which provider you should pin it to, etc.
No more.
Today, we’re very excited to announce the release of the OpenRouter MCP.
The OpenRouter MCP server puts live model data, benchmark rankings, pricing, docs, and test inference directly to help you and your agent to make the right decisions on the best model to use. Install in one command, and your favorite agent can answer “which model is the best at coding without bankrupting me” with the most up-to-date data Artificial Analysis, Design Arena, and OpenRouter’s own model rankings. Hint: it’s GLM-5.2.
Connect now | Docs
Install in one command
Claude Code:
claude mcp add --transport http openrouter https://mcp.openrouter.ai/mcp claude mcp login openrouterCodex CLI:
codex mcp add openrouter --url https://mcp.openrouter.ai/mcp codex mcp login openrouterCursor: Add to ~/.cursor/mcp.json :
{ "mcpServers": { "openrouter": { "url": "https://mcp.openrouter.ai/mcp" } } }See the connect guide for OAuth login and every supported client.
Pick the right model without tab-switching
You’re building a feature that needs structured JSON output, and you want a model that’s fast, cheap, and actually good at it. Normally you’d open the OpenRouter website, browse the model list, compare benchmarks, check pricing, maybe run a few test prompts in the playground. That’s 15 minutes of context-switching before you write a single line of integration code.
With the MCP server connected, you can do this all in your coding agent:
You: "I need a model for structured JSON extraction from legal documents.
Fast, under $1/M input tokens, good at following schemas."
Agent: [calls models-list with filters] → [calls benchmarks] → [calls model-endpoints]
Agent: "google/gemini-3-flash-preview fits well: $0.10/M input,
138k context, strong structured output support. Here's the
endpoint with the lowest latency..."The agent pulls from the live model catalog, cross-references Artificial Analysis intelligence scores and Design Arena ELO rankings, and checks per-provider pricing and latency. The recommendation is fully grounded in current data, not whatever was true when the model was last trained 6 months ago.
Test before you commit
chat-send lets your agent fire off a test prompt to any model and see the response, cost, and which provider served it. Your agent can compare answers across models side-by-side:
You: "Compare how Claude Opus 4.8, GPT-5.5, and DeepSeek V4 Pro
handle this structured extraction prompt."
Agent: [sends the same prompt to all three via chat-send]
[calls generation-get for each to get cost breakdowns]
Agent: "All three produced valid JSON. Opus 4.8 nailed the edge
case in row 12. GPT-5.5 was 40% cheaper. DeepSeek V4 Pro
was fastest at 180ms TTFB."Model slugs support suffixes:
:online for web search,
:nitro for speed,
:floor for the lowest price,
:free for free endpoints. Your agent can test across variants without you memorizing the syntax.Search the docs without leaving your editor
Your agent has docs-search, which runs a full-text search across the OpenRouter documentation. “How do I pin a model to a specific provider?” “What’s the format for tool calling?” “How does prompt caching work?” Your agent finds the answer and applies it, all in one flow.
This is where the MCP server earns its keep as a development assistant. Your agent can look up the exact API parameter it needs, check the right request format, and wire it into your code without you having to find and read the docs page yourself.
A dedicated, capped key
The server is remote (nothing installed locally), and the first login runs an OAuth flow that mints a dedicated API key with a 7-day expiry and a $10 spend cap (editable on the approval screen). It’s separate from your other keys and shows up on your keys dashboard. You can revoke it any time.
See the connect guide for setup in OpenCode, Claude Desktop, and every other supported client.
What’s in the toolbox
Tool What it does models-list Search the live model catalog with filters: price range, context length, modality, provider, model family, and more model-get Full details for one model: capabilities, pricing, context window, supported parameters model-endpoints Per-provider breakdown: price, latency, throughput, data policy benchmarks Third-party quality scores from Artificial Analysis and Design Arena rankings-daily Which models are most used and trending by token volume chat-send Send a test prompt to any model, get the response and cost generation-get Cost, token counts, and serving provider for a specific generation docs-search Full-text search across OpenRouter docs credits-get Your remaining account credit providers-list Available providers for routing preferences app-rankings Which apps drive the most OpenRouter traffic, by categoryAll tools except chat-send are read-only lookups. chat-send makes a billable inference call using your MCP key’s balance.
FAQ
Does this replace the OpenRouter API?
No. The MCP server is a development assistant for your coding agent. It pulls live OpenRouter data and can send test messages so your agent makes informed decisions while you build. Your app should still call the OpenRouter API directly.
How does authentication work?
Your MCP client triggers an OAuth flow that opens an OpenRouter consent page in your browser. You approve a dedicated API key with a 7-day expiry and a $10 spend cap. The key is separate from your other keys and can be disconnected anytime from your dashboard.
Does my source code get sent anywhere?
No. The tools are read-only lookups against the OpenRouter API. The only exception is chat-send, which sends the message you explicitly pass to it to a model. No source code leaves your machine unless you include it in a chat-send call.
Try it now: connect your agent and ask “what’s the best model for my use case?”
Original source - Jun 23, 2026
- Date parsed from source:Jun 23, 2026
- First seen by Releasebot:Jun 24, 2026
Introducing the Unified Image API
OpenRouter launches a dedicated Image API with unified access to 30+ models, standardized request handling, per-model capability discovery, granular endpoint pricing, and native streaming previews for GPT image models.
Image generation on OpenRouter now has a dedicated API with unified access to 30+ models.
Like all our media generation APIs, we’ve standardized the interface for easy model switching, allowed passthrough for unique model capabilities, and provided programmatic access to discover the details of each individual model. We support models from Google, OpenAI, Black Forest Labs, Recraft, ByteDance, Sourceful, Microsoft, and xAI, with more being added all the time.
Browse image models | API docs | Try it in the playground
Know What Each Model Can Do
Image models differ in ways that break requests. Seedream 4.5 supports 18 aspect ratios; Gemini 3.1 Flash Image supports 14 (overlapping, but not identical). Some models generate up to 10 images per call; others cap at 1. Some accept 16 input references; others accept 4.
The /api/v1/images/models endpoint returns typed capability descriptors for every model:
{ "id": "bytedance-seed/seedream-4.5", "supported_parameters": { "resolution": {"type": "enum", "values": ["1K", "2K", "4K"]}, "aspect_ratio": {"type": "enum", "values": ["1:1", "16:9", "9:16", "..."]}, "n": {"type": "range", "min": 1, "max": 10}, "input_references": {"type": "range", "min": 0, "max": 14}, "seed": {"type": "boolean"} }, "supports_streaming": false }Your code can adapt to any model without hardcoding provider differences or battling 400 errors over unacceptable parameters.
This is especially useful for agents. Give your coding agent the /api/v1/images/models response and it has everything it needs to pick a model, validate inputs, and generate images without trial-and-error.
Per-Provider Granularity
Each model may be served by multiple providers. The per-endpoint records (/api/v1/images/models/{id}/endpoints) give you the definitive truth for each one: which parameters this specific endpoint accepts, what passthrough keys are allowed, streaming support, and granular pricing.
curl "https://openrouter.ai/api/v1/images/models/google/gemini-3.1-flash-image/endpoints"Each endpoint also returns a pricing array with the exact billing structure. Different providers charge in different units:
"pricing": [ { "billable": "output_image", "unit": "image", "cost_usd": 0.04 } ]Seedream 4.5 charges a flat $0.04 per image. FLUX.2 Pro bills at $0.03 per megapixel (so resolution affects cost). GPT-5.4 Image 2 and Gemini 3.1 Flash Image bill per token. No more guessing why a generation cost what it did; the usage object in every response includes the exact cost in USD.
One Request Shape, Any Model
The API normalizes the fragmented world of image generation into one schema:
curl -X POST "https://openrouter.ai/api/v1/images" \ -H "Authorization: Bearer $OPENROUTER_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "bytedance-seed/seedream-4.5", "prompt": "a red panda astronaut floating in space, studio lighting", "resolution": "2K", "aspect_ratio": "16:9" }'Resolution, aspect ratio, quality, output format, background transparency, input references, streaming: all normalized across every provider. When you need provider-specific features (like Black Forest Labs’ steps or guidance), pass them through provider.options keyed by the provider slug from the endpoints API.
Streaming Previews for GPT Image Models
OpenAI’s GPT Image models (GPT-5 Image, GPT-5 Image Mini, GPT-5.4 Image 2) support native SSE streaming through the Image API. Set "stream": true and you’ll receive partial image previews as they’re rendered, so users see progress instead of waiting for the full generation. Check the supports_streaming field on any endpoint to see if it’s available.
FAQ
What happens to image generation through chat completions?
Until now, we supported image generation via completions and responses. All existing image models continue to be supported here, however new image models will be added exclusively to the dedicated Image API.
If you’re using openai/gpt-5-image, openai/gpt-5-image-mini, or openai/gpt-5.4-image-2, we recommend switching to one of the dedicated image models. The GPT 5 and 5.4 versions generate images through an LLM, so they don’t provide access to the full set of supported parameters and may incur extra inference cost.
Can I use provider-specific features?
Yes. Each endpoint exposes an allowed_passthrough_parameters list. Pass provider-specific keys under provider.options keyed by the provider slug. The endpoints API tells you exactly which keys are accepted.
How does pricing work?
Each endpoint returns granular pricing lines with a billable unit, cost in USD, and optional variant tiers (e.g., resolution-based pricing). The usage object in every response includes the exact cost.
Tell us what you think and which models you want next in #feedback on Discord.
Original source
Curated by the Releasebot team
Releasebot is an aggregator of official release notes from hundreds of software vendors and thousands of sources.
Our editorial process involves the manual review and audit of release notes procured with the help of automated systems.