> ## Documentation Index
> Fetch the complete documentation index at: https://docs.closient.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Manage Routing Rules

> List, create, update, activate and deactivate a product's conditional routing rules -- the per-product rules that decorate a scan's redirect when its date, lot or serial matches -- the programmatic equivalent of the dashboard's Routing rules pages.

Programmatic equivalent of the dashboard's `resolver/routing-rules/` page and the per-product
Routing rules page. A routing rule decorates the destination the resolver already chose: when a
scan's date, lot or serial matches the rule's predicate it sets query parameters on the redirect
and can swap the path. It never changes the host, and it never runs ahead of a recall,
unverified-serial or expiry treatment.

## When to use

* A brand wants scans of certain lots or serials sent to a different page, for example a
  campaign or a notice.
* A brand wants a seasonal treatment for scans whose use-by or best-before date falls in a window.
* A rule needs a new priority, predicate or decoration, or needs switching off.

Choosing the destination itself is `manage-resolution-rules`; a routing rule only decorates it.

## Auth

`X-API-Key` header or OAuth token with `resolver:write` scope (`resolver:read` for reads). Reading
needs membership of the organization; writing needs the contribute role (Editor or Manager). A
read-only key is refused with `403` on a write; an organization the caller cannot view, and a rule
of another organization, answer `404`.

## Flow

```
GET   /resolver/api/v1/organizations/{organization_id}/routing-rules
GET   /resolver/api/v1/organizations/{organization_id}/routing-rules/{rule_id}
POST  /resolver/api/v1/organizations/{organization_id}/routing-rules
PATCH /resolver/api/v1/organizations/{organization_id}/routing-rules/{rule_id}
POST  /resolver/api/v1/organizations/{organization_id}/routing-rules/{rule_id}/activate
POST  /resolver/api/v1/organizations/{organization_id}/routing-rules/{rule_id}/deactivate
```

* **`GET` list** -- every rule of the organization, active and inactive, paginated
  (`{data, pagination}`). `?gtin=` narrows it to one product.
* **`POST` create** -- body `gtin`, `name`, `predicate_kind`, plus the predicate and decoration
  fields below. The rule is active when created.
* **`PATCH` update** -- send only the fields you are changing. The merged rule is validated whole,
  so switching `predicate_kind` also needs the values the new kind uses.
* **`activate` / `deactivate`** -- switch a rule on or off. Both are idempotent.
* There is **no `DELETE`**: a rule is deactivated, never deleted, so its predicate and decoration
  survive.

## Predicates and decoration

`predicate_kind` is one of:

* `DATE_WINDOW` -- the scanned use-by (AI 17) or, failing that, best-before (AI 15) date falls in
  `[window_start, window_end]`. Either bound may be left out, not both.
* `LOT_LIST` -- the scanned lot (AI 10) is one of `match_values`.
* `SERIAL_SET` -- the scanned serial (AI 21) is one of `match_values`.

A scan that does not clearly match leaves the destination alone. When a rule matches it applies
`param_overrides` (a flat map of query keys to string values, which may use tokens such as `{gtin}`
and `{lot}`) and, when set, `path_override` (a same-host absolute path starting with a single `/`).
The lowest `priority` is evaluated first and the first match wins. A product may have at most 50
rules.

## Rules only take effect on Enhanced products

Authoring is allowed on any product, but a rule on a product without the Enhanced `ROUTING_RULES`
capability is saved and does nothing. Every rule reads back an `effective` flag: it is `true` only
when the rule is active and its product has the capability. After a write, read the rule back and
tell the brand when `effective` is `false`.

## Errors

* `403` -- the key is read-only.
* `404` -- unknown organization, rule or product, or one that belongs to another organization.
* `422` -- a value the rules refuse: a predicate that does not fit its kind, a `param_overrides`
  that is not a flat string map, a `path_override` that is not a same-host path, a product at its 50
  rule cap, a malformed GTIN, or a `PATCH` with nothing to change or a null on a required field.

## Verify

`GET` the rule and check the fields you sent and `effective`. To prove the effect on a scan, resolve
a GTIN with a matching lot or date (MCP tool `resolve_gtin`, or `GET /01/<gtin>` without following
redirects) as described in `manage-resolution-rules`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.