

# Use stage variables for a REST API in API Gateway
Use stage variables

Stage variables are key-value pairs that you can define as configuration attributes associated with a deployment stage of a REST API. They act like environment variables and can be used in your API setup and mapping templates. With deployment stages in API Gateway, you can manage multiple release stages for each API and use stage variables you can configure an API deployment stage to interact with different backend endpoints.

Stage variables are not intended to be used for sensitive data, such as credentials. To pass sensitive data to integrations, use an AWS Lambda authorizer. You can pass sensitive data to integrations in the output of the Lambda authorizer. To learn more, see [Output from an API Gateway Lambda authorizer](api-gateway-lambda-authorizer-output.md).

## Use cases for stage variables


The following are use cases for your stage variables.

**Specify a different backend endpoint**  
Your API can pass a `GET` request as an HTTP proxy to the backend web host. You can use a stage variable so that when API callers invoke your production endpoint, API Gateway calls `example.com`. Then, when API callers invoke the beta stage, API Gateway calls a different web host, such as `beta.example.com`. Similarly, stage variables can be used to specify a different AWS Lambda function name for each stage in your API. You can't use a stage variable to set a different integration endpoint, such as pointing the `GET` request to an HTTP proxy integration in one stage and a Lambda proxy integration in another stage.  
When specifying a Lambda function name as a stage variable value, you must configure the permissions on the Lambda function manually. When you specify a Lambda function in the API Gateway console, a AWS CLI command will pop-up to configure the proper permissions. You can also use the following AWS CLI command to do this.  

```
aws lambda add-permission --function-name "arn:aws:lambda:us-east-2:123456789012:function:my-function" --source-arn "arn:aws:execute-api:us-east-2:123456789012:api_id/*/HTTP_METHOD/resource" --principal apigateway.amazonaws.com --statement-id apigateway-access --action lambda:InvokeFunction
```

**Pass information using mapping templates**  
You can access stage variables in the mapping templates, or pass configuration parameters to your AWS Lambda or HTTP backend. For example, you might want to reuse the same Lambda function for multiple stages in your API, but the function should read data from a different Amazon DynamoDB table depending on the stage. In the mapping templates that generate the request for the Lambda function, you can use stage variables to pass the table name to Lambda.

To use a stage variable, you first configure a stage variable, and then you assign it a value. For example, to customize the HTTP integration endpoint, first create the `url` stage variable, and then in your API's integration request, enter the stage variable value, **http://\$1\$1stageVariables.url\$1**. This value tells API Gateway to substitute your stage variable `${}` at runtime, depending on which stage your API is running. For more information, see [Set up stage variables for REST APIs in API Gateway](how-to-set-stage-variables-aws-console.md). 

# Set up stage variables for REST APIs in API Gateway


This section shows how to set up various stage variables for two deployment stages of a sample API by using the Amazon API Gateway console. To understand how to use stage variables in API Gateway, we recommend that you follow all procedures in this section.

## Prerequisites


Before you begin, make sure the following prerequisites are met: 
+ You must have an API available in API Gateway. Follow the instructions in [Develop REST APIs in API Gateway](rest-api-develop.md).
+ You must have deployed the API at least once. Follow the instructions in [Deploy REST APIs in API Gateway](how-to-deploy-api.md).
+ You must have created the first stage for a deployed API. Follow the instructions in [Create a new stage](set-up-stages.md#how-to-create-stage-console).

  

## Invoke an HTTP endpoint through an API with a stage variable


This procedure describes how to create a stage variable for an HTTP endpoint and two stages for your API. In addition, you create the stage variables, `url`, `stageName`, and `function` that are used in the following procedures in this section.

**To invoke an HTTP endpoint through an API with a stage variable**

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

1. Create an API, and then create a `GET` method on the API's root resource. Set the integration type to **HTTP** and set the **Endpoint URL** to **http://\$1\$1stageVariables.url\$1**.

1. Deploy the API to a new stage named **beta**. 

1. In the main navigation pane, choose **Stages**, and then select the **beta** stage. 

1. On the **Stage variables** tab, choose **Edit**.

1. Choose **Add stage variable**.

1. For **Name**, enter **url**. For **value**, enter **httpbin.org/get**.

1. Choose **Add stage variable**, and then do the following:

   For **Name**, enter **stageName**. For **value**, enter **beta**.

1. Choose **Add stage variable**, and then do the following:

   For **Name**, enter **function**. For **value**, enter **HelloWorld**.

1. Choose **Save**.

1.  Now create a second stage. From the **Stages** navigation pane, choose **Create stage**. For **Stage name**, enter **prod**. Select a recent deployment from **Deployment**, and then choose **Create stage**.

1.  As with the **beta** stage, set the same three stage variables (**url**, **stageName**, and **function**) to different values (**petstore-demo-endpoint.execute-api.com/petstore/pets**, **prod**, and **HelloEveryone**), respectively. 

1. In the **Stages** navigation pane, choose **beta**. Under **Stage details**, choose the copy icon to copy your API's invoke URL, and then enter your API's invoke URL in a web browser. This starts the **beta** stage `GET` request on the root resource of the API. 
**Note**  
The **Invoke URL** link points to the root resource of the API in its **beta** stage. Entering the URL in a web browser calls the **beta** stage `GET` method on the root resource. If methods are defined on child resources and not on the root resource itself, entering the URL in a web browser returns a `{"message":"Missing Authentication Token"}` error response. In this case, you must append the name of a specific child resource to the **Invoke URL** link. 

1. The response you get from the **beta** stage `GET` request is shown next. You can also verify the result by using a browser to navigate to **http://httpbin.org/get**. This value was assigned to the `url` variable in the **beta** stage. The two responses are identical. 

1. In the **Stages** navigation pane, choose the **prod** stage. Under **Stage details**, choose the copy icon to copy your API's invoke URL, and then enter your API's invoke URL in a web browser. This starts the **prod** stage `GET` request on the root resource of the API. 

1. The response you get from the **prod** stage `GET` request is shown next. You can verify the result by using a browser to navigate to **http://petstore-demo-endpoint.execute-api.com/petstore/pets**. This value was assigned to the `url` variable in the **prod** stage. The two responses are identical. 

## Pass stage-specific metadata into an HTTP backend


This procedure describes how to use a stage variable value in a query parameter expression to pass stage-specific metadata into an HTTP backend. We will use the `stageName` stage variable declared in the previous procedure.

**To pass stage-specific metadata into an HTTP backend**

1. In the **Resource** navigation pane, choose the **GET** method. 

   To add a query string parameter to the method's URL, choose the **Method request** tab, and then in the **Method request settings** section, choose **Edit**. 

1. Choose **URL query string parameters** and do the following:

   1. Choose **Add query string**.

   1. For **Name**, enter **stageName**.

   1. Keep **Required** and **Caching** turned off.

1. Choose **Save**.

1. Choose the **Integration request** tab, and then in the **Integration request settings** section, choose **Edit**.

1. For **Endpoint URL**, append **?stageName=\$1\$1stageVariables.stageName\$1** to the previously defined URL value, so the entire **Endpoint URL** is **http://\$1\$1stageVariables.url\$1?stageName=\$1\$1stageVariables.stageName\$1**.

1. Choose **Deploy API** and select the **beta** stage.

1. In the main navigation pane, choose **Stages**. In the **Stages** navigation pane, choose **beta**. Under **Stage details**, choose the copy icon to copy your API's invoke URL, and then enter your API's invoke URL in a web browser. 
**Note**  
 We use the beta stage here because the HTTP endpoint (as specified by the `url` variable "http://httpbin.org/get") accepts query parameter expressions and returns them as the `args` object in its response. 

1. You get the following response. Notice that `beta`, assigned to the `stageName` stage variable, is passed in the backend as the `stageName` argument. 

      
![\[Response from the API's GET method with an HTTP endpoint using the url stage variable.\]](http://docs.aws.amazon.com/apigateway/latest/developerguide/images/stageVariables-new-console-invoke-beta-stage-with-url-and-stageName-response.png)

## Invoke a Lambda function through an API with a stage variable


This procedure describes how to use a stage variable to call a Lambda function as a backend of your API. You use the `function` stage variable declared in [Invoke an HTTP endpoint through an API with a stage variable](#how-to-set-stage-variables-aws-console-http-endpoint).

 When setting a Lambda function as the value of a stage variable, use the function's local name, possibly including its alias or version specification, as in **HelloWorld**, **HelloWorld:1** or **HelloWorld:alpha**. Do not use the function's ARN (for example, **arn:aws:lambda:us-east-1:123456789012:function:HelloWorld**). The API Gateway console assumes the stage variable value for a Lambda function as the unqualified function name and expands the given stage variable into an ARN. 

**To invoke a Lambda function through an API with a stage variable**

1. Create a Lambda function named **HelloWorld** using the default Node.js runtime. The code must contain the following:

   ```
   export const handler = function(event, context, callback) {
       if (event.stageName)
           callback(null, 'Hello, World! I\'m calling from the ' + event.stageName + ' stage.');
       else
           callback(null, 'Hello, World! I\'m not sure where I\'m calling from...');
   };
   ```

   For more information on how to create a Lambda function, see [Getting started with the REST API console](getting-started-rest-new-console.md#getting-started-rest-new-console-create-function).

1. In the **Resources** pane, select **Create resource**, and then do the following:

   1. For **Resource path**, select **/**.

   1. For **Resource name**, enter **lambdav1**.

   1. Choose **Create resource**.

1. Choose the **/lambdav1** resource, and then choose **Create method**.

   Then, do the following:

   1. For **Method type**, select **GET**.

   1. For **Integration type**, select **Lambda function**.

   1. Keep **Lambda proxy integration** turned off.

   1. For **Lambda function**, enter `${stageVariables.function}`.  
![\[Create a GET method integrated with a Lambda function as specified by the function stage variable.\]](http://docs.aws.amazon.com/apigateway/latest/developerguide/images/stageVariables-new-console-create-lambda-get-method.png)
**Tip**  
When prompted with the **Add permission command**, copy the [add-permission](https://docs.aws.amazon.com/cli/latest/reference/lambda/add-permission.html) command. Run the command on each Lambda function that will be assigned to the `function` stage variable. For example, if the `$stageVariables.function` value is `HelloWorld`, run the following AWS CLI command:   

      ```
      aws lambda add-permission --function-name arn:aws:lambda:us-east-1:account-id:function:HelloWorld --source-arn arn:aws:execute-api:us-east-1:account-id:api-id/*/GET/lambdav1 --principal apigateway.amazonaws.com --statement-id statement-id-guid --action lambda:InvokeFunction
      ```
 Failing to do so results in a `500 Internal Server Error` response when invoking the method. Replace `${stageVariables.function}` with the Lambda function name that is assigned to the stage variable.   
   

![\[AWS CLI command to add permission to the Lambda function to be invoked by the method you created.\]](http://docs.aws.amazon.com/apigateway/latest/developerguide/images/stageVariables-new-console-add-permission-to-lambda-function.png)


   1. Choose **Create method**.

1. Deploy the API to both the **prod** and **beta** stages.

1. In the main navigation pane, choose **Stages**. In the **Stages** navigation pane, choose **beta**. Under **Stage details**, choose the copy icon to copy your API's invoke URL, and then enter your API's invoke URL in a web browser. Append **/lambdav1** to the URL before you press enter.

   You get the following response.

   ```
   "Hello, World! I'm not sure where I'm calling from..."
   ```

## Pass stage-specific metadata to a Lambda function through a stage variable


This procedure describes how to use a stage variable to pass stage-specific configuration metadata into a Lambda function. You create a `POST` method and an input mapping template to generate payload using the `stageName` stage variable you declared earlier.

**To pass stage-specific metadata to a Lambda function through a stage variable**

1. Choose the **/lambdav1** resource, and then choose **Create method**.

   Then, do the following:

   1. For **Method type**, select **POST**.

   1. For **Integration type**, select **Lambda function**.

   1. Keep **Lambda proxy integration** turned off.

   1. For **Lambda function**, enter `${stageVariables.function}`.

   1. When prompted with the **Add permission command**, copy the the [add-permission](https://docs.aws.amazon.com/cli/latest/reference/lambda/add-permission.html) command. Run the command on each Lambda function that will be assigned to the `function` stage variable.

   1. Choose **Create method**.

1. Choose the **Integration request** tab, and then in the **Integration request settings** section, choose **Edit**.

1. Choose **Mapping templates**, and then choose **Add mapping template**.

1. For **Content type**, enter **application/json**.

1. For **Template body**, enter the following template:

   ```
   #set($inputRoot = $input.path('$'))
   {
       "stageName" : "$stageVariables.stageName"
   }
   ```
**Note**  
 In a mapping template, a stage variable must be referenced within quotes (as in `"$stageVariables.stageName"` or `"${stageVariables.stageName}"`). In other places, it must be referenced without quotes (as in `${stageVariables.function}`). 

1. Choose **Save**.

1. Deploy the API to both the **beta** and **prod** stages.

1. To use a REST API client to pass stage-specific metadata, do the following:

   1. In the **Stages** navigation pane, choose **beta**. Under **Stage details**, choose the copy icon to copy your API's invoke URL, and then enter your API's invoke URL in the input field of a REST API client. Append **/lambdav1** before you submit your request.

      You get the following response.

      ```
      "Hello, World! I'm calling from the beta stage."
      ```

   1. In the **Stages** navigation pane, choose **prod**. Under **Stage details**, choose the copy icon to copy your API's invoke URL, and then enter your API's invoke URL in the input field of a REST API client. Append **/lambdav1** before you submit your request.

      You get the following response.

      ```
      "Hello, World! I'm calling from the prod stage."
      ```

1. To use the **Test** feature to pass stage-specific metadata, do the following:

   1. In the **Resources** navigation pane, choose the **Test** tab. You might need to choose the right arrow button to show the tab.

   1. For **function**, enter **HelloWorld**.

   1. For **stageName**, enter **beta**.

   1. Choose **Test**. You do not need to add a body to your `POST` request.

      You get the following response.

      ```
      "Hello, World! I'm calling from the beta stage."
      ```

   1. You can repeat the previous steps to test the **Prod** stage. For **stageName**, enter **Prod**.

      You get the following response.

      ```
      "Hello, World! I'm calling from the prod stage."
      ```

# API Gateway stage variables reference for REST APIs in API Gateway
Stage variables reference

 You can use API Gateway stage variables in the following cases.

## Parameter mapping expressions


A stage variable can be used in a parameter mapping expression for an API method's request or response header parameter, without any partial substitution. In the following example, the stage variable is referenced without the `$` and the enclosing `{...}`. 
+ `stageVariables.<variable_name>`

## Mapping templates


 A stage variable can be used anywhere in a mapping template, as shown in the following examples. 
+  `{ "name" : "$stageVariables.<variable_name>"}`
+ `{ "name" : "${stageVariables.<variable_name>}"}`

## HTTP integration URIs


A stage variable can be used as part of an HTTP integration URL, as shown in the following examples:
+ A full URI without protocol – `http://${stageVariables.<variable_name>}`
+ A full domain – `http://${stageVariables.<variable_name>}/resource/operation`
+ A subdomain – `http://${stageVariables.<variable_name>}.example.com/resource/operation`
+ A path – `http://example.com/${stageVariables.<variable_name>}/bar`
+ A query string – `http://example.com/foo?q=${stageVariables.<variable_name>}` 

## AWS integration URIs


 A stage variable can be used as part of AWS URI action or path components, as shown in the following example.
+ `arn:aws:apigateway:<region>:<service>:${stageVariables.<variable_name>}`

## AWS integration URIs (Lambda functions)


 A stage variable can be used in place of a Lambda function name, or version/alias, as shown in the following examples. 
+ `arn:aws:apigateway:<region>:lambda:path/2015-03-31/functions/arn:aws:lambda:<region>:<account_id>:function:${stageVariables.<function_variable_name>}/invocations`
+ `arn:aws:apigateway:<region>:lambda:path/2015-03-31/functions/arn:aws:lambda:<region>:<account_id>:function:<function_name>:${stageVariables.<version_variable_name>}/invocations`

**Note**  
To use a stage variable for a Lambda function, the function must be in the same account as the API. Stage variables don't support cross-account Lambda functions.

## Amazon Cognito user pool


A stage variable can be used in place of a Amazon Cognito user pool for a `COGNITO_USER_POOLS` authorizer.
+ `arn:aws:cognito-idp:<region>:<account_id>:userpool/${stageVariables.<variable_name>}`

## AWS integration credentials


 A stage variable can be used as part of AWS user/role credential ARN, as shown in the following example. 
+  `arn:aws:iam::<account_id>:${stageVariables.<variable_name>}` 