Skip to content

API reference

API: Phone menus and transfers

Markdown version

MethodPathWhat it doesScope
GET/v1/voice/ivr/menusPhone menus (hosted IVR) per number, and the numbers that can take onesettings:read
POST/v1/voice/ivr/menusCreate a phone menu (owner): menus (keys or spoken words), messages, a business-hours branch; routes to the voice agent, a ring group, voicemail or another node. Off until enabledsettings:write
DELETE/v1/voice/ivr/menus/:idDelete a phone menu (owner): the number's own inbound routing answers againsettings:write
PUT/v1/voice/ivr/menus/:idChange a phone menu (owner): saved as a new versionsettings:write
POST/v1/voice/ivr/menus/:id/restorePublish an older version again (owner), as a new versionsettings:write
GET/v1/voice/ivr/menus/:id/versionsA phone menu's versions (newest first)settings:read
GET/v1/voice/ivr/navigationsRecent phone-tree navigations: goal, each menu heard and key pressed, and how it endedcalls:read
POST/v1/voice/ivr/navigationsCall a company and navigate its phone tree to a person (sales, support, the operator, someone by name). Placed through the calling gate (window, opt-outs, do-not-call, consent, caller ID, policy); call_id instead navigates a call already livemessages:send
GET/v1/voice/ivr/pathsLearned phone-tree paths per company number and goal (replayed on the next call, re-learned when the menu changes)calls:read
DELETE/v1/voice/ivr/paths/:idForget a learned path (owner)settings:write
GET/v1/voice/ivr/sessionsRecent calls through a phone menu: the path taken (keys, words, retries) and the routecalls:read
POST/v1/voice/ivr/simulateTry a phone menu without a call: its problems, and what happens to a caller who presses these keys or says these wordssettings:read
GET/v1/voice/transfer/queuesTransfer queues: who the AI hands live calls to (account owner first, then members by skill, round-robin), seconds to accept, attempts, fallbacksettings:read
POST/v1/voice/transfer/queuesAdd a transfer queue (owner)settings:write
DELETE/v1/voice/transfer/queues/:idDelete a transfer queue (owner)settings:write
PUT/v1/voice/transfer/queues/:idChange a transfer queue (owner)settings:write
GET/v1/voice/transfersRecent warm transfers with their legs and timings, and time to a person (p50/p95) and the success ratecalls:read
POST/v1/voice/transfersHand a live call to a person now (warm: they get the context and accept with 1)messages:send
GET/v1/voice/transfers/:idA transfer's screen pop: the caller, account, deal, reason, summary and transcript so far (withheld when the caller objected to recording), every legtranscripts:read
POST/v1/voice/transfers/:id/passPass on a transfer ringing you (the next person is rung)calls:write

Examples

GET /v1/voice/ivr/menus

Phone menus (hosted IVR) per number, and the numbers that can take one

curl -s "https://api.closefinch.com/v1/voice/ivr/menus" \
  -H "Authorization: Bearer $RA_API_KEY"
const res = await fetch(`https://api.closefinch.com/v1/voice/ivr/menus`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();

POST /v1/voice/ivr/menus

Create a phone menu (owner): menus (keys or spoken words), messages, a business-hours branch; routes to the voice agent, a ring group, voicemail or another node. Off until enabled

curl -s -X POST "https://api.closefinch.com/v1/voice/ivr/menus" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
const res = await fetch(`https://api.closefinch.com/v1/voice/ivr/menus`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();

DELETE /v1/voice/ivr/menus/$ID

Delete a phone menu (owner): the number's own inbound routing answers again

curl -s -X DELETE "https://api.closefinch.com/v1/voice/ivr/menus/$ID" \
  -H "Authorization: Bearer $RA_API_KEY"
const res = await fetch(`https://api.closefinch.com/v1/voice/ivr/menus/${id}`, {
  method: "DELETE",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();

PUT /v1/voice/ivr/menus/$ID

Change a phone menu (owner): saved as a new version

curl -s -X PUT "https://api.closefinch.com/v1/voice/ivr/menus/$ID" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
const res = await fetch(`https://api.closefinch.com/v1/voice/ivr/menus/${id}`, {
  method: "PUT",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();

POST /v1/voice/ivr/menus/$ID/restore

Publish an older version again (owner), as a new version

curl -s -X POST "https://api.closefinch.com/v1/voice/ivr/menus/$ID/restore" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
const res = await fetch(`https://api.closefinch.com/v1/voice/ivr/menus/${id}/restore`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();

GET /v1/voice/ivr/menus/$ID/versions

A phone menu's versions (newest first)

curl -s "https://api.closefinch.com/v1/voice/ivr/menus/$ID/versions" \
  -H "Authorization: Bearer $RA_API_KEY"
const res = await fetch(`https://api.closefinch.com/v1/voice/ivr/menus/${id}/versions`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();

GET /v1/voice/ivr/navigations

Recent phone-tree navigations: goal, each menu heard and key pressed, and how it ended

curl -s "https://api.closefinch.com/v1/voice/ivr/navigations" \
  -H "Authorization: Bearer $RA_API_KEY"
const res = await fetch(`https://api.closefinch.com/v1/voice/ivr/navigations`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();

POST /v1/voice/ivr/navigations

Call a company and navigate its phone tree to a person (sales, support, the operator, someone by name). Placed through the calling gate (window, opt-outs, do-not-call, consent, caller ID, policy); call_id instead navigates a call already live

curl -s -X POST "https://api.closefinch.com/v1/voice/ivr/navigations" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
const res = await fetch(`https://api.closefinch.com/v1/voice/ivr/navigations`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();

GET /v1/voice/ivr/paths

Learned phone-tree paths per company number and goal (replayed on the next call, re-learned when the menu changes)

curl -s "https://api.closefinch.com/v1/voice/ivr/paths" \
  -H "Authorization: Bearer $RA_API_KEY"
const res = await fetch(`https://api.closefinch.com/v1/voice/ivr/paths`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();

DELETE /v1/voice/ivr/paths/$ID

Forget a learned path (owner)

curl -s -X DELETE "https://api.closefinch.com/v1/voice/ivr/paths/$ID" \
  -H "Authorization: Bearer $RA_API_KEY"
const res = await fetch(`https://api.closefinch.com/v1/voice/ivr/paths/${id}`, {
  method: "DELETE",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();

GET /v1/voice/ivr/sessions

Recent calls through a phone menu: the path taken (keys, words, retries) and the route

curl -s "https://api.closefinch.com/v1/voice/ivr/sessions" \
  -H "Authorization: Bearer $RA_API_KEY"
const res = await fetch(`https://api.closefinch.com/v1/voice/ivr/sessions`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();

POST /v1/voice/ivr/simulate

Try a phone menu without a call: its problems, and what happens to a caller who presses these keys or says these words

curl -s -X POST "https://api.closefinch.com/v1/voice/ivr/simulate" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
const res = await fetch(`https://api.closefinch.com/v1/voice/ivr/simulate`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();

GET /v1/voice/transfer/queues

Transfer queues: who the AI hands live calls to (account owner first, then members by skill, round-robin), seconds to accept, attempts, fallback

curl -s "https://api.closefinch.com/v1/voice/transfer/queues" \
  -H "Authorization: Bearer $RA_API_KEY"
const res = await fetch(`https://api.closefinch.com/v1/voice/transfer/queues`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();

POST /v1/voice/transfer/queues

Add a transfer queue (owner)

curl -s -X POST "https://api.closefinch.com/v1/voice/transfer/queues" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
const res = await fetch(`https://api.closefinch.com/v1/voice/transfer/queues`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();

DELETE /v1/voice/transfer/queues/$ID

Delete a transfer queue (owner)

curl -s -X DELETE "https://api.closefinch.com/v1/voice/transfer/queues/$ID" \
  -H "Authorization: Bearer $RA_API_KEY"
const res = await fetch(`https://api.closefinch.com/v1/voice/transfer/queues/${id}`, {
  method: "DELETE",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();

PUT /v1/voice/transfer/queues/$ID

Change a transfer queue (owner)

curl -s -X PUT "https://api.closefinch.com/v1/voice/transfer/queues/$ID" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
const res = await fetch(`https://api.closefinch.com/v1/voice/transfer/queues/${id}`, {
  method: "PUT",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();

GET /v1/voice/transfers

Recent warm transfers with their legs and timings, and time to a person (p50/p95) and the success rate

curl -s "https://api.closefinch.com/v1/voice/transfers" \
  -H "Authorization: Bearer $RA_API_KEY"
const res = await fetch(`https://api.closefinch.com/v1/voice/transfers`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();

POST /v1/voice/transfers

Hand a live call to a person now (warm: they get the context and accept with 1)

curl -s -X POST "https://api.closefinch.com/v1/voice/transfers" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
const res = await fetch(`https://api.closefinch.com/v1/voice/transfers`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();

GET /v1/voice/transfers/$ID

A transfer's screen pop: the caller, account, deal, reason, summary and transcript so far (withheld when the caller objected to recording), every leg

curl -s "https://api.closefinch.com/v1/voice/transfers/$ID" \
  -H "Authorization: Bearer $RA_API_KEY"
const res = await fetch(`https://api.closefinch.com/v1/voice/transfers/${id}`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();

POST /v1/voice/transfers/$ID/pass

Pass on a transfer ringing you (the next person is rung)

curl -s -X POST "https://api.closefinch.com/v1/voice/transfers/$ID/pass" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
const res = await fetch(`https://api.closefinch.com/v1/voice/transfers/${id}/pass`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();

Request and response schemas: https://www.closefinch.com/openapi.json. All resources: API reference.

Send feedback

Tell us what's broken, confusing or missing on this page, or an idea. It goes to the team that builds the product.

Please don't include passwords or card numbers.
Only to reply about this. Never added to any mailing list.