Claude Function Calling with API Gateway: Build a Secure Serverless LLM Endpoint A developer detailed how to build a secure serverless endpoint for Claude function calling using AWS API Gateway and Lambda, contrasting it with simpler Lambda URLs. The post highlights the need for Lambda proxy integration to preserve JSON payloads and recommends Zod for type safety in TypeScript, positioning API Gateway as the production-grade choice for authentication, throttling, observability, and versioning. When Claude wants to run code, you need a webhook it can call. Most teams slam together a Lambda URL, but that skips critical security and versioning features. Learn how API Gateway + Lambda gives you a production‑grade, type‑safe bridge for Claude’s function calls. Claude or any large language model, LLM can generate a piece of JSON that describes “I want to call a function named addUser with these arguments”. function calling is the process where the model sends that JSON to a webhook – an HTTP endpoint you control – and you turn the JSON into real work e.g., a database write . Key terms name , email , etc. Claude expects the response to follow a tiny schema: { "status": "success", "result": { "userId": "1234" } } If the payload is malformed or the endpoint rejects the request, Claude will fall back to a generic answer, which defeats the purpose of function calling. In plain English:Claude is trying to hand you a note with a request. You need a reliable, secure mailbox the endpoint that can read the note, do the work, and hand back a reply Claude understands. A Lambda URL is tempting because it’s a single line of code: aws lambda add-permission … && aws lambda create-function-url-config … . It works for quick demos, but production systems need more than “just works”. | Feature | Lambda URL | API Gateway | |---|---|---| Authentication | Optional IAM auth only; no JWT support | Built‑in JWT authorizers Cognito, OIDC | Throttling | Global per‑account limit | Per‑stage, per‑method limits | Observability | CloudWatch logs only | Access logs, execution logs, metrics, tracing | Versioning | You must manage separate URLs per version | Stages dev, prod let you roll out safely | CORS cross‑origin | Manual header handling | Automatic CORS configuration | Timeout | 30 s max cannot be extended | Same, but you can set up retries and dead‑letter queues | When you create a REST API v1 in API Gateway without enabling Lambda proxy integration , API Gateway flattens the request body. Any nested object inside Claude’s arguments is stripped away, so the Lambda receives an empty {} . The model’s request silently disappears, and debugging becomes a nightmare. Fix: enable Lambda proxy integration or write a mapping template that preserves the JSON structure. Tip:Think of the non‑proxy mode as a mailroom that only forwards the envelope, not the letter inside. Proxy mode hands the whole envelope including the note to the kitchen. Type safety means the compiler will tell you when you mistype a field or pass the wrong shape to the AWS SDK. In TypeScript we can achieve that with Zod for runtime validation and the satisfies keyword for compile‑time guarantees. js // src/types.ts import { z } from "zod"; / Claude sends a function call with a name and an arguments object. We describe that shape with Zod so we can validate it at runtime. / export const ClaudeAddUserSchema = z.object { name: z.string , email: z.string .email , age: z.number .int .positive .optional , } ; / The full request body Claude will send. / export const ClaudeRequestSchema = z.object { function: z.literal "addUser" , arguments: ClaudeAddUserSchema, } ; / Export TypeScript types derived from the schemas. / export type ClaudeAddUser = z.infer