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.
| Item | Value |
|---|---|
| Base URL | https://<service-host> (provided by Fonada). The API introduction also documents https://api.fonada.example/v1 as a placeholder. |
| Authentication | Header X-API-Key: <api-key> on every request (when configured). The REST API introduction and OpenAPI spec also accept Authorization: Bearer <token> (JWT). |
| Content-Type | application/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}/consultPlaces 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.
- Bot calls POST /sessions/{id}/consult.
- Fonada places the caller on hold with music.
- Fonada dials the agent.
- Agent answers; Fonada returns 200 answered.
- Bot talks privately to the agent.
- Agent hangs up; caller is taken off hold and rejoined with the bot.
Consult request body
| Field | Type | Required | Definition |
|---|---|---|---|
calledParty | string | Yes * | Bare number of the second party to dial. Fonada applies the outgoing prefix, operator, and technology. |
callerId | string | No | Bare 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
| Field | Type | Definition |
|---|---|---|
sessionId | string | The session id. |
consultId | string | Channel id of the second-party leg (consult-<sessionId>). |
status | string | answered, failed (busy / rejected / no-answer / error), or timeout. |
dialStatus | string | ANSWER, NOANSWER, BUSY, CONGESTION, or CHANUNAVAIL. Present when known. |
cause | int | Q.850 hangup cause code. Present only when status=failed. |
causeText | string | Human-readable form of cause. Present only when status=failed. |
Status codes
| Code | Meaning |
|---|---|
| 200 | Request processed; inspect status for the telephony outcome. |
| 400 | Malformed JSON body. |
| 401 | Missing or invalid X-API-Key. |
| 404 | No active session with the given sessionId. |
| 500 | Could 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.
- Your LLM decides a human is needed and pauses the conversation.
- Call POST /sessions/{session_id}/consult with the agent's number. The caller is placed on hold with music while the agent is dialled.
- 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.
- The bot decides to transfer and sends
end_of_callafter a short handoff message, or places a consult and then drops the bot leg once the agent answers. - The caller and agent continue; Fonada closes the WebSocket for the bot session.
Conference
POST /sessions/{sessionId}/conferenceAdds 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.
- Bot calls POST /conference with action: add.
- Fonada dials the new party.
- Party answers and joins the mixing bridge.
- Caller, bot, and party all hear each other.
- Bot calls POST /conference with action: delete to hang up that leg.
Conference request body
| Field | Type | Required | Definition |
|---|---|---|---|
action | string | Yes | add (dial and join the number) or delete (hang up that number's leg). |
number | string | Yes | Bare number of the party. For add it is dialled; for delete it identifies which participant to hang up. |
callerId | string | No | (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
| Field | Type | Definition |
|---|---|---|
sessionId | string | The session id. |
number | string | The bare number that was dialled. |
channelId | string | Channel id of the conference leg (conf-<sessionId>-<number>). |
status | string | answered, failed, or timeout. |
dialStatus | string | ANSWER, NOANSWER, BUSY, CONGESTION, or CHANUNAVAIL, when known. |
cause / causeText | int / string | Q.850 cause; present only when status=failed. |
Response — action: delete
| Field | Type | Definition |
|---|---|---|
ok | bool | true when the hangup was requested. |
number | string | The number that was removed. |
Status codes
| Code | Meaning |
|---|---|
| 200 | Processed; for add, inspect status. |
| 400 | Malformed JSON, or action is not add or delete. |
| 401 | Missing or invalid X-API-Key. |
| 404 | Session 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.
dialStatusis the most reliable field for why a call did not connect — more specific thancause. For a failed outcome,causeandcauseTextgive the Q.850 reason.- Consult and conference work identically on inbound and outbound calls.