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

# Set routing strategy

> Create a routing strategy, or save its next version.

What each setting does is explained in [Routing strategies](https://docs.weflayr.com/product/routing-strategies.md).

## Parameters

Passed in the request body.

**user\_email** `string`

The email of the member of your organization recorded as the version's author. Defaults to the person who created the API key, or to the project's creator for a key without one. The response's `recorded_for_email` says which email was recorded.

**document** `object` *required*

The strategy. Each deployment in it is `{"model", "provider", "region"}`, named as a gateway request names it, the region being a macro region (`EU`, `US`, `GLOBAL`) or the provider's own (`eu-west-1` on Bedrock): the AI gateway's [`GET /v1/models`](https://docs.weflayr.com/api/gateway/models) lists them. [Get benchmark](https://docs.weflayr.com/api/management/get-benchmark.md) with `suggested_routing_strategies` gives one made from a finished benchmark.

**document**

**name** `string` *required*

The strategy's name.

**slug** `string`

The id calls route with: they send `strategy/<slug>` as their `model`. Letters, digits, `-` and `_`, at most 100 characters. Omit it on a new strategy to derive it from the name.

**allowed\_deployments** `object[]` *required*

The deployments that requests matching no override rule are routed between, in preference order: `fixed_order` calls the first and falls back on the next ones. Each is `{"model", "provider", "region"}`. Under `fixed_order` only, each can add a `reasoning_effort`, used when the call names none ([how it works](https://docs.weflayr.com/product/routing-strategies.md#what-your-call-sends-wins)): `default` (the model's own), `none` (thinking off), or `minimal`, `low`, `medium`, `high`, `xhigh` or `max`, each only where the model takes it.

**global\_rule** `string` *required*

How requests matching no override rule are routed: a benchmark's optimization objective, which [ranks the models for each request](https://docs.weflayr.com/concepts/routing.md), or `fixed_order`. An optimization objective routes from a benchmark's answers, so it needs a `benchmark_source`; `fixed_order` does not. One of `same_quality_lowest_cost`, `same_cost_best_quality`, `best_quality` or `fixed_order`.

**switch\_from\_cached\_model\_or\_cheaper\_better\_model\_condition** `string`

When the global rule sends a request away from the model whose provider holds the start of its prompt in cache, even if that costs more. See [Prompt caching](https://docs.weflayr.com/concepts/prompt-caching.md) for each value. Required when `global_rule` is an optimization objective, refused with `fixed_order`. One of `never`, `same_or_better_quality_is_unlikely`, `best_quality_is_unlikely` or `anytime`.

**fallback** `object`

`{"retry_attempts": 0 to 10, "strategy": "default" | "unavailable" | "unhealthy"}`: the retries on the preferred model before falling back, and when a deployment Weflayr [finds unhealthy](https://docs.weflayr.com/concepts/fallback-and-model-health.md) is tried: `default` after the model's other deployments, `unhealthy` after every other deployment, `unavailable` as if healthy. A deployment Weflayr finds unavailable, or rate limited in the last minute, is tried last under all three. Defaults to `{"retry_attempts": 0, "strategy": "unavailable"}`.

**override\_rules** `object[]`

Rules checked top to bottom before the global rule; the first match wins. Each has a `type` (`margin`, `customer_cost` or `customer_selection`), an `objective`, its own `allowed_deployments`, `excluded_customers` and `switch_from_cached_model_or_cheaper_better_model_condition` (as the global rule's), and its condition: `triggers_when`, `threshold_value` and `threshold_unit` for `margin` and `customer_cost` (which adds `spend_period`), `included_customers` for `customer_selection`. List customers with [Get customers](https://docs.weflayr.com/api/management/get-customers.md).

**self\_heal** `boolean` *required*

Turn on [self-heal](https://docs.weflayr.com/concepts/self-heal.md).

**apply\_auto\_caching\_from\_benchmark** `boolean` (default: false)

Place on each request the cache breakpoints the source benchmark recommends for the model called, when it recommends some (see [Prompt caching](https://docs.weflayr.com/concepts/prompt-caching.md)). Needs a `benchmark_source`.

**benchmark\_source** `object`

`{"benchmark_uuid": "..."}`: the benchmark the strategy is made from. Omit it for a strategy made from scratch, whose global rule and override rules can then only be `fixed_order`: an optimization objective returns a 422.

**expected\_version** `integer`

Omit it to create a strategy. To save the next version, pass the version you read as live: the save is refused with a 409 `stale_version` when another version has gone live since.

The response also carries `blockers` (what prevents the usual next step), in plain words. It is empty when the usual workflow applies.

```python Python theme={null}
import weflayr
from weflayr.openapi.models import SetRoutingStrategyInput

client = weflayr.client()  # reads WEFLAYR_API_KEY

client.set_routing_strategy(body=SetRoutingStrategyInput.from_dict({
    "document": {
        "name": "Summarize profile router",
        "slug": "summarize-profile-router",
        "allowed_deployments": [
            {
                "model": "gpt-6-luna",
                "provider": "openai",
                "region": "GLOBAL",
            },
            {
                "model": "claude-sonnet-5-5",
                "provider": "anthropic",
                "region": "GLOBAL",
            },
        ],
        "global_rule": "same_quality_lowest_cost",
        "switch_from_cached_model_or_cheaper_better_model_condition": "same_or_better_quality_is_unlikely",
        "fallback": {
            "retry_attempts": 0,
            "strategy": "default",
        },
        "override_rules": [],
        "self_heal": True,
        "benchmark_source": {
            "benchmark_uuid": "7b0f3f0e-5d8e-4a57-9d52-0a3f6a2c1e11",
        },
    },
    "user_email": "alex@acme.com",
}))
```

```js Node.js theme={null}
const weflayr = require('weflayr');

const client = weflayr.client(); // reads WEFLAYR_API_KEY

await weflayr.api.setRoutingStrategy({
  client,
  throwOnError: true,
  body: {
    document: {
      name: 'Summarize profile router',
      slug: 'summarize-profile-router',
      allowedDeployments: [
        {
          model: 'gpt-6-luna',
          provider: 'openai',
          region: 'GLOBAL',
        },
        {
          model: 'claude-sonnet-5-5',
          provider: 'anthropic',
          region: 'GLOBAL',
        },
      ],
      globalRule: 'same_quality_lowest_cost',
      switchFromCachedModelOrCheaperBetterModelCondition: 'same_or_better_quality_is_unlikely',
      fallback: {
        retryAttempts: 0,
        strategy: 'default',
      },
      overrideRules: [],
      selfHeal: true,
      benchmarkSource: {
        benchmarkUuid: '7b0f3f0e-5d8e-4a57-9d52-0a3f6a2c1e11',
      },
    },
    userEmail: 'alex@acme.com',
  },
});
```

```bash cURL theme={null}
curl -X POST https://app.weflayr.com/api/routing-strategies/ \
  -H "Authorization: Bearer $WEFLAYR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "document": {
      "name": "Summarize profile router",
      "slug": "summarize-profile-router",
      "allowed_deployments": [
        {
          "model": "gpt-6-luna",
          "provider": "openai",
          "region": "GLOBAL"
        },
        {
          "model": "claude-sonnet-5-5",
          "provider": "anthropic",
          "region": "GLOBAL"
        }
      ],
      "global_rule": "same_quality_lowest_cost",
      "switch_from_cached_model_or_cheaper_better_model_condition": "same_or_better_quality_is_unlikely",
      "fallback": {
        "retry_attempts": 0,
        "strategy": "default"
      },
      "override_rules": [],
      "self_heal": true,
      "benchmark_source": {
        "benchmark_uuid": "7b0f3f0e-5d8e-4a57-9d52-0a3f6a2c1e11"
      }
    },
    "user_email": "alex@acme.com"
  }'
```

```json 200 theme={null}
{
  "slug": "summarize-profile-router",
  "version": 1,
  "document": {
    "name": "Summarize profile router",
    "slug": "summarize-profile-router",
    "allowed_deployments": [
      {
        "model": "gpt-6-luna",
        "provider": "openai",
        "region": "GLOBAL",
        "reasoning_effort": null
      },
      {
        "model": "claude-sonnet-5-5",
        "provider": "anthropic",
        "region": "GLOBAL",
        "reasoning_effort": null
      }
    ],
    "global_rule": "same_quality_lowest_cost",
    "switch_from_cached_model_or_cheaper_better_model_condition": "same_or_better_quality_is_unlikely",
    "fallback": {
      "retry_attempts": 0,
      "strategy": "default"
    },
    "override_rules": [],
    "self_heal": true,
    "apply_auto_caching_from_benchmark": false,
    "benchmark_source": {
      "benchmark_uuid": "7b0f3f0e-5d8e-4a57-9d52-0a3f6a2c1e11"
    }
  },
  "archived_at": null,
  "updated_at": "2026-10-20T09:30:00+00:00",
  "url": "https://app.weflayr.com/dashboard/routing-strategies/?strategy=summarize-profile-router",
  "recorded_for_email": "alex@acme.com",
  "blockers": []
}
```

```json 400 theme={null}
{"error": "No member of your organization has the email alex@acme.com. Ask the person for the email they use in Weflayr, and send it again.", "code": "unknown_user"}
```

```json 401 theme={null}
{"error": "Invalid or missing API key. Send it as \"Authorization: Bearer <your key>\"."}
```

```json 404 theme={null}
{"error": "No routing strategy has the slug 'nope'. List the project's strategies, archived ones included, with get_routing_strategies (status=all)."}
```

```json 409 theme={null}
{"error": "'summarize-profile-router' is already the id of a routing configuration of this project. Choose another name or slug: a slug stays taken by an archived strategy too. To change the existing strategy, pass its slug in the document and the version you read as live in expected_version.", "code": "slug_taken"}
```

```json 422 theme={null}
{"error": "Invalid request payload.", "detail": [{"field": "document", "error": "Value error, The gateway serves none of [GatewayDeploymentName(model_name='gpt-9', provider='openai', region='GLOBAL')]"}]}
```


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