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

# TypeScript SDK

> @elanotes/sdk — generated types plus a thin openapi-fetch client.

`@elanotes/sdk` is packaging of the HTTP contract, not a new surface.
Types come from `openapi-typescript` over
`contracts/openapi/elanotes.v1.json`. The client is `openapi-fetch`.

Not published to npm in v1. Workspace package: `packages/sdk`.
Browser-safe: no Node-only modules.

```bash theme={null}
pnpm --filter @elanotes/sdk build
```

## Create a client

```ts theme={null}
import { createElanotesClient, ElanotesError } from "@elanotes/sdk";

const client = createElanotesClient({
  baseUrl: "http://127.0.0.1:4000",
  token: process.env.ELA_API_TOKEN,
});

const { data } = await client.GET("/v1/search", {
  params: { query: { q: "Paddle" } },
});
```

`baseUrl` is the API origin (no `/v1` suffix). Production uses the same
client with `baseUrl: "https://api.elanotes.com"` and a bearer in `token`.
Writes get an automatic
`Idempotency-Key` (UUID) unless you set one. Failed responses throw
`ElanotesError` with `reason`, `hint`, `help`, `retryAfterSeconds`, and
`details`.

## VERSION\_MOVED

```ts theme={null}
try {
  await client.POST("/v1/notes/{note}:edit", {
    params: { path: { note: "hello" } },
    body: {
      version_id: stale,
      old_string: "Hello",
      new_string: "Hello again",
      agent_id: "sdk",
    },
  });
} catch (err) {
  if (err instanceof ElanotesError && err.reason === "VERSION_MOVED") {
    console.error(err.hint);
  }
}
```

Regenerate after an OpenAPI change: `node scripts/sdk-generate.mjs`.
Drift check: `node scripts/assert-sdk-current.mjs` (wired into
`pnpm verify`). The [Python SDK](/sdk-python) is generated from the
same spec.
