API Docs: Quickstart and SDKs
Use TrustedRouter with any OpenAI-compatible SDK after one base_url change. Get quickstarts, Python and TypeScript SDKs, privacy controls, and API reference.
Quickstart: one base_url change.
- ✓ OpenAI-compatible — point any OpenAI/Anthropic SDK at TrustedRouter
- ✓ Read your key from
TRUSTEDROUTER_API_KEY - ✓ Use
trustedrouter/autofor provider failover - ✓ Use
trustedrouter/euwith the EU regional API for Europe-focused routing - ✓ Use
trustedrouter/socratesfor the rolling advisor preset, ortrustedrouter/socrates-1.1for the pinned current version - ✓ Use
trustedrouter/iris-2.0,trustedrouter/prometheus-2.0, ortrustedrouter/zeus-1.0for versioned Synth presets - ✓ Use
trustedrouter/openpatcher-s2for Kimi K3 plus GLM 5.2 synthesis - ✓ Use
trustedrouter/openpatcher-g2for a Kimi K3 worker with parallel Gemma 4 and Prometheus 2.0 advisors - ✓ Use
trustedrouter/plato-pro-2.0for GLM 5.2 advised by Prometheus 2.0 - ✓ Use
trustedrouter/iris-code-1.0,trustedrouter/prometheus-code-1.0, ortrustedrouter/zeus-code-1.0for code-tuned Synth presets - ✓ Add
provider.min_privacy = "zdr"for a hard zero-retention floor - ✓ Add
provider.min_privacy = "confidential"to require verified provider compute + E2EE + ZDR
const client = new OpenAI({
apiKey: process.env.TRUSTEDROUTER_API_KEY,
baseURL: "https://api-azure.trustedrouter.com/v1"
})
const r = await client.chat.completions.create({
model: "trustedrouter/auto",
messages: [{ role: "user", content: "Hello" }]
})
Two hosts: inference and account management
Use the attested gateway for inference and the control plane for key management. Both accept Authorization: Bearer <API key>; key management requires a management key.
| Host | What it serves |
|---|---|
https://api-azure.trustedrouter.com/v1 | Inference: POST /v1/chat/completions, /v1/responses, /v1/messages, /v1/embeddings, images, and videos. Also GET /v1/models and GET /v1/key (inspect the current key). |
https://trustedrouter.com/v1 | Account management: POST /v1/keys and GET /v1/keys; GET, PATCH, and DELETE /v1/keys/{hash}; credits, activity, and workspaces. GET /v1/key also works here. |
Management calls to the inference host return 404. For example, list your keys on the control plane:
curl https://trustedrouter.com/v1/keys \
-H "Authorization: Bearer $TR_MANAGEMENT_KEY"
Keep management keys on your server. Use an inference key in your model client.
New York Token Exchange API
Use https://api.nytokenexchange.com/v1 as an alternate inference base URL. It accepts the same TrustedRouter API keys, request arguments, provider controls and streaming formats. Requests use your existing balance and key limits. Key creation and account management remain at https://trustedrouter.com/v1.
Every trustedrouter/ model also accepts the nyte/ prefix: nyte/auto, nyte/fast, nyte/zdr, nyte/confidential and named combination models. These are alternate names, with identical routing and billing. The catalog keeps one entry per model and lists aliases in trustedrouter.aliases.
For confidential-only inference, use https://api.confidential.nytokenexchange.com/v1 and include provider.min_privacy: "confidential". This endpoint rejects missing or weaker privacy settings and unsupported operations. It requires verified provider-side confidential compute, end-to-end encryption and explicit zero retention, and fails closed when no qualifying route is available. The ordinary endpoint does not impose this privacy floor.
curl https://api.confidential.nytokenexchange.com/v1/chat/completions \
-H "Authorization: Bearer $TR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"nyte/auto","messages":[{"role":"user","content":"Hello"}],"provider":{"min_privacy":"confidential"},"stream":true}'
Use GET /v1/models for discovery and /attestation on either API hostname for gateway verification. See the trust center and the spot exchange quickstart.
Fail-closed privacy filters
Require zero retention
{
"model": "your/model",
"provider": {"min_privacy": "zdr"}
}
This is a hard minimum. If no endpoint for the selected model and provider filters has a tracked ZDR guarantee, the request fails before inference.
Require Confidential: verified compute + E2EE + ZDR
{
"model": "your/model",
"provider": {"min_privacy": "confidential"}
}
Confidential requires all three on the same route: verified provider-side confidential compute, end-to-end encryption and explicit zero data retention. Missing or false ZDR makes a route ineligible even when its compute and encryption are verified. The model's own vendor never qualifies, so a Confidential request never reaches it. e2e and e2ee are accepted value aliases. Unsupported model/provider combinations fail closed.
Catalog fields provider_confidential_compute and provider_e2ee report individual technical properties. The Confidential label and endpoint privacy_tier: 3 additionally require provider_zero_data_retention: true for that exact route.
trustedrouter/e2e and trustedrouter/confidential select the same verified compute + E2EE + ZDR pool. A TR-funded ZDR agreement qualifies only the funded route, not BYOK. provider.data_collection = "deny" remains an OpenRouter-compatible routing preference; use min_privacy when the privacy floor must never be relaxed.
Confidential-only API hostname
Use https://api.confidential.trustedrouter.com/v1 and explicitly include "provider": {"min_privacy": "confidential"} in every inference request. The hostname is an additional guard, not an implicit default: missing, weaker, or alias values such as e2e return 400 confidential_privacy_required before inference.
from openai import OpenAI
import os
client = OpenAI(
api_key=os.environ["TRUSTEDROUTER_API_KEY"],
base_url="https://api.confidential.trustedrouter.com/v1",
)
response = client.chat.completions.create(
model="trustedrouter/confidential",
messages=[{"role": "user", "content": "Hello"}],
extra_body={"provider": {"min_privacy": "confidential"}},
)
Chat Completions, Responses, and Anthropic Messages use the same hard confidential filter, including internal orchestration calls and fallback candidates. If no eligible endpoint remains, the request fails instead of using an ordinary provider. Hosted web search, batch/files, embeddings, and media APIs are not supported on this hostname.
The equivalent mirror base URLs are https://api.confidential.quillrouter.com/v1, https://api.confidential.allyrouter.com/v1, and https://api.confidential.uptimerouter.com/v1. They require the same explicit setting. Health, attestation, and public catalog discovery remain available without it; the catalog is not a filtered list of eligible endpoints.
The ordinary API hostname is unchanged. A hostname and HTTPS alone are not independent proof of confidential execution: clients that verify hardware attestation should still follow the attestation verification guide.
Guides
60-second quickstart
Make one request, inspect the catalog, and verify the live prompt path.
Open →Agent setup
Point Codex, Claude Code, Hermes, Cursor, or any OpenAI-compatible client at TrustedRouter.
Open →MCP server
Let agents inspect live models, pricing, provider posture, credits, docs, and quick test messages.
Open →Agent skill
Help Codex, Claude Code, Hermes, and other agents choose models using speed, cost, AI IQ, privacy, context length, and prompt-cache fit.
Open →Migrate from OpenRouter
Swap one base_url and keep your existing calls working.
Open →Request tagging
Allocate cost and usage with AWS style tags while keeping metadata out of model prompts.
Open →Provider routing & pinning
Pin, prefer, or exclude providers per request — filters that fail closed, never silently relax.
Open →Performance routing
Set latency and throughput preferences while preserving hard provider and privacy requirements.
Open →Spend controls
Choose key budgets and opt into strict estimated-cost admission for concurrent requests.
Open →Model precision
Read reviewed weight formats, model revisions, and serving-code evidence for each provider.
Open →Signed inference receipts
Opt into an offline-verifiable proof of every response — exact bytes, routed model, and a hardware-attested signing key.
Open →Client reliability telemetry
See the content-free fields TrustedRouter SDKs report, the retention policy, and every opt-out.
Open →Prompt caching
Reuse stable prompt prefixes, inspect cache hits, and keep the router itself free of prompt storage.
Open →Decision models
Send state plus typed yes/no, choice, and score questions to POST /api/alpha/decide. Get verified answers with probabilities from trev-1.0, Jev, or any chat model.
Batch API
Submit OpenRouter-compatible inline batches and poll encrypted results through the attested gateway.
Open →Responses web search
Search the live web inside the attested gateway and return source citations through the OpenAI Responses API.
Open →Video generation
Generate video with Seedance, Veo, Sora, Runway, Kling, Wan, Vidu, PixVerse, LTX, Gemini Omni, and Hailuo 3 through asynchronous jobs with exact quoted billing.
Open →Evals
Run eval suites across providers through one API.
Open →Provider conformance
Check an OpenAI-compatible provider endpoint against the production gateway contract before applying.
Open →Synth
Run Iris, Prometheus, Zeus, and code-tuned Synth presets inside the attested gateway.
Open →Socrates
Run the advisor preset, or configure the generic advisor primitive directly.
Open →User-provided models
List your own endpoint — a machine, an agent, or yourself typing — at a price you set, and keep 70% in credits.
Open →Custom models
Publish a base model with a hidden prompt and earn 70% of the markup you set.
Open →x402 stablecoin funding
Let agents add prepaid credits automatically without changing the prompt path.
Open →EU routing
Use the Europe West attested gateway and the EU-focused model alias.
Open →Sign in with TrustedRouter
Let your users bring their own account and credits.
Open →Y Combinator company sign-in
Add verified company-domain context, with a copyable agent prompt.
Open →StartX company sign-in
Recognize StartX company email domains through TrustedRouter.
Open →VC-backed company sign-in
Match company domains against ten venture firms, with reusable sign-in buttons.
Open →vs OpenRouter
How TrustedRouter compares to closed routers.
Open →Security & attestation
How the attested gateway and trust record work.
Open →SDKs
Model route changes
Poll GET https://trustedrouter.com/v1/models/changes or subscribe to the Atom feed. Both are public and need no API key. They report model and provider-route additions and removals, route metadata changes, confidential route gains and losses, best privacy tier changes, and upcoming provider retirements.
GET /v1/models/changes?model=deepseek/deepseek-v4-flash&since=2026-09-01T00:00:00Z
GET /v1/models/changes.atom?type=confidential_route_lost
GET /v1/models/changes?upcoming=true
Each entry has a stable id, model, type, before, after, recorded_at and effective_at. Results are complete and ordered by (recorded_at, id), ascending. since is inclusive and filters when entries were recorded, so newly announced future changes are discoverable immediately. Save the greatest recorded_at you receive and deduplicate the next poll by id. Use timezone-qualified timestamps; model matches an exact public id. Repeat type to select several change types. upcoming=true selects future effective dates; false selects changes already effective; omit it for both.
Announcements use retirement_scheduled; projected route changes have source: "scheduled" and the announced effective date. They describe the current plan. If a forecast is withdrawn or replaced, it disappears from the current feed and a schedule_cancelled entry identifies its old id. Scheduled pricing policies use pricing_schedule_changed, excluded by default: select that type or add include_prices=true. Ordinary price refreshes and each recurring peak/off-peak switch are omitted to keep subscriptions readable; pricing policy entries contain the recurring schedule.
trustedrouter.last_route_change_at in /v1/models gives the latest recorded route change that is already effective, or null if none is known. The history starts with a September 1, 2026 baseline and replays committed catalog revisions using their contemporary privacy rules. Backfilled observations use commit dates, not deployment timestamps. Later entries describe catalog observations and announced cutovers; they do not establish release completion, live provider health, capacity, or credential availability. Conditional discovery-expiry deadlines are recorded when observed, rather than forecast as provider retirements.
Model request capabilities
GET /v1/models includes trustedrouter.capabilities on concrete model rows. For example, GPT-5.5 reports:
"capabilities": {
"reasoning_effort": ["none", "low", "medium", "high", "xhigh"],
"tools": true,
"seed": true,
"vision": true,
"confidential": false
}
Model-level tools and seed match membership in the model row's final supported_parameters; vision matches image input in architecture.input_modalities. These discovery fields include model declarations and current Credits and BYOK route declarations after known overclaims are removed. Some routes declare less than the model supports: GPT-5.5's OpenAI routes report seed: false even though its model-level discovery union includes seed. tools means function tools; seed means a supported seed control (not guaranteed deterministic output); vision means image input, not image generation. These flags describe each control independently, not every combination.
Per route, reasoning_effort has three states: a non-empty list gives verified accepted values; [] means do not send effort because the route is verified to accept none; null means not verified. At model level, it is the union of verified lists, or [] when every route is verified to reject effort, otherwise null. Mistral Large reports []. Values appear in this order: none, minimal, low, medium, high, xhigh, max. The string "none" is an explicit accepted value, distinct from null and []. Values describe the top-level chat reasoning_effort control after gateway translation, which can map to a token budget or thinking level. Do not combine it with a conflicting reasoning.enabled or budget setting.
Default routing filters by the parameters that decide what kind of response comes back: tools and tool_choice (tool calling) and response_format (structured output). It skips a route the catalog says lacks the capability. For tool calling, that is a route that does not declare tools while another route of the same model does. For either, a routing pool such as trustedrouter/auto skips a model that declares the capability neither on its own row nor on any route. A model you name keeps its routes when the catalog says nothing either way, because some models take tools without declaring them. When no route is left, the request fails with a 400 that names the parameter. Other parameters are filtered only with provider.require_parameters: true, which keeps only routes whose own supported_parameters include every parameter sent. Check the per-route values first: trustedrouter.endpoints[].capabilities and the route's supported_parameters, because some routes declare less than the model supports. This filters parameter names, not effort values or image input; pin a suitable provider when values differ. GET /v1/models/{author}/{slug}/endpoints returns each endpoint's trustedrouter.capabilities without an API key. The default list omits per-route detail to stay small; GET /v1/models?include=endpoints adds trustedrouter.endpoints[] and the model-level trustedrouter.provider_policy text to every row.
confidential is an availability flag: at least one current endpoint satisfies the same confidential privacy rule used in routing, including verified compute, end-to-end encryption, zero retention, and exclusion of the model's own vendor. On the confidential host, send provider.min_privacy: "confidential"; the host requires it and ordinary endpoints are excluded. The flag describes catalog eligibility, not live health, your credentials, or capacity. Zero retention alone does not qualify.
Routing aliases such as trustedrouter/auto, orchestration models, and hidden routes omit the object because their selected models and internal calls can vary. Absence is not a declaration of no support. A routing pool (trustedrouter/auto, cheap, fast, frontier, advanced, professional, efficient, eu, zdr, e2e, green) lists a parameter in supported_parameters only when every model it can route to has one of the pool's routes that accepts it, so a request that sends it with provider.require_parameters: true keeps every model in the pool. Its architecture.input_modalities lists what any of its routes accepts; routing sends image input only to routes that accept images. Its context_length is the largest window among the models it routes to: chat routing sends a request only to models whose window holds its estimated prompt plus max_tokens, and answers 400 context_length_exceeded when none does. Otherwise the legacy supported_parameters union and architecture.input_modalities remain discovery fields; they need not describe every endpoint.
API reference
OpenAI-compatible endpoints
Base URL https://api-azure.trustedrouter.com/v1. Authenticate inference calls with a Bearer sk-tr-… key.
POST /v1/chat/completionsPOST /v1/responsesPOST /v1/embeddingsPOST /v1/audio/speechPOST /v1/audio/transcriptionsPOST /api/alpha/decide— decision models: sharedstateplus typedquestions(boolean, choice, score) in, verified answers with probabilities out. Like chat completions,trustedrouter.routingidentifies the model and provider that served the decision, omitting fields the gateway cannot establish. It also answers to the paths Vercel AI Gateway (/v1/evaluate) and OpenRouter (/api/alpha/decisions) use for the same request. Usetrustedrouter/trev-1.0,typesafe-ai/jev, or any chat model. See /docs/decide.POST /v1/videosGET /v1/modelspublic, no API key
Agent-readable docs
Point your coding agent at the machine-readable docs for the full surface:
- /docs/llms.txt — concise index
- /docs/llms-full.txt — full context
- /docs/mcp — MCP tools for live catalog, credits, docs, and test-chat lookups
- Agent skill — model advisor for Codex, Claude Code, Hermes, and other agents
- trustedrouter-model-advisor — source repo and raw playbook for agent installation
- Socrates — advisor orchestration guide
- /docs/synth — Synth model panel guide
- /docs/user-models — post your own endpoint as a priced model; verification, dispatch, payouts
- /docs/custom-models — publish a hidden-prompt model, set markup, and collect creator earnings
- /docs/prompt-caching — provider cache behavior, usage fields, billing, and routing tradeoffs
- /docs/decide — decision models: typed questions, verified answers with probabilities, trev-1.0 and Jev, reasoning and routing options
- /docs/batch — inline Batch API quickstart, response contract, limits, and encrypted retention
- /docs/web-search — Responses API web search, citations, controls, and privacy boundaries
- /docs/provider-conformance — public provider contract checks, result meanings, and production parity
- /docs/video — asynchronous video generation, models, billing, and retention boundaries
- GitHub — source + issues
- OpenAI-compatible API — SDK migration surface
- Latency benchmarks — measured provider data
Manage keys at scale
Key management runs on the control plane, https://trustedrouter.com/v1, with a management key. Every operation is limited to the caller's workspace. Keep management keys on your server.
List and page through keys
GET /v1/keys?limit=100&offset=0 returns {"data": [...], "next_offset": 100}. Pass next_offset as the next request's offset with the same limit and filter. A null next_offset marks the last page. limit accepts 1–1000 and offset accepts any non-negative integer. Other values return HTTP 400 with error.type: "bad_request".
Keys sort newest first, with ascending hash as the tie-breaker. Disabled keys are included unless you pass include_disabled=false, which filters before paging. Without limit, the response keeps its original {"data": [...]} shape and lists every key after the offset. offset and include_disabled match OpenRouter's parameters; limit and next_offset are TrustedRouter additions.
Each page reads keys and their usage together in one database query. Creating or deleting keys between requests shifts later offsets. To delete every key, collect the hashes first, or keep reading page zero while you delete.
Delete many keys in one request
POST /v1/keys/bulk-delete
Authorization: Bearer $TR_MANAGEMENT_KEY
Content-Type: application/json
{"hashes": ["key_first", "key_second"]}
HTTP 200
{"data": [{"hash": "key_first", "status": "deleted"},
{"hash": "key_second", "status": "not_found"}]}
Send 1–1000 hashes per request. Results follow the input order, and a repeated hash repeats its first result. Missing keys and keys in another workspace both report not_found. Each group of up to 100 distinct hashes is deleted atomically, together with its lookup indexes. Groups commit independently, so after a failure you can retry the whole request; keys already deleted then report not_found. DELETE /v1/keys/{hash} also deletes atomically and returns {"data": {"deleted": true, "hash": "..."}}, or 404 when the key does not exist.
Request rate limits and retries
The control plane limits each source IP address, across every credential behind it:
- 300 state-changing requests per 60 seconds:
POST,PUT,PATCH, andDELETE. EachDELETE /v1/keys/{hash}counts once. - 2,400 requests per 60 seconds of any method, including
GET /v1/keys.
A request over either limit gets HTTP 429 from the edge, before it reaches the API. That response may be HTML or plain text and need not carry Retry-After. Management calls have no separate per-key request quota. A bulk delete counts as one write, so revoking 1,000 keys takes one request instead of more than three minutes of single deletes.
Back off on every 429. Honor Retry-After when present; otherwise use capped exponential backoff with jitter. Database contention returns 503 with error.type: "service_unavailable" and Retry-After: 1; retry it the same way. Inference spend-window limits use the separate RateLimit-* headers below.
Usage freshness
Key usage counters advance when a request settles. GET /v1/key reads them from a snapshot up to five seconds old. GET /v1/keys reads them with a strong read.
Activity comes from a separate analytics pipeline. It can show a request before GET /v1/key does, or after it, and it trails further when the pipeline has a backlog. data.analytics.drain_lag_seconds in status.json reports that backlog. A key's updated_at changes with its settings, not with usage.
Billing and usage
Token counts and token list prices are the starting point for billing. Review the rounding rules below, then inspect credits and activity at https://trustedrouter.com/v1 to reconcile charges.
Minimum charges and per-request rounding
Eligible standard routes use the prices in effect when the request was authorized, with the rounding and minimum below. Streamed usage for these routes includes cost_microdollars.
Standard prepaid text and embedding usage is billed in whole microdollars: 1 microdollar = $0.000001. Here is how the charge is calculated:
- Start with the selected route's retail token rates and applicable context-length tier. Standard retail rates are provider cost plus 5.5%, rounded up to a whole microdollar per million tokens, with a $0.01 per million token price floor. The published retail rates already include this markup and price floor; do not add 5.5% again.
- Multiply each component's token count by its rate per million tokens, then divide by 1,000,000. Round input, output, cache read, and cache write separately to whole microdollars, half up (0.5 rounds to 1; 1.5 rounds to 2). Cached tokens use their applicable cache rates, without counting them again as ordinary input.
- Add the rounded components and any fixed per-request fee. Apply a 1 microdollar minimum per billed request whenever there is positive usage at a positive rate or a positive request fee, even if all token components round to zero. With no chargeable usage and no fee, the charge is zero.
Route-specific fees and minimums can increase the total: Perplexity routes include a per-request fee, and Parasail Liberty 2.0 has a $0.001 minimum per top-level request. Check the selected route's pricing on the models page. Video jobs use their separate quoted billing described in the video guide.
Worked examples: tiny calls
These examples use illustrative retail rates, in the same form as the published per-million prices, with no cached tokens or request fees. The raw token cost is the listed rate times tokens, before per-component rounding and the request minimum.
| Usage | Retail rates per million | Raw token cost | Rounded components | Billed | Multiple of raw cost |
|---|---|---|---|---|---|
| 10 input + 5 output tokens | $0.01 input / $0.02 output | 0.2 microdollars | 0 input + 0 output; request minimum applies | 1 microdollar ($0.000001) | 5× |
| 30 input + 10 output tokens | $0.05 input / $0.05 output | 2 microdollars | 2 input + 1 output (1.5 and 0.5 each round up) | 3 microdollars ($0.000003) | 1.5× |
On very small calls to cheap models, rounding and the request minimum can make the bill several times the raw token cost. The multiple depends on the token counts and route; the 5.5% markup alone does not explain it.
Spend-window rate limits
A key with a hard daily, weekly, or monthly spend limit gets the governing window on every response. Values are integer microdollars, the same unit used by the key-limit API. Keys without a hard spend window do not get fabricated rate-limit headers.
Response headers
RateLimit-Limit— configured spend limit for the governing windowRateLimit-Remaining— settled spend headroom observed by this requestRateLimit-Reset— whole seconds until the fixed UTC window resetsRetry-After— also present on429; the reset delay rounded up, with a minimum of one second
By default, window checks are approximate: in-flight holds are not included. Use RateLimit-Remaining to slow down before rejection, and treat Retry-After as authoritative after a 429.
Strict budget admission
Full spend-controls guide: key creation, mode selection, and retry handling. Strict mode is off by default.
Set budget_strict: true when creating an API key to count outstanding reservations against daily, weekly, and monthly limits atomically. This mode is fixed at creation; create a new key to switch. It can be much slower because authorization uses a shared database counter instead of approximate snapshots or local spend leases.
{"name":"Strict project budget","limit_daily":5,"limit_monthly":100,"budget_strict":true}
Strict mode bounds admission using estimated cost, not final provider usage. Actual charges can exceed estimates. Outstanding holds continue to count across UTC window resets until settlement or refund. budget_alert_only: true still means notify without blocking; use its default false for enforced limits.
Strict authorization has a five-second database-work budget and bounded concurrency without an in-memory waiting queue. Busy requests return a retryable 503; use exponential backoff with jitter. Window exhaustion returns 429 with Retry-After. Successful authorizations release the admission slot before generation, so long model responses do not hold it.
import math
import time
import httpx
jobs = [{"model": "trustedrouter/auto", "messages": [...]}]
next_budget_microdollars = 50_000
with httpx.Client() as client:
while jobs:
response = client.post(API_URL, headers=AUTH, json=jobs[0])
reset = max(1, math.ceil(float(
response.headers.get("RateLimit-Reset", "1")
)))
if response.status_code == 429:
time.sleep(max(1, int(response.headers.get("Retry-After", "5"))))
continue
response.raise_for_status()
jobs.pop(0)
remaining = int(response.headers.get(
"RateLimit-Remaining", next_budget_microdollars
))
if jobs and remaining < next_budget_microdollars:
time.sleep(reset)
Web Fetch
POST https://api.trustedrouter.com/v1/tools/fetch forwards an explicitly submitted public URL to DeepSeek and returns {"title":"...","content":"..."}, with Markdown content.
curl https://api.trustedrouter.com/v1/tools/fetch \
-H "Authorization: Bearer $TRUSTEDROUTER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url":"https://example.com"}'
Credits only; billed per successful nonempty response, with no token charge. See current pricing. X-Usage-Cost reports USD and X-Generation-Id identifies the billing record. Failed fetches release the reservation. Reusing an idempotency key returns 409 without fetching again.
This endpoint is not ZDR or confidential inference. Those privacy floors reject the request. Do not submit URLs containing credentials or private access tokens. URLs and fetched text stay out of control-plane billing payloads and persistent router content storage.
Text to speech
POST https://api.trustedrouter.com/v1/audio/speech accepts the OpenRouter speech format and returns raw audio. Use your existing TrustedRouter key and credits. Discover models, voices, formats, billing units, and prices at /v1/models?output_modalities=speech.
curl --fail-with-body https://api.trustedrouter.com/v1/audio/speech \
-H "Authorization: Bearer $TRUSTEDROUTER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"x-ai/grok-voice-tts-1.0","input":"Hello from TrustedRouter.","voice":"eve","response_format":"mp3"}' \
--output speech.mp3
xAI, Mistral, ElevenLabs, and Microsoft charge by input characters, including spaces and punctuation. Gemini charges by text-input and audio-output tokens: it reserves a maximum-token hold for 8,192 text-input and 16,384 audio-output tokens before synthesis, then charges only provider-reported usage and releases the unused hold. Token rates are frozen at authorization.
Audio is buffered before settlement and delivery; this is not incremental synthesis streaming. Errors return JSON. X-Generation-Id identifies the billing record and X-Usage-Cost reports the charge in USD. Reusing an Idempotency-Key returns 409 without generating or charging again; audio is not stored for replay.
Speech models, parameters, SDK examples, privacy, and billing
Audio transcription
Upload PCM WAV or MP3 to POST https://api.trustedrouter.com/v1/audio/transcriptions. Use multipart with the OpenAI SDK, or JSON with base64 input_audio. Audio and transcripts stay out of the control plane and durable router logs.
curl --fail-with-body https://api.trustedrouter.com/v1/audio/transcriptions \
-H "Authorization: Bearer $TRUSTEDROUTER_API_KEY" \
-F model=openai/whisper-large-v3-turbo \
-F 'provider={"only":["tinfoil"],"min_privacy":"confidential"}' \
-F file=@recording.wav
Tinfoil and Privatemode transcription routes use attestation-verified encrypted connections. OpenAI Whisper and direct Mistral Voxtral are separate routes, not confidential-compute routes. Discover current prices and supported formats at transcription models. Limits: 7 MiB uploads, ten minutes, and 24 MB decoded MP3 audio. Voxtral Small and Privatemode Voxtral Mini return JSON without timestamps. Whisper also supports verbose JSON. URL inputs and realtime transcription are not supported.
Cost in response usage
Single-endpoint Chat Completions, Responses, and Anthropic Messages requests return usage.cost_microdollars and usage.total_cost_microdollars when the request's charge is known. Both are integer microdollars: 1,000,000 equals $1. A known free request reports 0; an unknown cost is omitted.
For streaming chat, request stream_options.include_usage: true to receive the terminal usage chunk. Responses includes cost in response.completed.response.usage; Messages includes it in message_delta.usage. Answer deltas continue streaming while the terminal event waits briefly for settlement.
Eligible standard routes are billed at the prices in effect when the request was authorized. Their streamed usage carries cost_microdollars and total_cost_microdollars, even if settlement is delayed.
Other routes report a settled or durable charge when known; an unknown cost is omitted, not shown as zero. BYOK, partner minimums, orchestration, hosted search, video, refunds, receipt surcharges, and custom or app markups retain their existing billing and reporting contracts.