---
title: Analytics Engine
description: "Write event data points with env.NAME.writeDataPoint and read the latest back."
---

## Configuration

```jsonc
"analytics_engine_datasets": ["EVENTS"]
```

A dataset takes a bare name only. It has no id and needs no provisioning: it exists from its first `writeDataPoint`.

## Usage

```ts
export default {
  async fetch(request, env, ctx) {
    // The standard Workers call: returns nothing, and is not awaited.
    env.EVENTS.writeDataPoint({
      indexes: ["signup"],
      blobs: [request.headers.get("cf-ipcountry") ?? "unknown"],
      doubles: [1],
    });
    return new Response("recorded\n", { status: 202 });
  },
} satisfies ExportedHandler<Env>;
```

`writeDataPoint` is the Workers Analytics Engine call, so this code runs on Workers unchanged. Reading data back is where the two differ. On Workers you query a dataset with the separate SQL API; Sproutboat adds a `query()` method to the binding, so a handler can see what it wrote with no second API:

```ts
// Sproutboat only: this call does not exist on Workers.
const { count, rows } = await env.EVENTS.query({ limit: 50 });
// rows: [{ timestamp, indexes, blobs, doubles }], newest first
```

## Methods

| Method | Signature | Returns |
| --- | --- | --- |
| `writeDataPoint` | `({ indexes?, blobs?, doubles? })` | `void` |
| `query` | `({ limit? })` | `{ count, rows }`: the total number of data points, and the newest `limit` of them (default 20, at most 200). A Sproutboat addition. |
