---
title: Route
description: Routes are JSON-encoded configuration files that you add to PingGateway to manage requests. You can add routes in the following ways:
component: pinggateway
version: 2026
page_id: pinggateway:reference:Route
canonical_url: https://docs.pingidentity.com/pinggateway/2026/reference/Route.html
revdate: 2026-02-23T12:00:00Z
section_ids:
  Route-usage: Usage
  Route-properties: Properties
  route-conditions: Example
---

# Route

Routes are JSON-encoded configuration files that you add to PingGateway to manage requests. You can add routes in the following ways:

* Manually into the filesystem.

* Through Common REST commands. Learn more in [PingGateway routes and common REST](../configure/crest.html).

* Through Studio. Learn more in [PingGateway Studio](../studio-guide/preface.html).

Routes handle requests and their context, and then hand off any request they accept to a [Handler](Handlers.html).

When a route has a condition, it handles only requests that meet the condition. When a route has no condition, it handles any request.

Routes inherit settings from their parent configuration. This means that you can configure global objects in the `config.json` heap, for example, and then reference the objects by name in any other PingGateway configuration.

Learn about Route metrics:

* [Metrics at the Prometheus Scrape Endpoint](MonitoringMetrics.html)

* [Route metrics at the Common REST Monitoring Endpoint (deprecated)](MonitoringMetricsCrest.html#prom-route-metrics-crest)

## Usage

```none
{
  "handler": Handler reference,
  "heap": [ object, ... ],
  "condition": runtime condition<boolean>,
  "name": string,
  "session": AsyncSessionManager reference,
  "auditService": AuditService reference,
  "globalDecorators": map,
  "decorator name": Decorator object
}
```

## Properties

* `"handler"`: *Handler [reference](preface.html#definition-reference), required*

  The [Handler](Handlers.html) to which PingGateway dispaches requests.

  Provide the name of a Handler object defined in the heap or an inline Handler configuration object.

* `"heap"`: *array of [objects](preface.html#definition-object), optional*

  Heap object configuration for objects local to this route.

  Objects referenced but not defined here are inherited from the parent.

  You can omit an empty array. If you only have one object in the heap, you can inline it as the handler value.

  Refer to [Heap objects](heap-objects.html).

* `"condition"`: *runtime condition<[boolean](preface.html#definition-boolean)>, optional*

  A [condition](Conditions.html) based on the request, context, or PingGateway runtime environment, such as system properties or environment variables.

  The action depends on the evaluation of the condition's expression:

  * `true`: PingGateway dispatches the request to the route.

  * `false`: PingGateway evaluates the condition for the next route in the configuration.

  * No condition: PingGateway dispatches the request unconditionally to the route.

  When configuring conditions, keep the following in mind:

  * Condition expressions can't depend on URL fragments, because fragments aren't sent in a request to the server.

  * No external request can match a condition that uses the reserved administrative route. Therefore, routes that use these conditions are effectively ignored even if you configure PingGateway to use the same ports for all requests.

  |   |                                                                                                                                                                                                                                                                                                                                                                                             |
  | - | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
  |   | For debugging, log the routes for which PingGateway evaluates a condition, and the route that matches a condition. Add the following line to a custom `$HOME/.openig/config/logback.xml`, and restart PingGateway:```xml
  <logger name="org.forgerock.openig.handler.router.RouterHandler" level="trace" />
  ```Learn more in [Managing PingGateway logs](../maintenance-guide/logging.html). |

  Find example conditions with requests that match them in [Example](#route-conditions).

  Default: `true`

* `"name"`: *[string](preface.html#definition-string), optional*

  Route name.

  The Router uses the `name` property to order the routes in the configuration. If the route doesn't have a `name` property, the Router uses the route ID.

  The route ID is managed as follows:

  * When you add a route manually to the routes folder, the route ID is the value of the `_id` field. If there is no `_id` field, the route ID is the filename of the added route.

  * When you add a route through the Common REST endpoint, the route ID is the value of the mandatory `_id` field.

  * When you add a route through Studio, you can edit the default route ID.

    CAUTION: The filename of a route cannot be `default.json`. The route `name` property or route ID cannot be `default`.

  Default: route ID

* `"session"`: *AsyncSessionManager reference. [reference](preface.html#definition-reference), optional*

  An [InMemorySessionManager](InMemorySessionManager.html) or [JwtSessionManager](JwtSessionManager.html).

  When a request enters the route, PingGateway builds a new session object for the route. The session content is available to the route's downstream handlers and filters. Session content available in the parent route or `config.json` isn't available in the new session.

  Default: [InMemorySessionManager](InMemorySessionManager.html) with default values

  Learn more in [PingGateway sessions](../about/about-sessions.html).

* `"auditService"`: *AuditService [reference](preface.html#definition-reference), optional*

  An audit service for the route. Provide either the name of an AuditService object defined in the heap or an inline AuditService configuration object.

  Default: No auditing of a configuration. The NoOpAuditService provides an empty audit service to the top-level heap and its child routes.

* `"globalDecorators"`: *[map](preface.html#map), optional*

  A map of one or more data pairs with the format `Map<String, JsonValue>`, where:

  * The key is a decorator name

  * The value is a decorator configuration, passed *as is* to the decorator

  The following format is required:

  ```json
  {
    "globalDecorators": {
      "decorator name": "decoration configuration",
      ...
    }
  }
  ```

  All compatible objects in a route are decorated with the mapped decorator value. For more information, refer to [PingGateway decorators](Decorators.html).

  In the following example, the property decorates all compatible objects in the route with capture, timer, and tracing decorators:

  ```json
  "globalDecorators": {
    "capture": "all",
    "timer": true,
    "tracing": true
  }
  ```

  Default: Empty

* `"decorator name"`: *Decorator [object](preface.html#definition-object), optional*

  Decorate the main handler of this route with a decorator referred to by the decorator name, and provide the configuration as described in [PingGateway decorators](Decorators.html).

  Default: No decoration.

## Example

The following table gives examples of route conditions and matching requests.

| Condition                                                                                                                                            | Requests that meet the condition                                                                                                                                                                          |
| ---------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ```json
"${true}"
```                                                                                                                                | All requests, because this expression always evaluates to `true`.                                                                                                                                         |
| ```json
"${find(request.uri.path, '^/login')}"
```                                                                                                   | `https://app.example.com/login`, …​                                                                                                                                                                       |
| ```json
"${request.uri.host == 'api.example.com'}"
```                                                                                               | `https://api.example.com/`, `https://api.example.com/home`, `https://api.example.com:8444/home`, …​                                                                                                       |
| ```json
"${find(contexts.client.remoteAddress, '127.0.0.1')}"
```                                                                                    | `https://localhost:8443/keygen`, `https://127.0.0.1:8443/keygen`, …​Where `/keygen` isn't mandatory and could be anything else.                                                                           |
| ```json
"${find(request.uri.query, 'demo=simple')}"
```                                                                                              | `https://ig.example.com:8443/login?demo=simple`, …​You can find more information about URI query parameters in [URI](URI.html).                                                                           |
| ```json
"${request.uri.scheme == 'https'}"
```                                                                                                       | `https://ig.example.com:8443`, …​                                                                                                                                                                         |
| ```json
"${find(request.uri.path, '^/dispatch') or find(request.uri.path, '^/mylogin')}"
```                                                         | `https://ig.example.com:8443/dispatch`, `https://ig.example.com:8443/mylogin`, …​                                                                                                                         |
| ```json
"${request.uri.host == 'sp1.example.com' and not find(request.uri.path, '^/saml')}"
```                                                      | `https://sp1.example.com:8443/`, `https://sp1.example.com/mypath`, …​Not `https://sp1.example.com:8443/saml`, `https://sp1.example.com/saml`, …​                                                          |
| ```json
"condition": "${find (request.uri.path, '&{uriPath}')}"
```                                                                                  | `https://ig.example.com:8443/hello`, when the following property is configured:```json
{
  "properties": {
    "uriPath": "hello"
  }
}
```Learn more in [PingGateway route properties](Properties.html). |
| ```json
"condition": "${request.headers['X-Forwarded-Host'][0] == 'service.example.com'}"
```                                                        | Requests with the header `X-Forwarded-Host`, whose first value is `service.example.com`.                                                                                                                  |
| ```json
"condition": "#{find(request.uri.path, '^/openam/oauth2/access_token') && request.entity.form['client_id'][0] == 'client-service'}"
```      | Requests where an OAuth 2.0 client named `client-service` issues the original access token request.                                                                                                       |
| ```json
"condition": "#{find(request.uri.path, '^/openam/oauth2/access_token') && request.entity.form['grant_type'][0] == 'client_credentials'}"
``` | Requests using the client credentials grant-type.                                                                                                                                                         |
