Stop 14 · Payments & Third-Party IntegrationsTopics · 6/6

AI API Integration

Part of the Full Stack Developer Roadmap

In short

A 'summarise this' button or chat feature is now a backend task: call an LLM with your key, stream the words back as they're generated, and protect your bill from abuse.

Adding AI-powered features (chat, summarization, generation) by calling an LLM provider's API from your backend and streaming results to your frontend.

The blob character sits on a stool holding a vintage transistor radio to one ear, smiling.

Think of it like this

Live commentary, not tomorrow's paper

You can wait for tomorrow's newspaper to read the match report, or listen to the radio and hear every ball as it happens. LLMs can reply both ways. Streaming is the radio: words reach the user as they're generated, so even a long answer feels quick.

Watch it happen

Streaming an answer to the browser

Browser
Your API
LLM API

POST /api/chat

1/6The user sends a question. Only the conversation text goes to your API.

The big ideas

What you need to know

Never call it from the browser

The API key must stay on your server. A key in frontend code can be found and used to run up a huge bill.

Stream long answers

Streaming shows the first words almost at once instead of a long blank wait for the full reply.

Limit and log usage

Rate limit per user, cap max_tokens, and record token usage so one user can't drain your budget.

Treat output as untrusted

Render model output as text or sanitised Markdown, and validate it before using it in code or SQL.

See it in code

Walk through the code

ts
1import Anthropic from "@anthropic-ai/sdk";2const client = new Anthropic(); // reads ANTHROPIC_API_KEY from the environment3 4app.post("/api/chat", requireUser, rateLimit({ perDay: 50 }), async (req, res) => {5  res.setHeader("Content-Type", "text/plain; charset=utf-8");6  const stream = client.messages.stream({7    model: "claude-opus-5-5",8    max_tokens: 2048,9    messages: req.body.messages, // [{ role: "user", content: "..." }]10  });11  stream.on("text", (text) => res.write(text));12  const final = await stream.finalMessage();13  await logUsage(req.user.id, final.usage);14  res.end();15});

1/4The SDK reads the key from an environment variable on the server.

On the frontend, read the reply with res.body.getReader() and append each decoded chunk to the message. rateLimit and logUsage are your own helpers.

Save yourself the pain

Common mistakes

Oops

Trusting the client to send the whole prompt, including your own instructions.

Do this instead

Build the prompt on the server. Accept only the user's text and add your instructions there.

Oops

Waiting for the full reply before sending anything to the browser.

Do this instead

Stream it. Users see progress immediately, and long replies won't run into request timeouts.

Your mission

A streaming 'ask me' box

~40 min

Quick check

Where should the LLM API key live in a full stack app?

Go deeper

  1. 1Call an LLM API from your backend and return the result to your frontend.
  2. 2Implement streaming so responses appear incrementally instead of all at once.
  3. 3Keep your API key on the backend only — never expose it in frontend code.

More topics at this stop

Stuck on this topic? Ask an Insider

Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.

Download
InsideEdge