Skip to content

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.

This CRUD API always works, but invoking 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#

GET/v1/routing-policies
POST/v1/routing-policies
ParameterTypeRequiredDescription
slugstringRequiredThe invocation id. Pattern ^[a-z0-9][a-z0-9-]{0,62}$. Used as "policy/<slug>". Unique per user (409 on duplicate).
display_namestringRequiredDisplay name. 1 to 100 characters.
policy_typestringRequiredOne 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.
entriesarrayRequired1 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.
configobjectOptionalOrchestration 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_idstringOptionalOrganization 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.
ParameterTypeRequiredDescription
modelstringRequiredThe model ID to route to. Must be a real, active model (1–100 chars).
weightintegerOptionalWeight 1–10000. Only meaningful for the weighted type.
retriesintegerOptionalRepeats 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.

create policy
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}
    ]
  }'
response
{
  "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/v1/routing-policies/{policy_id}
DELETE/v1/routing-policies/{policy_id}

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.

deactivate 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}'