Skip to Content
Installing the Recorder

Installing the Recorder

The recorder observes your API traffic and sends patterns to Stoney. Zero latency — all reporting is async.


Getting Your Token

  1. Go to Settings → Connections
  2. Enter your app name and environment
  3. Click Add app
  4. Copy the token (shown once)

Next.js

Create middleware.ts in your project root:

import { NextResponse } from "next/server"; import type { NextRequest } from "next/server"; const STONEY_TOKEN = process.env.STONEY_RECORDER_TOKEN; export function middleware(request: NextRequest) { const start = Date.now(); const response = NextResponse.next(); if (STONEY_TOKEN) { fetch("https://stoneydev.com/api/recorder/ingest", { method: "POST", headers: { "Authorization": `Bearer ${STONEY_TOKEN}`, "Content-Type": "application/json", }, body: JSON.stringify({ environment: process.env.NODE_ENV, observations: [{ method: request.method, pathPattern: request.nextUrl.pathname, statusCode: response.status, durationMs: Date.now() - start, }], }), }).catch(() => {}); } return response; } export const config = { matcher: "/api/:path*" };

Express

const STONEY_TOKEN = process.env.STONEY_RECORDER_TOKEN; app.use((req, res, next) => { const start = Date.now(); res.on("finish", () => { if (STONEY_TOKEN) { fetch("https://stoneydev.com/api/recorder/ingest", { method: "POST", headers: { "Authorization": `Bearer ${STONEY_TOKEN}`, "Content-Type": "application/json", }, body: JSON.stringify({ environment: process.env.NODE_ENV || "production", observations: [{ method: req.method, pathPattern: req.route?.path || req.path, statusCode: res.statusCode, durationMs: Date.now() - start, }], }), }).catch(() => {}); } }); next(); });

Fastify

const STONEY_TOKEN = process.env.STONEY_RECORDER_TOKEN; fastify.addHook("onResponse", (request, reply, done) => { if (STONEY_TOKEN) { fetch("https://stoneydev.com/api/recorder/ingest", { method: "POST", headers: { "Authorization": `Bearer ${STONEY_TOKEN}`, "Content-Type": "application/json", }, body: JSON.stringify({ environment: process.env.NODE_ENV || "production", observations: [{ method: request.method, pathPattern: request.url.split("?")[0], statusCode: reply.statusCode, durationMs: reply.elapsedTime, }], }), }).catch(() => {}); } done(); });

Hono

const STONEY_TOKEN = process.env.STONEY_RECORDER_TOKEN; app.use("*", async (c, next) => { const start = Date.now(); await next(); if (STONEY_TOKEN) { fetch("https://stoneydev.com/api/recorder/ingest", { method: "POST", headers: { "Authorization": `Bearer ${STONEY_TOKEN}`, "Content-Type": "application/json", }, body: JSON.stringify({ environment: process.env.NODE_ENV || "production", observations: [{ method: c.req.method, pathPattern: new URL(c.req.url).pathname, statusCode: c.res.status, durationMs: Date.now() - start, }], }), }).catch(() => {}); } });

Verifying Installation

After adding the middleware:

  1. Make a few API requests
  2. Check Settings → Connections
  3. Routes should appear within 30 seconds
Last updated on