Plugins, files, batches & media
Everything beyond a plain chat completion: grounding with web search, documents as input, safe built-in tools, asynchronous batches, and image, rerank, speech and transcription endpoints — all billed on the same receipt with every fee itemised.
Plugins
Plugins run inside the gateway before (or around) the model call. Ask for them with plugins: [{ id }]. Each plugin that charges anything appears as its own line in elevenrouter_metadata.pipeline.plugins and is included in cost.total; guardrail policies can block plugins or cap what they may cost per request.
webgrounding · fee per result- Searches the web for the last user message (or
search_prompt) and inserts up tomax_results(default 5) cited sources as a system message. Billed per result returned (see the pricing page); the sources are listed on the receipt. The:onlinemodel variant is shorthand for this plugin. Customers never see which search vendor is used. file-parserdocuments · free- Turns PDF attachments (
{ type: "file", file: { file_data | file_id } }) into text for models without native file input. Models that accept files natively receive the PDF unchanged. Scanned PDFs without a text layer fail withpdf_unreadablerather than silently sending nothing. server-toolsbuilt-in tools · rounds billed as generations- Exposes safe built-ins the model can call —
datetime(current time in any timezone) andsearch_models(the catalog with prices and capabilities). Tool rounds run inside the gateway (up tomax_rounds, default 3); each round is a normal, billed generation and the final answer is returned to you once, streamed if you asked for streaming. response-healingoutput · free- Repairs malformed JSON (fences, trailing commas, truncation) when you asked for a JSON response.
# Grounded answer with two cited sources, receipt enabled
curl https://elevenrouter.com/api/v1/chat/completions -H "Authorization: Bearer $ELEVENROUTER_API_KEY" -H "Content-Type: application/json" \
-H "X-ER-Metadata: enabled" -d '{
"model": "anthropic/claude-sonnet-5",
"plugins": [{ "id": "web", "max_results": 2 }],
"messages": [{ "role": "user", "content": "What changed in the latest ElevenRouter release?" }]
}'
# …or simply: "model": "anthropic/claude-sonnet-5:online"
# A PDF for a model without native file input
curl https://elevenrouter.com/api/v1/chat/completions -H "Authorization: Bearer $ELEVENROUTER_API_KEY" -H "Content-Type: application/json" -d '{
"model": "deepseek/deepseek-v4-flash",
"plugins": [{ "id": "file-parser" }],
"messages": [{ "role": "user", "content": [
{ "type": "text", "text": "Summarise this report." },
{ "type": "file", "file": { "file_id": "file_abc123" } }
]}]
}'
# Let the model check the time before answering
curl https://elevenrouter.com/api/v1/chat/completions -H "Authorization: Bearer $ELEVENROUTER_API_KEY" -H "Content-Type: application/json" -d '{
"model": "openai/gpt-5.6-luna",
"plugins": [{ "id": "server-tools", "tools": ["datetime"] }],
"messages": [{ "role": "user", "content": "Is it still business hours in Tokyo?" }]
}'Policy controls: rules.plugins.blocked (e.g. ["web"]), rules.plugins.maxPluginCostUsdPerRequest and rules.plugins.maxWebResults — see guardrails.
Files API
Upload documents once and reference them from messages, or upload JSONL for batches. Two upload styles work from any HTTP client: JSON with base64 content, or a raw body with x-er-purpose and x-er-filename headers. Files are limited to 50 MB and 2 GB per organization; set expires_after_seconds to have them deleted automatically.
# Raw upload
curl https://elevenrouter.com/api/v1/files -H "Authorization: Bearer $ELEVENROUTER_API_KEY" \
-H "Content-Type: application/pdf" -H "x-er-purpose: user_data" -H "x-er-filename: report.pdf" \
--data-binary @report.pdf
# JSON upload
curl https://elevenrouter.com/api/v1/files -H "Authorization: Bearer $ELEVENROUTER_API_KEY" -H "Content-Type: application/json" \
-d "{\"purpose\":\"batch\",\"filename\":\"requests.jsonl\",\"content_base64\":\"$(base64 -w0 requests.jsonl)\"}"
curl https://elevenrouter.com/api/v1/files -H "Authorization: Bearer $ELEVENROUTER_API_KEY" # list
curl https://elevenrouter.com/api/v1/files/file_abc123/content -H "Authorization: Bearer $ELEVENROUTER_API_KEY" # download
curl -X DELETE https://elevenrouter.com/api/v1/files/file_abc123 -H "Authorization: Bearer $ELEVENROUTER_API_KEY"Batch API
Run thousands of requests asynchronously. Each JSONL line is { "custom_id", "method": "POST", "url": "/v1/chat/completions", "body" }; the file is validated line by line at upload, then POST /batches starts it. Requests run through the normal gateway — same policies, budgets, fallbacks, billing and logs — at bounded concurrency. Results land in an output file (one JSON object per line with custom_id and the full response), failures in an error file. Batches expire after their completion window; cancellation stops after the in-flight requests.
import { ElevenRouter } from '@elevenrouter/sdk';
const client = new ElevenRouter();
const lines = docs.map((d, i) => JSON.stringify({
custom_id: `doc-${i}`, method: 'POST', url: '/v1/chat/completions',
body: { model: 'openai/gpt-5.6-luna', messages: [{ role: 'user', content: `Classify: ${d}` }] },
}));
const file = await client.files.upload({ purpose: 'batch', filename: 'classify.jsonl', content: lines.join('\n') });
const batch = await client.batches.create({ input_file_id: file.id, endpoint: '/v1/chat/completions' });
const done = await client.batches.wait(batch.id);
const output = new TextDecoder().decode(await client.files.content(done.output_file_id!));
for (const line of output.trim().split('\n')) {
const { custom_id, response } = JSON.parse(line);
console.log(custom_id, response.body.choices[0].message.content);
}Images, rerank, speech and transcription
Models whose modality is not text-to-text are served by dedicated endpoints with the same routing, failover and receipt. GET /models/modalities lists what is available. Billing units are per modality and shown as usage.units:
POST /images/generationsper image- OpenAI-compatible image generation.
nimages at the official per-image price;response_formatb64_jsonorurl. POST /rerankper token- Relevance scores for
documentsagainst aquery, Cohere/Jina-compatible, optionallytop_n. POST /audio/speechper character- Text to speech; returns audio bytes (
audio/mpegby default) with the cost in thex-er-costheader. POST /audio/transcriptionsper minute- Speech to text from base64 audio in a JSON body (
file,filename) — no multipart needed. Billed on the duration the model reports.
curl https://elevenrouter.com/api/v1/images/generations -H "Authorization: Bearer $ELEVENROUTER_API_KEY" -H "Content-Type: application/json" \
-d '{ "model": "openai/gpt-image-2", "prompt": "a lighthouse at dawn, watercolor", "n": 1, "size": "1024x1024", "usage": { "include": true } }'
curl https://elevenrouter.com/api/v1/audio/transcriptions -H "Authorization: Bearer $ELEVENROUTER_API_KEY" -H "Content-Type: application/json" \
-d "{\"model\":\"openai/whisper-2\",\"filename\":\"call.mp3\",\"file\":\"$(base64 -w0 call.mp3)\"}"Video generation and containers are not offered yet; they will appear here the moment an upstream credential supports them, with the same receipt and privacy guarantees.