# API for AI assistants

> Instructions an AI assistant follows to build tables, templates, Flows and automations in Avox with an API key: read this first.

Source: https://docs.theavoxai.com/avox-api/ai-assistants

This page is written for an AI assistant (ChatGPT, Claude, Gemini, an agent in your own code)
that has been given an Avox API key and asked to build something: a booking table, a template,
a WhatsApp Flow, an automation. If you are a person, give your assistant this page's address
together with the key, and ask it to read the page first.

> **Note**
>
> Everything below is an instruction to the assistant. The full list of endpoints is on
> [Builder API reference](https://docs.theavoxai.com/avox-api/reference), the machine-readable version is
> [/openapi.json](https://docs.theavoxai.com/openapi.json), and every error code is on [API errors](https://docs.theavoxai.com/api/errors).

## Instructions for the assistant

Follow these rules in order. They keep the person's Switchboard safe and make every call succeed
the first time.

**1. Read the docs before calling anything**

Read this page, then [Builder API quick start](https://docs.theavoxai.com/avox-api/builder) and the reference page for the
area you will build in: [Tables and rows](https://docs.theavoxai.com/avox-api/tables), [Flows](https://docs.theavoxai.com/avox-api/flows),
[Templates](https://docs.theavoxai.com/avox-api/templates) or [Automations](https://docs.theavoxai.com/avox-api/automations). The machine-readable
schema of every request body is at [/openapi.json](https://docs.theavoxai.com/openapi.json). Never guess a field name: use
the ones the docs and the schema show.

**2. Authenticate with the key you were given, and nothing else**

Send `Authorization: Bearer <key>` on every request to `https://api.avox.com/api/v1/...`. The key
starts with `avx_live_` or `avx_test_`. Never ask the person for a password, a dashboard sign-in,
a Meta or WhatsApp token, or any other secret: the key is all you need. Never print the key back,
write it into files you share, or put it in a URL.

**3. Call GET /api/v1/me first**

It tells you the key's Switchboard, its WhatsApp number, its **scopes** (what it may do), and
every limit with what's already used: tables, rows per table, Flows, templates, automations,
live requests this month, and today's builder calls (reads and writes). Plan your work so it fits.
If a scope you need is missing, stop and tell the person which one (for example
`tables:write`): an Admin adds it in **Settings > API Keys > Permissions**.

**4. Call GET /api/v1/catalog next**

It lists the premade tables, Flows, templates and automations with their ids, what each needs,
and the allowed column types, trigger types and step types. Starting from a premade is faster
and safer than building from scratch: prefer one when it fits what the person asked for.

**5. Build in this order: table, template, Flow, automation**

Later pieces point at earlier ones by id, so make them in this order:

1. **Tables** first (`POST /api/v1/tables`, then rows). A Flow or automation that uses a table
   needs its id and its column ids.
2. **Templates** next (`POST /api/v1/templates`). WhatsApp reviews every new template; it is
   `PENDING` until WhatsApp decides. An automation can only be switched on with **approved**
   templates, so check `GET /api/v1/templates/{id}` until `status` is `APPROVED` (reviews can take
   from minutes to a day; don't poll faster than once a minute).
3. **Flows** next (`POST /api/v1/flows` makes a draft). Validate it, fix what the validation
   reports, then publish it.
4. **Automations** last (`POST /api/v1/automations`). They are created as drafts; switch one on
   with `POST /api/v1/automations/{id}/activate` only when the person wants it live.

**6. Always validate before you publish**

For a Flow, call `POST /api/v1/flows/{id}/validate` (or `POST /api/v1/flows/validate` with JSON
before you create it) and fix every item in `validation.lint.errors`,
`validation.lint.live` (severity `error`) and `validation.validationErrors` before
`POST /api/v1/flows/{id}/publish`. A published Flow can't change. For an automation, read the
`problems` list each save returns and fix them before you activate it.

**7. Send an Idempotency-Key with every create**

Make a new random value (a UUID) for each new thing you create and send it as the
`Idempotency-Key` header. If a request times out or you aren't sure it worked, retry with the
**same** key and the **same** body: you get the first result back and nothing is made twice. A
different body with the same key is refused (`idempotency_conflict`).

**8. Send If-Match when you change something**

Every item comes with an `etag`. When you change it, send `If-Match: <etag>`. If someone changed
it in the meantime you get `412 version_conflict` and nothing is written: read it again, apply
your change to the new version, and retry. For rows, send each row's `updatedAt` instead.

**9. Respect the limits**

Every call counts against the plan's daily builder calls (reads and writes apart; see
`limits.apiCallsToday` in `/me`, and the `Avox-Daily-Remaining` header on every answer). Prefer
one bulk request (up to 1,000 rows) over many single ones. On `429`, wait the number of seconds
in `Retry-After` before retrying. Never loop on an error.

**10. Read every error and fix the cause**

Errors look like `{ "ok": false, "error": { "code", "message", "docs_url", "request_id", "details" } }`.
`details` lists each problem with a `path` (the field, like `rows[3].price` or
`actions[1].actionConfig.templateId`) and a `message`. Fix exactly those fields and retry. The
`docs_url` explains the code and what to do. Retry unchanged only for `rate_limited`,
`idempotency_in_progress`, `meta_unreachable` and `internal_error`.

**11. Confirm before anything is deleted or goes live**

Ask the person before you delete a table, column, row, Flow, template or automation, before you
publish a Flow, and before you switch an automation on. Never send `force: true` or
`confirm: true` without telling the person what will happen (the error that asks for it lists
what would break or which values would be emptied).

## What you can't do with a key

Some things stay in the dashboard on purpose. Tell the person to do these there when they come up:

- Connecting a WhatsApp number, billing, plans and team members.
- Creating, rotating or revoking API keys, and changing a key's permissions.
- Uploading a sample image, video or document for a template header.
- Making the signing secret for a Flow's own server (pass-through live data).
- Connecting apps (payments, calendars, meetings, CRM) that automations use.

A **test key** (`avx_test_...`) can read everything its scopes allow and run every check
(`/me`, `/catalog`, lists, `validate`, a CSV import `dry_run`), but every change is refused with
`test_key_read_only`. Use one to plan and check your work; use a live key to make it.

## A complete session, step by step

This is what a good session looks like for "set up booking reminders for my salon".

```bash
# 1. Who am I, what may I do, what's left on the plan?
curl https://api.avox.com/api/v1/me -H "Authorization: Bearer $AVOX_API_KEY"

# 2. What can I start from?
curl https://api.avox.com/api/v1/catalog -H "Authorization: Bearer $AVOX_API_KEY"

# 3. The Appointments table, from its premade.
curl -X POST https://api.avox.com/api/v1/tables \
  -H "Authorization: Bearer $AVOX_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 6f1e8a1c-4b6e-4a55-9a43-2a1c3e7d9b10" \
  -d '{"premadeId":"appointments"}'

# 4. The reminder template, from the Avox library (WhatsApp reviews it).
curl -X POST https://api.avox.com/api/v1/templates \
  -H "Authorization: Bearer $AVOX_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 0d3b2f9e-8f61-4c0b-a0a7-5d7f1e2c4b88" \
  -d '{"libraryId":"booking_reminder","language":"en_US"}'

# 5. Once the template is APPROVED: the premade automation, as a draft.
curl -X POST https://api.avox.com/api/v1/automations \
  -H "Authorization: Bearer $AVOX_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 9a7c5e3b-1d2f-4e6a-8b9c-0f1e2d3c4b5a" \
  -d '{"premadeId":"booking_reminder_day","timeZone":"Asia/Kolkata"}'

# 6. After the person says yes: switch it on.
curl -X POST https://api.avox.com/api/v1/automations/AUTOMATION_ID/activate \
  -H "Authorization: Bearer $AVOX_API_KEY"
```

If step 5 answers `automation_not_ready`, its `details` say exactly what's missing (a table made
from a premade table, an approved template, a connected app) and how to make it.

## Related
