# @restlessai/sdk

> Capture API traffic and send it to Restless. Works with Express, Fastify, Koa, Hono, Next.js, and the bare Node http server. Runs on Node, Bun, and Deno.

Latest version **0.4.2** (published 2026-08-26) · MIT license · 0 weekly downloads

## Install

```sh
npm install @restlessai/sdk
pnpm add @restlessai/sdk
yarn add @restlessai/sdk
bun add @restlessai/sdk
```

## Health

**Score 70/100 (B)** — status: active.

Positive: has types; esm support; no vulnerabilities; recently updated; high maintenance score; high quality score.

Warnings: low downloads; pre 1.0.

## Facts

| | |
|---|---|
| Version | 0.4.2 |
| Published | 2026-08-26 |
| First published | 2026-04-22 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Node | >=18 |
| Dependencies | 0 |
| Unpacked size | 4.1 MB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Author | Restless |
| Maintainers | gkoberger, mjcuva |
| Keywords | restless, metrics, api, logging, observability, express, fastify, koa, hono, nextjs |

## Links

- npm: https://www.npmjs.com/package/@restlessai/sdk
- Repository: https://github.com/restlesshq/node
- Homepage: https://restless.ai
- Issues: https://github.com/restlesshq/node/issues
- npm.io page: https://npm.io/package/@restlessai/sdk

## Alternatives

- [cli-color](https://npm.io/package/cli-color.md) — 3.4M weekly downloads
- [log](https://npm.io/package/log.md) — 1.3M weekly downloads
- [logstash-client](https://npm.io/package/logstash-client.md) — 4.5K weekly downloads
- [@nocobase/plugin-logger](https://npm.io/package/@nocobase/plugin-logger.md) — 2.0K weekly downloads
- [child-process-debug](https://npm.io/package/child-process-debug.md) — 695 weekly downloads

## Recent versions

- 0.4.2 (latest) — 2026-08-26
- 0.4.1 — 2026-08-07
- 0.4.0 — 2026-07-22
- 0.3.8 — 2026-05-21
- 0.3.7 — 2026-05-12
- 0.3.6 — 2026-05-02
- 0.3.5 — 2026-04-28
- 0.3.4 — 2026-04-26
- 0.3.3 — 2026-04-23
- 0.3.2 — 2026-04-22
- 0.3.1 — 2026-04-22
- 0.3.0 — 2026-04-22
- 0.1.1 — 2026-04-22
- 0.1.0 — 2026-04-22

## README

<picture>
  <source media="(prefers-color-scheme: dark)" srcset="docs/restless-init-dark.svg">
  <img width="100%" src="docs/restless-init.svg" alt="Restless">
</picture>

Run in your codebase to get started:

```sh
npx restless init
```

This scans your project, figures out your framework, generates an OpenAPI spec, and automatically wires the SDK into your server.

# @restlessai/sdk

Capture your API traffic and send it to [Restless](https://restless.ai).

Supports **Express**, **Fastify**, **Koa**, **Hono**, **Next.js**, and bare Node `http`. Runs on Node 18+, Bun, and Deno.

## Manual installation

If you'd rather wire it up by hand:

```sh
npm install @restlessai/sdk
```

```js
const restless = require('@restlessai/sdk')(process.env.RESTLESS_KEY);

app.use(restless.setup((req) => ({
  apiKey: restless.mask(req.headers.authorization),
  owner: {
    // `id` is permanent and immutable. Pick a stable internal identifier
    // (workspace id, tenant uuid, user pk). Never an API key, email, or
    // anything else that can change for the same customer.
    id: /* this customer's stable, immutable internal id */,
    enrich: async (id) => {
      // Lazy-resolved: runs once per owner id, then cached.
      // Fill in with your own lookup (DB, JWT, API, etc.).
      //
      //   const workspace = await db.workspaces.findById(id);

      return {
        /*
          label: workspace.name,
          email: workspace.adminEmails,  // string or string[]
        */
      };
    },
  },
})));
```

Here's how to set it up for your framework:

| framework | registration                                                             |
| --------- | ------------------------------------------------------------------------ |
| Express   | `app.use(restless.setup(cb))` + `app.use(restless.errorHandler)` last    |
| Fastify   | `await fastify.register(restless.setup(cb))`                             |
| Koa       | `app.use(restless.setup(cb))`                                            |
| Hono      | `app.use(restless.setup(cb))`                                            |
| Next.js   | `withRestless(nextConfig)` + `restless.config.ts` — no per-route changes |
| http      | `http.createServer(restless.setup(cb)(myHandler))`                       |

Full per-framework examples are in [`install.md`](./install.md).

## What you get

- **One line of setup.** The factory returns a client; `setup(cb)` gives you framework-ready middleware back.
- **Lazy owner enrichment.** Expensive DB lookups for owner metadata (display name, contact emails, plan tier) run only on the first request from each owner id, then cache until the server asks for a refresh. 100 requests from the same workspace don't hit your database 100 times.
- **Safe by default.** Headers like `Authorization` / `Cookie` and body fields like `password` / `token` / `ssn` are redacted before anything leaves your server. The redaction list extends itself from your OpenAPI spec: the `npx restless init` flow scans your auth mechanisms and flags custom fields automatically.
- **Error-triage built in.** Every response gets an `x-log-url` header pointing at the captured log, and 4xx / 5xx responses also get a `debug` block in the JSON body so you can jump straight to it. If a customer attaches a "next steps" message to an error in the dashboard's Agent Recovery view, the SDK injects it into the response as `debug.recovery` — looked up sync from an in-process cache, never blocking the response on a network call.
- **Crashes are logged, and grouped by where they crashed.** A handler that throws still produces a log, and the exception's throw site (file + function, never line numbers) is what groups it - so the same bug stays one group in the dashboard no matter what the error message interpolates. The exception is always re-thrown untouched: your framework's error handling behaves exactly as it did without the SDK. **Express needs one extra line** for this, because Express only routes errors to middleware registered after your routes:

  ```js
  app.use(restless.setup(cb));
  app.use("/api", routes);
  app.use(restless.errorHandler); // ← after your routes
  ```

  Every other framework wires itself up. Without it, an Express crash still logs, it just groups by the text of your error response instead of by throw site.

- **Blocking.** Return `{ block: true }` from the setup callback to reject a request with a 403 before your handler runs. Blocked requests skip `enrich` entirely, so a banned tenant costs you no database lookups.

## Environment variables

| variable            | purpose                                                                                                                          |
| ------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `RESTLESS_KEY`      | Your project API key. Used if you don't pass one explicitly. Auto-loaded from `.env` (walking up from `cwd`) if not already set. |
| `RESTLESS_BASE_URL` | Override the metrics server URL (self-hosted / staging). `restless(key, { baseUrl })` takes precedence over it.                  |
| `DEBUG=restless`    | Print upload diagnostics to stderr.                                                                                              |

## Docs

- **[install.md](./install.md)**: comprehensive installation reference. Framework examples, option tables, every gotcha. Structured so both humans and AI coding assistants can follow it.
- **[docs/INTERNALS.md](./docs/INTERNALS.md)**: how batching, blocking, redaction, and request ID generation actually work.
- **[spec/](./spec/)**: the cross-language SDK contract. This package is the reference implementation for every Restless SDK; `spec/` holds the normative spec, generated conformance vectors, and a harness that runs them against an implementation in any language.

## License

MIT

---
_Source: https://npm.io/package/@restlessai/sdk · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
