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

# TypeScript client

> Install @datalyr/client for typed access to every Datalyr API endpoint.

`@datalyr/client` is the official TypeScript client for the Datalyr API. It types every
endpoint from the OpenAPI contract: reads, metric queries, attribution, and the scoped
write API.

## Install

```bash theme={null}
npm install @datalyr/client
```

The package has zero runtime dependencies. It works in Node.js 18 or later and in
serverless runtimes.

## Quick start

```typescript theme={null}
import { createDatalyrClient } from "@datalyr/client";

const datalyr = createDatalyrClient({ apiKey: process.env.DATALYR_API_KEY });

// Reads — the path and the response are both typed.
const workspace = await datalyr.get("/workspace");
const funnel = await datalyr.get("/funnel", {
  query: { steps: "pageview,purchase" },
});

// Metric queries
const metrics = await datalyr.post("/metrics", {
  body: { metric_ids: ["visitors", "revenue"] },
});
```

## What the client handles for you

* **Auth.** Sends your key as a bearer token on every request.
* **Types.** The request parameters and the response shape for each path come from the
  published OpenAPI contract. A wrong parameter fails at compile time, not at runtime.
* **Retries.** Retries `429` and `503` responses, and it honors the `Retry-After`
  header. Every other error throws immediately with the response body attached.
* **Idempotency.** Pass an `Idempotency-Key` on create requests to make retries safe.
* **Rate-limit visibility.** Read `datalyr.rateLimit` after any request to see your
  remaining budget, and whether the limiter is degraded.

## Writes

Write endpoints need a named key with the matching scope. See
[API keys](/account/api-keys) for how to create one, and the
[API reference](/api-reference/index) for which scope each endpoint needs.

```typescript theme={null}
// Preview a rule change without applying it.
const preview = await datalyr.post("/rules", {
  body: { dry_run: true, rule: { /* ... */ } },
});
```

## Errors

The client throws `DatalyrApiError` with the status, the error `code`, and the parsed
body. A `403` with `code: "insufficient_scope"` names the scope your key is missing in
`requiredScope`.

## Source

The client is generated from the same OpenAPI file this reference is built from, so the
two cannot drift. The package lives in the Datalyr repository under
`packages/datalyr-api-client`.
