Claude API Serverless Function Example (AWS Lambda & Vercel)
If you're looking for a Claude API serverless function example, you want working code you can drop into Lambda or a Vercel function and adapt — not a theoretical overview. Below are two complete examples: one for AWS Lambda (Node.js runtime) and one for a Vercel serverless function, both calling Claude to generate a response from a prompt and returning JSON.
The short answer to "how do I call Claude from a serverless function": make an HTTPS POST request to the Messages API (or a compatible endpoint), handle the response inside your handler, and return it to the caller. The tricky parts are not the request itself — it's managing API keys securely, handling cold starts, respecting function timeout limits, and deciding whether streaming makes sense in a request/response serverless model at all. We cover each of those below.
AWS Lambda example (Node.js)
This handler accepts a prompt via the event body and returns Claude's response. It uses the native fetch available in Node 18+ Lambda runtimes, so no extra HTTP library is needed.
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: {
"x-api-key": process.env.ANTHROPIC_API_KEY,
"anthropic-version": "2023-06-01",
"content-type": "application/json",
},
body: JSON.stringify({
model: "claude-sonnet-4-5",
max_tokens: 1024,
messages: [{ role: "user", content: prompt }],
}),
});
const data = await response.json();
return {
statusCode: 200,
body: JSON.stringify({ reply: data.content?.[0]?.text }),
};
};
Set ANTHROPIC_API_KEY as a Lambda environment variable, not hardcoded. Set the function timeout to at least 30 seconds — Claude responses for longer generations can take more time than Lambda's default 3-second timeout allows.
Vercel serverless function example
Vercel functions follow a similar pattern but use the standard Request/Response objects:
export const config = { runtime: "edge" };
export default async function handler(req) {
const { prompt } = await req.json();
const res = await fetch("https://api.anthropic.com/v1/messages", {
method: "POST",
headers: {
"x-api-key": process.env.ANTHROPIC_API_KEY,
"anthropic-version": "2023-06-01",
"content-type": "application/json",
},
body: JSON.stringify({
model: "claude-sonnet-4-5",
max_tokens: 1024,
messages: [{ role: "user", content: prompt }],
}),
});
const data = await res.json();
return new Response(JSON.stringify({ reply: data.content?.[0]?.text }), {
headers: { "content-type": "application/json" },
});
}
Edge functions have shorter execution windows than Node-based serverless functions, so this pattern works best for shorter prompts and lower max_tokens values. For longer generations, use a standard Node.js serverless function instead of the edge runtime.
Cold starts and timeouts
Two constraints shape how you should build this:
- Cold starts. Serverless functions spin down when idle. The first request after idle time pays a startup penalty — typically 100–500ms for Node runtimes, more if you're bundling large dependencies. Keep your handler's dependency footprint minimal; the two examples above use only
fetch, which avoids pulling in a full SDK. - Execution timeouts. Lambda defaults to 3 seconds but can be configured up to 15 minutes. Vercel functions have provider-specific limits depending on your plan. Claude responses with large
max_tokensor complex reasoning can take 10–30+ seconds, so set your timeout accordingly, and consider loweringmax_tokensif you need faster turnaround for synchronous calls.
Streaming in a serverless context
Streaming responses token-by-token works well in long-lived connections (like a Node Express server or WebSocket), but serverless functions are request/response by design, and many platforms buffer the full response before returning it to the client. If your use case needs live streaming to a browser, you'll want a runtime that supports streaming responses natively (Vercel Edge functions support this via ReadableStream), or you should handle streaming on a separate layer rather than inside a short-lived Lambda invocation.
Where SubToAPI fits in
Managing raw Anthropic API keys across multiple serverless functions and environments gets messy fast — rotating keys, tracking per-function usage, and giving teammates separate credentials usually means building your own key-management layer on top of the API. SubToAPI turns your existing Claude access into application-scoped keys (sub_live_...) you can issue per function, per environment, or per team member, with usage metadata and streaming support built in.
A Lambda handler using SubToAPI instead of a raw key looks almost identical — just swap the endpoint and auth header:
const response = await fetch("https://api.subtoapi.app/v1/messages", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.SUBTOAPI_KEY}`,
"content-type": "application/json",
},
body: JSON.stringify({
model: "claude-sonnet-4-5",
max_tokens: 1024,
messages: [{ role: "user", content: prompt }],
}),
});
This gives you a separate key per Lambda function or per environment (staging, production), so a leaked key in one function's logs doesn't compromise your entire account. See the quickstart and Messages API docs for the full request/response shape, and the streaming docs if you're building a non-serverless layer that needs token-by-token output.
Practical checklist for production
- Store your API key in environment variables, never in source code
- Set function timeouts to at least 30 seconds for typical Claude calls
- Keep bundle size small to minimize cold start latency
- Avoid streaming inside short-lived serverless invocations unless your runtime explicitly supports it
- Separate keys per function/environment if you're using SubToAPI — compare plans on the pricing page
questions
Can I stream Claude responses from an AWS Lambda function? Lambda can technically support streaming via Function URLs with InvokeMode: RESPONSE_STREAM, but it adds complexity. For most use cases, return the full response and handle streaming on a different layer, like an Express server or Edge function.
What timeout should I set for a Claude API serverless function? Start at 30 seconds and increase if you use large max_tokens values or complex prompts. Lambda supports up to 15 minutes; check your platform's specific limits before going higher.
Do I need the Anthropic SDK in a serverless function, or can I just use fetch? Native fetch is sufficient and keeps your bundle small, which reduces cold start time. The SDK adds convenience but isn't required for simple request/response calls like the examples above.