> ## Documentation Index
> Fetch the complete documentation index at: https://docs.usesentinel.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Hono SDK

> Integrate Sentinel with your Hono application to automatically track API requests

## Installation

<CodeGroup>
  ```bash bun theme={null}
  bun add @usesentinel/hono
  ```

  ```bash npm theme={null}
  npm install @usesentinel/hono
  ```

  ```bash pnpm theme={null}
  pnpm add @usesentinel/hono
  ```
</CodeGroup>

## Basic usage

Simply add the middleware to your Hono app:

```typescript app.ts theme={null}
import { Hono } from "hono";
import { sentinel } from "@usesentinel/hono";

const app = new Hono();

app.use("*", sentinel()); // That's it!

app.get("/", (c) => {
  return c.text("Hello World");
});

export default app;
```

<Check>
  The middleware automatically tracks all incoming requests, captures
  request/response metadata, and sends events to Sentinel with minimal
  performance impact.
</Check>

## Configuration

The SDK automatically reads configuration from environment variables. You can also pass options directly to the middleware.

### Configuration options

You can pass configuration options directly when initializing the middleware:

```typescript app.ts theme={null}
app.use(
  "*",
  sentinel({
    apiKey: "sk_...", // Optional if SENTINEL_API_KEY is set
    batchSize: 50, // Optional, default 50
    flushInterval: 5000, // Optional, default 5000ms
    excludePaths: ["/health", "/metrics"], // Optional
  })
);
```

<ResponseField name="apiKey" type="string">
  Your Sentinel API key. Overrides the `SENTINEL_API_KEY` environment variable
  if provided.
</ResponseField>

<ResponseField name="batchSize" type="integer" default="50">
  Maximum number of events to batch before sending to the Sentinel API.
</ResponseField>

<ResponseField name="flushInterval" type="integer" default="5000">
  Time in milliseconds to wait before sending a batch of events, even if the
  batch size hasn't been reached.
</ResponseField>

<ResponseField name="excludePaths" type="string[]">
  Array of path patterns to exclude from tracking. If you specify
  `/v1/projects`, it will exclude all paths starting with that prefix (e.g.,
  `/v1/projects`, `/v1/projects/123`, `/v1/projects/123/tasks`).
</ResponseField>

## Tracking steps

Track sub-operations within a request to monitor database queries, external API calls, and other operations.

```typescript app.ts theme={null}
import { registerStep } from "@usesentinel/hono";

app.get("/users", async (c) => {
  const sentinel = c.get("sentinel");

  // Track a database query
  let endDbStep: (() => void) | undefined;
  if (sentinel) {
    endDbStep = registerStep(sentinel.requestId, "db_query", {
      table: "users",
      operation: "SELECT",
    });
  }
  const users = await db.query("SELECT * FROM users");
  endDbStep?.(); // Step completes here

  // Track an external API call
  let endApiStep: (() => void) | undefined;
  if (sentinel) {
    endApiStep = registerStep(sentinel.requestId, "external_api_call", {
      service: "payment_gateway",
    });
  }
  const payment = await fetch("https://api.payment.com/charge", {
    method: "POST",
    body: JSON.stringify({ amount: 100 }),
  });
  endApiStep?.();

  return c.json(users);
});
```

<Tip>
  Steps are automatically included in the event sent to Sentinel, allowing you
  to see which parts of your request took the longest. This helps identify
  performance bottlenecks.
</Tip>

## Setting user context

Identify users making requests by setting the `userId` for tracking user behavior:

```typescript app.ts theme={null}
import { setUserId } from "@usesentinel/hono";

app.get("/users", async (c) => {
  // Get user from your auth system
  const user = await getCurrentUser(c);

  // Identify the user making the request
  const sentinel = c.get("sentinel");
  if (sentinel) {
    setUserId(sentinel.requestId, user.id);
  }

  return c.json(users);
});
```

<Tip>
  The `userId` is automatically included in the event sent to Sentinel, enabling
  user-specific analytics and tracking.
</Tip>

## How it works

The middleware automatically handles the following:

* **Request tracking**: Captures all incoming requests and their metadata
* **Response capture**: Records response status codes and timing information
* **Event batching**: Groups events together to minimize API calls
* **Automatic retries**: Handles failures gracefully with exponential backoff (up to 3 retries by default)
* **Performance optimization**: Non-blocking event sending ensures minimal impact on your application

Events are batched and sent automatically in the background. Failed requests are automatically retried with exponential backoff, so your application flow is never interrupted.

<Warning>
  Ensure your `SENTINEL_API_KEY` environment variable is set in production.
  Without it, events will not be sent to Sentinel.
</Warning>

## Accessing Sentinel context

The middleware attaches a `sentinel` context to the Hono context, which you can access using `c.get("sentinel")`:

```typescript app.ts theme={null}
app.get("/example", (c) => {
  const sentinel = c.get("sentinel");
  // sentinel.requestId, sentinel.path, etc.
  return c.json({ requestId: sentinel?.requestId });
});
```

<Info>
  The `sentinel` context provides access to request metadata including
  `requestId`, `path`, and other tracking information throughout your request
  lifecycle.
</Info>
