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

# SDK

> Use the @nemu-ai/sdk package for both OAuth flows, the user endpoint, and the REST API

The official SDK wraps both flows, manages tokens, and exposes the REST API as typed
resources.

## Install

<CodeGroup>
  ```bash npm theme={null}
  npm install @nemu-ai/sdk
  ```

  ```bash bun theme={null}
  bun add @nemu-ai/sdk
  ```
</CodeGroup>

## Two clients

<CardGroup cols={2}>
  <Card title="Nemu">
    The client credentials client. It fetches and caches a token from your `client_id` and
    `client_secret`. It acts as your own account.
  </Card>

  <Card title="NemuOAuth">
    The authorization code client. It builds the authorize URL, exchanges the code, and
    refreshes tokens. It acts as the user who approved access.
  </Card>
</CardGroup>

## Client credentials

```ts theme={null}
import { Nemu } from "@nemu-ai/sdk";

const nemu = new Nemu({
  client_id: process.env.nemu_client_id!,
  client_secret: process.env.nemu_client_secret!,
});

const account = await nemu.user.get();
const workspaces = await nemu.workspaces.list();
```

## Authorization code

```ts theme={null}
import { NemuOAuth } from "@nemu-ai/sdk";

const oauth = new NemuOAuth({
  client_id: process.env.nemu_client_id!,
  client_secret: process.env.nemu_client_secret!,
  redirect_uri: "https://your.app/callback",
});

const { url, code_verifier, state } = oauth.authorize_url({
  scopes: ["profile:read", "workspaces:read"],
  state: "a_random_value",
});

const nemu = await oauth.exchange_code({ code, code_verifier });
const user = await nemu.user.get();
```

Restore a session later with `from_tokens`, and persist rotated tokens with `on_refresh`.

```ts theme={null}
const nemu = oauth.from_tokens(saved_tokens, (tokens) => save(tokens));
```

## Options

Both clients accept the same options.

<ParamField body="client_id" type="string" required>
  Your application `client_id`.
</ParamField>

<ParamField body="client_secret" type="string" required>
  Your application `client_secret`.
</ParamField>

<ParamField body="redirect_uri" type="string">
  Required for `NemuOAuth`. Must match a registered redirect URI.
</ParamField>

<ParamField body="api_version" type="string">
  The dated API version to pin. Defaults to the latest version the SDK knows about.
</ParamField>

<ParamField body="base_url" type="string" default="https://platform.nemu.cc/api/v1">
  The versioned REST base.
</ParamField>

<ParamField body="timeout" type="number" default="30000">
  Request timeout in milliseconds.
</ParamField>

## The user resource

```ts theme={null}
const user = await nemu.user.get();
const same = await nemu.user.me();
```

`get` and `me` both return the user described in [Get the current user](/oauth/reference#get-the-current-user).

## Version helpers

```ts theme={null}
import { Nemu, ApiVersion, LATEST_API_VERSION } from "@nemu-ai/sdk";

const nemu = new Nemu({
  client_id: process.env.nemu_client_id!,
  client_secret: process.env.nemu_client_secret!,
  api_version: ApiVersion.V2026_07_14,
});

const info = await nemu.version();
console.log(LATEST_API_VERSION, info.supported);
```

## Working with resources

Resources return live entities you can act on directly.

```ts theme={null}
const workspace = await nemu.workspaces.create({ name: "prod" });
await workspace.update({ name: "production" });

const providers = await workspace.providers.list();
const members = await workspace.members.list();

await workspace.delete();
```

## Errors

The SDK throws typed errors so you can branch on the failure.

```ts theme={null}
import { NemuValidationError, NemuAuthError, NemuRateLimitError } from "@nemu-ai/sdk";

try {
  await nemu.workspaces.list();
} catch (err) {
  if (err instanceof NemuAuthError) reauthenticate();
  else if (err instanceof NemuRateLimitError) wait(err.retry_after);
  else if (err instanceof NemuValidationError) report(err.message);
  else throw err;
}
```

| Error                 | Raised on                                   |
| --------------------- | ------------------------------------------- |
| `NemuValidationError` | `400`, including an unsupported API version |
| `NemuAuthError`       | `401`                                       |
| `NemuPermissionError` | `403`                                       |
| `NemuNotFoundError`   | `404`                                       |
| `NemuRateLimitError`  | `429`, carries `retry_after`                |
| `NemuServerError`     | `500` and above                             |
| `NemuNetworkError`    | The request never completed                 |
