Routing Policies
Create, list, update, and delete routing policies — fallback/weighted/latency plus cascade/parallel orchestrators. Invoke with model:"orch/<slug>" (policy/<slug> alias).
The routing-policy management endpoints authenticate with your dashboard session token (a logged-in JWT) — Authorization: Bearer $PLEUM_SESSION_TOKEN. These are dashboard-management APIs, not SDK-compatible endpoints. For how policies behave at call time, see the Routing Policies feature docs.
orch/<slug> (policy/<slug>), fallback, weighted and latency are on by default, while cascade and parallel are beta and off by default. Calling a type that is off returns 400.List & create#
| Parameter | Type | Required | Description |
|---|---|---|---|
| slug | string | Required | The invocation id. Pattern ^[a-z0-9][a-z0-9-]{0,62}$. Used as "policy/<slug>". Unique per user (409 on duplicate). |
| display_name | string | Required | Display name. 1 to 100 characters. |
| policy_type | string | Required | One of fallback, weighted, latency, cascade, parallel. cascade and parallel are orchestrators (beta) — see the feature docs. |
| entries | array | Required | 1 to 10 model entries. Fields in the table below. For cascade this is the tier order from cheap to strong; for parallel it is the worker pool. |
| config | object | Optional | Orchestration parameters (JSON DSL): cascade (hard_categories, judge_model, response_check), parallel (deep_categories, synthesis), plus shared routing_prefs and limits. See the feature docs for the structure. |
| Parameter | Type | Required | Description |
|---|---|---|---|
| model | string | Required | The model ID to route to. Must be a real, active model (1–100 chars). |
| weight | integer | Optional | Weight 1–10000. Only meaningful for the weighted type. |
| retries | integer | Optional | Repeats of the same entry, 0–3 (default 0). Only meaningful for the fallback and cascade types. |
Entries accept only real, active, unit-price leaf models. An entry that points to another policy (policy/…) or an orchestrator (orch/…) is rejected with 422; the routed parent (auto) and missing or inactive models are rejected with 400.
POST returns 201 on success, 409 if the slug already exists. GET /v1/routing-policies returns {items: [...], total: n}, newest first.
curl https://apirouter.pleum.ai/v1/routing-policies \
-H "Authorization: Bearer $PLEUM_SESSION_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"slug": "prod-chat",
"display_name": "Prod Chat",
"policy_type": "fallback",
"entries": [
{"model": "claude-sonnet-4-6", "retries": 1},
{"model": "gpt-5.5", "retries": 0},
{"model": "gpt-5.4-mini", "retries": 0}
]
}'{
"id": "1f0a4c2e-...",
"slug": "prod-chat",
"display_name": "Prod Chat",
"policy_type": "fallback",
"entries": [
{"model": "claude-sonnet-4-6", "retries": 1},
{"model": "gpt-5.5", "retries": 0},
{"model": "gpt-5.4-mini", "retries": 0}
],
"config": null,
"is_active": true,
"created_at": "2026-07-01T09:00:00Z",
"updated_at": "2026-07-01T09:00:00Z"
}Update & delete#
PATCH updates only the fields you send (display_name, policy_type, entries, config, is_active). config is replaced as a whole by the value you send. slug cannot be changed. A policy you don't own (or that doesn't exist) returns 404. DELETE returns {"ok": true}. Setting is_active: false blocks invocation without deleting the policy.
curl -X PATCH https://apirouter.pleum.ai/v1/routing-policies/1f0a4c2e-... \
-H "Authorization: Bearer $PLEUM_SESSION_TOKEN" \
-H "Content-Type: application/json" \
-d '{"is_active": false}'