---
title: "Set Policy"
method: POST
path: "/v1/routing/policies"
tags: ["routing"]
---

# Set Policy

`POST /v1/routing/policies`

Create or update a stored policy, global or scoped to one user.

The spec is validated here and stored as given, so a row can never contain a
body this build would refuse at load. The cache is refreshed twice: once before
validating (so the shadowing checks see other writers' policies) and once after
committing (so this worker serves the new policy immediately).

``rename_from`` renames the row instead of keying on ``name``. It is part of
this write rather than an endpoint of its own so that an edit which both renames
a policy and re-targets it cannot land half-applied, leaving the old name serving
the new spec. The new name is validated exactly as a fresh one is, because a
rename can walk a policy into every collision a create can. Sending the field
asserts the named policy is stored, so it never falls back to creating one.

## Request body

- PolicyRequest — Request to create or update a routing policy.
  - `name` string, required — Model name callers send, e.g. 'fast'.
  - `rename_from` string, nullable — Current name of the policy to rename, in the same scope. The stored row keeps its id and created_at and takes `name` and `spec`. Sending it asserts that policy exists, so a name with no stored row is a 404 rather than a create, even when it equals `name`. Omit to create or update the policy named `name`. Renaming changes what callers must send as `model`; usage already recorded keeps the old name.
  - `spec` object, required — The policy body: select (with exactly one `default` entry, last), optional on_failure and guardrails. Same schema as a `routing.policies` entry in config.yml, and closed to unknown keys, so a typo is a 400 rather than a silently ignored setting.
  - `user_id` string, nullable — User this policy belongs to. Omit for a global policy every caller sees. A user-scoped policy resolves only for that user and shadows a global one of the same name.

## Response `200`

Successful Response

- PolicyResponse — A routing policy and where it is defined.
  - `created_at` string, nullable
  - `is_dynamic` boolean
  - `name` string, required
  - `source` string, required
  - `spec` object, required
  - `updated_at` string, nullable
  - `user_id` string, nullable

## Other responses

- `422` — Validation Error

---

[API](https://skmtc.net/mozilla-ai/apis/otari.md) · [All operations](https://skmtc.net/mozilla-ai/apis/otari/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/mozilla-ai/otari/revisions/cea76e85cdac/schema)
