# Reference: routes

URL: https://scalws.com/docs/reference/routes/
Source: `docs/reference/schema` in the ScalWS repository

<h3 id="tenants-.applications-.routes"><code>tenants[].applications[].routes</code></h3>

| | |
|---|---|
| Syntax | `routes: [{...}, ...]` |
| Default | `[]` |
| Context | `tenants[].applications[]` |
| Reload | applies on reload |

Routes with their own runtime: prefix (default), exact or regex paths plus method, header and query matchers; see ADR-0050.


<h3 id="tenants-.applications-.routes-.allow"><code>tenants[].applications[].routes[].allow</code></h3>

| | |
|---|---|
| Syntax | `allow: [<string>, ...]` |
| Default | `none` |
| Context | `tenants[].applications[].routes[]` |
| Reload | applies on reload |

Client addresses and CIDR blocks allowed; if set, only these clients (403 else).


<h3 id="tenants-.applications-.routes-.basic_auth"><code>tenants[].applications[].routes[].basic_auth</code></h3>

| | |
|---|---|
| Syntax | `basic_auth: {...}` |
| Default | `none` |
| Context | `tenants[].applications[].routes[]` |
| Reload | applies on reload |

HTTP basic authentication against an htpasswd file.


<h3 id="tenants-.applications-.routes-.basic_auth.realm"><code>tenants[].applications[].routes[].basic_auth.realm</code></h3>

| | |
|---|---|
| Syntax | `realm: <string>` |
| Default | `Restricted` |
| Context | `tenants[].applications[].routes[].basic_auth` |
| Reload | applies on reload |

Realm shown by the browser (default `Restricted`).


<h3 id="tenants-.applications-.routes-.basic_auth.users_file"><code>tenants[].applications[].routes[].basic_auth.users_file</code></h3>

| | |
|---|---|
| Syntax | `users_file: <string>` |
| Default | `required` |
| Context | `tenants[].applications[].routes[].basic_auth` |
| Reload | applies on reload |

Absolute path of an htpasswd file (bcrypt, SHA-256/512 crypt or Apache MD5 entries).


<h3 id="tenants-.applications-.routes-.cors"><code>tenants[].applications[].routes[].cors</code></h3>

| | |
|---|---|
| Syntax | `cors: {...}` |
| Default | `none` |
| Context | `tenants[].applications[].routes[]` |
| Reload | applies on reload |

Cross-origin resource sharing; preflight requests are answered by ScalWS.


<h3 id="tenants-.applications-.routes-.cors.allow_credentials"><code>tenants[].applications[].routes[].cors.allow_credentials</code></h3>

| | |
|---|---|
| Syntax | `allow_credentials: true \| false` |
| Default | `false` |
| Context | `tenants[].applications[].routes[].cors` |
| Reload | applies on reload |

Allow credentials (cookies, authorization); not with `allow_origins: ["*"]`.


<h3 id="tenants-.applications-.routes-.cors.allow_headers"><code>tenants[].applications[].routes[].cors.allow_headers</code></h3>

| | |
|---|---|
| Syntax | `allow_headers: [<string>, ...]` |
| Default | `["DNT","Keep-Alive","User-Agent","X-Requested-With","If-Modified-Since","Cache-Control","Content-Type","Range","Authorization"]` |
| Context | `tenants[].applications[].routes[].cors` |
| Reload | applies on reload |

Request headers allowed in preflight answers (ingress-nginx defaults).


<h3 id="tenants-.applications-.routes-.cors.allow_methods"><code>tenants[].applications[].routes[].cors.allow_methods</code></h3>

| | |
|---|---|
| Syntax | `allow_methods: [<string>, ...]` |
| Default | `["GET","PUT","POST","DELETE","PATCH","OPTIONS"]` |
| Context | `tenants[].applications[].routes[].cors` |
| Reload | applies on reload |

Methods allowed in preflight answers (default: GET, PUT, POST, DELETE, PATCH, OPTIONS).


<h3 id="tenants-.applications-.routes-.cors.allow_origins"><code>tenants[].applications[].routes[].cors.allow_origins</code></h3>

| | |
|---|---|
| Syntax | `allow_origins: [<string>, ...]` |
| Default | `required` |
| Context | `tenants[].applications[].routes[].cors` |
| Reload | applies on reload |

Allowed origins, e.g. `https://app.example.com`, `https://*.example.com`, or `["*"]`.


<h3 id="tenants-.applications-.routes-.cors.expose_headers"><code>tenants[].applications[].routes[].cors.expose_headers</code></h3>

| | |
|---|---|
| Syntax | `expose_headers: [<string>, ...]` |
| Default | `none` |
| Context | `tenants[].applications[].routes[].cors` |
| Reload | applies on reload |

Response headers exposed to the page.


<h3 id="tenants-.applications-.routes-.cors.max_age"><code>tenants[].applications[].routes[].cors.max_age</code></h3>

| | |
|---|---|
| Syntax | `max_age: <duration> (e.g. 30s)` |
| Default | `1728000s` |
| Context | `tenants[].applications[].routes[].cors` |
| Reload | applies on reload |

How long a preflight answer may be cached, at most 365 days (default 20 days).


<h3 id="tenants-.applications-.routes-.deny"><code>tenants[].applications[].routes[].deny</code></h3>

| | |
|---|---|
| Syntax | `deny: [<string>, ...]` |
| Default | `none` |
| Context | `tenants[].applications[].routes[]` |
| Reload | applies on reload |

Client addresses and CIDR blocks refused with 403; checked after `allow`.


<h3 id="tenants-.applications-.routes-.headers"><code>tenants[].applications[].routes[].headers</code></h3>

| | |
|---|---|
| Syntax | `headers: [{...}, ...]` |
| Default | `none` |
| Context | `tenants[].applications[].routes[]` |
| Reload | applies on reload |

Request headers that must match (all of them).


<h3 id="tenants-.applications-.routes-.headers-.name"><code>tenants[].applications[].routes[].headers[].name</code></h3>

| | |
|---|---|
| Syntax | `name: <string>` |
| Default | `required` |
| Context | `tenants[].applications[].routes[].headers[]` |
| Reload | applies on reload |

Header name (case-insensitive) or query parameter name.


<h3 id="tenants-.applications-.routes-.headers-.regex"><code>tenants[].applications[].routes[].headers[].regex</code></h3>

| | |
|---|---|
| Syntax | `regex: <string>` |
| Default | `none` |
| Context | `tenants[].applications[].routes[].headers[]` |
| Reload | applies on reload |

Regular expression the value must match (searched anywhere unless anchored).


<h3 id="tenants-.applications-.routes-.headers-.value"><code>tenants[].applications[].routes[].headers[].value</code></h3>

| | |
|---|---|
| Syntax | `value: <string>` |
| Default | `none` |
| Context | `tenants[].applications[].routes[].headers[]` |
| Reload | applies on reload |

Exact, case-sensitive value.


<h3 id="tenants-.applications-.routes-.https_redirect"><code>tenants[].applications[].routes[].https_redirect</code></h3>

| | |
|---|---|
| Syntax | `https_redirect: true \| false` |
| Default | `none` |
| Context | `tenants[].applications[].routes[]` |
| Reload | applies on reload |

Answer plain-HTTP requests that select this route with a 301 to HTTPS; unset: the application's `https_redirect`.


<h3 id="tenants-.applications-.routes-.max_body"><code>tenants[].applications[].routes[].max_body</code></h3>

| | |
|---|---|
| Syntax | `max_body: <size> (e.g. 16KiB)` |
| Default | `none` |
| Context | `tenants[].applications[].routes[]` |
| Reload | applies on reload |

Largest request body; overrides `limits.max_request_body_bytes`; 413 above.


<h3 id="tenants-.applications-.routes-.methods"><code>tenants[].applications[].routes[].methods</code></h3>

| | |
|---|---|
| Syntax | `methods: [<string>, ...]` |
| Default | `none` |
| Context | `tenants[].applications[].routes[]` |
| Reload | applies on reload |

Request methods this route matches, e.g. `[GET, POST]`; empty: any.


<h3 id="tenants-.applications-.routes-.path"><code>tenants[].applications[].routes[].path</code></h3>

| | |
|---|---|
| Syntax | `path: <string>` |
| Default | `required` |
| Context | `tenants[].applications[].routes[]` |
| Reload | applies on reload |

Path of the route; how it is compared depends on `path_type`.


<h3 id="tenants-.applications-.routes-.path_type"><code>tenants[].applications[].routes[].path_type</code></h3>

| | |
|---|---|
| Syntax | `path_type: prefix \| exact \| regex` |
| Default | `none` |
| Context | `tenants[].applications[].routes[]` |
| Reload | applies on reload |

`prefix` (default, whole segments, longest first), `exact` or `regex` (anchored at the start, in configuration order).


<h3 id="tenants-.applications-.routes-.query"><code>tenants[].applications[].routes[].query</code></h3>

| | |
|---|---|
| Syntax | `query: [{...}, ...]` |
| Default | `none` |
| Context | `tenants[].applications[].routes[]` |
| Reload | applies on reload |

Query parameters that must match (all of them, decoded, first occurrence).


<h3 id="tenants-.applications-.routes-.query-.name"><code>tenants[].applications[].routes[].query[].name</code></h3>

| | |
|---|---|
| Syntax | `name: <string>` |
| Default | `required` |
| Context | `tenants[].applications[].routes[].query[]` |
| Reload | applies on reload |

Header name (case-insensitive) or query parameter name.


<h3 id="tenants-.applications-.routes-.query-.regex"><code>tenants[].applications[].routes[].query[].regex</code></h3>

| | |
|---|---|
| Syntax | `regex: <string>` |
| Default | `none` |
| Context | `tenants[].applications[].routes[].query[]` |
| Reload | applies on reload |

Regular expression the value must match (searched anywhere unless anchored).


<h3 id="tenants-.applications-.routes-.query-.value"><code>tenants[].applications[].routes[].query[].value</code></h3>

| | |
|---|---|
| Syntax | `value: <string>` |
| Default | `none` |
| Context | `tenants[].applications[].routes[].query[]` |
| Reload | applies on reload |

Exact, case-sensitive value.


<h3 id="tenants-.applications-.routes-.request_headers"><code>tenants[].applications[].routes[].request_headers</code></h3>

| | |
|---|---|
| Syntax | `request_headers: {...}` |
| Default | `none` |
| Context | `tenants[].applications[].routes[]` |
| Reload | applies on reload |

Changes to the request headers (after the built-in proxy headers).


<h3 id="tenants-.applications-.routes-.request_headers.add"><code>tenants[].applications[].routes[].request_headers.add</code></h3>

| | |
|---|---|
| Syntax | `add: {<key>: <string>, ...}` |
| Default | `none` |
| Context | `tenants[].applications[].routes[].request_headers` |
| Reload | applies on reload |

Headers added next to any present.


<h3 id="tenants-.applications-.routes-.request_headers.remove"><code>tenants[].applications[].routes[].request_headers.remove</code></h3>

| | |
|---|---|
| Syntax | `remove: [<string>, ...]` |
| Default | `none` |
| Context | `tenants[].applications[].routes[].request_headers` |
| Reload | applies on reload |

Headers removed.


<h3 id="tenants-.applications-.routes-.request_headers.set"><code>tenants[].applications[].routes[].request_headers.set</code></h3>

| | |
|---|---|
| Syntax | `set: {<key>: <string>, ...}` |
| Default | `none` |
| Context | `tenants[].applications[].routes[].request_headers` |
| Reload | applies on reload |

Headers set to this value, replacing any present.


<h3 id="tenants-.applications-.routes-.request_timeout"><code>tenants[].applications[].routes[].request_timeout</code></h3>

| | |
|---|---|
| Syntax | `request_timeout: <duration> (e.g. 30s)` |
| Default | `none` |
| Context | `tenants[].applications[].routes[]` |
| Reload | applies on reload |

Time from the route match until the response head; 504 when exceeded.


<h3 id="tenants-.applications-.routes-.response_headers"><code>tenants[].applications[].routes[].response_headers</code></h3>

| | |
|---|---|
| Syntax | `response_headers: {...}` |
| Default | `none` |
| Context | `tenants[].applications[].routes[]` |
| Reload | applies on reload |

Changes to every response of the route, including errors generated by ScalWS.


<h3 id="tenants-.applications-.routes-.response_headers.add"><code>tenants[].applications[].routes[].response_headers.add</code></h3>

| | |
|---|---|
| Syntax | `add: {<key>: <string>, ...}` |
| Default | `none` |
| Context | `tenants[].applications[].routes[].response_headers` |
| Reload | applies on reload |

Headers added next to any present.


<h3 id="tenants-.applications-.routes-.response_headers.remove"><code>tenants[].applications[].routes[].response_headers.remove</code></h3>

| | |
|---|---|
| Syntax | `remove: [<string>, ...]` |
| Default | `none` |
| Context | `tenants[].applications[].routes[].response_headers` |
| Reload | applies on reload |

Headers removed.


<h3 id="tenants-.applications-.routes-.response_headers.set"><code>tenants[].applications[].routes[].response_headers.set</code></h3>

| | |
|---|---|
| Syntax | `set: {<key>: <string>, ...}` |
| Default | `none` |
| Context | `tenants[].applications[].routes[].response_headers` |
| Reload | applies on reload |

Headers set to this value, replacing any present.


<h3 id="tenants-.applications-.routes-.rewrite"><code>tenants[].applications[].routes[].rewrite</code></h3>

| | |
|---|---|
| Syntax | `rewrite: {...}` |
| Default | `none` |
| Context | `tenants[].applications[].routes[]` |
| Reload | applies on reload |

Path and Host rewrite before the runtime.


<h3 id="tenants-.applications-.routes-.rewrite.host"><code>tenants[].applications[].routes[].rewrite.host</code></h3>

| | |
|---|---|
| Syntax | `host: <string>` |
| Default | `none` |
| Context | `tenants[].applications[].routes[].rewrite` |
| Reload | applies on reload |

Host sent upstream (implies `preserve_host: false`), `host` or `host:port`.


<h3 id="tenants-.applications-.routes-.rewrite.path"><code>tenants[].applications[].routes[].rewrite.path</code></h3>

| | |
|---|---|
| Syntax | `path: <string>` |
| Default | `none` |
| Context | `tenants[].applications[].routes[].rewrite` |
| Reload | applies on reload |

Full path; `$1`..`$9` from a regex route, `$0` the match, `$$` a literal `$`; `?...` in it sets the query (else the query is kept).


<h3 id="tenants-.applications-.routes-.rewrite.prefix"><code>tenants[].applications[].routes[].rewrite.prefix</code></h3>

| | |
|---|---|
| Syntax | `prefix: <string>` |
| Default | `none` |
| Context | `tenants[].applications[].routes[].rewrite` |
| Reload | applies on reload |

Replaces the matched prefix (prefix routes only).


<h3 id="tenants-.applications-.routes-.runtime"><code>tenants[].applications[].routes[].runtime</code></h3>

| | |
|---|---|
| Syntax | `runtime: {...}` |
| Default | `required` |
| Context | `tenants[].applications[].routes[]` |
| Reload | applies on reload |

Runtime that handles requests under the path.
