

# Send traffic to your APIs through your custom domain name in API Gateway
<a name="rest-api-routing-mode"></a>

When you configure the routing mode for your custom domain name, you set how incoming traffic is directed to your APIs. You send traffic to your APIs using routing rules, API mappings, or routing rules and API mappings. The following section explains when to use routing rules, when to use API mappings, and how to set the routing mode for your custom domain name.

## When to use routing rules
<a name="when-to-use-routing-rules"></a>

When you use routing rules, you direct incoming requests that match certain conditions to specific REST APIs stages. For example, a rule can route a request to the `production` stage of your `users` REST API it if contains the header `version:v1` and the base path `/users`. Use routing rules to create advanced dynamic routing topologies that support use cases like A/B testing or increasing usage of new versions of your APIs.

We recommend that when directing traffic to a REST API, you use routing rules for your custom domain name. You can recreate any API mappings by using routing rules. For more information, see [Recreate an API mapping using routing rules](rest-api-routing-rules-recreate-api-mapping.md).

For REST APIs, you can also use routing rules and API mappings together. When you use routing rules and API mappings together, API Gateway always evaluates routing rules before it evaluates any API mappings. Use routing rules and API mappings together to migrate your current custom domain names or to explore routing rules.

### Considerations for routing rules
<a name="considerations-for-private-preview"></a>

The following considerations might impact your use of routing rules:
+ WebSocket or HTTP APIs aren't supported as target APIs for routing rules.
+ If your custom domain name has API mappings to both REST and HTTP APIs, routing rules isn't supported.
+ You can create a routing rule for a private custom domain to a private REST API. You can create a routing rule for a public custom domain to a Regional or edge-optimized API. 
+ You can't create a routing rule for a public custom domain to a private API. You can't create a routing rule for a private custom domain name to a public API.

## Choose between routing rules and API mappings
<a name="choose-between-routing-rules-and-api-mappings"></a>

We recommend that when possible, you use routing rules. Only use API mappings to send traffic to an HTTP or WebSocket API.

# Set the routing mode for your custom domain name
<a name="set-routing-mode"></a>

You can choose which routing mode API Gateway uses to route traffic to your APIs. For more information, see [Send traffic to your APIs through your custom domain name in API Gateway](rest-api-routing-mode.md). This section discusses routing modes for custom domain names. You must set a routing mode for your custom domain name to route traffic to your APIs. The following routing modes are supported:
+ **ROUTING\$1RULE\$1THEN\$1API\$1MAPPING** – Use this mode to send traffic to your APIs with both routing rules and API mappings. In this mode, all routing rules take priority over any API mappings. For an example of this mode, see [Example 2: Routing rules and API mappings](rest-api-routing-rules-examples.md#rest-api-routing-rules-examples-rule-and-mappings). 
+ **ROUTING\$1RULE\$1ONLY** – Use this mode to only allow routing rules to send traffic to your APIs. When your custom domain name uses this mode, you can't create an API mapping, but you can use the [get-api-mappings](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/get-api-mappings.html) command to view them. API callers can’t use API mappings to access this domain name.
+ **API\$1MAPPING\$1ONLY** – Use this mode to only allow API mappings to send traffic to your APIs. When your custom domain name uses this mode, you can't create a routing rule, but you can use the `list-routing-rules` command to view them. API callers can’t use routing rules to access this domain name.

  This is the default routing mode for all your existing domain names, and any new domain names you create.

When you create a custom domain name using `apigateway`, `API_MAPPING_ONLY` is called `BASE_PATH_MAPPING_ONLY` and `ROUTING_RULE_THEN_API_MAPPING` is called `ROUTING_RULE_THEN_BASE_PATH_MAPPING`. This behavior is only present for the AWS CLI, CloudFormation, or any SDKs, not in the AWS Management Console.

The following procedure shows how to change the routing mode for an existing custom domain name. When you change the routing mode of your custom domain name, API callers can’t access your domain name using any unsupported routing modes.

------
#### [ AWS Management Console ]

1. Sign in to the API Gateway console at [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway).

1. Choose **Custom domain names** from the main navigation pane.

1. Choose a custom domain name.

1. For **Domain details**, choose **Edit**.

1. For **Routing mode**, choose **ROUTING\$1RULE\$1THEN\$1API\$1MAPPING**.

1. Choose **Save**.

If you change the routing mode to `ROUTING_RULE_ONLY` or `API_MAPPING_ONLY`, any API mappings or routing rules you've created are removed from the domain name details page of the console. If you change the routing mode to support either routing rules or API mappings, these resources will return.

------
#### [ AWS CLI - apigatewayv2 ]

The following [update-domain-name](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/update-domain-name.html) command updates a domain name to use the routing mode `ROUTING_RULE_THEN_API_MAPPING`:

```
aws apigatewayv2 update-domain-name \
  --domain-name 'api.example.com' \
  --routing-mode "ROUTING_RULE_THEN_API_MAPPING"
```

The output will look like the following:

```
{
"ApiMappingSelectionExpression": "$request.basepath",
"DomainName": "api.example.com",
"DomainNameArn": "arn:aws:apigateway:us-west-2::/domainnames/api.example.com",
"DomainNameConfigurations": [
  {
      "ApiGatewayDomainName": "d-abcdefg.execute-api.us-west-2.amazonaws.com",
      "CertificateArn": "arn:aws:acm:us-west-2:111122223333:certificate/abcdefg-123456-abcdefg",
      "DomainNameStatus": "AVAILABLE",
      "EndpointType": "REGIONAL",
      "HostedZoneId": "Z2OJLYMUO9EFXC",
      "SecurityPolicy": "TLS_1_2"
   }
 ],
"RoutingMode": "ROUTING_RULE_THEN_API_MAPPING",
"Tags": {}
}
```

------
#### [ AWS CLI - apigateway ]

The following [update-domain-name](https://docs.aws.amazon.com/cli/latest/reference/apigateway/update-domain-name.html) command updates a private custom domain name to use the routing mode `ROUTING_RULE_THEN_BASE_PATH_MAPPING`:

```
aws apigateway update-domain-name \
  --domain-name 'private.example.com' \
  --patch-operations "op='replace',path='/routingMode',value='ROUTING_RULE_THEN_BASE_PATH_MAPPING'"
```

The output will look like the following:

```
{
"domainName": "private.example.com",
"domainNameId": "abcd1234",
"domainNameArn": "arn:aws:apigateway:us-west-2:111122223333:/domainnames/private.example.com+abcd1234",
"certificateArn": "arn:aws:acm:us-west-2:111122223333:certificate/a1b2c3d4-5678-90ab-cdef",
"certificateUploadDate": "2024-09-10T10:31:20-07:00",
"endpointConfiguration": {
  "types": [
    "PRIVATE"
   ],
  "ipAddressType": "dualstack"
  },
"domainNameStatus": "AVAILABLE",
"securityPolicy": "TLS_1_2",
"policy": "...",
"routingMode" : "ROUTING_RULE_THEN_BASE_PATH_MAPPING"
}
```

------

# Routing rules to connect API stages to a custom domain name for REST APIs
<a name="rest-api-routing-rules"></a>

A routing rule is a set of conditions that when matched, invoke an action. For example, a rule can route any incoming request to a custom domain name that contains the header `Hello:World` and contains the base path `users` to the `production` stage of a REST API.

Rules are evaluated in priority order, and if you set the routing mode to `ROUTING_RULE_THEN_API_MAPPING`, API Gateway always evaluates all routing rules before evaluating any API mappings. The following list describes how a routing rule uses conditions, actions, and priorities. 

**Conditions**  
When the conditions for a rule are met, then its actions are performed. API Gateway supports up to two header conditions and one path condition. API Gateway evaluates header conditions and base path conditions together.  
You can create a rule without any conditions. When API Gateway evaluates this rule, the action is always performed. You can create a rule without any conditions as a catch-all rule.  
For more information about header conditions, see [Match headers conditions](#rest-api-routing-rules-condition-headers). For more information about path conditions, see [Match base path conditions](#rest-api-routing-rules-condition-path). 

**Actions**  
Actions are the result of matching conditions to a routing rule. Currently, the only supported action is to invoke a stage of a REST API.  
Each rule can have one action.

**Priority**  
The priority determines what order the rules are evaluated in, from the lowest value to the highest value. Rules can't have the same priority.  
You can set the priority from 1-1,000,000. If a rule has a priority of one, API Gateway evaluates it first. We recommend that when you create a rule, you add gaps in priorities. This helps you switch the priority of rules and add new rules. For more information, see [Change the priority of a routing rule](apigateway-routing-rules-use.md#rest-api-routing-rules-change-priority).

For examples of how API Gateway evaluates routing rules, see [Examples of how API Gateway evaluates routing rules](rest-api-routing-rules-examples.md).

## API Gateway routing rule condition types
<a name="rest-api-routing-rules-condition-types"></a>

The following section describes the routing rule condition types. API Gateway only matches a rule if all conditions are true.

### Match headers conditions
<a name="rest-api-routing-rules-condition-headers"></a>

When you create a header condition, you can match the header name and header glob value, such as `Hello:World`. API Gateway uses a literal match to validate match headers conditions. Your condition can use up to two headers using `AND` between them. For example, your condition can match if an incoming request contains `Hello:World` and `x-version:beta`.

The header name matching is case insensitive, but the header glob value is case sensitive. `Hello:World` will match `hello:World`, but not `Hello:world`.

For a list of restricted header values see, [Restrictions](#rest-api-routing-rules-restrictions).

#### Using wildcards with header conditions
<a name="rest-api-routing-rules-condition-headers-wildcards"></a>

You can only use wildcards in the header glob value, and the wildcard must be `*prefix-match`, `suffix-match*`, or `*contains*`. The following table shows examples for how to use wildcards for matching for header conditions. 


|  Header conditions  |  Requests that match the routing rule  |  Requests that don't match the routing rule  | 
| --- | --- | --- | 
|  `x-version: a*`  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/apigateway/latest/developerguide/rest-api-routing-rules.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/apigateway/latest/developerguide/rest-api-routing-rules.html)  | 
|  `x-version: *a`  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/apigateway/latest/developerguide/rest-api-routing-rules.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/apigateway/latest/developerguide/rest-api-routing-rules.html)  | 
|  `x-version: *a*`  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/apigateway/latest/developerguide/rest-api-routing-rules.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/apigateway/latest/developerguide/rest-api-routing-rules.html)  | 
|  `x-version: *a*` and `x-version: *b*`  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/apigateway/latest/developerguide/rest-api-routing-rules.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/apigateway/latest/developerguide/rest-api-routing-rules.html)  | 
|  `x-version: b*` and `x-version: *a`  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/apigateway/latest/developerguide/rest-api-routing-rules.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/apigateway/latest/developerguide/rest-api-routing-rules.html)  | 
|  `x-version: *`  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/apigateway/latest/developerguide/rest-api-routing-rules.html)  |  None  | 

If you create conditions for multiple header values, such as `Accept:application/json,text/xml`, we recommend that you use `*contains*` for your header conditions and avoid creating conditions using the comma (`,`) character.

Because API Gateway matches header conditions literally, semantic matches might be routed differently. The following table shows the difference in routing rules outcomes.


|  Header conditions  |  Requests that match the routing rule  |  Requests that don't match the routing rule  | 
| --- | --- | --- | 
|  `Accept: *json`  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/apigateway/latest/developerguide/rest-api-routing-rules.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/apigateway/latest/developerguide/rest-api-routing-rules.html)  | 
|  `Accept: *json*`  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/apigateway/latest/developerguide/rest-api-routing-rules.html)  |  None  | 

### Match base path conditions
<a name="rest-api-routing-rules-condition-path"></a>

When you create a base path condition, if the incoming request contains the path you specified, the rule is matched. The matching is case sensitive, so the path `New/Users` will not match with `new/users`.

You can create a base path condition for only one base path.

For a list of restricted base path conditions, [Restrictions](#rest-api-routing-rules-restrictions).

#### Strip the base path with base path conditions
<a name="rest-api-routing-rules-condition-path-split"></a>

When you create a base path condition, you can choose to strip the base path. When you strip the base path, API Gateway removes the incoming matched base path when it invokes the target API. This is the same behavior as when you use an API mapping. When you don't strip the base path, API Gateway forwards the entire base path to the target API. We recommend that you only strip the base path when you are recreating an API mapping.

The following table shows examples for how API Gateway evaluates the strip base path condition.


|  Condition  | Strip base path |  Incoming request  |  Result  | 
| --- | --- | --- | --- | 
|  If base path contains `PetStoreShopper/dogs`  |  True  |  `GET https://example.com/PetStoreShopper/dogs`  |  API Gateway calls the `GET` method of the `/` resource.  | 
|  If base path contains `PetStoreShopper/dogs`.  |  False  |  `GET https://example.com/PetStoreShopper/dogs`  |  API Gateway calls the `GET` method of the `PetStoreShopper/dogs` resource.  | 
|  If base path contains `PetStoreShopper`  |  True  |  `GET https://example.com/PetStoreShopper/dogs`  |  API Gateway calls the `GET` method of the `dogs` resource.  | 
|  If base path contains `PetStoreShopper`  |  False  |  `GET https://example.com/PetStoreShopper/dogs`  |  API Gateway calls the `GET` method of the `PetStoreShopper/dogs` resource.  | 
|  If base path contains `PetStoreShopper`  |  True  |  `GET https://example.com/PetStoreShopper?birds=available`  |  API Gateway calls the `GET` method of the `/` resource with the query string parameter `birds=available`.  | 
|  If base path contains `PetStoreShopper`  |  False  |  `GET https://example.com/PetStoreShopper?birds=available`  |  API Gateway calls the `GET` method of the `/PetStoreShopper` resource with the query string parameter `birds=available`.  | 

## Restrictions
<a name="rest-api-routing-rules-restrictions"></a>
+ The target API and the custom domain name must be in the same AWS account.
+ Each rule can have one target API. 
+ You can only create a routing rule for a private custom domain name to a private API, and for a public custom domain name to a public API. You can't mix public and private resources.
+ If your custom domain name has API mappings to both REST and HTTP APIs, routing rules isn't supported.
+ The maximum priority number is 1,000,000.
+ Header restrictions:
  + Each `anyOf` condition can only contain one header value.
  + The only allowed characters for header names and header glob values are specified by [RFC 7230](https://datatracker.ietf.org/doc/html/rfc7230), which are `a-z`, `A-Z`, `0-9`, and the following special characters: `*?-!#$%&'.^_`|~`.
  + You can use a wildcard in the header glob value, but the wildcard must be `*prefix-match`, `suffix-match*`, or `*contains*`. You can't use `*` in the middle of a header glob value.
  + Wildcard header names aren't supported.
  + The header name must be less than 40 characters.
  + The header glob value must be less than 128 characters.
  + The header glob value for an infix match must be less than 40 characters.
  + The following headers aren't supported as conditions:
    + `access-control-*`
    + `apigw-*`
    + `Authorization`
    + `Connection`
    + `Content-Encoding`
    + `Content-Length`
    + `Content-Location`
    + `Forwarded`
    + `Keep-Alive`
    + `Origin`
    + `Proxy-Authenticate`
    + `Proxy-Authorization`
    + `TE`
    + `Trailers`
    + `Transfer-Encoding`
    + `Upgrade`
    + `x-amz-*`
    + `x-amzn-*`
    + `x-apigw-api-id`
    + `X-Forwarded-For`
    + `X-Forwarded-Host`
    + `X-Forwarded-Proto`
    + `x-restAPI`
    + `Via`
+ Base path restrictions:
  + The base path length must be less than 128 characters.
  + The base path must contain only letters, numbers, and the following characters: `$-_.+!*'()/`.

    These characters aren't supported for regular expressions (regex). 
  + The base path can't start or end with backslash (`\`) character.

# Examples of how API Gateway evaluates routing rules
<a name="rest-api-routing-rules-examples"></a>

The following section shows four examples of how API Gateway evaluates routing rules and API mappings.

## Example 1: Routing rules only
<a name="rest-api-routing-rules-examples-rule-only"></a>

In this example, the custom domain name `https://petstore.example.com` has the routing mode set to `ROUTING_RULE_ONLY` and has the following routing rules and priorities.


|  Rule ID  |  Priority  |  Conditions  |  Action  | 
| --- | --- | --- | --- | 
|  `abc123`  |   10   |   If request contains header: `Hello:World`   |   Target API 1   | 
|  `zzz000`  |   50   |   If request contains headers: `Accept:image/webp` and `Pet:Dog-*` and if the base path contains `PetStoreShopper`  |   Target API 2   | 
|  `efg456`  |   100   |  None  |   Target API 3   | 

The following table shows how API Gateway applies the previous routing rules to example requests.


| Request | Selected API | Explanation | 
| --- | --- | --- | 
|  `https://petstore.example.com -h "Hello:World"`  |  Target API 1  |  The request matches the routing rule `abc123`.  | 
|  `https://petstore.example.com/PetStoreShopper -h "Hello:World", "Pet:Dog-Bella", "Accept:image/webp"`  |  Target API 1  |  API Gateway evaluates all routing rules in priority order. Routing rule `abc123` has the first priority and the conditions match, so API Gateway invokes Target API 1. Although the conditions of the request also match routing rule `zzz000`, API Gateway doesn't evaluate any other routing rules after it makes a match.  | 
|  `https://petstore.example.com/PetStoreShopper -h "Pet:Dog-Bella", "Accept:image/webp"`  |  Target API 2  |  The request matches the routing rule `zzz000`. This was a match because the `Pet:Dog-Bella` was a string match to `Pet:Dog-*`  | 
|  `https://petstore.example.com/PetStoreShopper -h "Pet:Dog-Bella"`  |  Target API 3  |  The request doesn't match the routing rule `abc123`. The request doesn't match routing rule `zzz000` as all the required headers aren't present. The next priority rule matches all incoming requests, so API Gateway invokes Target API 3.  | 

## Example 2: Routing rules and API mappings
<a name="rest-api-routing-rules-examples-rule-and-mappings"></a>

In this example, the custom domain name `https://petstore.diagram.example.com` has the routing mode set to `ROUTING_RULE_THEN_API_MAPPING` and has the following routing rules and API mappings.


|  Rule ID  |  Priority  |  Conditions  |  Action  | 
| --- | --- | --- | --- | 
|  `abc123`  |   1   |   If request the base contains `pets`   |   Invoke the `Prod` stage of the `PetStore` API.   | 
|  `000zzz`  |   5   |   If request contains headers: `Cookie`:`*ux=beta*` and and if the base path contains `/refunds`  |   Invoke the `Beta` stage of the `Refunds` API.   | 

The following table shows API mappings for `https://petstore.backup.example.com`.


|  API mapping  |  Selected API  | 
| --- | --- | 
|   `/refunds`   |   Invoke the `Prod` stage of the `Refunds` API.   | 
|   `(none)`   |   Invoke the `Prod` stage of the `Search` API.   | 

The following diagram shows how API Gateway applies the previous routing rules and API mappings to example requests. The example requests are summarized in the table after this diagram.

![\[Diagram of how API Gateway applies the previous routing rules and API mappings.\]](http://docs.aws.amazon.com/apigateway/latest/developerguide/images/rr-diagram.png)


The following table shows how API Gateway applies the previous routing rules and API mappings to example requests.


| Request | Selected API | Explanation | 
| --- | --- | --- | 
|  `https://petstore.diagram.com/pets`  |  The `Prod` stage of the `PetStore` API.  |  The request matches routing rule `abc123`.  | 
|  `https://petstore.diagram.example.com/refunds -h "Cookie:lang=en-us;ux=beta"`  |  The `Beta` stage of the `Refunds` API.  |  The request matches routing rule `000zzz`. The `Cookie` header contains the correct `*contains*` match and base path match for this condition.   | 
|  `https://petstore.diagram.example.com/refunds`  |  The `Prod` stage of the `Refunds` API.   |  The request doesn't have the required headers to match the routing rule `zzz000`. If API Gateway can't successfully match a routing rule, it falls back to API mappings. API Gateway can map the base path to the `Prod` stage of the `Refunds` API.   | 
|  `https://petstore.diagram.example.com/`  |  The `Prod` stage of the `Search` API.   |  The request matches the API mapping to the empty path `(none)`.  | 

## Example 3: Routing rules and API mappings with multiple level
<a name="rest-api-routing-rules-examples-rule-and-mappings-with-multiple-levels"></a>

In this example, the custom domain name `https://petstore.backup.example.com` has the routing mode set to `ROUTING_RULE_THEN_API_MAPPING` and has the following routing rules and API mappings.

The following table shows routing rules for `https://petstore.backup.example.com`.


|  Rule ID  |  Priority  |  Conditions  |  Action  | 
| --- | --- | --- | --- | 
|  `abc123`  |   10   |   If request contains header: `Hello:World`   |   Target API 1   | 
|  `000zzz`  |   50   |   If request contains headers: `Accept`:`image/webp` and `Pet:Dog-*` and if the base path contains `PetStoreShopper`  |  Target API 2  | 

The following table shows API mappings for `https://petstore.backup.example.com`.


|  API mapping  |  Selected API  | 
| --- | --- | 
|   `PetStoreShopper`   |   Target API 3   | 
|   `PetStoreShopper/cats`   |   Target API 4   | 

The following table shows how API Gateway applies the previous routing rules and API mappings to example requests.


| Request | Selected API | Explanation | 
| --- | --- | --- | 
|  `https://petstore.example.com/PetStoreShopper -h "Accept:image/webp", "Pet:Cats" `  |  Target API 3  |  The request doesn't have the required headers to match the routing rule `zzz000`. If API Gateway can't successfully match a routing rule, it falls back to API mappings. API Gateway can map the base path to Target API 3.  | 
|  `https://petstore.example.com/PetStoreShopper/cats -h "Hello:World"`  |  Target API 1  |  The request matches routing rule `abc123`. If the routing mode is set to `ROUTING_RULE_THEN_API_MAPPING`, routing rules always take priority over API mappings.  | 
|  `https://petstore.example.com/Admin -h "Pet:Dog-Bella"`  |  None  |  The request doesn't match any routing rules or API mappings. Since there is no default routing rule, API Gateway rejects the call and sends the caller a `403 Forbidden` status code.  | 

## Example 4: Routing rules for wildcard domain names
<a name="rest-api-routing-rules-examples-rule-for-wildcard-domains"></a>

In this example, the custom domain name `https://*.example.com` is a wildcard domain name. The wildcard supports all subdomains which route back to the same domain. The following example routing rules change this behavior to allow subdomains to route to different target APIs by using the `Host` header.

The following table shows routing rules for `https://*.example.com`.


|  Rule ID  |  Priority  |  Conditions  |  Action  | 
| --- | --- | --- | --- | 
|  `abc123`  |   10   |   If request contains header: `Host:a.example.com`   |   Target API 1   | 
|  `000zzz`  |   50   |   If request contains headers: `Host:b.example.com`  |  Target API 2  | 
|  `efg456`  |   500   |  None  |  Target API 3  | 

The following table shows how API Gateway applies the previous routing rules to example requests.


| Request | Selected API | Explanation | 
| --- | --- | --- | 
|  `https://a.example.com`  |  Target API 1  |  The `Host` header is `a.example.com`. This request matches routing rule `abc123`.  | 
|  `https://b.example.com`  |  Target API 2  |  The `Host` header is `b.example.com`. This request matches routing rule `000zzz`.  | 
|  `https://testing.example.com`  |  Target API 3  |  This matches the catch-all routing rule `efg456`.  | 

# How to use routing rules
<a name="apigateway-routing-rules-use"></a>

You can create a routing rule using the AWS Management Console, AWS CLI, or any AWS SDK. After you create a rule, you can change it's priority.

## Create a routing rule
<a name="rest-api-routing-rules-create"></a>

The following procedure shows how to create a routing rule for a custom domain name with a routing mode set to either `ROUTING_RULE_THEN_API_MAPPING` or `ROUTING_RULE_ONLY`.

------
#### [ AWS Management Console ]

1. Sign in to the API Gateway console at [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway).

1. Choose **Custom domain names** from the main navigation pane. 

1. Choose a custom domain name.

1. On the **Routing details** tab, choose **Add routing rule**.

1. Choose **Add a new condition** to add a new condition.

   You can add a header or base path condition. To match all incoming requests to your custom domain name, don't add a condition. 

1. For **Action**, use the dropdown to select your target API and target stage.

1. Choose **Next**.

1. In the priority field, enter a number for your priority.

   API Gateway evaluates rules in priority order, from the lowest value to the highest value.

   If you're creating a rule without a condition, we recommend that you use a high value priority.

1. Choose **Create routing rule**.

------
#### [ AWS CLI ]

The following [create-routing-rule](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/create-routing-rule.html) command creates a routing rule with a priority of 50. In this example, API Gateway routes any incoming requests that have the headers `Hello:World` and `x-version:beta` and the base path `PetStoreShopper` to the target API `a1b2c3`.

```
 aws apigatewayv2 create-routing-rule \
  --domain-name 'api.example.com' \
  --priority 50 \
  --conditions '[
    {
      "MatchHeaders": {
        "AnyOf": [
          {
            "Header": "Hello",
            "ValueGlob": "World"
          }
        ]
      }
    },
    {
      "MatchHeaders": {
        "AnyOf": [
          {
            "Header": "x-version",
            "ValueGlob": "beta"
          }
        ]
      }
    },
    {
      "MatchBasePaths": {
        "AnyOf": [
          "PetStoreShopper"
        ]
      }
    }
  ]'\
  --actions '[
  {
    "InvokeApi": {
      "ApiId": "a1b2c3",
      "Stage": "prod"
    }
  }
 ]'
```

The output will look like the following.

```
{
    "Actions": [
        {
            "InvokeApi": {
                "ApiId": "a1b2c3",
                "Stage": "prod",
                "StripBasePath": false
            }
        }
    ],
    "Conditions": [
        {
            "MatchHeaders": {
                "AnyOf": [
                    {
                        "Header": "Hello",
                        "ValueGlob": "World"
                    }
                ]
            }
        },
        {
            "MatchHeaders": {
                "AnyOf": [
                    {
                        "Header": "x-version",
                        "ValueGlob": "beta"
                    }
                ]
            }
        },
        {
            "MatchBasePaths": {
                "AnyOf": [
                    "PetStoreShopper"
                ]
            }
        }
    ],
    "Priority": 50,
    "RoutingRuleArn": "arn:aws:apigateway:us-west-2:111122223333:/domainnames/api.example.com/routingrules/abc123",
    "RoutingRuleId": "abc123"
}
```

------

## Change the priority of a routing rule
<a name="rest-api-routing-rules-change-priority"></a>

You can change the priority of a routing rule. This takes effect immediately and might impact how API consumers invoke your custom domain names. We recommend that when you set the priorities of your routing rules, you leave gaps between rules.

For example, consider two routing rules, rule `abc123` with a priority of 50 and rule `zzz000` with a priority of 150. To change the priority of the rules so that API Gateway evaluates rule `zzz000` first, you can change the priority of rule `zzz000` to 30.

------
#### [ AWS Management Console ]

1. Sign in to the API Gateway console at [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway).

1. Choose **Custom domain names** from the main navigation pane. 

1. Choose a custom domain name.

1. On the **Routing details** tab, choose your routing rule, and then choose **Edit**. 

1. Choose **Next**.

1. For priority, enter the new priority.

1. Choose **Save changes**.

------
#### [ AWS CLI ]

The following [put-routing-rule](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/put-routing-rule.html) command changes the priority of a routing rule `abc123`.

```
 aws apigatewayv2 put-routing-rule \
  --domain-name 'api.example.com' \
  --priority 30 \
  --routing-rule-id abc123 \
  --conditions '[
    {
      "MatchHeaders": {
        "AnyOf": [
          {
            "Header": "Hello",
            "ValueGlob": "World"
          }
        ]
      }
    },
    {
      "MatchHeaders": {
        "AnyOf": [
          {
            "Header": "x-version",
            "ValueGlob": "beta"
          }
        ]
      }
    },
    {
      "MatchBasePaths": {
        "AnyOf": [
          "PetStoreShopper"
        ]
      }
    }
  ]'\
  --actions '[
  {
    "InvokeApi": {
      "ApiId": "a1b2c3",
      "Stage": "prod"
    }
  }
 ]'
```

The output will look like the following:

```
{
    "Actions": [
        {
            "InvokeApi": {
                "ApiId": "a1b2c3",
                "Stage": "prod",
                "StripBasePath": false
            }
        }
    ],
    "Conditions": [
        {
            "MatchHeaders": {
                "AnyOf": [
                    {
                        "Header": "Hello",
                        "ValueGlob": "World"
                    }
                ]
            }
        },
        {
            "MatchHeaders": {
                "AnyOf": [
                    {
                        "Header": "x-version",
                        "ValueGlob": "beta"
                    }
                ]
            }
        },
        {
            "MatchBasePaths": {
                "AnyOf": [
                    "PetStoreShopper"
                ]
            }
        }
    ],
    "Priority": 38,
    "RoutingRuleArn": "arn:aws:apigateway:us-west-2:111122223333:/domainnames/api.example.com/routingrules/abc123",
    "RoutingRuleId": "abc123"
}
```

------

# Recreate an API mapping using routing rules
<a name="rest-api-routing-rules-recreate-api-mapping"></a>

You can recreate an API mapping using routing rules. To recreate an API mapping, make sure to turn on base path striping. This preserves the behavior of API mappings. For more information, see [Strip the base path with base path conditions](rest-api-routing-rules.md#rest-api-routing-rules-condition-path-split).

The following tutorial shows how to recreate the API mapping `https:// api.example.com/orders/v2/items/categories/5` as a routing rule and how to update your access logs to log the routing rule ID API Gateway uses to send traffic to your API.

------
#### [ AWS Management Console ]

**To set the routing mode to ROUTING\$1RULE\$1THEN\$1API\$1MAPPING**

1. Sign in to the API Gateway console at [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway).

1. Choose **Custom domain names** from the main navigation pane. 

1. Choose your custom domain name.

1. For **Domain details**, choose **Edit**.

1. For **Routing mode**, choose **ROUTING\$1RULE\$1THEN\$1API\$1MAPPING**.

1. Choose **Save** 

After you set the routing mode, you create the routing rule.

**To create the routing rule**

1. On the **Routing details** tab, choose **Add routing rule**.

1. Choose **Add new condition** and then choose **Path**.

1. For **Path**, enter **orders/v2/items/categories/5**.

1. For **Strip base path**, choose **Active**.

1. For **Target API**, choose your target API.

1. For **Target stage**, choose your target stage.

1. Choose **Next**.

1. For priority, enter a priority.

   Even if you keep your existing API mapping, API Gateway will always use the new routing rule as routing rules always take priority over API mappings.

1. Choose **Save changes**.

After you create the routing rule, update the access log format for your stage or create a new log to confirm that API Gateway uses your routing rule to send traffic to your API.

**To update your access logs**

1. Sign in to the API Gateway console at [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway).

1. Choose your API.

1. In the main navigation pane, choose **Stages**.

1. For **Logs and tracing**, choose **Edit**.

   If you don't have a log group, see [Set up CloudWatch logging for REST APIs in API Gateway](set-up-logging.md).

1. Add **\$1context.customDomain.routingRuleIdMatched** to your log format.

   This log group records the routing rule ID that API Gateway used to send traffic to your API. For more information, see [I can't tell how API Gateway sent traffic to my APIs](rest-api-routing-rules-troubleshoot.md#rest-api-routing-rules-logging).

1. Choose **Save**.

After you update your access logs, invoke your custom domain name. The following is an example curl command to invoke the custom domain name `https://api.example.com` with the base path `orders/v2/items/categories/5`.

```
curl "https://api.example.com/orders/v2/items/categories/5"
```

After you have successfully invoked your custom domain name, confirm that CloudWatch Logs shows the `routingRuleIdMatched`. To learn how to use the CloudWatch Logs console to view a log group, see [View API Gateway log events in the CloudWatch console](view-cloudwatch-log-events-in-cloudwatch-console.md).

------
#### [ AWS CLI ]

1. Use the following [update-domain-name](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/update-domain-name.html) command to update the domain name `api.example.com` to use the routing mode `ROUTING_RULE_THEN_API_MAPPING`.

   ```
   aws apigatewayv2 update-domain-name \
     --domain-name 'api.example.com' \
     --routing-mode ROUTING_RULE_THEN_API_MAPPING
   ```

1. Use the following [create-routing-rule](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/create-routing-rule.html) command to create a new routing rule to recreate the API mapping `https://api.example.com/orders/v2/items/categories/5`.

   ```
   aws apigatewayv2 create-routing-rule \
     --domain-name 'api.example.com' \
     --priority 50 \
     --conditions '[
     {
       "MatchBasePaths": {
         "AnyOf": [
           "orders/v2/items/categories/5"
         ]
       }
     }
   ]' \
     --actions '[
     {
       "InvokeApi": {
         "ApiId": "a1b2c3",
         "Stage": "prod",
         "StripBasePath": true
       }
     }
   ]'
   ```

1. Use the following [update-stage](https://docs.aws.amazon.com/cli/latest/reference/apigateway/update-stage.html) command to update the access logs format to include the `$context.customDomain.routingRuleIdMatched` variable. This variable records the routing rule ID that API Gateway used to send traffic to your API. You use this log to confirm that API Gateway uses your routing rule to send traffic to your API. For more information, see [I can't tell how API Gateway sent traffic to my APIs](rest-api-routing-rules-troubleshoot.md#rest-api-routing-rules-logging).

   ```
   aws apigateway update-stage \
     --rest-api-id a1bc2c3 \
     --stage-name prod \
     --patch-operations "op=replace,path=/accessLogSettings/format,value='\$context.path \$context.customDomain.routingRuleIdMatched \$context.requestId \$context.extendedRequestId'"
   ```

   If you don't have a log group, see [Set up CloudWatch logging for REST APIs in API Gateway](set-up-logging.md).

1. Use the following example curl command to invoke your custom domain name with the base path `orders/v2/items/categories/5`.

   ```
   curl "https://api.example.com/orders/v2/items/categories/5
   ```

1. Use the following [filter-log-events](https://docs.aws.amazon.com/cli/latest/reference/logs/filter-log-events.html) command to get the log events from the log group `access-log-group-orders` that contain routing rule ID `abc123`.

   ```
   aws logs filter-log-events --log-group-name access-log-group-orders --filter-pattern abc123
   ```

    This confirms that API Gateway used the routing rule to send traffic to your API.

------

# Troubleshooting issues with routing rules
<a name="rest-api-routing-rules-troubleshoot"></a>

The following troubleshooting guidance might help resolve issues with your routing rules.

## I can't tell how API Gateway sent traffic to my APIs
<a name="rest-api-routing-rules-logging"></a>

You can use access logs for your REST API stage to log and troubleshoot your routing rules. You can view the routing rule ID that API Gateway used to send traffic to your API using the `$context.customDomain.routingRuleIdMatched` variable. To view the API mapping that API Gateway used to send traffic to your API, use the `$context.customDomain.basePathMatched` variable. 

 To log your routing rules, you need to configure [an appropriate CloudWatch Logs role](set-up-logging.md#set-up-access-logging-permissions) ARN for your account and create a log group.

The following example access log group can retrieve the relevant information for troubleshooting routing rules and API mappings. API Gateway only populates the context variable for the routing mechanism it used, otherwise the context variable is `-`. 

------
#### [ CLF ]

```
$context.path $context.customDomain.routingRuleIdMatched $context.customDomain.basePathMatched $context.requestId $context.extendedRequestId
```

------
#### [ JSON ]

```
{"requestPath": "$context.path", "routingRuleId" : "$context.customDomain.routingRuleIdMatched", "API mapping" : "$context.customDomain.basePathMatched", "requestId":"$context.requestId", "extendedRequestId":"$context.extendedRequestId"}
```

------
#### [ XML ]

```
<request id="$context.requestId"> <requestPath>$context.path</requestPath> <ruleId>$context.customDomain.routingRuleIdMatched</ruleId> <ApiMapping>$context.customDomain.basePathMatched</ApiMapping> <extendedRequestId>$context.extendedRequestId</extendedRequestId> </request>
```

------
#### [ CSV ]

```
$context.path,$context.customDomain.routingRuleIdMatched,$context.customDomain.basePathMatched,$context.requestId,$context.extendedRequestId
```

------

We also recommend that you confirm the routing mode for your custom domain name. For more information, see [Set the routing mode for your custom domain name](set-routing-mode.md).

## I can't enable routing rules on my custom domain name
<a name="rest-routing-rules-access-denied"></a>

You might receive the following error from API Gateway:

```
Your account doesn’t have permission to use RoutingRules.
This might be caused by an IAM policy in your account with a deny statement on BasePathMapping or ApiMapping.
To grant permission for this account to use RoutingRules, use the UpdateAccount API.
This will impact any existing IAM policies that deny access to BasePathMapping or ApiMapping.
See API Gateway documentation for further details.
```

You'll receive this error if have or had an IAM policy that denies access to [BasePathMapping](https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonapigatewaymanagement.html#amazonapigatewaymanagement-resources-for-iam-policies) or [ApiMapping](https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonapigatewaymanagementv2.html#amazonapigatewaymanagementv2-resources-for-iam-policies). When you enable routing rules for a custom domain name, although your policy will continue to deny access to `BasePathMapping` or `ApiMapping`, the same policy can be used to access `RoutingRule`. This might allow a user to change the routing behavior of your custom domain name.

For example, if you had a policy like the following:

```
{
    "Sid": "DenyCreatingApiMappings",
    "Effect": "Deny",
    "Action": "apigateway:POST",
    "Resource": [
        "arn:aws:apigateway:us-west-2::/domainnames/example.com/apimappings"
    ]
}
```

When you enable routing rules for `example.com`, this policy will continue to deny access to creating an `ApiMapping` but will not deny access to creating a `RoutingRule`.

We recommend that you audit the IAM policies in your account. The following example policy will deny access to creating `ApiMapping`, `BasePathMapping`, and `RoutingRule`:

```
{
    "Sid": "DenyCreatingBasePathMappingsApiMappings",
    "Effect": "Deny",
    "Action": "apigateway:POST",
    "Resource": [
        "arn:aws:apigateway:us-west-2::/domainnames/example.com/basepathmappings",
        "arn:aws:apigateway:us-west-2::/domainnames/example.com/apimappings"
    ]
},
{
    "Sid": "DenyCreatingRoutingRules",
    "Effect": "Deny",
    "Action": "apigateway:CreateRoutingRule",
    "Resource": [
        "arn:aws:apigateway:us-west-2:111122223333:/domainnames/example.com/routingrules/*"
    ]
}
```

After you have confirmed all your policies have been updated, you can update your API's account-level settings to enable routing rules for a Region.

Use the following [update-account](https://docs.aws.amazon.com/cli/latest/reference/apigateway/update-account.html) command to update the settings for your API's account-level settings for a Region:

```
aws apigateway update-account --patch-operations 'op=remove,path=/features,value=BlockedForRoutingRules' --region us-west-2
```

After you update your API's account-level settings, you can change the routing mode of your custom domain name. You can also continue to use IAM policies to deny access to `RoutingRules`, `ApiMapping` or `BasePathMapping`.

# Use API mappings to connect API stages to a custom domain name for REST APIs
<a name="rest-api-mappings"></a>

You use API mappings to connect API stages to a custom domain name. This sends traffic to your APIs through your custom domain name.

An API mapping specifies an API, a stage, and optionally a path to use for the mapping. For example, you can map `https://api.example.com/orders` to the `production` stage of an API.

You can map HTTP and REST API stages to the same custom domain name.

Before you create an API mapping, you must have an API, a stage, and a custom domain name. To learn more about creating a custom domain name, see [Set up a Regional custom domain name in API Gateway](apigateway-regional-api-custom-domain-create.md).

## Incoming requests to your custom domain name
<a name="rest-api-mappings-incoming-requests"></a>

When you map a custom domain name to a stage of your API, API Gateway strips the incoming base path. This removes the mapped base path from the invocation to the API. For instance, if your base path mapping was `https://api.example.com/orders/shop/5` to the `test` stage, and you used the following request, `https://api.example.com/orders/shop/5/hats`, API Gateway would invoke the `/hats` resource of the `test` stage of your API, not the `orders/shop/5/hats` resource.

## Mapping API requests
<a name="rest-api-mappings-evalutation"></a>

The following explains how API Gateway evaluates API mappings.

You can create an API mapping using single-level mappings, such an API mapping from `orders` to the `beta` stage of an API and an API mapping from `shipping` to the `alpha` stage of an API. For a Regional custom domain names with the TLS 1.2 security policy, API Gateway supports multi-level API mappings. You can create an API mapping from `orders/v1/items` to the `alpha` stage of an API and `orders/v2/items` to the `beta` stage of an API. When you create a mapping with multiple levels, API Gateway sends requests to the API mapping that has the longest matching path.

You can create an API mapping to the empty path `(none)`. If no path matches the request, API Gateway sends the request to the empty path `(none)`.

In this example, the custom domain name `https://api.example.com` has the following API mappings.


|  API Mapping  |  Selected API  | 
| --- | --- | 
|  `(none)`  |   API 1   | 
|   `orders`   |   API 2   | 
|  `orders/v1/items`  |   API 3   | 
|  `orders/v2/items`  |   API 4   | 
|  `orders/v1/items/categories`  |   API 5   | 

The following table shows how API Gateway applies the previous API mappings to example requests.


| Request | Selected API | Explanation | 
| --- | --- | --- | 
|  `https://api.example.com/orders`  |  API 2  |  The request exactly matches this API mapping.  | 
|  `https://api.example.com/orders/v1/items`  |  API 3  |  The request exactly matches this API mapping.  | 
|  `https://api.example.com/orders/v2/items`  |  API 4  |  The request exactly matches this API mapping.  | 
|  `https://api.example.com/orders/v1/items/123`  |  API 3  |  API Gateway chooses the mapping that has the longest matching path. The `123` at the end of the request doesn't affect the selection. See [Incoming requests to your custom domain name](#rest-api-mappings-incoming-requests).  | 
|  `https://api.example.com/orders/v2/items/categories/5`  |  API 5  |  API Gateway chooses the mapping that has the longest matching path.  | 
|  `https://api.example.com/customers`  |  API 1  |  API Gateway uses the empty mapping as a catch-all.  | 
|  `https://api.example.com/ordersandmore`  |  API 2  |  API Gateway chooses the mapping that has the longest matching prefix. For a custom domain name configured with single-level mappings, such as only `https://api.example.com/orders` and `https://api.example.com/`, API Gateway would choose `API 1`, as there is no matching path with `ordersandmore`.  | 

## Restrictions
<a name="rest-api-mappings-restrictions"></a>
+ In an API mapping, the custom domain name and mapped APIs must be in the same AWS account.
+ API mappings must contain only letters, numbers, and the following characters: `$-_.+!*'()/`.
+ The maximum length for the path in an API mapping is 300 characters.
+ You can have 200 API mappings with multiple levels for each domain name. This limit doesn't include API mapping with single levels, such as `/prod`.
+ You can only map HTTP APIs to a regional custom domain name with the TLS 1.2 security policy.
+ You can't map WebSocket APIs to the same custom domain name as an HTTP API or REST API.
+ After you create your API mappings, you must create or update your DNS provider's resource record to map to your API endpoint.
+ If you create an API mappings with multiple levels, API Gateway converts all header names to lowercase.

## Create an API mapping
<a name="rest-api-mappings-examples"></a>

To create an API mapping, you must first create a custom domain name, API, and stage. Your custom domain name must have a routing mode set to either `ROUTING_RULE_THEN_API_MAPPING` or `API_MAPPING_ONLY`. For information about how to set the routing mode, see [Set the routing mode for your custom domain name](set-routing-mode.md).

For example AWS Serverless Application Model templates that create all resources, see [Sessions With SAM](https://github.com/aws-samples/sessions-with-aws-sam/tree/master/custom-domains) on GitHub.

------
#### [ AWS Management Console ]

1. Sign in to the API Gateway console at [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway).

1. Choose **Custom domain names** from the main navigation pane. 

1. Choose a custom domain name.

1. On the **Routing details** tab, choose **Configure API mappings**.

1. Enter the **API**, **Stage**, and **Path** for the mapping.

1. Choose **Save**.

------
#### [ AWS CLI ]

The following [create-api-mapping](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/create-api-mapping.html) command creates an API mapping. In this example, API Gateway sends requests to `api.example.com/v1/orders` to the specified API and stage.

**Note**  
To create API mappings with multiple levels, you must use `apigatewayv2`.

```
aws apigatewayv2 create-api-mapping \
    --domain-name api.example.com \
    --api-mapping-key v1/orders \
    --api-id a1b2c3d4 \
    --stage test
```

------
#### [ CloudFormation ]

The following CloudFormation example creates an API mapping.

**Note**  
To create API mappings with multiple levels, you must use `AWS::ApiGatewayV2`.

```
MyApiMapping:
  Type: 'AWS::ApiGatewayV2::ApiMapping'
  Properties:
    DomainName: api.example.com
    ApiMappingKey: 'orders/v2/items'
    ApiId: !Ref MyApi
    Stage: !Ref MyStage
```

------