For the complete documentation index, see llms.txt. This page is also available as Markdown.

Mapping: Route Variables vs Global Variables

Use route variables for one-off overrides and global variables for cross-route defaults. Global variables in the top-level `variables` block apply to all

Use route variables for one-off overrides and global variables for cross-route defaults. Global variables in the top-level variables block apply to all routes. Route-level variables defined inside a specific path entry override globals with the same key for that route only.

Last reviewed: 2026-03-06

When to use this

Use the mapping and variables reference when you need to transform, inject, or replace values in upstream requests. Mapping lets you forward selected headers, query parameters, JWT claims, and config variables to the upstream without modifying your backend code.

Key concepts

  • The mapping block on a path entry defines which headers and query parameters to send to the upstream. Only mapped values are forwarded -- unmapped client headers and query params are dropped.

  • Mapping sources include $request.headers.*, $request.query.*, $request.jwt.* (any JWT claim), $config.* (global variables), and $route.* (route-level variables).

  • Global variables are defined at the top level of the config and available to all routes. Route-level variables are defined inside a path entry and override global variables with the same name.

  • $env.* and $secrets.* placeholders are replaced at config load time, not at request time. This means environment variables and secrets are baked into the parsed config once at startup.

  • If a mapping source resolves to null or undefined, the gateway sends an empty string for that header or query parameter. Use the debugging guide to trace missing values.

Repo-grounded example

{
  "variables": { "region": "eu-west-1" },
  "paths": [
    {
      "method": "GET",
      "path": "/proxy/{.+}",
      "auth": true,
      "integration": { "type": "http_proxy", "server": "upstream" },
      "mapping": {
        "headers": {
          "x-user-id": "$request.jwt.sub",
          "x-region": "$config.region"
        },
        "query": {
          "source": "$request.query.source"
        }
      },
      "variables": { "api_key": "internal-key" }
    }
  ]
}

This snippet defines a global region variable at the top level and a route-level api_key variable inside the path entry. The route-level variable is only available to this specific path, while region is available to all routes via $config.region.

Troubleshooting

  • If a mapped header arrives empty at the upstream, verify the source exists: check that the JWT claim is present in the token, the request header was sent by the client, or the variable is defined in config.

  • If $request.jwt.sub is null on a route without auth: true, remember that JWT claims are only available after successful token validation -- add auth: true to the route.

  • If route variables are not overriding global variables, confirm the variable name matches exactly (case-sensitive) and that the route-level variables block is inside the path entry, not at the top level.

  • Use a tool like jwt.io to decode your test token and confirm the claim names match what your mapping expects (e.g., sub vs user_id).

Last updated