Frameworks
Express.js
Input and output guard middleware for existing Express chat routes.
About 4 minutes hands-on
What this guide does not cover
- Assumes an existing Express app with a chat route. It is not an Express tutorial.
- Does not cover WebSocket or Server-Sent Event streaming, where the output guard needs to buffer before it can decide.
Step 1: Install
Terminal
npm install @soterai/core expressStep 2: Basic usage
Guard user input, call your LLM with safe text, then guard the model output:
TypeScript
1import express from "express";
2import { Soter } from "@soterai/core";
3
4const app = express();
5app.use(express.json());
6
7const soter = new Soter({
8 apiKey: process.env.SOTER_API_KEY,
9 projectId: process.env.SOTER_PROJECT_ID,
10});
11
12app.post("/chat", async (req, res) => {
13 const protection = await soter.protect({
14 input: req.body.message,
15 context: {
16 userId: req.user?.id,
17 sessionId: req.session?.id,
18 },
19 });
20
21 if (!protection.allowed) {
22 // 🛑 Blocked before LLM
23 return res.status(403).json({
24 blocked: true,
25 reason: protection.reason,
26 });
27 }
28
29 // ✅ Continue to LLM with safe text
30 const safeInput = protection.safeText ?? req.body.message;
31 const llmReply = await callLLM(safeInput);
32
33 // Guard model output
34 const output = await soter.guardOutput({ text: llmReply });
35
36 res.json({
37 reply: output.safeText ?? output.redactedText ?? llmReply,
38 blocked: !output.allowed,
39 });
40});Step 3: Use middleware (recommended)
Use built-in middleware from @soterai/core/express for cleaner code:
TypeScript
import { soterInputMiddleware, soterOutputMiddleware } from "@soterai/core/express";
app.post(
"/chat",
soterInputMiddleware({ apiKey: process.env.SOTER_API_KEY! }),
async (req, res) => {
const reply = await callLLM(req.body.message);
res.json({ reply });
},
);💡
req.soter.inputResult holds the full guard result for inspection.Example project
See examples/express-chatbot for a complete working example.