Routing Policies
Create, list, update, and delete routing policies — fallback/weighted/latency/auto 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 <JWT>. 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>) requires the operations gate to be enabled — the original four types need routing.policies_enabled (on by default), while cascade/parallel need routing.orchestrators_enabled (beta, off by default). Calls while the gate is off return 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, auto, cascade, parallel. auto auto-selects the highest-scoring model per intent (category) within your pool (selected_smart). 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 cheap→strong tier order; 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. |
| org_id | string | Optional | Organization sharing — UUID of an org you belong to. When set, org members can invoke it and the author plus org owner/admin can edit or delete it. Unset (or empty string) means private. |
| 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 type. |
Entries accept only real, active, unit-price leaf models. Another policy (policy/…), current routed parents (benchmark_smart, analytics_smart, perfect), and retired parents (pleum-smart, pleum-perfect) are rejected with 400, as are missing or inactive models.
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 <JWT>" \
-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-4o", "retries": 0},
{"model": "gpt-4o-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-4o", "retries": 0},
{"model": "gpt-4o-mini", "retries": 0}
],
"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, is_active). slugcannot 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 <JWT>" \
-H "Content-Type: application/json" \
-d '{"is_active": false}'