Workspaces, guardrails and presets
Organise keys into environments, enforce policies before a request costs anything, and ship saved request configurations as @preset/slug.
Workspaces
A workspace is an environment inside your organization — production, staging, a team's project. Keys are created in a workspace and never move; budgets, guardrail assignments and notification routing can be scoped to it. Credits and members stay shared at the organization. Every organization has a default workspace; team organizations can add more from environment templates and copy budgets and policy assignments between them.
Organization owners and admins can act in every workspace. Other members can use the default workspace and any workspace they were explicitly added to, as admin (manage keys, budgets and members there) or member. Archiving a workspace requires its keys to be deleted first, so nothing is ever silently cut off.
Guardrails (policies)
A policy is a rule set that runs on every request before credits are reserved or an upstream is contacted. Policies apply wherever they are assigned: the whole organization, a workspace, a key, or a member (their keys). Several policies can apply to one request; a block from any of them wins.
modelsallow_all_except | allow_only- Model access by pattern: exact ids, vendor/* or *. Blocks with 403 policy_blocked.
vendorsallow_all_except | allow_only- Access by the model's official vendor slug (anthropic, openai, google…).
limitsobject- maxOutputTokens, maxPromptTokens (estimated) and maxCostUsdPerRequest (upper-bound estimate). Exceeding any of them blocks.
promptInjectionblock | flag | redact- Built-in heuristics for instruction-override attempts over user and tool content, plus your own regex patterns and an allow-list of legitimate phrases.
sensitiveInfoblock | flag | redact- Detectors for emails, phones, payment cards (Luhn), IPs, API keys/tokens, IBANs and US SSNs, plus custom regexes. Direction: prompts, non-streamed answers, or both.
Redaction rewrites matched spans to [REDACTED EMAIL]-style markers before the request leaves ElevenRouter; the original text is never stored. Policy events (blocked, flagged, redacted) record only which rule fired and detector counts. The route receipt carries a pipeline.policies summary and blocked requests return:
HTTP/1.1 403 Forbidden
{
"error": {
"type": "permission_error",
"code": "policy_blocked",
"message": "Request blocked by policy \"Production guardrails\" (vendors).",
"metadata": { "policy": "Production guardrails", "rule": "vendors", "vendor": "anthropic", "mode": "allow_only" }
}
}Before enabling a policy, dry-run it against the last 1–30 days of real traffic to see how many requests (and how much spend) its model, vendor and limit rules would have blocked. Text rules cannot be replayed because prompts are not stored; use the live tester instead.
Presets
A preset is a saved request configuration: a system prompt, a primary model with up to three fallbacks, a routing block, default parameters, caching and transforms. Address it in model:
curl https://elevenrouter.com/api/v1/chat/completions \
-H "Authorization: Bearer $ELEVENROUTER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "@preset/support-bot",
"messages": [{ "role": "user", "content": "My invoice is wrong." }]
}'Fields you send always win over the preset's defaults; the preset only fills gaps. When the request has no system or developer message the preset's system prompt is prepended. Every save creates a new version; @preset/support-bot serves the current version and @preset/support-bot@3 pins one. Presets can also be pinned to a key, in which case every request through that key receives the preset's prompt, parameters and routing while keeping the model it asked for. The route receipt records pipeline.preset with the slug, version and whether it was referenced or pinned.
Account privacy controls
maxKeyLifetimeDaysinteger- Every key must expire within this many days of creation; keys created without an expiry get the maximum.
allowedVendors / blockedVendorsstring[]- Account-wide vendor allow- or block-list applied before key allow-lists and policies. Refusals return 403 vendor_not_allowed.
logPromptsboolean- Whether prompts and completions are stored with logs (off by default).
responseCacheboolean- Whether keys may opt into the per-key response cache.
forwardRetiredModelsboolean- Whether requests to retired models are served by their announced successor.
The eligibility preview under Settings → Privacy & controls shows, for the account or for one key, which models can be called right now and exactly which control or policy excludes the rest.
Management API
Everything above has a programmatic equivalent for management keys under /management: workspaces, budgets, policies (with assignments and dry-run), presets (with versions), notification rules, BYOK credentials (add, restrict to key hashes, rotate) and members. Responses use the { "data": … } envelope with snake_case fields, every call is audit-logged with the management key as actor, and the surface is rate-limited per key (default 120 requests per minute). The full schema is in the OpenAPI document.
M="Authorization: Bearer $ELEVENROUTER_MANAGEMENT_KEY"
B=https://elevenrouter.com/api/v1/management
# A production workspace with a hard daily budget
curl -X POST $B/workspaces -H "$M" -d '{ "name": "Production", "environment": "production" }'
curl -X POST $B/budgets -H "$M" -d '{ "scope_type": "workspace", "scope_id": "production", "interval": "daily", "limit": 250 }'
# Dry-run a vendor policy, then create it assigned to the workspace
curl -X POST $B/policies/dry-run -H "$M" -d '{ "rules": { "vendors": { "mode": "allow_only", "slugs": ["anthropic", "openai"] } }, "days": 7 }'
curl -X POST $B/policies -H "$M" -d '{ "name": "Approved vendors", "rules": { "vendors": { "mode": "allow_only", "slugs": ["anthropic", "openai"] } }, "assignments": [{ "target_type": "workspace", "target_id": "production" }] }'
# A preset and a key in the workspace that pins it
curl -X POST $B/presets -H "$M" -d '{ "slug": "support-bot", "name": "Support bot", "config": { "models": ["anthropic/claude-sonnet-5", "openai/gpt-5.6-terra"], "systemPrompt": "You are a support agent." } }'
curl -X POST https://elevenrouter.com/api/v1/keys -H "$M" -d '{ "name": "support-backend", "workspace_id": "production", "preset_id": "support-bot" }'