← Blog

Claude API Integration With Existing SaaS Backend

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

Integrating Claude into an existing SaaS backend usually isn't about learning a new API — it's about fitting a new dependency into code that already has auth, billing, rate limits, and a request/response shape your frontend expects. The real work is deciding where Claude calls live in your stack, how you authenticate and meter them, and how you handle streaming and tool use without rewriting half your app.

This guide walks through the integration patterns that actually matter: calling Claude directly from your existing endpoints, putting a thin gateway in front of it, and the operational details (auth, retries, usage tracking, streaming) that separate a working prototype from a production feature.

Two integration paths

There are two realistic ways to add Claude to a backend you already run:

1. Direct integration — your backend calls Anthropic's API directly using an SDK or raw HTTPS requests. This is the fastest path for a single app with one API key and no per-customer billing requirements.

2. Gateway/proxy integration — your backend calls an intermediary service that holds the Anthropic credentials, applies key management, usage metering and rate limiting, and exposes a stable HTTPS endpoint to your app. This matters once you have multiple environments, multiple team members, or need per-customer usage data for billing.

If you're already running a SaaS with its own billing and multi-tenant auth, the gateway pattern tends to save time, because it gives you usage metadata and key rotation without building that layer yourself. This is the gap a service like SubToAPI fills — it turns Claude access into a standard HTTPS API with application keys (sub_live_...), streaming, tool use, and usage metadata you can attach to your existing billing logic.

Where the integration point lives

In most backends, the cleanest place to add Claude is a dedicated service module, not scattered calls inside controllers:

// services/claude.js
async function askClaude(messages, { stream = false } = {}) {
  const res = 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",
      max_tokens: 1024,
      messages,
      stream
    })
  });
  if (!res.ok) throw new Error(`Claude request failed: ${res.status}`);
  return res.json();
}

module.exports = { askClaude };

Your existing route just calls this module and handles the response like any other internal service call:

app.post("/api/support/reply-suggestion", async (req, res) => {
  const { ticketBody } = req.body;
  const result = await askClaude([
    { role: "user", content: `Draft a reply to this support ticket:\n${ticketBody}` }
  ]);
  res.json({ suggestion: result.content[0].text });
});

This isolates the Claude dependency so swapping models, adding retries, or changing providers later touches one file, not every route that happens to use AI.

Authentication and key management

If your SaaS already issues API keys or session tokens to customers, don't conflate those with your Claude credentials. Keep a single server-side key (or one per environment) and never expose it to the frontend. For teams with multiple developers and environments, a dashboard with per-environment keys and seat-based access control removes the need to pass a shared secret around in Slack. See /docs/quickstart for the exact header format and key setup.

Handling streaming inside an existing response cycle

Most SaaS backends serve JSON over REST, not SSE, so adding streaming responses requires a deliberate choice: proxy the stream through to the client, or buffer it server-side and return the final text. If your frontend already expects a single JSON payload, buffering is simpler and requires no client changes. If you want token-by-token UI updates, you'll need to proxy the stream — details and examples are in /docs/streaming.

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", max_tokens: 1024, messages, stream: true })
});

res.setHeader("Content-Type", "text/event-stream");
upstream.body.pipe(res);

Tool use with internal services

A common integration goal is letting Claude call your own internal functions — fetch an order, check inventory, update a record — rather than only generating text. This works the same way whether you're adding it to a new app or an existing backend: define the tool schema, send it with the request, and execute the matching function in your code when Claude requests it. The request/response contract for this is documented in /docs/tools, and the message format itself in /docs/messages.

Usage tracking and billing

If your SaaS charges per seat, per usage tier, or has metered AI features, you need per-request usage data (tokens in, tokens out) tied back to the customer or team that triggered the call. Build this into your Claude service module from day one — log usage fields from each response alongside the customer ID — rather than retrofitting it later. Plans like Solo, Team and Scale on /pricing already separate usage and seats, so if you're billing customers based on AI usage, mapping your own tiers to that model early avoids a painful migration.

Rollout checklist

Start with a feature flag around the Claude-powered endpoint so you can roll back to the previous behavior without a deploy if something goes wrong in production.

Questions

Do I need a gateway, or can I call Anthropic directly from my backend? Direct calls work fine for a single app with one credential and no per-customer billing needs. A gateway becomes useful once you need usage metadata, multiple keys, or team access control without building that infrastructure yourself.

How do I add streaming without breaking my existing REST API shape? Keep your current endpoint returning buffered JSON for existing clients, and add a separate streaming endpoint (SSE) for new UI that needs token-by-token updates. You don't have to convert everything at once.

How do I bill customers for Claude usage inside my existing plans? Log the usage object from every response against the customer or tenant ID that made the request, then map that to your billing tiers. Doing this from the first integration avoids retrofitting metering later.

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 →