curl --request POST \
--url https://{host}/api/v1/ivr-flows \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "<string>",
"description": "<string>",
"direction": "inbound",
"organisation_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"team_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}
'const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: '<string>',
description: '<string>',
direction: 'inbound',
organisation_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
team_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a'
})
};
fetch('https://{host}/api/v1/ivr-flows', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://{host}/api/v1/ivr-flows"
payload = {
"name": "<string>",
"description": "<string>",
"direction": "inbound",
"organisation_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"team_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"created_at": "2023-11-07T05:31:56Z",
"direction": "inbound",
"draft_revision": 123,
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"organisation_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"updated_at": "2023-11-07T05:31:56Z",
"campaign_kind": "voice_broadcast",
"description": "<string>",
"published_revision": 123,
"team_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"test_caller": "<string>",
"test_number": "<string>",
"test_revision": "draft"
}{
"error": {
"code": "invalid_request",
"message": "<string>"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>"
}
}Create an IVR flow
Creates the flow with draft_revision 1, no published revision, and a single entry node. The flow takes no calls until it is published.
curl --request POST \
--url https://{host}/api/v1/ivr-flows \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "<string>",
"description": "<string>",
"direction": "inbound",
"organisation_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"team_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}
'const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: '<string>',
description: '<string>',
direction: 'inbound',
organisation_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
team_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a'
})
};
fetch('https://{host}/api/v1/ivr-flows', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://{host}/api/v1/ivr-flows"
payload = {
"name": "<string>",
"description": "<string>",
"direction": "inbound",
"organisation_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"team_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"created_at": "2023-11-07T05:31:56Z",
"direction": "inbound",
"draft_revision": 123,
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"organisation_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"updated_at": "2023-11-07T05:31:56Z",
"campaign_kind": "voice_broadcast",
"description": "<string>",
"published_revision": 123,
"team_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"test_caller": "<string>",
"test_number": "<string>",
"test_revision": "draft"
}{
"error": {
"code": "invalid_request",
"message": "<string>"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>"
}
}Authorizations
Every request sends Authorization: Bearer <token>. The token is either a panel session (a JWT from /auth/login, 12 hours) or an API key ft_<id>_<secret>. An API key is accepted only from an address on its IP allowlist (403 ip_not_allowed otherwise; 403 ip_allowlist_required for an old key that has none), is limited to its rate per minute (429 rate_limited with Retry-After; X-RateLimit-Limit/Remaining/Reset on every response), and at most 60 call placements a minute.
Body
A new flow is created with draft_revision 1, no published revision, and a single entry node, so it opens as a valid canvas rather than a blank one the designer cannot start from.
What the IVR is called, in lists and in the designer.
Only valid with direction=outbound; sending it on an inbound flow is refused rather than ignored. Omit it to make the flow usable by both campaign kinds.
voice_broadcast, auto_dial A note for the people who maintain it.
Defaults to inbound. An outbound flow's entry node is labelled for the moment a campaign's contact answers rather than for an incoming call.
inbound, outbound The organisation the number belongs to. May be left out by a caller with exactly one organisation.
The team that owns the IVR, if any.
Response
Created
A call flow as a graph. published_revision is the revision answering calls; a flow with none takes no traffic. draft_revision is what the designer edits.
Which way the call is going when this graph runs. An inbound flow answers a number; an outbound one runs after a campaign's contact picks up. A campaign will not accept an inbound flow.
inbound, outbound Which campaign kind an outbound flow was drawn for. Null means it suits both, and is the only valid value on an inbound flow.
voice_broadcast, auto_dial The revision currently answering calls. Null means the flow has never been published and must not receive traffic.
Who a test call tells the flow is calling, E.164 (read in the organisation's region when typed without +). Null for the tester's own extension.
3-8 digits any extension of the organisation dials to walk through this flow as a test. Never reachable from outside. Refused if it is an extension, a park slot (701-799) or another flow's test number. Null to remove.
Which version a test call runs. Default draft.
draft, published