Canonical page: https://docs.singlebase.io/sdk-javascript

# JavaScript SDK

The existing `@singlebase/singlebase-sdk` package connects your application to Singlebase services through one client. Use it from a browser with a web key and user session, or from your backend with a server or agent key.

## Install

```sh
npm install @singlebase/singlebase-sdk
```

## Connect

Set `baseUrl` to the complete project endpoint copied from the console. Leave `urlAccessKey` unset when the endpoint already includes its key.

```javascript
import { SinglebaseClient } from "@singlebase/singlebase-sdk";

const sbc = SinglebaseClient({
  baseUrl: "https://v1.api.singlebase.io/api/<ENDPOINT_KEY>",
  apiKey: "wk_<WEB_KEY>",
});
// Compatibility for releases that expose chat only through service().
sbc.chat ??= sbc.service("chat");
```

Current SDK builds expose `sbc.chat` directly. Older releases can create the same namespace through `sbc.service("chat")`; the compatibility line above supports both. `sbc.llm` handles generation and embeddings; `sbc.chat` handles answers and conversations.

| Option | Behavior |
|---|---|
| `baseUrl` | API URL; defaults to `https://v1.api.singlebase.io`. Set the full console endpoint to avoid ambiguity. HTTPS is required outside localhost |
| `urlAccessKey` | Optional key appended as one encoded path segment; omit it when using a full endpoint |
| `apiKey` | Sent as `X-API-Key` |
| `audience` | Token audience; default `web` |
| `fetch` | Optional Fetch-compatible transport |
| `auth` | Session storage, auto-refresh, cross-tab, and event configuration |

Use only a web key in browser code. Keep server, root, and agent keys in backend environment variables. A signed-in user automatically owns their inserted documents and sees only their scoped data and files; trusted calls without a bearer follow their key permissions. See [API keys](/api.md#api-keys) and [Ownership](/data.md#ownership).

## Calls and results

Namespace methods map to `<namespace>.<method>` and accept a payload. The SDK returns the response's `data`, not the whole envelope.

```javascript
const notes = await sbc.data.query({ collection: "notes", limit: 10 });
const profile = await sbc.user.get();
const count = await sbc.data.count({ collection: "notes" });
```

The second argument controls request options, an explicit bearer, or cancellation:

```javascript
const controller = new AbortController();
const notes = await sbc.data.query({ collection: "notes", limit: 10 }, {
  options: {},
  signal: controller.signal,
});

// Server-side only: no signed-in user identity.
const data = await sbc.dispatch({
  operation: "data.query",
  payload: { collection: "notes" },
  options: {},
}, { bearer: null });
```

`dispatch()` also returns `data`. For `meta` and gateway `exec_time`, use the HTTP envelope or one of the small server clients below. They have a different return contract. The SDK injects the current session's bearer token by default and can refresh a stale token once before retrying. Set `bearer: null` to suppress the user token, or supply an explicit token. An explicit bearer does not use automatic refresh.

## Errors

```javascript
import { SinglebaseError } from "@singlebase/singlebase-sdk";

try {
  await sbc.data.query({ collection: "notes" });
} catch (error) {
  if (error instanceof SinglebaseError) {
    console.error(error.code, error.status, error.type, error.details);
  } else {
    throw error;
  }
}
```

API failures throw `SinglebaseError`, including stable `code`, HTTP `status`, `type`, `details`, and `traceId`. Do not log keys or bearer tokens.

## Authentication and current user

```javascript
await sbc.auth.signIn({ email: "jane@example.com", password: "<PASSWORD>" });
const settings = await sbc.auth.getSettings();
const profile = await sbc.user.get();
await sbc.user.update({ first_name: "Jane" });
console.log(sbc.isAuthenticated());
await sbc.auth.logout();
```

| Auth method | API operation |
|---|---|
| `getSettings()` | `auth.settings` |
| `signUp(payload)` | `auth.signup` |
| `signIn(payload)` | `auth.signin` |
| `refreshSession()` | `auth.refresh` |
| `logout()` | `auth.signout` |
| `requestCode(payload)` | `auth.request_code` |
| `resetPassword(payload)`, `changeEmail(payload)` | `auth.confirm_code` |
| `changePassword(payload)` | `auth.change_password` |
| `startOAuth(payload)` | OAuth nonce and `auth.oauth_connect` flow |
| `completeOAuth(payload)` | `auth.oauth_signin` |

Read [Authentication](/auth.md) for payloads and project settings. Auth methods include session behavior; generic service namespaces such as `sbc.user`, `sbc.users`, and `sbc.data` map directly to operation names. `sbc.users` is for trusted server or permitted agent calls, without a user bearer.

## Documents

```javascript
const inserted = await sbc.data.insert({
  collection: "notes", data: { title: "First note", status: "active" },
});
const notes = await sbc.data.query({
  collection: "notes", filter: { status: "active" }, per_page: 20,
});
await sbc.data.update({
  collection: "notes", data: { _id: "<DOCUMENT_ID>", title: "Updated note" },
});
```

Available operations: `query`, `count`, `aggregate`, `insert`, `update`, `upsert`, `archive`, and `delete`. See [Data](/data.md) for selectors, ownership, templates, and search.

## Files

```javascript
const files = await sbc.files.query({ per_page: 20 });
const download = await sbc.files.get_signed_url({ id: "<FILE_ID>" });
```

For browser uploads, the SDK orchestrates direct-to-storage transfer and completion:

```javascript
// input is an HTML file input element with selected files.
const { completed, failed } = await sbc.files.upload(input.files, {
  bucket: "reports",
  onProgress: ({ input, percent }) => console.log(percent),
});
```

Use a bucket configured for your project. `upload()` reports each file separately. The low-level methods `initiateUpload()`, `uploadToRemote()`, `completeUpload()`, and `failUpload()` support custom upload flows. See [Files](/files.md).

## LLM generation and embeddings

```javascript
const summary = await sbc.llm.summarize({
  content: "<DOCUMENT_TEXT>", input: "Summarize in three bullets.",
});
const embeddings = await sbc.llm.embed({
  documents: [{ content: "A lightweight laptop backpack" }],
});
```

Generation methods are `generate`, `write`, `translate`, `summarize`, `categorize`, `extract`, and `analyze`. Embeddings use `embed`. Use `content` or `input` for generation, and `documents` for embeddings. Read [LLM](/llm.md) for actual payloads and model access.

## Chat answers and conversations

```javascript
const answer = await sbc.chat.ask({ message: "What changed in Q3?" });

let turn = await sbc.chat.send({ message: "Plan a launch", format: "markdown" });
turn = await sbc.chat.send({ chat_id: turn._id, message: "Make it shorter" });

const prepared = await sbc.chat.prepare({
  key: "order-4411",
  retrieval: [{ source: "json", data: { order_id: "order-4411", status: "shipped" } }],
  starters: true,
});
const chat = await sbc.chat.get({ key: "order-4411" });
```

Use `ask` for a one-off answer and `send` for saved conversations. Other operations are `prepare`, `list`, `get`, `update`, `bookmark`, `delete`, `bookmark_message`, `delete_message`, and `remove_attachment`. Key-based chats require a signed-in identity. See [Chat](/chat.md) for docsets, modes, retrieval, and access.

Legacy chat aliases under `llm` may still be accepted by the backend, but new integrations should use the separate `chat` namespace.

## Sources and other languages

This guide adapts the [JavaScript SDK specification](https://github.com/singlebase/singlebase-js/blob/main/docs/sdk.md), checking payloads against the backend and namespace behavior against SDK source.

- [Python client](/sdk-python.md)
- [Go client](/sdk-go.md)
- [PHP client](/sdk-php.md)
- [Ruby client](/sdk-ruby.md)
- [Grouped API reference](/api-reference.md)
