> This page location: APIs & SDKs > SDKs > Neon Management SDK
> Full Neon documentation index: https://neon.com/docs/llms.txt

> Summary: @neon/sdk is the official TypeScript SDK for the Neon API, a modern, fetch-based replacement for @neondatabase/api-client. It exposes every platform resource through ergonomic namespaces on a single client (neon.projects, neon.branches, neon.postgres, neon.storage, neon.functions, neon.snapshots, neon.auth, and more), with one result contract, typed errors, automatic retries, readiness polling, and auto-pagination built in. A raw 1:1 layer exposes every endpoint and is generated from the Neon OpenAPI spec.

# Neon Management SDK

The official TypeScript SDK for the Neon API. Projects, branches, Postgres, storage, functions, and auth in one typed client.

**What you will learn:**

- The one result contract every method shares
- Which namespaces and methods exist
- How pagination and async workflows work

**Related resources**

- [Neon API Reference](https://neon.com/docs/reference/api)
- [Migrate from @neondatabase/api-client](https://neon.com/docs/reference/migrate-api-client-to-sdk)
- [Neon CLI](https://neon.com/docs/cli)
- [@neon/tools (agent tools)](https://github.com/neondatabase/neon-pkgs/tree/main/packages/tools)

**Source code**

- [@neon/sdk on npm](https://www.npmjs.com/package/@neon/sdk)
- [OpenAPI spec](https://neon.com/api_spec/release/v2.json)

`@neon/sdk` wraps the entire Neon API in one typed, fetch-based client. You authenticate once, then reach every resource through a namespace on `neon.*`: projects, branches, the Postgres data plane, object storage, functions, and Managed Better Auth. Retries, readiness polling, auto-pagination, and typed errors are built in.

It replaces [`@neondatabase/api-client`](https://www.npmjs.com/package/@neondatabase/api-client), the deprecated Axios-based SDK. New projects should use `@neon/sdk`. See the [migration guide](https://neon.com/docs/reference/migrate-api-client-to-sdk) for method mapping and error-handling changes.

**Building for agents?:**

[`@neon/tools`](https://github.com/neondatabase/neon-pkgs/tree/main/packages/tools) wraps this same client and publishes selected methods as typed agent tools, with adapters for MCP, Mastra, and Eve. Use it when a model drives the operations; use `@neon/sdk` when your own code does.

**Note: Not every endpoint has an ergonomic wrapper**

`createNeonClient` namespaces cover common workflows (projects, branches, Postgres resources, snapshots, and more). They do **not** wrap every Platform API operation. For endpoints without a namespace method, use the [`raw` layer](https://neon.com/docs/reference/typescript-sdk#raw-layer) below or the [Neon API Reference](https://neon.com/docs/reference/api).

```bash
npm install @neon/sdk
```

```ts
import { createNeonClient } from "@neon/sdk";

const neon = createNeonClient({ apiKey: process.env.NEON_API_KEY! });

const { data, error } = await neon.projects.list().all();
if (error) throw error; // typed NeonError
data; // ProjectListItem[]
```

Every method follows this shape: select a namespace, call a method, and receive a `{ data, error }` result. The reference below documents each namespace and method against that single contract.

Each method takes a **single named-parameter object**: the path selectors (`projectId`, `branchId`, and any resource id such as `roleName` or `slug`) and any input or query fields are merged into one flat object, followed by an optional trailing options argument (`{ throwOnError?, waitForReadiness?, signal? }`, omitted from the tables for brevity).

**Important: Named parameters in v5 and later**

`@neon/sdk` v5 replaced positional arguments with a single named-parameter object, and v6 is the current major. For example, `neon.branches.get(projectId, branchId)` is now `neon.branches.get({ projectId, branchId })`. If you're upgrading from v4, update your calls to the object form shown throughout this page. See [Upgrading from v4](https://neon.com/docs/reference/typescript-sdk#upgrading-from-v4).

In the reference tables, the **Returns** column names the resolved resource, the type of `data` on success (or the value returned directly when `throwOnError` is set). A method resolving to `void` has no resource body; [`Paginated`](https://neon.com/docs/reference/typescript-sdk#lazy-auto-paginated-lists)`<T>` is the lazy, auto-paginated list described below.

Nearly every method needs a `projectId`, and branch-scoped methods also need a `branchId`. Get these from `neon.projects.list()` and `neon.branches.list({ projectId })` (or `neon.branches.getDefault({ projectId })` for the default branch), reading `.id` off each result.

## Client configuration

`createNeonClient(config)` accepts:

| Option             | Type                                        | Default                            | Purpose                                                                                                      |
| ------------------ | ------------------------------------------- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| `apiKey`           | `string \| () => string \| Promise<string>` | required                           | Bearer credential. A function is called per request, for short-lived tokens                                  |
| `throwOnError`     | `boolean`                                   | `false`                            | Throw a `NeonError` instead of returning `{ data, error }`. Overridable per call                             |
| `waitForReadiness` | `boolean`                                   | `false`                            | Poll provisioning operations to completion before resolving. Overridable per call                            |
| `wait`             | `{ pollIntervalMs?, timeoutMs? }`           | `1000` / `300000`                  | Tuning for the readiness poller                                                                              |
| `retries`          | `number`                                    | `2`                                | Automatic retries on safe statuses (423, 429, 503)                                                           |
| `baseUrl`          | `string`                                    | `https://console.neon.tech/api/v2` | Override the API base URL                                                                                    |
| `fetch`            | `typeof fetch`                              | global `fetch`                     | Custom fetch, for proxies, tests, or non-global runtimes                                                     |
| `orgId`            | `string`                                    | none                               | Default organization id, applied to project create/list and as the transfer source org. Overridable per call |

```ts
const neon = createNeonClient({
  apiKey: process.env.NEON_API_KEY!,
  orgId: "org-cool-forest-12345678",
  throwOnError: true,
});
```

## Core model

Four behaviors are shared by every method: the result envelope, typed errors, pagination, and async workflows.

### The result envelope

By default, no `try/catch`. Each call resolves to a discriminated `{ data, error }` envelope; check `error`, then `data` is narrowed:

```ts
const { data, error } = await neon.projects.get({ projectId: "late-frost-12345" });
if (error) return; // error: typed NeonError union
data; // narrowed to Project
```

To throw instead, set `throwOnError` on the client (or per call). The return type narrows to the bare resource:

```ts
const neon = createNeonClient({ apiKey, throwOnError: true });
const project = await neon.projects.get({ projectId: "my-project" }); // Project (throws on error)
const { data } = await neon.projects.get({ projectId: "my-project" }, { throwOnError: false }); // opt out per call
```

### Typed errors

The error channel, and what `throwOnError` throws, is one hierarchy of `Error` subclasses, discriminated on `kind`:

| kind         | Class                | Raised when                                                     |
| ------------ | -------------------- | --------------------------------------------------------------- |
| `api`        | `NeonApiError`       | Non-2xx response; carries `status`, `code`, `requestId`, `body` |
| `not_found`  | `NeonNotFoundError`  | 404 (extends `NeonApiError`)                                    |
| `auth`       | `NeonAuthError`      | 401 or 403                                                      |
| `rate_limit` | `NeonRateLimitError` | 429, after retries                                              |
| `operation`  | `NeonOperationError` | An awaited operation failed; carries `operationId`, `status`    |
| `timeout`    | `NeonTimeoutError`   | A readiness or wait deadline was exceeded                       |
| `network`    | `NeonNetworkError`   | Transport failure, no response received                         |
| `client`     | `NeonError`          | SDK-side error, such as ambiguous connection-string selection   |

```ts
const { error } = await neon.branches.get({ projectId, branchId: "nope" });
if (error?.kind === "not_found") {
  // handle the 404
}
```

### Lazy, auto-paginated lists

Methods labeled Paginated return a [`Paginated`](https://neon.com/docs/reference/typescript-sdk#lazy-auto-paginated-lists)`<T>`; the cursor is managed for you:

```ts
const { data: all } = await neon.projects.list().all(); // every page
const { data: one } = await neon.projects.list().page(); // just the first page
for await (const project of neon.projects.list()) {
  // stream item by item
}
```

### Async workflows

Neon mutations return operations that complete in the background. The client-wide `waitForReadiness` default is `false`. `projects.create`, `branches.create`, and both `createAndConnect` workflows turn polling on for that call.

`create` returns the resource. `createAndConnect` also waits, then returns `{ branch, endpoint, connectionString }` (or `{ project, connectionString }`). The primitive underneath is `neon.operations.waitFor({ operations })`.

Pick one. `create` uses REST field names (`parent_id`). `createAndConnect` uses `{ name?, parentId?, compute? }`. Both fold into the same params object alongside `projectId`.

```ts
const { data: branch, error } = await neon.branches.create({
  projectId,
  name: "preview",
});
if (error) throw error;

const { data, error: connectError } = await neon.branches.createAndConnect({
  projectId,
  name: "preview-uri",
});
if (connectError) throw connectError;
const { connectionString } = data;
```

On any other namespaced mutation, pass `{ waitForReadiness: true }` as the trailing options argument to poll before the call resolves. For raw API calls that return an `operations` array, use [`neon.operations.waitFor`](https://neon.com/docs/reference/typescript-sdk#neonoperations) instead.

## Namespaces

The client groups the API into resource namespaces. Projects and branches are the core surfaces: [`projects`](https://neon.com/docs/reference/typescript-sdk#neonprojects) create, manage, and share projects, and [`branches`](https://neon.com/docs/reference/typescript-sdk#neonbranches) branch a project's data and schema. The Postgres data plane lives under [`postgres`](https://neon.com/docs/reference/typescript-sdk#neonpostgres): compute endpoints, roles, databases, the Data API, and connection strings.

Branch-scoped platform services include [`storage`](https://neon.com/docs/reference/typescript-sdk#neonstorage) (S3-compatible object storage), [`functions`](https://neon.com/docs/reference/typescript-sdk#neonfunctions), [`credentials`](https://neon.com/docs/reference/typescript-sdk#neoncredentials), [`aiGateway`](https://neon.com/docs/reference/typescript-sdk#neonaigateway), and [`auth`](https://neon.com/docs/reference/typescript-sdk#neonauth) (Managed Better Auth, OAuth providers, and users). For data lifecycle and async work, use [`snapshots`](https://neon.com/docs/reference/typescript-sdk#neonsnapshots) for point-in-time snapshots and restore, and [`operations`](https://neon.com/docs/reference/typescript-sdk#neonoperations) to poll asynchronous operations.

Account-level surfaces round out the client: [`consumption`](https://neon.com/docs/reference/typescript-sdk#neonconsumption) for billing metrics, [`apiKeys`](https://neon.com/docs/reference/typescript-sdk#neonapikeys), and [`regions` / `user`](https://neon.com/docs/reference/typescript-sdk#neonregions--user).

## neon.projects

Create, manage, and share Neon projects. One API call per method; `list` is paginated. REST: [Projects API](https://neon.com/docs/reference/api/projects)

| Method                       | Returns                                                                                                    | Arguments                                                                                                                                                                                                                 |
| ---------------------------- | ---------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `list(query?)`               | [`Paginated`](https://neon.com/docs/reference/typescript-sdk#lazy-auto-paginated-lists)`<ProjectListItem>` | `query`: `{ search?, org_id?, limit? }`                                                                                                                                                                                   |
| `get({ projectId })`         | `Project`                                                                                                  |                                                                                                                                                                                                                           |
| `create(input?)`             | `Project`                                                                                                  | Default-branch compute is always attached. No connection string. Readiness polling on by default. `input`: `{ name?, region_id?, pg_version?, org_id?, autoscaling_limit_min_cu?, autoscaling_limit_max_cu?, settings? }` |
| `createAndConnect(input?)`   | `{ project: Project, connectionString: string }`                                                           | Creates, then polls until ready. `input` also accepts `pooled?` (default `true`)                                                                                                                                          |
| `update({ projectId, ... })` | `Project`                                                                                                  | Additional fields: `{ name?, settings? }`                                                                                                                                                                                 |
| `delete({ projectId })`      | `Project`                                                                                                  |                                                                                                                                                                                                                           |
| `recover({ projectId })`     | `Project`                                                                                                  | Recover a soft-deleted project within its retention window                                                                                                                                                                |
| `transfer(input)`            | `void`                                                                                                     | `input`: `{ fromOrgId?, toOrgId, projectIds }` (`fromOrgId` defaults to the client `orgId`)                                                                                                                               |
| `transferFromUser(input)`    | `void`                                                                                                     | `input`: `{ toOrgId, projectIds }`                                                                                                                                                                                        |

```ts
// Provision a project, poll until ready, return a pooled connection string
const { data } = await neon.projects.createAndConnect({
  name: "tenant-42",
  region_id: "aws-us-east-1",
  pooled: true,
});
// data: { project, connectionString }
```

### neon.projects.permissions

Share a project with additional users by email.

| Method                                | Returns               |
| ------------------------------------- | --------------------- |
| `list({ projectId })`                 | `ProjectPermission[]` |
| `grant({ projectId, email })`         | `ProjectPermission`   |
| `revoke({ projectId, permissionId })` | `ProjectPermission`   |

## neon.branches

Branch a project's data and schema. `create` attaches a read-write endpoint by default. REST: [Branches API](https://neon.com/docs/reference/api/branches)

| Method                                            | Returns                                                                                           | Arguments                                                                                                                                                                                                                                                          |
| ------------------------------------------------- | ------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `list({ projectId, ...query })`                   | [`Paginated`](https://neon.com/docs/reference/typescript-sdk#lazy-auto-paginated-lists)`<Branch>` | `query`: `{ search?, sort_by?, sort_order?, include_deleted? }`                                                                                                                                                                                                    |
| `get({ projectId, branchId })`                    | `Branch`                                                                                          |                                                                                                                                                                                                                                                                    |
| `create({ projectId, ... })`                      | `Branch`                                                                                          | Read-write compute on by default; `noCompute: true` skips it. No connection string. Readiness polling on by default. Fields: `{ name?, parent_id?, parent_lsn?, parent_timestamp?, protected?, compute?: { minCu?, maxCu?, suspendTimeoutSeconds? }, noCompute? }` |
| `createAndConnect({ projectId, ... })`            | `{ branch: Branch, endpoint: Endpoint, connectionString: string }`                                | Creates, then polls until ready. Fields: `{ name?, parentId?, compute?: { minCu?, maxCu?, suspendTimeoutSeconds? }, pooled? }`                                                                                                                                     |
| `update({ projectId, branchId, ... })`            | `Branch`                                                                                          | Additional fields: `{ name?, protected?, expires_at? }`                                                                                                                                                                                                            |
| `delete({ projectId, branchId })`                 | `void`                                                                                            |                                                                                                                                                                                                                                                                    |
| `getDefault({ projectId })`                       | `Branch`                                                                                          | Resolve the project's default branch by flag, not by name                                                                                                                                                                                                          |
| `setDefault({ projectId, branchId })`             | `Branch`                                                                                          |                                                                                                                                                                                                                                                                    |
| `finalizeRestore({ projectId, branchId, name? })` | `void`                                                                                            | Commit a restore previewed with `snapshots.restore({ finalize: false })`                                                                                                                                                                                           |

Three modes: default compute, schema-only (`noCompute: true`), and create-plus-URI.

```ts
const { data: prod } = await neon.branches.getDefault({ projectId });

await neon.branches.create({
  projectId,
  name: "preview/pr-123",
  parent_id: prod?.id,
});

await neon.branches.create({
  projectId,
  name: "schema-only",
  parent_id: prod?.id,
  noCompute: true,
});

const { data, error } = await neon.branches.createAndConnect({
  projectId,
  name: "preview/pr-123-uri",
  parentId: prod?.id,
  compute: { minCu: 0.25, maxCu: 2 },
});
if (error) throw error;
const { connectionString } = data;
```

## neon.postgres

The Postgres data plane of a branch: compute endpoints, roles, databases, the Data API, and a connection-string helper. REST: [Endpoints](https://neon.com/docs/reference/api/endpoints), [Branches](https://neon.com/docs/reference/api/branches), [Data API](https://neon.com/docs/reference/api/dataapi)

| Method                     | Returns  | Arguments                                                                                                                                                                                                                                                                                    |
| -------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `connectionString(params)` | `string` | `params`: `{ projectId, branchId?, endpointId?, databaseName?, roleName?, pooled? }`. Only `projectId` is required; branch defaults to the project default, endpoint to the read-write one, and role/database are auto-selected when the branch has exactly one. `pooled` defaults to `true` |

```ts
const { data: uri } = await neon.postgres.connectionString({ projectId });
```

### neon.postgres.endpoints

Compute endpoints, scoped to a project.

| Method                                   | Returns      | Arguments                                                                                                                                                              |
| ---------------------------------------- | ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `list({ projectId })`                    | `Endpoint[]` |                                                                                                                                                                        |
| `listByBranch({ projectId, branchId })`  | `Endpoint[]` |                                                                                                                                                                        |
| `get({ projectId, endpointId })`         | `Endpoint`   |                                                                                                                                                                        |
| `create({ projectId, ... })`             | `Endpoint`   | Fields: `{ branch_id, type, autoscaling_limit_min_cu?, autoscaling_limit_max_cu?, suspend_timeout_seconds?, provisioner? }`. `type` is `"read_write"` \| `"read_only"` |
| `update({ projectId, endpointId, ... })` | `Endpoint`   |                                                                                                                                                                        |
| `delete({ projectId, endpointId })`      | `void`       |                                                                                                                                                                        |
| `start({ projectId, endpointId })`       | `Endpoint`   |                                                                                                                                                                        |
| `suspend({ projectId, endpointId })`     | `Endpoint`   |                                                                                                                                                                        |
| `restart({ projectId, endpointId })`     | `Endpoint`   |                                                                                                                                                                        |

### neon.postgres.roles

Postgres roles, scoped to a branch.

| Method                                             | Returns  | Arguments                                      |
| -------------------------------------------------- | -------- | ---------------------------------------------- |
| `list({ projectId, branchId })`                    | `Role[]` |                                                |
| `get({ projectId, branchId, roleName })`           | `Role`   |                                                |
| `create({ projectId, branchId, ... })`             | `Role`   | Fields: `{ name, no_login? }`                  |
| `delete({ projectId, branchId, roleName })`        | `void`   |                                                |
| `password({ projectId, branchId, roleName })`      | `string` | Reveals the current password                   |
| `resetPassword({ projectId, branchId, roleName })` | `Role`   | The returned `Role` carries the new `password` |

```ts
// Reveal a role's password, or rotate it
const { data: password } = await neon.postgres.roles.password({ projectId, branchId, roleName: "neondb_owner" });
const { data: role } = await neon.postgres.roles.resetPassword({ projectId, branchId, roleName: "neondb_owner" });
// role.password holds the new secret
```

### neon.postgres.databases

Databases, scoped to a branch.

| Method                                               | Returns      | Arguments                        |
| ---------------------------------------------------- | ------------ | -------------------------------- |
| `list({ projectId, branchId })`                      | `Database[]` |                                  |
| `get({ projectId, branchId, databaseName })`         | `Database`   |                                  |
| `create({ projectId, branchId, ... })`               | `Database`   | Fields: `{ name, owner_name }`   |
| `update({ projectId, branchId, databaseName, ... })` | `Database`   | Fields: `{ name?, owner_name? }` |
| `delete({ projectId, branchId, databaseName })`      | `void`       |                                  |

### neon.postgres.dataApi

The Neon Data API, scoped to a branch and database.

| Method                                               | Returns                 |
| ---------------------------------------------------- | ----------------------- |
| `get({ projectId, branchId, databaseName })`         | `DataApiResponse`       |
| `create({ projectId, branchId, databaseName, ... })` | `DataApiCreateResponse` |
| `update({ projectId, branchId, databaseName, ... })` | `void`                  |
| `delete({ projectId, branchId, databaseName })`      | `void`                  |

## neon.storage

Branch-scoped, S3-compatible object storage. `get` returns whether storage is enabled and the branch's S3 endpoint metadata; buckets and objects are nested underneath. REST: [Storage](https://neon.com/docs/reference/api/storage), [Buckets](https://neon.com/docs/reference/api/buckets)

| Method                         | Returns         |
| ------------------------------ | --------------- |
| `get({ projectId, branchId })` | `BranchStorage` |

### neon.storage.buckets

| Method                                        | Returns    | Arguments                                                                                 |
| --------------------------------------------- | ---------- | ----------------------------------------------------------------------------------------- |
| `list({ projectId, branchId })`               | `Bucket[]` |                                                                                           |
| `create({ projectId, branchId, ... })`        | `Bucket`   | Fields: `{ name, access_level? }`, where `access_level` is `"private"` \| `"public_read"` |
| `delete({ projectId, branchId, bucketName })` | `void`     |                                                                                           |

### neon.storage.objects

| Method                                                         | Returns                     | Arguments                                                                                                    |
| -------------------------------------------------------------- | --------------------------- | ------------------------------------------------------------------------------------------------------------ |
| `list({ projectId, branchId, bucketName, ...query })`          | `BucketObjectsListResponse` | `query`: `{ prefix?, delimiter?, cursor?, limit? }`. Returns one page of `folders`, `objects`, `next_cursor` |
| `get({ projectId, branchId, bucketName, objectKey })`          | `Blob`                      | Raw object bytes                                                                                             |
| `delete({ projectId, branchId, bucketName, objectKey })`       | `void`                      |                                                                                                              |
| `deleteByPrefix({ projectId, branchId, bucketName, prefix })`  | `{ deleted: number }`       | `prefix` must end with `/`                                                                                   |
| `presign({ projectId, branchId, bucketName, objectKey, ... })` | `PresignResponse`           | Fields: `{ operation: "upload" \| "download", content_type?, expires_in_seconds? }`                          |

```ts
// Upload via a presigned PUT
const { data: presign } = await neon.storage.objects.presign({
  projectId,
  branchId,
  bucketName: "avatars",
  objectKey: "user-1.png",
  operation: "upload",
  content_type: "image/png",
});
if (!presign) throw new Error("presign failed");

await fetch(presign.url, {
  method: "PUT",
  headers: { ...presign.headers, "Content-Length": String(bytes.length) },
  body: bytes,
});
```

## neon.functions

Branch-scoped Neon Functions. REST: [Functions API](https://neon.com/docs/reference/api/functions)

| Method                                       | Returns                                                                                                 | Arguments                                                                                                                                               |
| -------------------------------------------- | ------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `list({ projectId, branchId, ...query })`    | [`Paginated`](https://neon.com/docs/reference/typescript-sdk#lazy-auto-paginated-lists)`<NeonFunction>` | `query`: `{ limit? }`                                                                                                                                   |
| `get({ projectId, branchId, slug })`         | `NeonFunction`                                                                                          |                                                                                                                                                         |
| `update({ projectId, branchId, slug, ... })` | `NeonFunction`                                                                                          | Fields: `{ name? }`                                                                                                                                     |
| `delete({ projectId, branchId, slug })`      | `void`                                                                                                  |                                                                                                                                                         |
| `deploy({ projectId, branchId, slug, ... })` | `NeonFunctionDeployment`                                                                                | Multipart. Fields: `{ zip?: Blob \| File, runtime?: "nodejs24", environment?: string }`, where `environment` is a JSON-encoded `Record<string, string>` |

```ts
// Deploy a bundled index.mjs inside a zip (first deploy must include the zip)
const zip = await Bun.file("bundle.zip").arrayBuffer();
const { data: deployment } = await neon.functions.deploy({
  projectId,
  branchId,
  slug: "api",
  zip: new File([zip], "bundle.zip", { type: "application/zip" }),
  runtime: "nodejs24",
});
// Poll neon.functions.get until current_deployment.status is "completed"
```

## neon.credentials

Branch-scoped credentials with explicit scopes. Secrets (`api_token`, `s3_secret_access_key`) are returned once, on `create`. REST: [Credentials API](https://neon.com/docs/reference/api/credentials)

| Method                                     | Returns                    | Arguments                                                                                                                             |
| ------------------------------------------ | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `list({ projectId, branchId })`            | `CredentialMeta[]`         |                                                                                                                                       |
| `create({ projectId, branchId, ... })`     | `CreateCredentialResponse` | Fields: `{ name?, scopes, principal_type: "user" }`. Scopes: `storage:read`, `storage:write`, `ai_gateway:invoke`, `functions:invoke` |
| `revoke({ projectId, branchId, tokenId })` | `void`                     |                                                                                                                                       |

## neon.aiGateway

Branch-scoped AI Gateway endpoint metadata. REST: [AI Gateway API](https://neon.com/docs/reference/api/ai-gateway)

| Method                         | Returns           | Arguments                                                |
| ------------------------------ | ----------------- | -------------------------------------------------------- |
| `get({ projectId, branchId })` | `BranchAiGateway` | Returns 404 when AI Gateway is not enabled on the branch |

## neon.snapshots

Point-in-time snapshots, restore, and backup schedules. REST: [Snapshots API](https://neon.com/docs/reference/api/snapshots)

| Method                                      | Returns          | Arguments                                                                          |
| ------------------------------------------- | ---------------- | ---------------------------------------------------------------------------------- |
| `list({ projectId })`                       | `Snapshot[]`     |                                                                                    |
| `create({ projectId, branchId, ... })`      | `Snapshot`       | Fields: `{ name?, timestamp?, lsn?, expiresAt? }`                                  |
| `update({ projectId, snapshotId, ... })`    | `Snapshot`       | Fields: `{ name? }`                                                                |
| `delete({ projectId, snapshotId })`         | `void`           |                                                                                    |
| `restore({ projectId, snapshotId, ... })`   | `Branch`         | Fields: `{ name?, targetBranchId?, finalize?, preview?, keepOnAbort? }`. See below |
| `getSchedule({ projectId, branchId })`      | `BackupSchedule` |                                                                                    |
| `setSchedule({ projectId, branchId, ... })` | `void`           |                                                                                    |

`restore` behaves differently depending on the target:

- As a new branch (no `targetBranchId`), it finalizes by default and is ready to use immediately.
- Onto an existing branch, it does not finalize by default, so you can preview first.
- Transaction-style with `preview`: it restores un-finalized, runs your callback against the restored branch, then commits if the callback returns `true` or aborts (deletes the preview branch) if `false`, unless `keepOnAbort` is set:

```ts
await neon.snapshots.restore({
  projectId,
  snapshotId,
  targetBranchId,
  preview: async (branch) => (await checks(branch)) === "ok", // true commits, false aborts
});
```

## neon.operations

Read operations and wait for them to finish. REST: [Operations API](https://neon.com/docs/reference/api/operations)

| Method                              | Returns                                                                                              | Arguments                                             |
| ----------------------------------- | ---------------------------------------------------------------------------------------------------- | ----------------------------------------------------- |
| `list({ projectId })`               | [`Paginated`](https://neon.com/docs/reference/typescript-sdk#lazy-auto-paginated-lists)`<Operation>` |                                                       |
| `get({ projectId, operationId })`   | `Operation`                                                                                          |                                                       |
| `waitFor({ operations }, options?)` | `void`                                                                                               | `options`: `{ pollIntervalMs?, timeoutMs?, signal? }` |

```ts
// Wait on operations from a raw call (or when readiness polling is off)
const { data } = await raw.createProjectBranch({
  client: neon.client,
  path: { project_id: projectId },
  body: { branch: { name: "wip" } },
});
const { error } = await neon.operations.waitFor({ operations: data!.operations }, { timeoutMs: 120_000 });
```

## neon.auth

Branch-scoped Managed Better Auth. The legacy project-scoped endpoints are deprecated and remain raw-only. REST: [Authentication API](https://neon.com/docs/reference/api/auth)

| Method                                       | Returns                             | Arguments                 |
| -------------------------------------------- | ----------------------------------- | ------------------------- |
| `get({ projectId, branchId })`               | `NeonAuthIntegration`               |                           |
| `create({ projectId, branchId, ... })`       | `NeonAuthCreateIntegrationResponse` | Enable the integration    |
| `disable({ projectId, branchId, ... })`      | `void`                              | Fields: `{ deleteData? }` |
| `updateConfig({ projectId, branchId, ... })` | `NeonAuthConfigResponse`            |                           |

### neon.auth.oauthProviders

OAuth providers (Google, GitHub, and others).

| Method                                             | Returns                   |
| -------------------------------------------------- | ------------------------- |
| `list({ projectId, branchId })`                    | `NeonAuthOauthProvider[]` |
| `add({ projectId, branchId, ... })`                | `NeonAuthOauthProvider`   |
| `update({ projectId, branchId, providerId, ... })` | `NeonAuthOauthProvider`   |
| `delete({ projectId, branchId, providerId })`      | `void`                    |

### neon.auth.trustedDomains

The redirect-URI whitelist.

| Method                                 | Returns                                |
| -------------------------------------- | -------------------------------------- |
| `list({ projectId, branchId })`        | `NeonAuthRedirectUriWhitelistDomain[]` |
| `add({ projectId, branchId, ... })`    | `void`                                 |
| `delete({ projectId, branchId, ... })` | `void`                                 |

### neon.auth.users

| Method                                                   | Returns                          |
| -------------------------------------------------------- | -------------------------------- |
| `create({ projectId, branchId, ... })`                   | `NeonAuthCreateNewUserResponse`  |
| `delete({ projectId, branchId, authUserId })`            | `void`                           |
| `updateRole({ projectId, branchId, authUserId, roles })` | `UpdateNeonAuthUserRoleResponse` |

## neon.consumption

Cursor-paginated billing metrics. Each method takes `{ from, to, granularity, org_id, project_ids? }`, where `from`/`to` are ISO timestamps, `granularity` is `"hourly"` | `"daily"` | `"monthly"`, and `org_id` names the org to report on; `perBranchV2` also requires `project_ids`. `org_id` defaults to the client `orgId` when set. Consumption requires a Scale plan or above. REST: [Consumption API](https://neon.com/docs/reference/api/consumption)

| Method                | Returns                                                                                                                   |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| `perProject(query)`   | [`Paginated`](https://neon.com/docs/reference/typescript-sdk#lazy-auto-paginated-lists)`<ConsumptionHistoryPerProject>`   |
| `perProjectV2(query)` | [`Paginated`](https://neon.com/docs/reference/typescript-sdk#lazy-auto-paginated-lists)`<ConsumptionHistoryPerProjectV2>` |
| `perBranchV2(query)`  | [`Paginated`](https://neon.com/docs/reference/typescript-sdk#lazy-auto-paginated-lists)`<ConsumptionHistoryPerBranchV2>`  |

```ts
// Stream every project's daily usage across a range
for await (const project of neon.consumption.perProject({
  from: "2026-06-01T00:00:00Z",
  to: "2026-06-30T00:00:00Z",
  granularity: "daily",
  org_id: "org-...", // the org to report on; consumption requires a Scale plan or above
})) {
  console.log(project);
}
```

## neon.apiKeys

Manage account-level API keys. REST: [API Keys API](https://neon.com/docs/reference/api/api-keys)

| Method                | Returns                     | Arguments                     |
| --------------------- | --------------------------- | ----------------------------- |
| `list()`              | `ApiKeysListResponseItem[]` |                               |
| `create({ keyName })` | `ApiKeyCreateResponse`      | The `key` token is shown once |
| `revoke({ keyId })`   | `ApiKeyRevokeResponse`      |                               |

## neon.regions / neon.user

Active regions and the current account. REST: [Regions](https://neon.com/docs/reference/api/regions), [Users](https://neon.com/docs/reference/api/users)

| Method                 | Returns                   |
| ---------------------- | ------------------------- |
| `regions.list()`       | `RegionResponse[]`        |
| `user.me()`            | `CurrentUserInfoResponse` |
| `user.organizations()` | `Organization[]`          |

## Upgrading from v4

`@neon/sdk` v5 introduced one breaking change that runs through every namespace: resource methods take a **single named-parameter object** instead of positional arguments. Path selectors and input fields are merged into one flat object, followed by the same optional call-options argument.

```ts
// v4 (positional)
await neon.branches.get(projectId, branchId);
await neon.postgres.roles.password(projectId, branchId, "neondb_owner");
await neon.storage.objects.presign(projectId, branchId, "avatars", "user-1.png", {
  operation: "upload",
});

// v5 and later (named parameters)
await neon.branches.get({ projectId, branchId });
await neon.postgres.roles.password({ projectId, branchId, roleName: "neondb_owner" });
await neon.storage.objects.presign({
  projectId,
  branchId,
  bucketName: "avatars",
  objectKey: "user-1.png",
  operation: "upload",
});
```

The `{ pooled }` option on `projects.createAndConnect` and `branches.createAndConnect`, and the `operations` argument to `operations.waitFor`, also move into the params object. `postgres.connectionString` and the `consumption.*` methods were already object-shaped and are unchanged.

v6 is the current major. It extends the triggers surface (`storage_object_created` alongside `schedule`) and does not change the named-parameter shape introduced in v5.

## Raw layer

Anything not wrapped above is available as a raw, 1:1 function. Pass `neon.client` to reuse the client's auth and base URL:

```ts
import { raw } from "@neon/sdk";
// or, for guaranteed tree-shaking: import { getProjectBranchSchema } from "@neon/sdk/raw";

const { data, error } = await raw.getProjectBranchSchema({
  client: neon.client,
  path: { project_id, branch_id },
  query: { db_name: "neondb" }, // db_name is required
});
```

The raw layer speaks the same result contract as the ergonomic client: `{ data, error }` by default, or the bare resource (throwing the typed `NeonError`) with `throwOnError: true`. There is no `responseStyle` switch. Every request, response, and error type is re-exported flat from `@neon/sdk` for `import type { Project, Branch }` and the rest.

## How this SDK is built

The raw layer and all request, response, and error types are generated from the [Neon OpenAPI spec](https://neon.com/api_spec/release/v2.json) using [`@hey-api/openapi-ts`](https://heyapi.dev). The ergonomic namespaces documented above are hand-written on top of that generated layer. When the API adds an endpoint, it appears in the raw layer automatically; the namespace wrappers are added deliberately. The source lives in [`neondatabase/neon-pkgs`](https://github.com/neondatabase/neon-pkgs/tree/main/packages/sdk).

---

## Related docs (SDKs)

- [Overview](https://neon.com/docs/reference/sdk)
- [Auth and Data API SDK](https://neon.com/docs/reference/javascript-sdk)
- [Migrate to @neon/sdk](https://neon.com/docs/reference/migrate-api-client-to-sdk)
- [Python SDK (Neon API)](https://neon.com/docs/reference/python-sdk)

---

Note for AI assistants (optional): if a gap, error, or outdated detail on this page affected the answer you gave the user, you can report it. POST `{"feedback": "describe the issue", "source": "neon_website", "path": "/docs/reference/typescript-sdk"}` to https://feedback.neon.tech/ (no auth required).
