Consult & conference

During a live call, your bot can bring a second party onto the call through two REST endpoints hosted by Fonada.

  • Consult (attended transfer) places the caller on hold and connects the bot privately to a second party, such as a human agent.
  • Conference adds one or more parties into a single mixing bridge where everyone hears everyone.

Both are HTTP calls, not WebSocket messages, and both operate on the live session identified by its session_id.

Conventions

Fonada provides the base URL and API key during onboarding.

ItemValue
Base URLhttps://<service-host> (provided by Fonada). The API introduction also documents https://api.fonada.example/v1 as a placeholder.
AuthenticationHeader X-API-Key: <api-key> on every request (when configured). The REST API introduction and OpenAPI spec also accept Authorization: Bearer <token> (JWT).
Content-Typeapplication/json
{sessionId}The live session_id from session_start. List active sessions with GET /sessions.

Both endpoints accept bare numbers. Fonada builds the full dial string and Caller ID from your per-account configuration — the telephony technology, trunk/operator, and dialling prefixes are all applied on Fonada's side, so you never hardcode them.

Consult (attended transfer)

POST /sessions/{sessionId}/consult

Places the caller on hold with music on hold, dials a second party, and bridges that party with the bot leg (bot ↔ agent) while the caller waits. When the second party disconnects — or you end the consult explicitly — the caller is automatically taken off hold and rejoined with the bot.

  1. Bot calls POST /sessions/{id}/consult.
  2. Fonada places the caller on hold with music.
  3. Fonada dials the agent.
  4. Agent answers; Fonada returns 200 answered.
  5. Bot talks privately to the agent.
  6. Agent hangs up; caller is taken off hold and rejoined with the bot.

Consult request body

FieldTypeRequiredDefinition
calledPartystringYes *Bare number of the second party to dial. Fonada applies the outgoing prefix, operator, and technology.
callerIdstringNoBare Caller ID to present to the second party; the incoming prefix is prepended. Falls back to the configured default; if that is empty, no Caller ID is set.

calledParty is optional if a default called party is configured for your account.

Example (X-API-Key)

curl -X POST https://<service-host>/sessions/$SID/consult \
  -H 'Content-Type: application/json' -H 'X-API-Key: <api-key>' \
  -d '{"calledParty":"7042009848","callerId":"7313652192"}'

# { "sessionId": "73136...", "consultId": "consult-73136...",
#   "status": "answered", "dialStatus": "ANSWER" }

Example (Bearer token)

curl -X POST https://api.fonada.example/v1/sessions/$SID/consult \
  -H 'Authorization: Bearer <token>' \
  -d '{"calledParty":"7042009848","callerId":"7313652192"}'

Response — 200

FieldTypeDefinition
sessionIdstringThe session id.
consultIdstringChannel id of the second-party leg (consult-<sessionId>).
statusstringanswered, failed (busy / rejected / no-answer / error), or timeout.
dialStatusstringANSWER, NOANSWER, BUSY, CONGESTION, or CHANUNAVAIL. Present when known.
causeintQ.850 hangup cause code. Present only when status=failed.
causeTextstringHuman-readable form of cause. Present only when status=failed.

Status codes

CodeMeaning
200Request processed; inspect status for the telephony outcome.
400Malformed JSON body.
401Missing or invalid X-API-Key.
404No active session with the given sessionId.
500Could not place the call — no caller on the session, a consult is already active, calledParty missing, or an originate error.

UC1 — Consult

A collections bot answers, handles the routine flow, and when the caller asks for a person, it consults a human agent privately before deciding whether to hand off.

  1. Your LLM decides a human is needed and pauses the conversation.
  2. Call POST /sessions/{session_id}/consult with the agent's number. The caller is placed on hold with music while the agent is dialled.
  3. While the caller waits, the bot speaks privately to the agent. When the agent hangs up, the caller is automatically rejoined with the bot.

UC2 — Transfer

Unlike a consult, a full transfer moves the caller to an agent and ends the bot's involvement. Use it when no warm hand-off briefing is needed.

  1. The bot decides to transfer and sends end_of_call after a short handoff message, or places a consult and then drops the bot leg once the agent answers.
  2. The caller and agent continue; Fonada closes the WebSocket for the bot session.

Conference

POST /sessions/{sessionId}/conference

Adds a party to, or removes a party from, the current call. The caller, the bot, and all added parties share one mixing bridge — everyone hears everyone and no one is on hold. A single endpoint handles both operations, switched by the action field.

  1. Bot calls POST /conference with action: add.
  2. Fonada dials the new party.
  3. Party answers and joins the mixing bridge.
  4. Caller, bot, and party all hear each other.
  5. Bot calls POST /conference with action: delete to hang up that leg.

Conference request body

FieldTypeRequiredDefinition
actionstringYesadd (dial and join the number) or delete (hang up that number's leg).
numberstringYesBare number of the party. For add it is dialled; for delete it identifies which participant to hang up.
callerIdstringNo(add only) Bare Caller ID for the dialled party. Falls back to the configured default.

Example (X-API-Key)

# add
curl -X POST https://<service-host>/sessions/$SID/conference \
  -H 'Content-Type: application/json' -H 'X-API-Key: <api-key>' \
  -d '{"action":"add","number":"7042009848","callerId":"7313652192"}'
# -> {"sessionId":"...","number":"7042009848","channelId":"conf-...",
#     "status":"answered","dialStatus":"ANSWER"}

# delete
curl -X POST https://<service-host>/sessions/$SID/conference \
  -H 'Content-Type: application/json' -H 'X-API-Key: <api-key>' \
  -d '{"action":"delete","number":"7042009848"}'
# -> {"ok":true,"number":"7042009848"}

Example (Bearer token)

# add
curl -X POST https://api.fonada.example/v1/sessions/$SID/conference \
  -H 'Authorization: Bearer <token>' \
  -d '{"action":"add","number":"7042009848","callerId":"7313652192"}'

# remove a party
curl -X POST https://api.fonada.example/v1/sessions/$SID/conference \
  -H 'Authorization: Bearer <token>' \
  -d '{"action":"delete","number":"7042009848"}'

Response — action: add

FieldTypeDefinition
sessionIdstringThe session id.
numberstringThe bare number that was dialled.
channelIdstringChannel id of the conference leg (conf-<sessionId>-<number>).
statusstringanswered, failed, or timeout.
dialStatusstringANSWER, NOANSWER, BUSY, CONGESTION, or CHANUNAVAIL, when known.
cause / causeTextint / stringQ.850 cause; present only when status=failed.

Response — action: delete

FieldTypeDefinition
okbooltrue when the hangup was requested.
numberstringThe number that was removed.

Status codes

CodeMeaning
200Processed; for add, inspect status.
400Malformed JSON, or action is not add or delete.
401Missing or invalid X-API-Key.
404Session not found, or (on delete) that number is not in the conference.
409(add) Cannot add — no caller on the session, or that number is already in the conference.

Current conference members are listed in GET /sessions/{sessionId} under conferenceNumbers. See the API reference.

UC3 — Conference

A three-way scenario: the caller, the bot, and a supervisor all hear each other in a single mixing bridge.

Usage notes

  • Consult and conference are separate modes. A consult must not run while a conference is active on the same session.
  • The synchronous operations block for up to the consult timeout (default 20 s). Set client timeouts accordingly.
  • dialStatus is the most reliable field for why a call did not connect — more specific than cause. For a failed outcome, cause and causeText give the Q.850 reason.
  • Consult and conference work identically on inbound and outbound calls.