Skip to content
RelationsAI
Try it uses test keys only. Requests go straight from your browser to https://voice-api.relationsai.com/v1 with a rai_test_ key, which never places a real call. It works once the API is enabled for your workspace (private preview: support@relationsai.com). Your key stays in this tab's memory; live keys are refused.
RelationsAI API

Place outbound calls and read their status, outcome, transcript, recording and analysis.


List calls

GET
https://voice-api.relationsai.com/v1
/calls
Bearer (rai_test_... or rai_live_...)

Lists calls, newest first, including calls placed from the console and by campaigns. Filter by agent, campaign, destination, status, outcome and creation time. List entries are the full call object without the transcript; read artifacts from their own endpoints.

Calls appear here as soon as they are accepted. Status and outcome are refreshed as the call progresses, typically within seconds, occasionally a minute or more behind; settled marks a call whose details are final.

When you filter by status, a page can hold fewer than limit calls while has_more is true; keep following next_cursor until it is null.

GET /v1/calls · Operation ID: listCalls

List calls › query Parameters

limit
​integer · min: 1 · max: 100

Maximum number of objects to return, from 1 to 100. Defaults to 25.

Default: 25
cursor
​string · minLength: 1 · maxLength: 512

The next_cursor of the previous page. Send it with exactly the same filters as the request that returned it; a changed filter set is 400 invalid_cursor.

created_after
​string · date-time

Only objects created at or after this time (RFC 3339, UTC).

created_before
​string · date-time

Only objects created before this time (RFC 3339, UTC).

agent_id
​string · pattern: ^agent_[A-Za-z0-9_-]…

Only calls handled by this agent.

campaign_id
​string · pattern: ^cmp_[A-Za-z0-9_-]{1…

Only calls placed by this campaign.

to
​string · e164 · pattern: ^\+[1-9][0-9]{7,14}$

Only calls to this number (E.164).

status
​string · enum

Only calls in this status.

Enum values:
queued
ringing
in_progress
ended
unknown
outcome
​string · enum

Only ended calls with this outcome.

Enum values:
completed
no_response
no_answer
busy
failed
unknown

List calls › Responses

A page of calls.

A page of calls, newest first.
object
​string · const · required

Always list.

Const value: list
has_more
​boolean · required

True when more objects exist after this page.

next_cursor
​string | null · required

Pass as cursor (with the same filters) to fetch the next page. Null on the last page.

​Call[] · required

Calls on this page.


Place a call

POST
https://voice-api.relationsai.com/v1
/calls
Bearer (rai_test_... or rai_live_...)

Places one outbound call from an agent to a phone number. The call runs after the request returns: the response is 202 Accepted with the call in queued status.

What 202 means. The call passed every check (agent readiness, account, balance and spend limits, the do-not-call list, consent, calling hours and the per-number daily limit) and is being started. It does not mean anyone has answered. Follow the call with the call.ended and call.settled webhooks, or poll GET /v1/calls/{call_id}. In rare cases the start is never confirmed; the call then ends with outcome: failed and end_reason: not_confirmed within about two minutes and is not charged.

Retries. Idempotency-Key is optional. With a key, a retry with the same key returns the original response and never places a second call, even if the first response was lost. Without one, a retry places another call: if a response was lost, list calls by to and created_after before retrying.

Caller number. Without phone_number_id, the agent's outbound number is used; when the agent has several, send phone_number_id.

Variables. variables are passed to the agent for this call. When to matches a contact, the contact's name and custom fields are added as variables too (your values win).

Charges. Live calls are charged per started minute of talk time at your workspace rate, from the workspace balance. A call that is not answered is not charged.

POST /v1/calls · Operation ID: createCall

Place a call › Headers

Idempotency-Key
​string · minLength: 1 · maxLength: 255 · pattern: ^[\x21-\x7E]+$

Optional. A unique key for this operation, 1 to 255 printable ASCII characters with no spaces (a UUID v4 is ideal). With it, a retry of the same request (same key, same body) returns the stored answer and never runs the action twice; reuse the same key for every retry, it is kept for 24 hours. Without it, every request runs: a retry after a timeout can repeat the action, so check the state with a GET before retrying.

Place a call › Request Body

Place one outbound call.
agent_id
​string · pattern: ^agent_[A-Za-z0-9_-]… · required

The agent that makes the call (agent_...). It must be ready (see the agent readiness endpoint).

to
​string · e164 · pattern: ^\+[1-9][0-9]{7,14}$ · required

The number to call, in E.164 format (a plus, then 8 to 15 digits, the first not 0).

phone_number_id
​string · pattern: ^pn_[A-Za-z0-9_-]{1,…

The workspace number to call from (pn_...). Optional: by default the agent's outbound number is used. Required when the agent has more than one outbound number.

​object · maxProps: 50

Values the agent can use in the conversation, for example {"first_name": "Asha"}. Up to 50 keys; keys are lowercase letters, digits and _, starting with a letter, up to 64 characters; values are strings up to 500 characters. If the destination matches a contact, the contact's name and custom fields are added automatically; values here take precedence.

​Metadata · maxProps: 16

Your own key-value data, stored with the object and returned as sent. Up to 16 keys; keys up to 40 characters (letters, digits, _, -, .), values strings up to 500 characters. Never sent to the person called and never used by the agent. Do not put secrets here.

Place a call › Responses

The call was accepted and is queued. Its id is final; follow it by webhook or polling.

An outbound call placed by an agent. A call moves through these statuses: `queued` (accepted; being placed) -> `ringing` (not reported today, see `capabilities.call_ringing_status` on the workspace) -> `in_progress` (connected) -> `ended`. After `ended`, the transcript, recording and analysis become ready (`artifacts`), and the charge is finalised. When everything is final, `settled` becomes true and a `call.settled` event is sent. `outcome`, `duration_seconds` and `cost` can still change between `ended` and `settled`; treat them as final only once `settled` is true.
id
​string · pattern: ^call_[A-Za-z0-9_-]{… · required

Call id (call_...).

object
​string · const · required

Always call.

Const value: call
livemode
​boolean · required

true for a live call, false for a simulated test-mode call.

status
​string · enum · required

Where the call is in its lifecycle. Open enum. unknown means the state could not be confirmed for an unusually long time; it is not a success.

Enum values:
queued
ringing
in_progress
ended
unknown
outcome
​string | null · enum · required

How the call ended. Null until status is ended. completed: answered and a conversation took place. no_response: answered but nobody spoke (this includes most voicemail greetings). no_answer, busy: not answered. failed: could not be connected. unknown: the result could not be determined. Open enum.

Enum values:
completed
no_response
no_answer
busy
failed
unknown
end_reason
​string | null · enum · required

Why the call ended. Null until status is ended. hangup: a normal end of a connected call. no_answer, busy, invalid_number, network_error: the call was not connected for that reason. insufficient_balance: ended because the workspace balance ran out. not_confirmed: the start was never confirmed, so the call is treated as failed and is not charged (whether the number briefly rang cannot be known). refused: the call was refused before it started. unknown. Open enum.

Enum values:
hangup
no_answer
busy
invalid_number
network_error
insufficient_balance
not_confirmed
refused
direction
​string · enum · required

Always outbound today. Open enum.

Enum values:
outbound
inbound
source
​string · enum · required

api (placed with POST /v1/calls), console, or campaign. Open enum.

Enum values:
api
console
campaign
agent_id
​string | null · required

The agent that handled the call. Null only if the agent was deleted.

campaign_id
​string | null · required

The campaign that placed the call, if any.

phone_number_id
​string | null · required

The workspace number the call was placed from, once known.

from
​string | null · required

The caller number shown to the person called (E.164), once known. Null when not known in full.

to
​string | null · required

The number called (E.164), always in full. Null only for some calls recorded before 2026-08-14 whose number was stored partially at the time; a partial number is never shown in place of a full one.

​Metadata · maxProps: 16 · required

Your own key-value data, stored with the object and returned as sent. Up to 16 keys; keys up to 40 characters (letters, digits, _, -, .), values strings up to 500 characters. Never sent to the person called and never used by the agent. Do not put secrets here.

created_at
​string · date-time · required

When the call was accepted.

ended_at
​string | null · date-time · required

When the call ended.

duration_seconds
​integer | null · min: 0 · required

Talk time in seconds once known. Final when settled is true.

billable_minutes
​integer | null · min: 0 · required

Minutes charged (whole minutes, rounded up). Zero for calls that are not charged. Final when settled is true.

​required

What the workspace was charged for this call. Null until known; always zero in test mode.

​CallArtifacts · required

Readiness of each artifact of the call. pending: not ready yet. ready: available from its endpoint. absent: there is none for this call (for example a call that was not answered has no recording). failed: it could not be produced. Open enum.

settled
​boolean · required

True when outcome, duration, artifacts and charge are all final.

settled_at
​string | null · date-time · required

When the call settled.


Retrieve a call

GET
https://voice-api.relationsai.com/v1
/calls/{call_id}
Bearer (rai_test_... or rai_live_...)

Returns one call with its status, outcome, timing, cost and the readiness of its artifacts. Poll it (no more than every few seconds) or, better, use webhooks. outcome, duration_seconds, billable_minutes and cost can still change until settled is true.

GET /v1/calls/{call_id} · Operation ID: getCall

Retrieve a call › path Parameters

call_id
​string · pattern: ^call_[A-Za-z0-9_-]{… · required

The call id (call_...).

Retrieve a call › Responses

The call.

An outbound call placed by an agent. A call moves through these statuses: `queued` (accepted; being placed) -> `ringing` (not reported today, see `capabilities.call_ringing_status` on the workspace) -> `in_progress` (connected) -> `ended`. After `ended`, the transcript, recording and analysis become ready (`artifacts`), and the charge is finalised. When everything is final, `settled` becomes true and a `call.settled` event is sent. `outcome`, `duration_seconds` and `cost` can still change between `ended` and `settled`; treat them as final only once `settled` is true.
id
​string · pattern: ^call_[A-Za-z0-9_-]{… · required

Call id (call_...).

object
​string · const · required

Always call.

Const value: call
livemode
​boolean · required

true for a live call, false for a simulated test-mode call.

status
​string · enum · required

Where the call is in its lifecycle. Open enum. unknown means the state could not be confirmed for an unusually long time; it is not a success.

Enum values:
queued
ringing
in_progress
ended
unknown
outcome
​string | null · enum · required

How the call ended. Null until status is ended. completed: answered and a conversation took place. no_response: answered but nobody spoke (this includes most voicemail greetings). no_answer, busy: not answered. failed: could not be connected. unknown: the result could not be determined. Open enum.

Enum values:
completed
no_response
no_answer
busy
failed
unknown
end_reason
​string | null · enum · required

Why the call ended. Null until status is ended. hangup: a normal end of a connected call. no_answer, busy, invalid_number, network_error: the call was not connected for that reason. insufficient_balance: ended because the workspace balance ran out. not_confirmed: the start was never confirmed, so the call is treated as failed and is not charged (whether the number briefly rang cannot be known). refused: the call was refused before it started. unknown. Open enum.

Enum values:
hangup
no_answer
busy
invalid_number
network_error
insufficient_balance
not_confirmed
refused
direction
​string · enum · required

Always outbound today. Open enum.

Enum values:
outbound
inbound
source
​string · enum · required

api (placed with POST /v1/calls), console, or campaign. Open enum.

Enum values:
api
console
campaign
agent_id
​string | null · required

The agent that handled the call. Null only if the agent was deleted.

campaign_id
​string | null · required

The campaign that placed the call, if any.

phone_number_id
​string | null · required

The workspace number the call was placed from, once known.

from
​string | null · required

The caller number shown to the person called (E.164), once known. Null when not known in full.

to
​string | null · required

The number called (E.164), always in full. Null only for some calls recorded before 2026-08-14 whose number was stored partially at the time; a partial number is never shown in place of a full one.

​Metadata · maxProps: 16 · required

Your own key-value data, stored with the object and returned as sent. Up to 16 keys; keys up to 40 characters (letters, digits, _, -, .), values strings up to 500 characters. Never sent to the person called and never used by the agent. Do not put secrets here.

created_at
​string · date-time · required

When the call was accepted.

ended_at
​string | null · date-time · required

When the call ended.

duration_seconds
​integer | null · min: 0 · required

Talk time in seconds once known. Final when settled is true.

billable_minutes
​integer | null · min: 0 · required

Minutes charged (whole minutes, rounded up). Zero for calls that are not charged. Final when settled is true.

​required

What the workspace was charged for this call. Null until known; always zero in test mode.

​CallArtifacts · required

Readiness of each artifact of the call. pending: not ready yet. ready: available from its endpoint. absent: there is none for this call (for example a call that was not answered has no recording). failed: it could not be produced. Open enum.

settled
​boolean · required

True when outcome, duration, artifacts and charge are all final.

settled_at
​string | null · date-time · required

When the call settled.