← Blog

Claude API AWS Lambda Integration Example

2026-10-26 · 5 min read · SubToAPI Team

Running Claude behind an AWS Lambda function is one of the most common ways teams add AI features to an existing serverless backend without standing up a new server. This article walks through a working Claude API AWS Lambda integration example in Node.js, covers the gotchas specific to Lambda (timeouts, payload limits, no native streaming), and shows how to deploy it.

The short answer: you call the Claude Messages endpoint with a standard HTTPS POST from inside your handler, store the API key in an environment variable or Secrets Manager, set a function timeout that accounts for generation time, and avoid chunked streaming responses unless you're using a Lambda Function URL with response streaming enabled. Everything below expands on that.

Why Lambda + Claude is a common pattern

Lambda is a good fit for Claude calls when:

It's a poor fit if you need long-lived streaming to a browser over several minutes, or very high invocation volume where cold starts and concurrency limits start to matter — in those cases a small always-on container is often simpler.

Prerequisites

Storing the API key safely

Never hardcode the key in your function code. Two common options:

  1. Lambda environment variable, encrypted with a KMS key (default AWS managed key is fine for most teams).
  2. AWS Secrets Manager, fetched once per cold start and cached in memory for the life of the execution environment.

For most small-to-medium workloads, an encrypted environment variable is simpler and avoids an extra API call per cold start:

aws lambda update-function-configuration \
  --function-name claude-handler \
  --environment "Variables={CLAUDE_API_KEY=sk-ant-xxxxx}"

The Lambda handler

Here's a minimal handler that accepts a prompt via the event body and returns Claude's response. This example calls the model provider directly:

export const handler = async (event) => {
  const body = JSON.parse(event.body || "{}");
  const prompt = body.prompt || "Say hello.";

  const response = await fetch("https://api.anthropic.com/v1/messages", {
    method: "POST",
    headers: {
      "content-type": "application/json",
      "x-api-key": process.env.CLAUDE_API_KEY,
      "anthropic-version": "2023-06-01",
    },
    body: JSON.stringify({
      model: "claude-3-5-sonnet-20241022",
      max_tokens: 1024,
      messages: [{ role: "user", content: prompt }],
    }),
  });

  const data = await response.json();

  return {
    statusCode: response.status,
    headers: { "content-type": "application/json" },
    body: JSON.stringify(data),
  };
};

If you'd rather manage one API surface instead of juggling provider-specific headers and versioning, swap the URL and auth header for SubToAPI's endpoint — the rest of the handler stays identical:

const response = await fetch("https://api.subtoapi.app/v1/messages", {
  method: "POST",
  headers: {
    "content-type": "application/json",
    "Authorization": `Bearer ${process.env.SUBTOAPI_KEY}`,
  },
  body: JSON.stringify({
    model: "claude-3-5-sonnet-20241022",
    max_tokens: 1024,
    messages: [{ role: "user", content: prompt }],
  }),
});

Full request/response shape and parameters are documented at /docs/messages.

Timeout and payload considerations

Lambda has hard limits that matter when calling an LLM:

aws lambda update-function-configuration \
  --function-name claude-handler \
  --timeout 60 \
  --memory-size 512

Streaming in Lambda: what actually works

Classic API Gateway (REST or HTTP API) does not support streaming responses — it buffers the full Lambda response before returning it to the client. If you need token-by-token output, you have two realistic options:

  1. Lambda Function URLs with response streaming (InvokeMode: RESPONSE_STREAM), which lets you pipe chunks as they arrive from Claude's streaming endpoint directly to the client.
  2. Skip Lambda for the streaming leg and have the browser connect directly to a streaming-capable endpoint (SubToAPI supports Server-Sent Events — see /docs/streaming) while Lambda handles everything else: auth, logging, pre/post-processing.

For most CRUD-style AI features (classify this, summarize that, extract these fields), non-streaming is fine and dramatically simpler to debug in Lambda. Reserve streaming for interactive chat UIs.

Deploying it

A minimal AWS SAM template wires the function to an HTTP API:

Resources:
  ClaudeFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: index.handler
      Runtime: nodejs18.x
      Timeout: 60
      MemorySize: 512
      Environment:
        Variables:
          CLAUDE_API_KEY: !Ref ClaudeApiKey
      Events:
        Api:
          Type: HttpApi
          Properties:
            Path: /chat
            Method: POST

Deploy with sam build && sam deploy --guided. If you're using SubToAPI keys instead, just swap the environment variable name and the fetch target — no infrastructure changes needed.

Error handling and retries

Wrap the fetch call in a try/catch and check response.status explicitly — rate limits and transient 5xx errors are common enough in production that you should retry once with a short backoff before failing the invocation. Log the request ID from the response headers so you can correlate failures with provider-side logs. If you're routing through SubToAPI, the dashboard usage view gives you per-key error breakdowns without extra logging code — see /docs for setup details.

Questions

Does Lambda support streaming Claude responses to the client? Only via Function URLs with RESPONSE_STREAM invoke mode. Standard API Gateway integrations buffer the entire response, so streaming chat UIs usually bypass Lambda for that leg.

What timeout should I set for a Claude Lambda function? 30–60 seconds for typical completions. Base it on your max_tokens setting — larger outputs take proportionally longer to generate.

Should I call the provider API directly or through a gateway like SubToAPI? Calling directly works fine for a single key and simple use. A gateway makes sense once you need multiple keys, usage metadata per team/project, or want to avoid managing provider auth headers yourself — see /pricing and /signup to try it.

Turn your Claude access into an HTTPS API

SubToAPI gives you application API keys, streaming, tool use and usage insights on top of your existing Claude access — set up in minutes.

Start free  Read the quickstart →