Skip to main content
One conversation with its transcript

Authorizations

Authorization
string
header
required

Every request sends Authorization: Bearer <token>. The token is either a panel session (a JWT from /auth/login, 12 hours) or an API key ft_<id>_<secret>. An API key is accepted only from an address on its IP allowlist (403 ip_not_allowed otherwise; 403 ip_allowlist_required for an old key that has none), is limited to its rate per minute (429 rate_limited with Retry-After; X-RateLimit-Limit/Remaining/Reset on every response), and at most 60 call placements a minute.

Response

OK

agent_id
string<uuid>
agent_kind
enum<string>
Available options:
human,
virtual
ai_billing_mode
enum<string>

byo means the tenant's own credential paid, so they were billed by the provider directly and no amount appears here.

Available options:
byo,
rated
ai_cost_amount
string

What the operator paid the provider. Absent without margin:read, and absent whenever the tenant's own key paid.

ai_sell_amount
string

What the AI on this call cost, as an exact decimal string. ABSENT, never zero, in three situations that must not be confused: the caller lacks billing:read, no price row matched the model, or the tenant's own credential paid the provider so there is nothing for us to charge.

audio_split_known
boolean

False when the provider itemised no audio tokens at all. It changes how every figure here should be read: tokens_audio is then "not reported" rather than "none", and the audio was priced at the TEXT rate because there is no other number to price it at. Reported so an approximate amount is not read as an exact one. Gemini reports no split.

call_uuid
string<uuid>
contact_e164
string
contact_id
string<uuid>
direction
enum<string>
Available options:
inbound,
outbound
ended_at
string<date-time> | null
flags
object[]

The post-call review of an AI agent's conversation. competitor: an agent turn named one of the profile's competitor_names (seq is the turn). never_searched: the knowledge base was too large to give the agent whole and it answered without searching it. Empty when the review found nothing, or did not run (a human agent).

id
string<uuid>
model
string
organisation_id
string<uuid>
provider
string

Null for a human-handled call.

started_at
string<date-time>
summary
string
tokens_audio
integer

The audio PORTION of tokens_input, not a third total. Adding it to input charges the audio twice. Counts as the provider reported them, not money: prices change, and an amount computed from a hardcoded price is silently wrong later.

tokens_input
integer
tokens_output
integer
turn_count
integer
virtual_agent_profile_id
string<uuid>

The profile that handled this call, as it was at the time. Not a live reference to the agent's current profile.

virtual_agent_profile_name
string

The profile's name as recorded when the call ran, so a later rename does not restate history.

assembled_context
string

Exactly what the agent was told before it spoke.

turns
object[]