Define Custom HTTP Status Codes to be Returned by Amazon API Gateway

If using Lambda proxy integration, you can directly return the proper HTTP status codes & headers from your Lambda function:

return {
    statusCode: '400',
    body: JSON.stringify({ error: 'invalid input' }),
    headers: { 'Content-Type': 'application/json' }
};

If not using Lambda proxy integration, create response mappings in API Gateway as shown below. First, add all HTTP status codes you intend to use in Method Response:

Next, in Integration Response, map each HTTP status code to a Lambda error regex:

Next, ensure that your Lambda functions either throw an exception or call context.fail() with an error message that’ll match the Lambda error regex defined above. When an error message matches a regex, API Gateway will return the mapped status code.

return context.fail('Bad Request: Invalid Input');

If your error message contains newlines, change the regex to match for those as well — Bad Request(.|\n)*

NOTE — You must throw an exception or call context.fail() to trigger the regex matcher. returning error message or object, or calling context.succeed() with error message or object won’t work. Also note that if you’re using context.fail(), you must pass-in just an error message as an input parameter to it. Passing an error object or any other complex object won’t match the regex.

You can however, pass-in a stringified JSON object (error or otherwise) to context.fail(). If you do it this way, you can even include a status code in the error object & use a mapping template $input.path('$.errorMessage') in API Gateway as described here; or use this mapping template:

#set($context.responseOverride.status = $input.path('$.statusCode'))

ASIDE — If you’re looking to return redirection HTTP status codes to your callers (HTTP 301 302 etc), see this blog post from AWS — Redirection in a Serverless API with AWS Lambda and Amazon API Gateway.