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

# Setup steps for your assistant

> The steps an AI assistant follows to get its own Brilo phone number and API key: start a pairing, show the owner a link and code, check until it completes, then place a call.

<Note>
  This page is written for AI assistants. Setting this up yourself? Go to
  [Give your assistant a phone number](/personal-assistants) and copy the prompt.
</Note>

Follow these steps to get your own Brilo phone number and an API key. Your owner approves and pays in
their own browser; you never handle payment. At the end you receive `api_key`, `phone_number` and
`agent_id`, and you can place calls from that number and read the calls people make to it.

## Rules

* Never pay, sign up or approve anything for your owner.
* Keep `device_code` and `api_key` out of the chat, logs, URLs and source files.
* **`approved` does not mean done.** It means your owner has paid and the number is still being set
  up. Keep checking until `status` is `completed`.
* Every response has `message` and `action` in plain English. Follow `action`.

## 1. Start

No API key is needed. Send your own product name as `client_name` (up to 64 characters). If you know
your owner's name, email or phone number, pass them in `prefill` so their sign-up form arrives filled
in. Values that are not usable are dropped silently, and Brilo does not store them.

```bash theme={null}
curl -X POST https://api.brilo.ai/v1/agent/onboarding/start \
  -H "Content-Type: application/json" \
  -d '{"client_name": "Meta Muse",
       "prefill": {"first_name": "Maya", "last_name": "Chen",
                   "email": "maya@example.com", "phone": "+14155550123"}}'
```

```json theme={null}
{
  "device_code": "Xk9pQ2mZ...",
  "user_code": "7FK9-BHDQ",
  "verification_url": "https://dashboard.brilo.ai/agent-setup",
  "verification_url_complete": "https://dashboard.brilo.ai/agent-setup?code=7FK9-BHDQ#first_name=Maya&last_name=Chen&email=maya%40example.com&phone=%2B14155550123",
  "expires_in": 900,
  "interval": 5
}
```

## 2. Show your owner the link and the code

Send this, filling in the values. Send the link as something they can tap, and put the code on its
own line so they can check it matches the page.

```text theme={null}
Here's your link: <verification_url_complete>
Your code: <user_code>
Sign up and pay on that page. The code should match. It lasts 15 minutes.
```

If you cannot send links, read out `verification_url` and the code instead. Do not open the link
yourself: the page is for your owner.

## 3. Check until it is done

Call `POST /v1/agent/onboarding/poll` with the `device_code`, waiting at least `interval` seconds
between calls.

**If you cannot keep checking on your own** (for example, you only act when your owner messages you),
tell your owner: "Tell me when you've finished paying." Then check once when they do.

```bash theme={null}
curl -X POST https://api.brilo.ai/v1/agent/onboarding/poll \
  -H "Content-Type: application/json" \
  -d '{"device_code": "Xk9pQ2mZ..."}'
```

| `status`                   | What it means                                         | What to do                                                                                                                                             |
| -------------------------- | ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `pending`                  | Your owner has not finished yet.                      | Keep checking. If they ask, their code is still waiting.                                                                                               |
| `payment_failed`           | The card was declined. The same code still works.     | Keep checking. Tell them they can try another card on the page they have open.                                                                         |
| `approved`, `provisioning` | Paid. The number is being set up.                     | Keep checking. This usually takes under a minute. If it is still setting up after 10 minutes, stop and tell your owner Brilo is finishing their setup. |
| `completed`                | Done. This response carries your key.                 | Store `api_key` in secret storage and stop checking.                                                                                                   |
| `denied`                   | Your owner said no.                                   | Stop. Do not start again unless they ask.                                                                                                              |
| `expired`                  | The 15 minutes ran out before they paid.              | Stop. Start again only if they still want it.                                                                                                          |
| `failed`                   | Setup could not finish. It is not your owner's fault. | Stop and tell them Brilo will be in touch.                                                                                                             |

Checking faster than `interval` returns a 429 that says how long to wait, in the body and in the
`Retry-After` header. Wait that long, then continue.

```json theme={null}
{
  "statusCode": 429,
  "error": "Too Many Requests",
  "code": "slow_down",
  "message": "You are checking too often.",
  "action": "Wait 10 seconds, then check again.",
  "retry_after": 10
}
```

## 4. Save your key

```json theme={null}
{
  "status": "completed",
  "message": "Pairing complete. This API key is ready to use.",
  "api_key": "sk_...",
  "workspace_id": "...",
  "phone_number": "+14155550199",
  "agent_id": "...",
  "limits": {
    "concurrent_calls": 1,
    "max_call_minutes": 60,
    "calls_per_hour": 20,
    "calls_per_day": 100,
    "call_minutes_per_day": 600,
    "calls_per_destination_per_day": 10
  }
}
```

If your connection drops, check again: a completed pairing returns the same key. If the response has
`code: pairing_key_replaced`, another assistant has been connected to this number since; start a new
pairing if your owner wants you back. Then tell your owner their new number.

## 5. Remember that you can make calls

Save a note in your long-term memory, custom instructions or notes file (whatever you keep across
chats), so that in any later conversation you know you can make and check phone calls for your owner.
Replace each `<...>` with the value from the step 4 response; do not copy the placeholders. Never put
the key itself in the note:

```text theme={null}
I can make and check phone calls for my owner with Brilo.
- My Brilo number: <phone_number>. My agent_id: <agent_id>. My Brilo key is in my secure storage.
- To call someone: POST https://api.brilo.ai/v1/call. How to write the call:
  https://docs.brilo.ai/personal-assistants/connect.md
- To see calls: GET https://api.brilo.ai/v1/call
- If I have no key, set up again from that page.
```

Then tell your owner: "Saved. In any chat, just ask me to call someone."

## 6. Make the first call

Send your key as `Authorization: Bearer <api_key>`. Ask your owner which number to call for the test,
then ring them.

Your owner's agent is set up to **answer** their calls. Its saved greeting ("Hi, you've reached ...")
is for people calling in, so every call you place brings its own script in `agent_overrides`:

| Field                 | Required                  | What to send                                                                                                                                            |
| --------------------- | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `instruction`         | Yes                       | What the call is for. Fill in the short template below.                                                                                                 |
| `greeting`            | Yes                       | The first thing the agent says when someone picks up, e.g. "Hi Maya, this is Sam's assistant, calling with a quick update."                             |
| `voicemail_behavior`  | No                        | `HANG_UP` or `LEAVE_MESSAGE` if the call reaches voicemail. Defaults to `HANG_UP`, or `LEAVE_MESSAGE` if you send a `voicemail_message`.                |
| `voicemail_message`   | Only with `LEAVE_MESSAGE` | The message to leave, word for word.                                                                                                                    |
| `summary_instruction` | Yes, always send it       | What the call summary should tell you, so you can report back to your owner. The API does not check this one, but without it you get a generic summary. |

Fill in `instruction` yourself from what your owner asked for. Do not ask them for these; a line
or two each is enough:

```text theme={null}
# Personality
Sam's personal assistant. Warm, brief and polite.

# Goal
Tell Maya that Sam's new assistant number is working.

# Guardrails
- Say you are Sam's assistant if asked. Never claim to be Sam or agree to anything on Sam's behalf.
- If Maya asks something not covered here, say you will check with Sam.
- Keep it under one minute.
```

The `instruction` replaces everything the agent knows, so put in it what the person answering will
ask about:

* **Who the call is for**: your owner or their business, by name, so the agent can answer "who is
  this?".
* **The facts**: who, what, where and when, and how to reach your owner. The agent has nothing else to
  go on.
* **What to do when it does not know**: offer to check and follow up, or take a message. Never guess.

Write `summary_instruction` the same way, from what your owner will want to know: whether the person
was reached, what they said, and anything they asked for, including whether and when they want a
call back. Brilo does not schedule callbacks for you: remember the time and place that call yourself.

The same call as a request body. In JSON the line breaks are written as `\n`:

```json theme={null}
{
  "agent_id": "...",
  "to": "+14155550123",
  "agent_overrides": {
    "instruction": "# Personality\nSam's personal assistant. Warm, brief and polite.\n\n# Goal\nTell Maya that Sam's new assistant number is working.\n\n# Guardrails\n- Say you are Sam's assistant if asked. Never claim to be Sam or agree to anything on Sam's behalf.\n- If Maya asks something not covered here, say you will check with Sam.\n- Keep it under one minute.",
    "greeting": "Hi Maya, this is Sam's assistant, calling with a quick update.",
    "voicemail_behavior": "LEAVE_MESSAGE",
    "voicemail_message": "Hi Maya, this is Sam's assistant. Just letting you know the new number works. No need to call back.",
    "summary_instruction": "Say whether Maya picked up and heard the message. List any question she asked or anything she wants Sam to do, in her words. Note if it went to voicemail or was a wrong number."
  }
}
```

Save it as `call.json` and send it:

```bash theme={null}
curl -X POST https://api.brilo.ai/v1/call \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  --data @call.json
```

A call without an `instruction` or a `greeting` is refused with `call_script_incomplete`, and the
response names what is missing. Calls ring straight away; they are not held for quiet hours.

You can call and text numbers in the US and Canada.

## 7. Find out how the call went

A call takes as long as it takes. Check `GET /v1/call/{id}`, waiting `retry_after` seconds between
checks, and stop when `retry_after` is no longer in the response. Checking faster does not finish the
call sooner.

| `status`                       | Meaning                                                                                                           |
| ------------------------------ | ----------------------------------------------------------------------------------------------------------------- |
| `queued`, `dialing`            | Starting. Keep checking.                                                                                          |
| `in-progress`                  | Someone answered and the call is live.                                                                            |
| `completed`                    | Over. Read `summary` (written to your `summary_instruction`) and `transcript`, and tell your owner what happened. |
| `failed`, `blocked`, `skipped` | It did not happen. Read the response before trying again.                                                         |

## Errors

Errors carry `code`, `message` and `action`. Limit errors also carry `limit`, `used` and `resets_at`,
so you can tell your owner exactly when they can try again.

| `code`                      | HTTP                 | Where          | What to tell your owner                                                     |
| --------------------------- | -------------------- | -------------- | --------------------------------------------------------------------------- |
| `slow_down`                 | 429                  | `/poll`        | Nothing. Wait `retry_after` seconds.                                        |
| `rate_limited`              | 429                  | any            | Nothing. Wait `retry_after` seconds.                                        |
| `pairing_not_found`         | 401                  | `/poll`        | Start a new pairing and show them the new code.                             |
| `pairing_key_replaced`      | 201 (a normal reply) | `/poll`        | Another assistant took over this number. Start again if they want you back. |
| `hourly_call_cap`           | 429                  | `/call`        | 20 calls an hour is the limit. Tell them when it resets.                    |
| `daily_call_cap`            | 429                  | `/call`        | 100 calls a day is the limit. Tell them when it resets.                     |
| `daily_minute_cap`          | 429                  | `/call`        | 600 call minutes a day is the limit. Tell them when it resets.              |
| `destination_call_limit`    | 429                  | `/call`        | That number has had 10 calls today, or 30 this month. Do not retry it.      |
| `destination_not_supported` | 400                  | `/call`, texts | Only numbers in the US and Canada can be called or texted.                  |
| `call_script_incomplete`    | 400                  | `/call`        | Nothing. Add the fields listed in `missing` and send the call again.        |

Check what is left before you call: `GET /v1/usage` returns each limit with `limit`, `used`,
`remaining` and `resets_at`. Full request and response shapes are in the
[API reference](/api-reference/introduction).

## Keep it safe

* Your owner can end your access by connecting another assistant, which replaces your key.
* One call at a time: while a call is live, a second one is refused.
* For machine-readable docs, read [/llms.txt](https://docs.brilo.ai/llms.txt), or add `.md` to any
  page URL.
