← Blog

How to Deploy the Claude API on Serverless Functions

2026-11-03 · 5 min read · SubToAPI Team

Deploying the Claude API on serverless functions means wrapping your API calls in a stateless handler — an AWS Lambda function, a Vercel Edge Function, a Cloudflare Worker, or a Google Cloud Function — so you never run a persistent server. The function receives a request, calls Claude, and returns a response, scaling automatically from zero to thousands of concurrent invocations without you provisioning anything.

The short answer: pick a runtime that supports streaming responses (or accept buffered responses on platforms that don't), store your API key as an encrypted environment variable, set your function timeout above Claude's typical response time, and handle retries for rate limits. The rest of this guide walks through the specifics for each major platform and the gotchas that trip people up.

Why Serverless Fits Claude API Workloads

Claude API calls are I/O-bound — your function spends most of its time waiting on a network response, not burning CPU. That's exactly the profile serverless platforms are built for:

The tradeoff is execution limits. Lambda caps functions at 15 minutes (but your API gateway timeout is usually much shorter), Vercel Edge Functions have stricter CPU limits, and cold starts add latency on the first request after idle periods. None of this is a dealbreaker for Claude, but it shapes how you architect the function.

Step 1: Choose Your Runtime

AWS Lambda is the most flexible — full Node.js or Python runtime, generous memory configuration, and native integration with API Gateway or Lambda Function URLs. Best if you need background processing or complex orchestration around the Claude call.

Vercel Functions / Edge Functions are the easiest if you're already deploying a Next.js app. Edge Functions run close to the user and support streaming natively, but have a smaller runtime (no full Node APIs).

Cloudflare Workers have the fastest cold starts (effectively none) and the best global distribution, but the V8 isolate model means no native Node modules unless you're using compatible polyfills.

For most teams, Vercel or Cloudflare is the right starting point if the function is request/response; Lambda is better if you need queues, retries, or longer processing chains.

Step 2: Store Your API Key Securely

Never hardcode an API key in your function source. Use the platform's secret manager:

# AWS Lambda
aws lambda update-function-configuration \
  --function-name claude-proxy \
  --environment "Variables={API_KEY=sk-...}"

# Vercel
vercel env add API_KEY

# Cloudflare Workers
wrangler secret put API_KEY

If multiple applications or team members need access, a single raw key becomes a liability — anyone who sees the environment variable has full account access. This is one reason teams put a layer like SubToAPI in front of their Claude access: it issues scoped sub_live_... keys per application, so a serverless function compromise doesn't expose your whole Claude account, and you can see exactly which function is burning tokens from the dashboard.

Step 3: Write the Handler

A minimal Lambda handler using Node.js:

export const handler = async (event) => {
  const body = JSON.parse(event.body);

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

  const data = await response.json();

  return {
    statusCode: 200,
    body: JSON.stringify(data),
  };
};

This works, but it buffers the full response before returning — fine for short answers, painful for long ones where the user stares at a spinner for 10+ seconds.

Step 4: Handle Streaming Correctly

Streaming is where serverless platforms diverge most. Lambda via Function URLs now supports response streaming, Vercel Edge Functions stream natively through the Web Streams API, and Cloudflare Workers do the same. The pattern is to pipe the upstream SSE stream directly to the client rather than buffering it:

export default async function handler(req) {
  const upstream = 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,
      stream: true,
      messages: [{ role: "user", content: "Summarize this ticket." }],
    }),
  });

  return new Response(upstream.body, {
    headers: { "content-type": "text/event-stream" },
  });
}

This example calls SubToAPI's HTTPS endpoint instead of the raw Anthropic API — functionally identical request/response shape, but it means your serverless function authenticates with a revocable sub_live_ key rather than your root Anthropic key, and you get per-key usage metadata without building that tracking yourself. See /docs/streaming for the full event format.

Step 5: Handle Timeouts and Retries

Claude API calls occasionally hit rate limits (HTTP 429) or take longer than expected. Build retry logic with exponential backoff into the handler itself — serverless platforms won't retry for you:

async function callWithRetry(fn, attempts = 3) {
  for (let i = 0; i < attempts; i++) {
    try {
      return await fn();
    } catch (err) {
      if (i === attempts - 1) throw err;
      await new Promise((r) => setTimeout(r, 500 * 2 ** i));
    }
  }
}

Also set your function's timeout explicitly higher than your expected max_tokens generation time — a 30-second default timeout will kill long responses mid-stream.

Step 6: Monitor and Control Cost

Serverless scaling is a double-edged sword: a bug that causes retry loops can also scale cost quickly. Add basic guardrails — cap max_tokens, log every request's token usage, and set a budget alert. If you're running multiple functions or environments (staging, production, per-customer), a dashboard that shows usage per API key saves you from digging through CloudWatch or Worker logs to find which deployment caused a spike. Teams using SubToAPI get this out of the box per key; otherwise you'll want to log usage fields from every response yourself.

Quick Checklist

What's the biggest risk when deploying Claude API on serverless functions?

Unbounded cost from retry loops or runaway concurrency. A bug that triggers thousands of invocations per minute will hit your Claude rate limits and your cloud bill simultaneously. Cap max_tokens, add circuit breakers, and monitor per-key usage.

Can I stream Claude responses from AWS Lambda?

Yes, using Lambda Function URLs with response streaming enabled, or by fronting Lambda with an API Gateway that supports chunked transfer. Vercel Edge and Cloudflare Workers support streaming more simply if your app doesn't need Lambda's other features.

Do I need a backend server if I use serverless functions for Claude?

No — that's the point. The serverless function is the backend. You still need somewhere to store secrets and track usage, which is why many teams put a managed layer like SubToAPI in front: start with the free trial at signup, check /pricing, and see request/response shapes in /docs/quickstart.

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 →