I managed to do it after a long mess. Here's a walkthrough:
I assume you have the Gateway and Lambda APIs. If not, here is a good guide . You need parts-1 and part-2. You can skip the end of Part 2 by clicking the recently entered "Enable CORS" button in the API Gateway
Go to the API.
Press here:

Press here:

Then expand Body Mapping Templates , enter application/json as the content type, click the Add button, then select a mapping template, click Edit

And paste the following content into the Mapping Pattern:
{ "body" : $input.json('$'), "headers": { #foreach($param in $input.params().header.keySet()) "$param": "$util.escapeJavaScript($input.params().header.get($param))" #if($foreach.hasNext),#end #end }, "stage" : "$context.stage" }
Then click the "Deploy API" button (this is important for the changes in the API to take effect)
You can check by changing the Lambda function to this:
var AWS = require('aws-sdk'); var DOC = require('dynamodb-doc'); var dynamo = new DOC.DynamoDB(); exports.handler = function(event, context) { var currentStage = event['stage']; if (true || !currentStage) {
Then call your endpoint. You should have an HTTP 200 response with the following response body:
{"errorMessage":"Cannot find currentStage. stage is:development"}
Important Note:
If you have a Body Mapping Template that is too simple, for example: {"stage" : "$context.stage"} , this will override the parameters in the request. Therefore, the body and headers keys are present in the Body Mapping Template . If this is not the case, your Lambda does not have access to it.