Skip to main content
A conference room is a dial-in bridge your organisation owns: a short number, a participant PIN and, optionally, a moderator PIN. Through the API you create rooms, dial people into them, and control a room while it is up. The same controls work on a room made by merging two calls from the Desk. Every request carries Authorization: Bearer $FIRETONE_KEY. Creating and editing rooms needs conferences:write; running a live room needs conferences:control; reading needs conferences:read.

Create a room

  • number is 2 to 8 digits: what an extension dials, and what a caller keys when a shared “Conference” phone number asks which room. Unique within the organisation; an extension with the same digits wins.
  • participant_pin is 4 to 10 digits, or empty for a room anyone may dial straight into. moderator_pin is optional and must differ; empty means the room has no moderator role. The PINs are returned on every read: they are invitation codes, not credentials.
  • wait_for_moderator holds participants on music until a moderator joins, and needs a moderator PIN. max_members 0 means no cap.
Default members. PUT /conference-rooms/{id}/members with the same shape replaces the extensions rung when the room opens. A busy or unregistered member is rung as soon as it is free while the room is up; a session’s history (GET /conference-rooms/{id}/sessions) carries each invites row with its state and last_reason. minutes_email on the room is where a virtual member’s minutes are sent. Minutes. GET /conference-rooms/{id}/sessions/{sid}/meeting (AI module; conferences:read) is what a virtual member made of one session: minutes (or minutes_error, why none were written), the notes it took as things were decided, turns with each caller line’s speaker, replies_unheard (replies the model produced that nobody had asked for, held back), and delivered_to (the addresses the minutes were queued to). Per SESSION, not per room: a room used three times a day has three sets of minutes. 404 when no virtual agent sat in that session. GET /conference-rooms/{id}/meetings is the same for every session of the room at once, one summary row per seat (session_id, agent, state, has_minutes, minutes_error, notes, turns), which is what the room’s page reads. The same minutes arrive as the conference.minutes webhook event. Extensions that need no PIN. PUT /conference-rooms/{id}/exemptions with {"items": [{"extension_id": "…", "role": "moderator"}]} replaces the set of the organisation’s extensions that dial the room number and are seated without keying anything, each in its role. The room returns them as exemptions. Only a leg the directory authenticated carries an extension, so an outside caller can never be exempt. GET /conference-rooms, GET /conference-rooms/{id}, PATCH and DELETE follow the usual conventions. A room’s row carries numbers, the phone numbers pointed at it alone, and live_members, how many are in it right now. Deleting a room a number still points at answers 409 naming them. To let outside callers in, point a phone number at destination conference: with destination_id set to a room the caller is asked only for the PIN; with none, for the room number first.

Dial somebody in

The extension rings, showing the room’s number and name. Whoever answers is seated in the room in role (participant or moderator) without keying a PIN. For an outside number send "kind": "external" and target in E.164; it is routed and billed as an outbound call, refused without credit, and sees the organisation’s first phone number as caller ID. The response is 202 with {"dialling": "…"}: the call is ringing. Whether it was answered shows in the room’s live list.

The room while it is up

Live rooms are keyed by the switch’s room name: ft-room-<room id> for a dial-in room, ft-conf-<call uuid> for two calls merged from the Desk. That is what lets a merged call be run with the same requests.
id is the switch’s member id, and it is what the member controls take. can_control says whether the caller of this request may use them. 404 means nobody is in that room right now. GET /conferences lists every room live in your scope, and GET /conferences/by-call/{uuid} names the room a call is in, which is how the Desk knows to show a merged call’s participants. Inside a room the keypad also works: *1 mute yourself, *2 unmute; a moderator has *5 lock, *7 mute everyone else, *0 end.

History and recordings

GET /conference-rooms/{id}/sessions lists every occupancy of the room, newest first: when it ran, peak_members, who was in it with their roles and times, the default members’ invites and how each went (above), and has_recording with recording_bytes. A recording is played from GET /conference-rooms/{id}/sessions/{sid}/recording/audio (recordings:listen), a WAV with Range support, and is kept under the organisation’s recording retention like any call recording.

Events

The live stream (see Events) carries conference.updated with room and an action (joined, left, locked, recording, all_muted, ended, and the switch’s mute and talking changes), and call.conferenced when calls are merged from the Desk. Treat them as a nudge to re-read GET /conferences/{room}; the read is the truth.