Recipe: backend for frontend

Keeping the integration key on your server while a browser UI does the talking.

Server Integration key dev · https://api.dev.oprag.ai

Reach for this when the browser needs something an embed key cannot do — cross-project access, per-user authorisation, or your own rate limiting and logging in front of chat.

server/routes/ask.ts TypeScript
import { createClient, OpragError } from "@oprag/sdk";

const oprag = createClient({
  apiUrl: process.env.OPRAG_API_URL!,
  apiKey: process.env.OPRAG_SECRET_KEY!,
});

app.post("/api/ask", async (req, res) => {
  // Your auth, your rules — the integration key never leaves this process.
  const user = await requireUser(req);

  try {
    const answer = await oprag.chat.ask({
      question: req.body.question,
      // Return these to the client so the next turn keeps its context.
      sessionId: req.body.sessionId,
      conversationId: req.body.conversationId,
      visitorId: user.id,
    });

    if (answer.type === "lead_capture_prompt") {
      return res.json({ kind: "lead", prompt: answer.promptMessage, fields: answer.fields });
    }
    return res.json({ kind: "answer", answer: answer.answer, sources: answer.sources ?? [] });
  } catch (err) {
    if (err instanceof OpragError) {
      return res.status(err.status).json({ error: err.message });
    }
    throw err;
  }
});

If you do not need any of that, an embed key straight from the browser is fewer moving parts — see keys & security.

Ready to ship?

Get started free