Claude Code and AWS API Gateway: Build an HTTP API with SAM, Auth Reviews, CORS, Logs, and Throttling
Build AWS API Gateway with Claude Code using SAM, CORS, logs, auth reviews, and throttling examples.
API Gateway is the front door of your public API
AWS API Gateway is the layer that receives public API requests and centralizes authentication, rate controls, logging, and backend integration. A browser, mobile app, partner system, or internal job calls one URL. API Gateway decides which route it is, whether it is allowed, how it should be logged, and which Lambda function, HTTP endpoint, or AWS service should receive it.
That definition matters when you use Claude Code. If the prompt only says “create an API,” Claude Code can produce a working Lambda and still miss the production concerns around the entrance: CORS, authorizers, request identifiers, throttling targets, stage names, and whether REST API or HTTP API is the correct product. The result looks fine in a demo and becomes painful when a frontend gets blocked by CORS or support cannot trace a failed request.
This article rebuilds the API Gateway topic as an implementation and review guide. It uses official AWS documentation as the source of truth, then shows a copy-paste AWS SAM sample for an HTTP API with Lambda integration, CORS, access logs, and throttling. It also gives Claude Code review prompts so the generated infrastructure is not just runnable, but easier to operate.
Pick the right API Gateway type first
API Gateway has three common shapes: REST APIs, HTTP APIs, and WebSocket APIs. AWS describes API Gateway as a service for creating, deploying, and managing RESTful APIs and WebSocket APIs that expose HTTP backends, Lambda functions, or other AWS services.
| Type | Best fit | Practical decision rule |
|---|---|---|
| HTTP API | JSON APIs for SPAs, mobile apps, and Lambda or HTTP integrations | Start here when you need lower cost, lower latency, JWT auth, CORS, logs, and straightforward routes |
| REST API | Feature-rich API management | Choose it when you need API keys, usage plans, per-client throttling, request validation, AWS WAF, private endpoints, or canary deployments |
| WebSocket API | Two-way communication | Use it for chat, notifications, live progress, or server-pushed events |
AWS notes that REST APIs support more features, while HTTP APIs are designed with a smaller feature set so they can be offered at a lower price. That is the core tradeoff. Many application teams should start with HTTP APIs and move to REST APIs only when the missing management features are explicit requirements.
Official references used for this article:
- Amazon API Gateway concepts
- Choose between REST APIs and HTTP APIs
- Overview of WebSocket APIs
- AWS SAM AWS::Serverless::HttpApi
Four use cases worth designing before code
The first use case is Lambda integration. A contact form, booking form, webhook receiver, or small admin API can expose an API Gateway route and send validated requests to Lambda. API Gateway owns the public URL and routing. Lambda owns business behavior. Keeping that boundary clear makes Claude Code reviews much sharper.
The second use case is CORS. If your frontend runs on https://example.com and your API is on an execute-api domain, browser security rules treat those as different origins. AWS documents that HTTP API CORS configuration can make API Gateway respond to preflight OPTIONS requests. It also warns that when CORS is configured for the API, API Gateway ignores CORS headers returned from the backend integration. So the reliable place to design CORS is API Gateway, not a scattered set of Lambda responses.
The third use case is JWT or IAM authorization. For user-facing APIs, a JWT authorizer can validate tokens from Cognito or another OIDC provider. API Gateway checks issuer, audience, expiry, and optional scopes before the request reaches Lambda. For AWS-to-AWS calls, IAM authorization requires SigV4-signed requests and execute-api permission. A Lambda authorizer remains useful when you must call a custom user database or enforce partner-specific rules.
The fourth use case is stage logging and throttling. HTTP API access logs can be written to CloudWatch Logs, and AWS recommends logging for all stages to improve security posture. Throttling protects your API from request spikes, but AWS describes throttles and quotas as best-effort targets rather than hard ceilings. Treat a 429 Too Many Requests response as a signal that clients need backoff, not as your only protection for downstream systems.
Copy-paste SAM sample
Create template.yaml.
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Claude Code Lab HTTP API sample with CORS, logs, throttling, and Lambda proxy
Parameters:
StageName:
Type: String
Default: Prod
AllowedOrigin:
Type: String
Default: https://example.com
Globals:
Function:
Runtime: nodejs20.x
Architectures:
- arm64
Timeout: 10
MemorySize: 256
Resources:
ApiAccessLogs:
Type: AWS::Logs::LogGroup
Properties:
RetentionInDays: 14
PublicHttpApi:
Type: AWS::Serverless::HttpApi
Properties:
StageName: !Ref StageName
CorsConfiguration:
AllowOrigins:
- !Ref AllowedOrigin
AllowHeaders:
- authorization
- content-type
- x-request-id
AllowMethods:
- GET
- POST
- OPTIONS
MaxAge: 300
AccessLogSettings:
DestinationArn: !GetAtt ApiAccessLogs.Arn
Format: '{"requestId":"$context.requestId","routeKey":"$context.routeKey","status":"$context.status","ip":"$context.identity.sourceIp","requestTime":"$context.requestTime","responseLength":"$context.responseLength"}'
DefaultRouteSettings:
ThrottlingBurstLimit: 20
ThrottlingRateLimit: 10
RouteSettings:
"POST /contacts":
ThrottlingBurstLimit: 5
ThrottlingRateLimit: 2
FailOnWarnings: true
HealthFunction:
Type: AWS::Serverless::Function
Properties:
Handler: src/handler.health
Events:
Health:
Type: HttpApi
Properties:
ApiId: !Ref PublicHttpApi
Path: /health
Method: GET
PayloadFormatVersion: "2.0"
ContactFunction:
Type: AWS::Serverless::Function
Properties:
Handler: src/handler.contact
Events:
Contact:
Type: HttpApi
Properties:
ApiId: !Ref PublicHttpApi
Path: /contacts
Method: POST
PayloadFormatVersion: "2.0"
TimeoutInMillis: 10000
Outputs:
ApiUrl:
Description: Invoke URL
Value: !Sub "https://${PublicHttpApi}.execute-api.${AWS::Region}.${AWS::URLSuffix}/${StageName}/"
Create package.json.
{
"type": "module",
"scripts": {
"check": "node --check src/handler.js"
}
}
Create src/handler.js.
const json = (statusCode, body) => ({
statusCode,
headers: {
"content-type": "application/json"
},
body: JSON.stringify(body)
});
export const health = async () => {
return json(200, {
ok: true,
service: "claude-code-api-gateway",
checkedAt: new Date().toISOString()
});
};
export const contact = async (event) => {
let payload;
try {
payload = JSON.parse(event.body ?? "{}");
} catch {
return json(400, { message: "Request body must be valid JSON." });
}
const name = String(payload.name ?? "").trim();
const email = String(payload.email ?? "").trim();
if (!name || !email.includes("@")) {
return json(422, {
message: "name and a valid email are required.",
requestId: event.requestContext?.requestId
});
}
return json(202, {
message: "accepted",
requestId: event.requestContext?.requestId,
received: { name, email }
});
};
Deploy and test it from Git Bash, macOS, or Linux.
npm run check
sam build
sam deploy --guided \
--stack-name clc-api-gateway-sample \
--parameter-overrides AllowedOrigin=https://example.com
API_URL=$(aws cloudformation describe-stacks \
--stack-name clc-api-gateway-sample \
--query "Stacks[0].Outputs[?OutputKey=='ApiUrl'].OutputValue" \
--output text)
curl "${API_URL}health"
curl -X POST "${API_URL}contacts" \
-H "content-type: application/json" \
-d '{"name":"Masa","email":"masa@example.com"}'
For Windows PowerShell, keep the URL handling explicit.
$apiUrl = aws cloudformation describe-stacks `
--stack-name clc-api-gateway-sample `
--query "Stacks[0].Outputs[?OutputKey=='ApiUrl'].OutputValue" `
--output text
curl.exe ($apiUrl + "health")
curl.exe -X POST ($apiUrl + "contacts") `
-H "content-type: application/json" `
-d "{\"name\":\"Masa\",\"email\":\"masa@example.com\"}"
Make authentication a review gate
The sample starts public so the infrastructure can be deployed and tested without an identity provider. Production should not stop there. Ask Claude Code to review whether every route has the right authorization model before the API is exposed.
JWT authorizers are a natural fit for user-facing APIs. They validate tokens at the API Gateway layer and can enforce scopes per route. That means the Lambda function receives a request only after the entrance has checked the token shape. The Lambda still performs business authorization, but it no longer needs to be the first line of token validation.
IAM authorization is better for AWS workloads, automation, and internal tools. When IAM authorization is enabled for an HTTP API route, clients must sign requests with SigV4 and have permission to invoke the route through execute-api. That is useful for batch jobs or administrative calls where you already trust AWS credentials more than browser tokens.
Lambda authorizers are the escape hatch. Use them for legacy user databases, partner contracts, IP restrictions, or complex entitlement checks. Do not choose them by default. They add latency, caching decisions, and another failure mode.
Use this prompt before deployment:
Review this AWS SAM template before production.
Check:
- routes that are still public
- whether JWT, IAM, or Lambda authorizer is the right model
- whether CORS allows only the intended frontend origin
- whether access logs include requestId, routeKey, status, IP, and time
- whether throttling values fit a contact-form workload
- whether Lambda validation and error responses are safe
- whether requirements such as API keys, usage plans, WAF, or private endpoints mean REST API is a better fit
Return concrete template changes, not general advice.
Common failure modes
The first failure is returning CORS headers only from Lambda. With HTTP API CORS configured, API Gateway handles preflight responses and may ignore backend CORS headers. Configure origins, allowed headers, methods, and credentials deliberately in the API layer.
The second failure is missing access logs. Lambda logs do not explain every 403, 404, or 429 that API Gateway can return before Lambda is invoked. Add access logs early and include request identifiers that support staff can search.
The third failure is treating throttling as a guaranteed hard cap. API Gateway throttling uses a token bucket model and excess requests can receive 429. Downstream protection still belongs in Lambda reserved concurrency, database limits, queueing, and client retry behavior.
The fourth failure is choosing HTTP API or REST API by habit. HTTP API is excellent for many Lambda-backed APIs. REST API is still the right product for API keys, per-client usage plans, request validation, WAF integration, private endpoints, and some advanced deployment controls.
How Claude Code fits the workflow
The strongest workflow is not “ask Claude Code to build everything.” Start with routes and product choice. Then generate the SAM template. Then add Lambda handlers. Then run a security and operations review. This keeps the conversation small enough for Claude Code to reason about the entrance layer instead of mixing UI, Lambda, IAM, and logging in one noisy prompt.
For adjacent topics, read Claude Code AWS Lambda Complete Guide, Claude Code AWS CloudWatch, and Claude Code AWS IAM Guide. If you want a structured path for teams, the training and materials page collects the practical review checklists behind these articles.
What Masa tested
Masa tested this pattern by separating the work into template review and handler review. The most useful findings were not syntax fixes. Claude Code caught that contact-form routes deserve stricter throttling than health checks, that access logs should include requestId and routeKey, and that public routes should be tracked as a deliberate temporary state. Starting with API Gateway boundaries made the later Lambda implementation simpler and reduced review noise.
Free PDF: Claude Code Cheatsheet
Enter your email and download the one-page Claude Code cheatsheet for commands, review habits, and safe workflows.
We handle your data with care and never send spam.
Level up your Claude Code workflow
Start with the free PDF, use Gumroad guides when you need repeatable workflows, and book consultation when rollout or revenue paths need human judgment.
About the Author
Masa
Engineer focused on practical Claude Code workflows. Runs claudecode-lab.com, a 10-language technical media site.
Related Posts
Claude Code Obsidian to CLAUDE.md Workflow: Stop Re-explaining Context
Turn Obsidian working notes into concise CLAUDE.md operating notes that make Claude Code sessions easier to resume.
Claude Code Revenue CTA Routing: Send Articles to PDF, Gumroad, and Consultation
A Claude Code workflow for routing article readers to the free PDF, Gumroad products, or consultation by intent.
Claude Code Team Handoff Rules: Review Evidence, Permissions, Rollback, and Revenue Paths
A practical Claude Code handoff format for team review, proof, permission rules, rollback, free PDF, Gumroad, and consultation paths.
Related Products
50 Battle-Tested Claude Code Prompt Templates
Copy, paste, ship. 50 production-ready prompts.
Use proven prompts for code review, refactoring, testing, documentation, debugging, architecture, and incident response.
The Complete Claude Code Setup & Configuration Guide
From install to team-ready workflow.
A practical guide to installation, CLAUDE.md, hooks, MCP servers, permissions, IDE setup, and CI/CD workflows.