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

# Changelog

> What changed in the public API, and how changes are made.

## How the API changes

* **The public API is `/api/v1`.** Operations in the
  [public document](/api/reference) don't change incompatibly within `v1`. New
  fields, new events and new optional parameters can appear at any time, so
  ignore what you don't recognise.
* **An incompatible change** means a new version. The old one keeps working
  for at least six months after the new one is announced here.
* **Endpoints outside the public document** are the panel's own interface and
  can change without notice.

## 2026-09-20: capacity refusals, and a call's currency

* **`503 node_busy`** on `POST /calls` and `POST /calls/ai`, with
  `Retry-After: 30`: the call was not placed because the node has no room right
  now — it is at its channel limit, the machine is loaded, or every AI session
  it allows is in use. Nothing rang and nothing was billed; send the same
  request again. This is deliberately not `422`, which still means the request
  itself is wrong.
* **Call records gain `currency`**: the ISO 4217 code that `sell_amount`,
  `cost_amount` and `margin` are in. It is absent on calls recorded before this
  date — the field existed and was never filled.
* With `margin:read`, call records also gain `cost_currency`,
  `cost_amount_original`, `fx_rate` and `cost_unconverted`: what the carrier
  charged in its own currency, the exchange rate applied, and whether a rate was
  missing. When `cost_unconverted` is `true`, **`margin` is not a margin** — it
  is one currency subtracted from another — and must not be shown as money.

## 2026-09-15: the public API

* **Integration keys:**
  * owned by the organisation, with presets;
  * a **compulsory IP allowlist**;
  * per-key rate limits;
  * `Idempotency-Key`.
* **Calls:**
  * click-to-call by `from` (extension, agent or login email);
  * `POST /calls/ai` for an AI agent to call someone;
  * `reference` and signed `callback_url` on every call;
  * `?dry_run=true`;
  * `GET /calls/{uuid}` and `/call-requests/{id}`.
* **Campaigns:**
  * contacts loaded with your references and variables;
  * start, pause, resume and stop;
  * per-contact results to `result_callback_url`, with `GET /campaigns/{id}/results`.
* **Contacts and data:**
  * `GET /contacts/lookup`;
  * `PUT /contacts/by-reference/{ref}`;
  * `GET /cdrs/export`.
* **Webhooks:**
  * durable delivery, retried for about 15 hours and switched off after three
    days of failures;
  * redelivery;
  * new events: `call.missed`, `voicemail.received`, `recording.ready`,
    `conversation.completed`, `callback.requested`, `ticket.created`,
    `ticket.updated`, `contact.created`, `campaign.contact.completed`,
    `campaign.completed`, `csat.submitted`.
* **The Developer section** in the panel: console, callback inbox, request log
  and test numbers.
