> ## 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.

# Agent Runbook

> Hand this page to an AI coding agent so it can build UIs on the Telzino API without guessing

Building a dashboard, portal, or internal tool on the Telzino API with an AI coding
agent (Claude Code, Cursor, Windsurf, …)? Give your agent this one instruction:

> Before writing any code, read [https://docs.telzino.com/agent-runbook.md](https://docs.telzino.com/agent-runbook.md) and follow
> its ground rules. Fetch [https://api.telzino.com/api-doc/openapi](https://api.telzino.com/api-doc/openapi) for exact request
> and response schemas.

Everything below is written for the agent.

## Ground rules

1. **The OpenAPI spec is the source of truth.** Fetch
   `https://api.telzino.com/api-doc/openapi` (OpenAPI 3.0 JSON) and use its schemas for
   every request body and response. A Postman collection generated from the same spec is
   at `https://api.telzino.com/api-doc/postman`. Never invent an endpoint, parameter, or
   field that is not in the spec or in the catalog below.
2. **All calls go through your backend — never from the browser.** The API does not send
   CORS headers, and the OAuth `client_secret` must never ship in client-side code. Build
   a thin server proxy (pattern below) and have the UI call that.
3. **Handle auth failures.** Tokens last 24 hours (`expires_in: 86400`). On a 401,
   refresh the token once and retry; if it still fails, surface the error.
4. **Respect pagination.** List endpoints take `page` and `limit` (max 100) and return
   `{ "data": [...], "pagination": { "page", "limit", "total", "totalPages" } }`.
   Build paging into every list view.
5. **Surface API errors.** Error responses are `{ "error": "<message>" }` (often with an
   `error_description`) and a 4xx/5xx status. Show the message; don't swallow it.

## Authentication

OAuth 2.0 Client Credentials against Auth0. Exchange your `client_id` + `client_secret`
(from the Telzino dashboard) for a bearer token:

```bash theme={null}
curl -X POST https://api.telzino.com/oauth/token \
  -H "Content-Type: application/json" \
  -d '{
    "client_id": "YOUR_CLIENT_ID",
    "client_secret": "YOUR_CLIENT_SECRET",
    "audience": "https://api.telzino.com/",
    "grant_type": "client_credentials"
  }'
```

Send the resulting token on every request: `Authorization: Bearer <access_token>`.
Then call `GET /v1/me` to discover the account ID tied to your credentials.

### Required server-side proxy pattern

```ts theme={null}
// server/telzino.ts — cache the token, proxy the calls. Secrets stay server-side.
let token: { value: string; expiresAt: number } | null = null;

async function getToken() {
  if (token && Date.now() < token.expiresAt - 60_000) return token.value;
  const res = await fetch("https://api.telzino.com/oauth/token", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      client_id: process.env.TELZINO_CLIENT_ID,
      client_secret: process.env.TELZINO_CLIENT_SECRET,
      audience: "https://api.telzino.com/",
      grant_type: "client_credentials",
    }),
  });
  if (!res.ok) throw new Error(`token exchange failed: ${res.status}`);
  const data = await res.json();
  token = { value: data.access_token, expiresAt: Date.now() + data.expires_in * 1000 };
  return token.value;
}

export async function telzino(path: string, init: RequestInit = {}) {
  const res = await fetch(`https://api.telzino.com${path}`, {
    ...init,
    headers: {
      ...init.headers,
      Authorization: `Bearer ${await getToken()}`,
      "Content-Type": "application/json",
    },
  });
  if (res.status === 401) token = null; // force refresh on next call
  return res;
}
```

Expose only the routes your UI needs from your own backend; forward to `telzino()`.

## Resource model

```
account (your credentials)
└── resellers
    └── organizations
        ├── agents            ← the AI phone agents
        │   ├── call logs     → recordings
        │   ├── outbound calls
        │   ├── SIP registration
        │   └── music-on-hold (MOH)
        ├── knowledge bases   → sources → ingestion jobs
        └── guardrails
```

Voices, custom voices, STT providers, LLM models, and email servers are catalogs you
read when building agent-configuration UIs. Metrics and reports aggregate usage.

## Endpoint catalog

Exact schemas: fetch the [OpenAPI spec](https://api.telzino.com/api-doc/openapi).
Human-readable detail: each row links to the reference page.

| Method + Path | Purpose |
| - | - |
| `POST /oauth/token` | [Get an access token](/api-reference/authentication) |
| `GET /v1/me` | [Account for these credentials](/api-reference/me) |
| `GET \| POST /v1/agents` | [List / create agents](/api-reference/agents/list) |
| `GET \| PUT \| DELETE /v1/agents/{agentId}` | [Read / update / delete an agent](/api-reference/agents/get) |
| `PATCH /v1/agents/{agentId}/status` | [Enable or disable an agent](/api-reference/agents/update-status) |
| `PUT \| PATCH \| DELETE /v1/agents/{agentId}/sip/registration` | [Manage SIP registration](/api-reference/agents/sip-registration) |
| `GET /v1/agents/{agentId}/sip/registration/status` | [Live SIP registration status](/api-reference/agents/sip-registration-status) |
| `POST \| DELETE /v1/agents/{agentId}/moh` | [Upload / remove hold music](/api-reference/agents/upload-moh) |
| `GET /v1/agents/{agentId}/call-logs` | [List an agent's calls](/api-reference/call-logs) |
| `GET /v1/call-logs/{callLogId}/recording` | [Fetch a call recording](/api-reference/call-logs/recording) |
| `POST \| GET /v1/agents/{agentId}/outbound-calls` | [Trigger / list outbound calls](/api-reference/outbound-calls/create) |
| `GET \| DELETE /v1/agents/{agentId}/outbound-calls/{callId}` | [Inspect](/api-reference/outbound-calls/get) / [cancel or delete](/api-reference/outbound-calls/delete) an outbound call |
| `DELETE /v1/outbound-calls/queued?to_number=…` | [Cancel every scheduled retry to a number](/api-reference/outbound-calls/cancel-queued) |
| `GET /v1/outbound-calls/export` | [Compliance audit export](/api-reference/outbound-calls/export) |
| `GET \| POST /v1/retry-policies` · `GET \| PATCH \| DELETE /v1/retry-policies/{policyId}` | [Retry policies](/api-reference/retry-policies/list-create) |
| `GET \| POST /v1/organizations/{organization_id}/suppression-list` · `DELETE …/suppression-list/{number}` | [Do-not-call list](/api-reference/suppression-list/list-add) |
| `GET \| POST /v1/organizations/{organization_id}/knowledge-bases` | [List / create knowledge bases](/api-reference/knowledge-bases/list-create) |
| `PUT \| DELETE /v1/knowledge-bases/{knowledgeBaseId}` | [Update / delete a knowledge base](/api-reference/knowledge-bases/update-delete) |
| `GET \| POST /v1/knowledge-bases/{knowledgeBaseId}/sources` | [List / add sources](/api-reference/knowledge-bases/sources) |
| `DELETE /v1/knowledge-sources/{sourceId}` | [Remove a source](/api-reference/knowledge-bases/source-actions) |
| `POST /v1/knowledge-sources/{sourceId}/enqueue` · `/reingest` | [Queue (re)ingestion](/api-reference/knowledge-bases/source-actions) |
| `GET /v1/knowledge-sources/{sourceId}/download` | [Download a source file](/api-reference/knowledge-bases/source-actions) |
| `GET /v1/rag/jobs/{jobId}` | [Poll an ingestion job](/api-reference/knowledge-bases/job-status) |
| `GET \| POST /v1/organizations/{organization_id}/guardrails` | [List / create guardrails](/api-reference/guardrails/list-create) |
| `PATCH \| DELETE /v1/guardrails/{guardrailId}` | [Update / delete a guardrail](/api-reference/guardrails/update-delete) |
| `GET /v1/voices` · `POST /v1/voices/preview` | [Voice catalogue / audio preview](/api-reference/voices/list) |
| `GET \| POST /v1/custom-voices` · `DELETE /v1/custom-voices/{voiceId}` | [Cloned voices](/api-reference/custom-voices/list) |
| `GET /v1/stt-providers` · `GET /v1/llm-models` · `GET /v1/email-servers` | [Config catalogs](/api-reference/stt-providers) |
| `GET \| POST /v1/accounts/{accountId}/resellers` | [List / create resellers](/api-reference/resellers/list) |
| `DELETE /v1/resellers/{resellerId}` | [Delete a reseller](/api-reference/resellers/delete) |
| `GET \| POST /v1/resellers/{resellerId}/organizations` | [List / create organizations](/api-reference/organizations/list) |
| `DELETE /v1/organizations/{organization_id}` | [Delete an organization](/api-reference/organizations/delete) |
| `POST /v1/organizations/{organization_id}/agents` | [Create a minimal agent in an organization](/api-reference/organizations/create-agent) |
| `POST /v1/sessions` · `POST /v1/sessions/netsapiens` | [Session bootstrap](/api-reference/sessions) |
| `POST /v1/organizations/{organization_id}/payments/onboarding` | [Start payment onboarding](/api-reference/payments/onboarding) |
| `GET /v1/organizations/{organization_id}/payments/status` | [Payment onboarding status](/api-reference/payments/status) |
| `GET /v1/payments/merchants` · `GET /v1/payments/transactions` | [Merchants / transactions](/api-reference/payments/merchants) |
| `GET /v1/agents/{agentId}/payments/readiness` · `PUT .../payments/tool` | [Agent payment readiness / tool](/api-reference/payments/agent-readiness) |
| `GET /v1/metrics` | [Usage metrics](/api-reference/metrics) |
| `GET /v1/reports/minutes-by-agent` · `/minutes-by-organization` | [Minutes reports](/api-reference/reports/minutes-by-agent) |
| `GET /v1/billing-report` | [Billing report](/api-reference/billing-report) |
| `GET /v1/places/search` | [Business/place search](/api-reference/places/search) |
| `POST /v1/mcp/test-connection` | [Validate an MCP server URL](/api-reference/mcp/test-connection) |

## UI recipes

Endpoint sequences for common screens. All calls via your server proxy.

**Agent manager** — list, create, edit, enable/disable:

1. `GET /v1/me` → account ID → `GET /v1/accounts/{accountId}/resellers` →
   `GET /v1/resellers/{resellerId}/organizations` to build the org picker.
2. `GET /v1/agents?organization_id={id}&page=1&limit=50` for the table.
3. Create: `POST /v1/agents`. Edit: `GET /v1/agents/{agentId}` then `PUT` with changed
   fields. Enable/disable toggle: `PATCH /v1/agents/{agentId}/status` (also carries SIP
   registration state — reflect the response, don't assume).

**Call-log viewer with playback:**

1. `GET /v1/agents/{agentId}/call-logs?page=…` for the table (timestamps, duration,
   sentiment, summary; filter with `startDate`/`endDate`).
2. On row click, `GET /v1/call-logs/{callLogId}/recording` and feed the result to an
   `<audio>` element via your proxy.

**Outbound call trigger:**

1. `POST /v1/agents/{agentId}/outbound-calls` with the destination number (`to_number`,
   E.164). Handle the 429 `agent_at_capacity` response.
2. Poll `GET /v1/agents/{agentId}/outbound-calls/{callId}` for status; offer `DELETE`
   to remove a finished call's record.

**Knowledge-base manager:**

1. `GET /v1/organizations/{organization_id}/knowledge-bases` → pick or `POST` a new one.
2. `GET /v1/knowledge-bases/{knowledgeBaseId}/sources`; add with `POST`. For files:
   `PUT` the bytes to the returned `presignedUrl`, then
   `POST /v1/knowledge-sources/{sourceId}/enqueue` with the returned `jobId`.
3. Poll `GET /v1/rag/jobs/{jobId}` until the job completes; show per-source status.

**Usage dashboard:**

1. `GET /v1/metrics?startDate=…&endDate=…` for headline numbers and charts.
2. `GET /v1/reports/minutes-by-agent` and `/minutes-by-organization` for breakdown
   tables; `GET /v1/billing-report` for the billing view.


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