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

# Server SDK

> Send SMS and place outbound calls from your backend

`@telzino/server` sends texts and places outbound calls with a Telzino API key. It runs on your server (Node.js 18 or later). Never ship it, or the key, to a browser: for the browser use [chat](https://docs.telzino.com/sdk/chat.md) and [voice](https://docs.telzino.com/sdk/quickstart.md) with a publishable key.

```bash theme={null}
npm install @telzino/server
```

```ts theme={null}
import { TelzinoServer } from '@telzino/server';

const telzino = new TelzinoServer({
  clientId: process.env.TELZINO_CLIENT_ID!,
  clientSecret: process.env.TELZINO_CLIENT_SECRET!,
});
```

The SDK gets an access token with the [client credentials flow](https://docs.telzino.com/api-reference/authentication.md), keeps it until shortly before it expires, and gets a new one if the key's secret was rotated. Every request gives up after 30 seconds.

## Send a text

```ts theme={null}
const msg = await telzino.sms.send({
  agentId: '3f1c2a4e-8b7d-4c3a-9e2f-1a2b3c4d5e6f',
  to: '+15551234567',
  body: 'Your order is ready for pickup.',
  idempotencyKey: 'order-9312-ready', // optional: a retry never sends twice
});
// { id, status: 'queued', to, from, agent_id }
```

The text goes out from the agent's SMS number and joins that customer's conversation. When the customer replies, the agent answers. See [Send SMS](https://docs.telzino.com/api-reference/agents/send-sms.md) for the rules: the agent needs an enabled SMS number, and recipients who texted STOP are refused.

## Place an outbound call

```ts theme={null}
const call = await telzino.calls.create({
  agentId: '3f1c2a4e-8b7d-4c3a-9e2f-1a2b3c4d5e6f',
  to: '+15551234567',
  callContext: 'You are calling Sam to confirm tomorrow at 3pm.',
  greeting: 'Hi Sam, this is Ava from Bright Dental.',
});
```

`callbackUrl` and `metadata` are supported too. Any other field of [Trigger Outbound Call](https://docs.telzino.com/api-reference/outbound-calls/create.md) goes in `extra`, in the API's snake\_case, for example `extra: { retry_policy_id: '...' }`.

## Which key to use

Create the key in the dashboard under **API Keys**. For a backend that only texts and calls for one agent, choose **Access → One agent**: that key can send that agent's texts and place its calls, and nothing else. See [Agent-scoped API keys](https://docs.telzino.com/api-reference/authentication.md#agent-scoped-api-keys).

## Errors

Failures throw a `TelzinoApiError` with the HTTP `status` and the API's `code`:

```ts theme={null}
import { TelzinoApiError } from '@telzino/server';

try {
  await telzino.sms.send({ agentId, to, body });
} catch (err) {
  if (err instanceof TelzinoApiError && err.code === 'opted_out') {
    // the customer texted STOP: do not retry
  } else throw err;
}
```

Common codes: `opted_out`, `sms_not_enabled`, `rate_limited`, `not_found`, `insufficient_scope`, `invalid_request`.


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