Octopus
1.x
Docs/Octopus/Routes
Open

Reading3 min
Updated31 Jul 2026
Sourcev1/configuration/routes.mdx

Routes

A route maps an incoming request to an upstream. The routes field is an array; it defaults to empty. Each route must reference an upstream that exists in upstreams (validation fails otherwise), and its path must start with /.

routes:
  - path: /api/users
    methods: [GET, POST]
    upstream: user-service
    priority: 10
    strip_prefix: /api
    timeout: 15s
    auth_provider: primary-jwt
    require_roles: [admin]
    rate_limit:
      requests_per_window: 100
      window_size: 1m
    cors:
      allowed_origins: ["https://app.example.com"]
      allow_credentials: true

routes[]01

KeyTypeDefaultDescription
pathstringPath pattern to match. Required (must start with /).
methodsarray of string[]HTTP methods to match. Empty means all methods.
upstreamstringTarget upstream name. Required (must exist in upstreams).
priorityinteger0Higher priority routes are matched first.
strip_prefixstringnonePrefix removed from the path before proxying.
add_prefixstringnonePrefix prepended to the path before proxying.
metadatamap of string→string{}Arbitrary route metadata.
auth_providerstringnoneAuth provider name for this route (overrides the global auth.default_provider).
skip_authbooleanfalseSkip authentication for this route.
require_rolesarray of string[]Roles required for authorization.
require_scopesarray of string[]Scopes required for authorization.
authz_rulestringnoneCustom authorization rule (a Rhai expression).
timeoutdurationnonePer-route request timeout, overriding gateway.request_timeout.
rate_limitobjectnonePer-route rate limit. See below.
corsobjectnonePer-route CORS override. See below.
Note

Routes have no retry or canary fields. Authentication and authorization behavior set here is evaluated by the auth middleware — see Authentication & authorization and the Security section for the request flow.

Rate limit02

Note

Per-route rate_limit and cors are enforced. rate_limit applies a fixed window per route (keyed by the route's path), returning 429 with Retry-After when exceeded — note it currently uses an in-process counter (per replica; a shared backend for cross-replica limits is planned). cors applies the matched route's override when a top-level cors block is set (which adds the CORS middleware to the chain). See Middleware.

The per-route rate_limit object uses a fixed window: a number of requests allowed per window duration.

rate_limit:
  requests_per_window: 100
  window_size: 1m
KeyTypeDefaultDescription
requests_per_windowintegerRequests allowed per window. Required.
window_sizedurationWindow length. Required.
Warning

This is the real schema. Older example files use rate_limit: { requests_per_second: ... }, which is not a valid field and is silently ignored.

CORS03

The per-route cors object overrides the global cors policy for this route.

cors:
  allowed_origins: ["https://app.example.com"]
  allowed_methods: [GET, POST]
  allowed_headers: [Authorization, Content-Type]
  allow_credentials: true
  max_age: 3600
KeyTypeDefaultDescription
allowed_originsarray of string[]Permitted origins.
allowed_methodsarray of string[]Permitted HTTP methods.
allowed_headersarray of string[]Permitted request headers.
allow_credentialsbooleanfalseAllow credentials (cookies, auth headers).
max_ageinteger (seconds)3600Preflight cache max age.

See Routing for how path matching and priority resolve to a single route.