docketrouter
DocumentationBrowse
Concepts

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_policyUpstream provider objectMeaning
shareddata_collection: "deny"Default. Never a provider whose published policy says it stores prompts non-transiently or may train on them.
no_retentiondata_collection: "deny", zdr: trueZero-data-retention endpoints only. If none can serve the model, the request fails with 503 rather than routing to a retaining endpoint.
private_podnoneOnly 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.

anthropicopenaigoogle-vertexgoogle-ai-studioxaimistralmoonshotaiz-aialibabaminimaxazureamazon-bedrockdeepinfratogetherfireworksgroqcerebrassambanovanebiusnovitaparasailbasetencoreweavesiliconflowphalavenicedigitalocean
  • Base slugs match every variant, as in OpenRouter's own routing: deepinfra covers deepinfra/fp8 and deepinfra/turbo. A list that names only deepinfra/fp8 does not permit bare deepinfra.
  • 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 as allowed_providers so 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 fieldTypeProvider fieldNotes
data_policyshared | no_retention | private_poddata_collection, zdrSee above.
provider_allowstring[] | nullonlySubset of the allowlist. Null means the whole allowlist.
provider_orderstring[] | nullorderTried in this order. Must sit inside provider_allow. Replaces the older pin_provider column when set.
allow_fallbacksboolean, default trueallow_fallbacksFalse: only the providers in order are tried; the request fails instead of going elsewhere.
require_parametersboolean, default falserequire_parametersOnly endpoints that support every parameter in the request. Forced true whenever response_format is sent.
Legacy columns

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
  }'
400 on a provider outside the allowlist
{ "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.

FieldMayMay not
ignoreadd slugs to skip
onlypick a subset of the key's allowlistname a provider outside it
orderorder providers inside the allowlist (and inside the key's order when fallbacks are off)reach outside either
allow_fallbacksset falseset true when the key has it off
require_parametersset trueset false when the key has it on
data_collectionsend "deny" (a no-op)send "allow"
zdrset trueset false when the key requires ZDR
quantizationsfilter, e.g. ["fp8", "bf16"]
sortprice, 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"] }
    }
  }'
400 on a widening attempt
{ "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 (non-stream body; the final SSE chunk carries provider_served)
"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_prefs is the exact object sent upstream; provider_served is OpenRouter's report of who answered. The usage row keeps the provider too: GET /usage/{request_id}.
  • Private pod: provider_prefs is null and upstream is "private_pod".
When no permitted provider can serve

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.