Skip to main content
Conditional routing allows you to route requests to different models based on conditions that evaluate request metadata. You can use conditional routing to:
  • Segment by user tier — route premium users to flagship models and free users to cost-effective ones.
  • Route by geography — direct requests to different models based on geography.
  • Optimize by complexity — send simple prompts to fast, cheap models and complex ones to high-capability models.

Basic Structure

Routes are defined directly on the Router. Each route has a route object and a condition object.
{
  "name": "routers/my-router",
  "routes": [
    {
      "route": {
        "route_id": "premium-tier",
        "variants": [
          {
            "variant": {
              "variant_id": "premium-gpt5",
              "model_id": "openai/gpt-5.2"
            },
            "weight": 100
          }
        ]
      },
      "condition": {
        "cel_expression": "tier == \"premium\""
      }
    },
    {
      "route": {
        "route_id": "free-tier",
        "variants": [
          {
            "variant": {
              "variant_id": "free-flash",
              "model_id": "google-ai-studio/gemini-2.5-flash"
            },
            "weight": 100
          }
        ]
      },
      "condition": {
        "cel_expression": "tier == \"free\""
      }
    }
  ],
  "defaultRoute": {
    "route_id": "default",
    "variants": [
      {
        "variant": {
          "variant_id": "default-variant",
          "model_id": "google-ai-studio/gemini-2.5-flash"
        },
        "weight": 100
      }
    ]
  }
}
The condition field accepts a CEL expression that is evaluated based on request metadata from extra_body.metadata when calling the Chat Completions API.
Routes are evaluated in order, and the first route whose expression evaluates to true is selected.
Below are some available operations:
OperationExampleDescription
Equalitytier == "premium"Matches a specific value.
Comparisonrequest_count > 100Numeric comparisons (>, <, >=, <=).
Logical ANDtier == "premium" && region == "us-east"Both conditions must be true.
Logical ORtier == "premium" || tier == "enterprise"Either condition must be true.
Range checkscore >= 80 && score <= 100Matches values within a range.
startsWith()user_id.startsWith("enterprise-")Checks if a string starts with a prefix.
endsWith()user_id.endsWith("-admin")Checks if a string ends with a suffix.
contains()user_id.contains("test")Checks if a string contains a substring.
size()user_id.size() > 10Gets the length of a string.
Expressions are typed — ensure your metadata types match. Use count == 100 when the value is a number and tier == "premium" when it’s a string. Mismatched types will not match.

Making a Request

When calling your router, pass metadata in your requests using extra_body.metadata to provide the values referenced by your conditions, enabling dynamic route selection.
curl --request POST \
  --url https://api.inworld.ai/v1/chat/completions \
  --header 'Authorization: Bearer <your-api-key>' \
  --header 'Content-Type: application/json' \
  --data '{
    "model": "inworld/my-router",
    "messages": [
      {"role": "user", "content": "Hello"}
    ],
    "extra_body": {
      "metadata": {
        "tier": "premium",
        "user_id": "user-123",
        "region": "us-east"
      }
    }
  }'
In this example, the provided metadata (tier, user_id, and region) will be available for the router’s CEL expressions, enabling conditional routes to match and select the appropriate model configuration based on those values.

Example Use Cases

User Subscription Tiers

Route users to different models based on their subscription tier:
{
  "cel_expression": "subscription_tier == \"pro\""
}

Geographic Routing

Route requests based on user location:
{
  "cel_expression": "region == \"eu\""
}

Request-Based Routing

Route based on request characteristics:
{
  "cel_expression": "request_type == \"coding\" && complexity == \"high\""
}

Dynamic Tiering

Route requests to different model tiers based on prompt complexity. Use a lightweight classifier in your application to score complexity, then let the router pick the right model:
{
  "routes": [
    {
      "route": {
        "route_id": "complex",
        "variants": [
          {
            "variant": { "variant_id": "gpt5-premium", "model_id": "openai/gpt-5.2" },
            "weight": 100
          }
        ]
      },
      "condition": {
        "cel_expression": "complexity_score >= 8"
      }
    },
    {
      "route": {
        "route_id": "standard",
        "variants": [
          {
            "variant": { "variant_id": "gpt5", "model_id": "openai/gpt-5-mini" },
            "weight": 100
          }
        ]
      },
      "condition": {
        "cel_expression": "complexity_score >= 4"
      }
    }
  ],
  "defaultRoute": {
    "route_id": "simple",
    "variants": [
      {
            "variant": { "variant_id": "flash", "model_id": "openai/gpt-5-nano" },
        "weight": 100
      }
    ]
  }
}
Simple tasks go to fast, cheap models while complex tasks get flagship models — optimizing cost without sacrificing quality where it matters.