# Quickstart (https://docs2.smao.ai/docs/public/quickstart)



From a fresh API key to a live outbound call. All examples use
`https://api2.smao.ai/api/v1`.

## 1. Create an API key [#1-create-an-api-key]

In the dashboard, go to **Settings → API Keys** and create a key. Each key is
scoped to your organization and to a single **Role**, which determines the
endpoints it may call. Newly generated keys are \~43-character base64url
strings with no prefix; legacy `smao_`-prefixed keys remain valid. Export it
for the examples below:

```bash
export SMAO_API_KEY="<your_api_key>"
```

## 2. Check connectivity [#2-check-connectivity]

```bash
curl https://api2.smao.ai/api/v1/ping \
  -H "Authorization: Bearer $SMAO_API_KEY"
```

```json
{ "data": { "ok": true, "now": "2026-07-01T12:00:00.000Z" } }
```

A `401` with `error.code = "unauthorized"` means the key is missing or
invalid — see [Errors](/docs/errors).

## 3. Choose a voice [#3-choose-a-voice]

Fetch the voices currently selectable for new assistants and voice changes:

```bash
curl https://api2.smao.ai/api/v1/voices \
  -H "Authorization: Bearer $SMAO_API_KEY"
```

Use an `id` from the response as `voice_id` below. See
[listVoices](/docs/public/voices/listVoices) for the response schema.

## 4. Create an assistant [#4-create-an-assistant]

`name`, `language`, `voice_id`, `company_name`, `company_industry`, and
`introduction` are required. The platform assigns the phone number.

```bash
curl -X POST https://api2.smao.ai/api/v1/assistants \
  -H "Authorization: Bearer $SMAO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Sarah",
    "language": "en",
    "voice_id": "<voice_id>",
    "company_name": "Example GmbH",
    "company_industry": "Retail",
    "introduction": "Hello, you have reached Example GmbH. How can I help you?"
  }'
```

The `201` response contains the assistant under `data`, including its
generated `id` (needed below) and assigned `phone_number`. See
[createAssistant](/docs/public/assistants/createAssistant) for all optional fields.

## 5. Add knowledge [#5-add-knowledge]

Knowledge items live in groups: create a `knowledges` group, add an item,
attach the group to your assistant.

```bash
curl -X POST https://api2.smao.ai/api/v1/groups \
  -H "Authorization: Bearer $SMAO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "type": "knowledges", "name": "FAQ" }'
```

Take `data.id` from the response and create the item:

```bash
curl -X POST https://api2.smao.ai/api/v1/knowledge-items \
  -H "Authorization: Bearer $SMAO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "group_id": "<group_id>",
    "name": "Opening hours",
    "text": "We are open Monday to Friday, 9:00 to 18:00."
  }'
```

Attach the group to the assistant:

```bash
curl -X PATCH https://api2.smao.ai/api/v1/assistants/<assistant_id> \
  -H "Authorization: Bearer $SMAO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "knowledge_group_ids": ["<group_id>"] }'
```

<Callout>
  Embedding is asynchronous: `sync_status.state` moves `pending` → `syncing` →
  `synced` (or `failed`). There are no event webhooks — poll
  [getKnowledgeItem](/docs/public/knowledge-items/getKnowledgeItem) until the
  item is `synced` or `failed`, and apply a client-side timeout so a persistent
  `pending` state does not create an endless poll loop.
</Callout>

## 6. Place an outbound call [#6-place-an-outbound-call]

Provide exactly one of `assistant_id` or `assistant_phone`, and exactly one of
`to` or `target_phone`. Numbers are E.164 (`+` followed by 6–20 digits).

```bash
curl -X POST https://api2.smao.ai/api/v1/calls \
  -H "Authorization: Bearer $SMAO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "assistant_id": "<assistant_id>",
    "to": "+491701234999",
    "details": "Follow-up on order 4711."
  }'
```

```json
{
  "data": {
    "call_id": "65f8fa6f1a9d8e0012ab34cd",
    "assistant_id": "<assistant_id>",
    "assistant_phone": "+491701234567",
    "to": "+491701234999",
    "status": "queued",
    "created_at": "2026-07-01T12:00:00.000Z"
  }
}
```

<Callout type="warn">
  `POST /calls` defaults to a **60 requests/hour** bucket per API key and also
  permits only one outbound call per assistant in any 60-second window. On
  `429`, use `Retry-After` when present; otherwise wait at least 60 seconds and
  retry with exponential backoff.
</Callout>

Once the call completes, poll [getCall](/docs/public/calls/getCall) for the
transcript and analyses, and [getCallRecording](/docs/public/calls/getCallRecording)
for the audio.

## 7. Where next [#7-where-next]

* The full endpoint reference in the sidebar — every page has an interactive playground.
* [Errors](/docs/errors) — error envelope, codes, and retry guidance.
* [Authentication](/docs/authentication) — key handling and role scoping.
