# Track events from your backend

27 Oct 2026 · Install & API · https://highseat.com/changelog/highseat-server

`route.ts`
```
import { track } from "highseat/server"

export async function POST(request: Request) {
  const user = await createAccount(request)
  track("signup", { plan: "pro" }, { request, userId: user.id })
  return Response.json(user)
}
```

`highseat/server` records events from your own code: a server action, a route handler, a webhook handler or a job. An event that never reaches the browser now reaches your dashboard, and an ad blocker can't stop it.

`track()` takes the same names and properties as in the browser, typed the same way. Pass the request you are handling, and the event gets the visitor's country and device from it. Pass a `userId` and it counts as that user.

Set `HIGHSEAT_SITE` and `HIGHSEAT_SECRET` from your site's Installation settings on the server. `track()` returns at once and never throws. Events go out in batches, retry on their own, and carry an id, so a retried batch is stored once. In a serverless function, pass `waitUntil` so the send outlives the response.

Update the `highseat` package to 0.5.0 or later to get it.

**Improvements**

- `beforeSend` changes or drops each event in the browser before the tracker sends it. Return `null` to drop one.
- The tracker no longer measures scroll depth, which no report read, so it's lighter on every page and down to 2,894 bytes gzipped.
- Goals and the Events card count people by user id, as funnels do, so one person on two devices counts once.

**Fixes**

- The query parameters to keep setting is gone. Only the raw export read those values, so Highseat now drops every query string.
