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

# Use the SDK

> Resource methods, API operations, pagination, typed responses and file requests

The examples below use a configured `client` from the [Quickstart](/sdk/quickstart). Replace resource IDs with IDs from your workspace.

## Resource shortcuts

The following groups offer concise methods. Use `client.api` for operations not listed here.

| Group | Methods | Resource |
| - | - | - |
| `client.assistants` | `list`, `create`, `get`, `update`, `delete`, `iterate` | Assistants |
| `client.calls` | `list`, `create`, `get`, `recording`, `iterate` | Calls and recordings |
| `client.campaigns` | `list`, `create`, `get`, `update`, `delete`, `start`, `stop`, `iterate` | Campaigns |
| `client.contacts` | `list`, `create`, `iterate` | Workspace audience contacts |
| `client.voices` | `list`, `preview`, `iterate` | Voice catalog and previews |
| `client.knowledgeBases` | `list`, `create`, `get`, `delete`, `iterate` | Knowledge bases |
| `client.account` | `me` | Current account and workspace |

Campaign-specific leads are available through `client.api.listLeads` with the campaign ID in `path.id`, or `famulor list-leads <campaign-id>` in the CLI. `client.contacts` manages the shared workspace audience.

## Read responses

Resource methods keep the API response envelope: your result is in `data`, and list responses can include `meta.pagination`.

```typescript theme={null}
const response = await client.calls.list({
  status: 'completed',
  limit: 20,
  offset: 0,
});

console.log(response.data);
console.log(response.meta?.pagination);

const { data: call } = await client.calls.get('call-id');
console.log(call.status, call.summary);
```

Use optional chaining for metadata and nullable response fields. Some results, such as a call summary or recording, become available only after processing finishes. Omitting an optional request field and sending `null` are different actions; send `null` only where the [API reference](/api-reference/introduction) allows it.

## Fetch pages as you need them

Use the async iterator for supported paginated resources:

```typescript theme={null}
for await (const call of client.calls.iterate({
  status: 'completed',
  limit: 50,
})) {
  console.log(call.id, call.status);
}
```

`limit` is the page size, not a limit on the total items yielded. The iterator preserves your filters and advances the offset until it reaches the end. Breaking out of the loop stops fetching new pages. Offset pagination is not a snapshot: concurrent inserts or updates can change page contents. To set a safety bound, pass a second argument such as `{ maxPages: 100 }`. Reaching the bound before the list ends throws an error; it does not silently return a partial result.

For manual page control, call `client.calls.list()` with `limit` and `offset`, then inspect `meta.pagination`. Typical list endpoints default to 50 items and allow up to 200; follow each endpoint's limits.

The equivalent CLI request is `famulor list-calls --status completed --limit 50`; add `--all` to fetch all pages.

## Use any public API operation

`client.api` exposes the operation IDs from the [API reference](/api-reference/introduction) as typed methods. Inputs are grouped into `path`, `query`, `body` and `headers` instead of combining unrelated parameters.

```typescript theme={null}
const { data: account } = await client.api.getMe();

const { data: calls } = await client.api.listCalls({
  query: { status: 'completed', limit: 10 },
});

const { data: call } = await client.api.getCall({
  path: { id: 'call-id' },
});

console.log(account, calls.length, call.status);
```

For an outbound call, the complete API method is:

```typescript theme={null}
const result = await client.api.createCall({
  body: {
    assistant_id: '11111111-1111-4111-8111-111111111111',
    to_number: '+4915123456789',
  },
});

console.log(result.data.id);
```

The resource shorthand is `client.calls.create(body)`. Both methods call the same API and retain the same response envelope and permissions.

| SDK method | REST operation | CLI command |
| - | - | - |
| `client.api.getMe()` | `GET /api/v1/me` | `famulor get-me` |
| `client.api.listCalls()` | `GET /api/v1/calls` | `famulor list-calls` |
| `client.api.getCall()` | `GET /api/v1/calls/{id}` | `famulor get-call <id>` |
| `client.api.createCall()` | `POST /api/v1/calls` | `famulor create-call --assistant-id <id> --to-number <number>` |

Use your editor's autocomplete for all operation methods. See [MCP tools and scopes](/mcp/tools-and-scopes) for using the corresponding capabilities inside an AI assistant.

## Download binary responses

Audio endpoints return an `ArrayBuffer`, without a JSON `data` wrapper. For example, download an existing Full Duplex voice preview as WAV audio:

```typescript theme={null}
import { writeFile } from 'node:fs/promises';

const preview = await client.api.getVoicePreview({
  path: { id: 'voice-id' },
  query: { realtime_variant: 'full_duplex' },
});

await writeFile('preview.wav', new Uint8Array(preview));
```

Choose an opaque Full Duplex voice ID from the voice catalog. Your workspace needs access to the corresponding voice mode. A missing preview returns an API error; this request does not create a new sample.

## Upload files

Pass a `FormData` body to operations that accept multipart uploads. The SDK sets the multipart content type and boundary:

```typescript theme={null}
import { readFile } from 'node:fs/promises';

const file = await readFile('avatar.png');
const form = new FormData();
form.set('file', new Blob([new Uint8Array(file)], { type: 'image/png' }), 'avatar.png');

await client.api.setAssistantAvatar({
  path: { id: 'assistant-id' },
  body: form,
});
```

Avatar uploads accept PNG, JPEG or WebP, with a maximum incoming file size of 1 MB. Follow each operation's file requirements. The CLI equivalents for both examples are:

```bash theme={null}
famulor get-voice-preview <voice-id> --realtime-variant full_duplex --output-file preview.wav
famulor set-assistant-avatar <assistant-id> --file avatar.png
```

## Override one request

Request options are the last argument, after the method’s input parameters. Generated `client.api` methods take grouped input first and request options second. Resource shortcuts have different argument counts. For example, a list takes its query first, then options:

```typescript theme={null}
const response = await client.assistants.list(
  { limit: 10 },
  { timeoutMs: 10_000, maxRetries: 0 },
);
```

Place options after the ID and body when updating an assistant, after the ID and query when downloading audio, and as the only argument for `account.me()`. Pass an empty query to keep its defaults. Replace the resource IDs below before running these examples; updating an assistant changes its configuration.

```typescript theme={null}
const controller = new AbortController();
const options = { signal: controller.signal, timeoutMs: 10_000, maxRetries: 0 };

await client.assistants.update('assistant-id', { name: 'Support' }, options);
const recording = await client.calls.recording('call-id', {}, options);
const preview = await client.voices.preview('voice-id', {}, options);
const account = await client.account.me(options);

await client.api.getMe(undefined, options);
```

See [Configuration and errors](/sdk/reference) for cancellation, error classes and retry behavior.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.