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

# Quickstart

> From nothing to a signed callback in about ten minutes.

## 1. Make an integration key

In your panel, open **Developer → API keys → New key**:

* **Kind:** Integration. The key belongs to your organisation and keeps working
  when staff change.
* **What it may do:** *Click-to-call*.
* **Allowed IP addresses:** the public address your code will call from.
  **Add my current address** fills in yours if you're running the code from
  where you are now.

Copy the secret; it's shown once.

```bash theme={null}
export FIRETONE_KEY=ft_…
export API=https://api.firet.one/api/v1
```

## 2. Ask who you are

```bash theme={null}
curl $API/auth/me -H "authorization: Bearer $FIRETONE_KEY"
```

You get your organisation and the permissions the key holds.

* `403 ip_not_allowed`: the request came from an address the key doesn't list.
* `401`: the key was copied wrongly.

## 3. Get somewhere to receive callbacks

* **Developer → Callback inbox → New inbox** gives you a URL that keeps what
  it's sent.
* **Developer → Webhooks & callbacks → Callback signing secret → Create**
  creates the secret callbacks are signed with.

## 4. Place a call, dry first

```bash theme={null}
curl -X POST "$API/calls?dry_run=true" \
  -H "authorization: Bearer $FIRETONE_KEY" -H 'content-type: application/json' \
  -d '{ "from": { "extension": "1001" }, "to": "+61412345678" }'
```

The dry run checks everything a real call would, and places nothing:

* the extension has a phone that can ring;
* the number resolves;
* a route reaches it;
* there's credit.

Then drop `dry_run` and add your own id and the inbox:

```bash theme={null}
curl -X POST $API/calls \
  -H "authorization: Bearer $FIRETONE_KEY" -H 'content-type: application/json' \
  -H "Idempotency-Key: quickstart-1" \
  -d '{ "from": { "extension": "1001" }, "to": "+61412345678",
        "reference": "quickstart-1", "callback_url": "<your inbox URL>" }'
```

Extension 1001 rings. When it answers, the number is dialled.

## 5. Watch it arrive

The inbox shows `call.started`, `call.answered` and `call.ended`, each with
`"reference": "quickstart-1"` and marked **signed: callback secret**. That's
exactly what your receiver will get. Check the signature the same way:

```js theme={null}
const crypto = require("crypto");
function verified(secret, header, rawBody) {
  const { t, v1 } = Object.fromEntries(header.split(",").map((p) => p.split("=")));
  const mac = crypto.createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex");
  return Math.abs(Date.now() / 1000 - Number(t)) < 300 && v1?.length === mac.length &&
    crypto.timingSafeEqual(Buffer.from(mac), Buffer.from(v1));
}
```

## Next

* [Placing calls](/api/calls): AI calls and following a call.
* [Running campaigns](/api/campaigns) from your system.
* [Webhooks](/api/webhooks) for everything else that happens.
* [Errors](/api/errors) and what to do about each.
