IntegrationsExpress

Express Observability

Record Vouched KYA verdicts from the Express middleware

Overview

withCheckpoint reports every verdict to your dashboard when you set apiKey. To also keep verdicts in your own logs, metrics or database, record them from the onResult(result, req) callback. It runs after every verification, before the verdict is applied, and receives the engine's full VerifyResult.

Looking for createStorageAdapter, withSessionTracking or req.checkpoint? They were removed from @kya-os/checkpoint-express: the session tracker never started a session, and the storage adapters had no consumer in the package. Record verdicts from onResult and read them in routes from res.locals, as shown below.

For the full middleware reference (config options, response headers, response shape) covering Next.js, Express, and .NET, see Middleware Enforcement.

Record Verdicts

Write each verdict to whatever store you already use:

import express from 'express';
import { withCheckpoint } from '@kya-os/checkpoint-express';

const app = express();

app.use(
  withCheckpoint({
    apiKey: process.env.CHECKPOINT_API_KEY,
    onResult: async (result, req) => {
      await events.insert({
        decision: result.decision.kind,
        detectionClass: result.detectionDetail.detectionClass.type,
        agent: result.detectionDetail.detectedAgent?.name ?? null,
        confidence: result.detectionDetail.confidence,
        path: req.path,
        method: req.method,
        at: new Date().toISOString(),
      });
    },
  })
);

app.listen(3000);

Errors thrown inside onResult are swallowed so an observability failure can't break the verdict path. onResult is awaited before the response, so a slow write delays the request; hand slow writes to a queue.

Read the Verdict in a Route

withCheckpoint attaches nothing to req. To use the verdict in a route handler, keep it on res.locals, Express's per-request store, from onResult:

app.use(
  withCheckpoint({
    onResult: (result, req) => {
      if (req.res) req.res.locals.checkpoint = result;
    },
  })
);

app.get('/data', (req, res) => {
  const agent = res.locals.checkpoint?.detectionDetail.detectedAgent?.name;
  res.json({ data: 'your data here', agent: agent ?? null });
});

Response Headers

The engine path sets X-Checkpoint-* headers and a __checkpoint_verdict cookie (byte-identical to the Next.js sibling package). In observe mode it adds X-Checkpoint-Would-Have-Been.

Next Steps