# Read raw events

> Read every event your sites collected, page by page, with an API key, for your own data tools.

Source: https://docs.bifrostorbit.com/insights/developers/raw-event-api/

The raw event API gives your own tools, such as a data warehouse, every page view and event a site collected. It comes with the Growth plan.

The same events can be read through [GraphQL](https://docs.bifrostorbit.com/insights/developers/graphql/), with the same keys.

## Make a key

An Admin opens **API keys** under **Developers**, selects **New API key** and ticks **Read events**. The key, starting with `ins_live_`, is shown once: copy it to your server or data tool. A key reads every site in your organisation. Remove a key under **API keys** to stop it at once. A key that may only send events gets `403` here. See [API keys](https://docs.bifrostorbit.com/insights/developers/api-keys/).

## Read events

```sh
curl "https://api.bifrostorbit.com/insights/v1/events?site=SITE_KEY&from=2026-10-01&to=2026-10-02" \
  -H "Authorization: Bearer ins_live_…"
```

| Parameter | What it does |
| --- | --- |
| `site` | The site's key, from **Install**. Required. |
| `from`, `to` | The period, as a date or a time, such as `2026-10-01` or `2026-10-01T09:00:00Z`. `from` counts, `to` doesn't. Without them, the last 24 hours. |
| `name` | Only events with this name, such as `Signed up`. Page views are named `pageview`. |
| `type` | `pageview` or `event`. |
| `limit` | Events per page, 100 by default and at most 1,000. |
| `cursor` | The `next` value from the page before. |

The answer lists events oldest first:

```json
{
  "data": [
    {
      "id": "6717…",
      "type": "event",
      "name": "Signed up",
      "at": "2026-10-01T09:14:03.000Z",
      "host": "northwilds.com",
      "path": "/pricing",
      "referrer": "google.com",
      "channel": "Search",
      "utm": {},
      "country": "DE",
      "device": "desktop",
      "browser": "Chrome",
      "os": "Windows",
      "properties": { "plan": "growth" },
      "revenue": 49,
      "currency": "EUR",
      "contentId": null,
      "label": null,
      "visit": "8c1f…"
    }
  ],
  "next": "MTcyNzc…"
}
```

When `next` isn't `null`, ask again with `cursor` set to it, and the same other parameters, until it is. Events that belong to one visit share a `visit`. No visitor is identified: there is no visitor id, address or browser string in the answer. With known users switched on, events your website sent with a user id carry `person`: a scrambled form of the id made with your organisation's own key, the same for every event of that person. The id itself is never stored, so it isn't in the answer.

## Limits and errors

Each key may make 60 requests a minute. Errors answer with `{ "error": { "code", "message" } }`:

| Status | When |
| --- | --- |
| 400 | A date, `type` or `cursor` isn't valid. |
| 401 | The key is missing, wrong or removed. |
| 403 | The key may only send events (`wrong_scope`), or your organisation's plan doesn't include the API (`not_in_plan`). |
| 404 | No site with that key in your organisation. |
| 429 | Too many requests. Wait a minute. |

The newest events can take a few seconds to show up.
