DocumentationBrowse
Providers and data
Which model provider sees a prompt, and what it may do with it, is a property of the key, set once and enforced on every request. A request can narrow that policy but never widen it. This page is the mapping, field by field, from what you set to what goes upstream.
The plain-language version, with the quotations from OpenRouter's documentation, is at How we operate.
Data policy
One of three values on the key. Owners may move between the first two; private_pod is set by DocketRouter.
| data_policy | Upstream provider object | Meaning |
|---|---|---|
shared | data_collection: "deny" | Default. Never a provider whose published policy says it stores prompts non-transiently or may train on them. |
no_retention | data_collection: "deny", zdr: true | Zero-data-retention endpoints only. If none can serve the model, the request fails with 503 rather than routing to a retaining endpoint. |
private_pod | none | Only local/ models on our own hardware. Nothing is sent to any provider, so no provider object is built. |
The allowlist
Every request carries `only`. With no per-key narrowing it is this list; a key's provider_allow replaces it with a subset.
- Base slugs match every variant, as in OpenRouter's own routing:
deepinfracoversdeepinfra/fp8anddeepinfra/turbo. A list that names onlydeepinfra/fp8does not permit baredeepinfra. - Any provider outside the list, on a key or on a request, is a 400 whose message includes the list.
- The list is set per host;
GET /keys/{id}returns it asallowed_providersso a client never has to hard-code it.
Key settings to the provider object
The full mapping. Field names on the right are OpenRouter's, verbatim.
| Key field | Type | Provider field | Notes |
|---|---|---|---|
data_policy | shared | no_retention | private_pod | data_collection, zdr | See above. |
provider_allow | string[] | null | only | Subset of the allowlist. Null means the whole allowlist. |
provider_order | string[] | null | order | Tried in this order. Must sit inside provider_allow. Replaces the older pin_provider column when set. |
allow_fallbacks | boolean, default true | allow_fallbacks | False: only the providers in order are tried; the request fails instead of going elsewhere. |
require_parameters | boolean, default false | require_parameters | Only endpoints that support every parameter in the request. Forced true whenever response_format is sent. |
Keys created before this policy existed may carry routing and pin_provider. They still work: routing: "zdr" behaves as no_retention's zdr: true, and routing: "pinned" with a pin_provider behaves as provider_order: [pin] with fallbacks off. Saving providers from the keys page clears them.
Setting a key's policy
PATCH the key. Every field is optional; arrays accept null to clear.
curl -X PATCH https://docketrouter.ai/api/v1/keys/$KEY_ID \
-H "Authorization: Bearer $ADMIN_OR_SESSION" -H "Content-Type: application/json" \
-d '{
"data_policy": "no_retention",
"provider_allow": ["deepinfra", "together", "fireworks"],
"provider_order": ["deepinfra/fp8", "together"],
"allow_fallbacks": false,
"require_parameters": true
}'{ "error": { "message": "provider_allow: chutes not permitted. DocketRouter routes only to: anthropic, openai, …",
"type": "invalid_request_error",
"allowed_providers": ["anthropic", "openai", "…"] } }Narrowing per request
docketrouter.provider on a chat request. Each field may tighten the key's policy; anything looser is a 400 that says why.
| Field | May | May not |
|---|---|---|
ignore | add slugs to skip | |
only | pick a subset of the key's allowlist | name a provider outside it |
order | order providers inside the allowlist (and inside the key's order when fallbacks are off) | reach outside either |
allow_fallbacks | set false | set true when the key has it off |
require_parameters | set true | set false when the key has it on |
data_collection | send "deny" (a no-op) | send "allow" |
zdr | set true | set false when the key requires ZDR |
quantizations | filter, e.g. ["fp8", "bf16"] | |
sort | price, throughput or latency |
docketrouter.pin is shorthand for order: [pin] with allow_fallbacks: false. Any other field (max_price, the throughput and latency thresholds) is rejected as unknown.
curl https://docketrouter.ai/api/v1/chat/completions \
-H "Authorization: Bearer dr-…" -H "Content-Type: application/json" \
-d '{
"model": "deepseek/deepseek-v4-flash",
"messages": [{ "role": "user", "content": "Deadline to answer after service in Texas district court?" }],
"docketrouter": {
"provider": { "zdr": true, "order": ["deepinfra/fp8"], "allow_fallbacks": false, "ignore": ["novita"] }
}
}'{ "error": {
"message": "docketrouter.provider.data_collection \"allow\" would widen this key's policy: every key routes with data_collection \"deny\" (no provider that trains on or retains prompts). A request can only narrow the key's policy: add slugs to ignore, set data_collection \"deny\", set zdr true, set allow_fallbacks false, set require_parameters true, or give an order/only inside the key's allowlist. Change the key's policy with PATCH /api/v1/keys/{id}.",
"type": "invalid_request_error" } }Reading back what happened
The response carries the policy that was in force and the provider that served it.
"docketrouter": {
"data_policy": "no_retention",
"zdr_requested": true,
"provider_prefs": { "data_collection": "deny", "zdr": true, "only": ["deepinfra", "together", "fireworks"],
"order": ["deepinfra/fp8"], "allow_fallbacks": false, "ignore": ["novita"] },
"provider_served": "DeepInfra",
"generation_id": "gen-…",
"request_id": "req_…"
}- Headers:
x-docketrouter-provider,x-docketrouter-generation-id,x-docketrouter-request-id. provider_prefsis the exact object sent upstream;provider_servedis OpenRouter's report of who answered. The usage row keeps the provider too:GET /usage/{request_id}.- Private pod:
provider_prefsisnullandupstreamis"private_pod".
OpenRouter answers a request whose constraints leave no endpoint with 503 ("There is no available model provider that meets your routing requirements") or, for an empty only intersection, 404. We pass that through as a 503 service_unavailable_error whose body carries data_policy and provider_prefs. The request is not retried under a looser policy. Widen the key, or the request, yourself.
Something here wrong or missing? Mail hello@docketrouter.ai with the request_id and we will fix the docs or the API, whichever is broken.