curl --request POST \
--url https://{host}/api/v1/ivr-flows/{id}/publish \
--header 'Authorization: Bearer <token>'const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
fetch('https://{host}/api/v1/ivr-flows/{id}/publish', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://{host}/api/v1/ivr-flows/{id}/publish"
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, headers=headers)
print(response.text){
"draft_revision": 123,
"errors": [
{
"code": "no_entry",
"message": "<string>",
"kind": "<string>",
"label": "<string>",
"node_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"outlet": "<string>"
}
],
"published": true,
"warnings": [
{
"code": "no_entry",
"message": "<string>",
"kind": "<string>",
"label": "<string>",
"node_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"outlet": "<string>"
}
],
"error": {
"code": "<string>",
"message": "<string>"
},
"published_revision": 123
}{
"error": {
"code": "invalid_request",
"message": "<string>"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>"
}
}{
"draft_revision": 123,
"errors": [
{
"code": "no_entry",
"message": "<string>",
"kind": "<string>",
"label": "<string>",
"node_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"outlet": "<string>"
}
],
"published": true,
"warnings": [
{
"code": "no_entry",
"message": "<string>",
"kind": "<string>",
"label": "<string>",
"node_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"outlet": "<string>"
}
],
"error": {
"code": "<string>",
"message": "<string>"
},
"published_revision": 123
}Publish the draft revision
The validation gate. The runtime refuses an unpublished flow, so this is where a flow becomes answerable and therefore where it is checked.
On success the validated revision becomes published_revision unchanged and a copy of it becomes the new draft, so a revision that is or was live is never edited and a call already walking the graph is unaffected.
Errors block (no entry node; a kind the runtime cannot execute; a route_extension/route_queue/virtual_agent target that does not exist or belongs to another organisation; an unknown timezone on a time_condition, which fails the call; a menu with no wired digit outlets). Warnings do not (an unwired outlet, a node unreachable from entry, a branch/voicemail node).
curl --request POST \
--url https://{host}/api/v1/ivr-flows/{id}/publish \
--header 'Authorization: Bearer <token>'const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
fetch('https://{host}/api/v1/ivr-flows/{id}/publish', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://{host}/api/v1/ivr-flows/{id}/publish"
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, headers=headers)
print(response.text){
"draft_revision": 123,
"errors": [
{
"code": "no_entry",
"message": "<string>",
"kind": "<string>",
"label": "<string>",
"node_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"outlet": "<string>"
}
],
"published": true,
"warnings": [
{
"code": "no_entry",
"message": "<string>",
"kind": "<string>",
"label": "<string>",
"node_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"outlet": "<string>"
}
],
"error": {
"code": "<string>",
"message": "<string>"
},
"published_revision": 123
}{
"error": {
"code": "invalid_request",
"message": "<string>"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>"
}
}{
"draft_revision": 123,
"errors": [
{
"code": "no_entry",
"message": "<string>",
"kind": "<string>",
"label": "<string>",
"node_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"outlet": "<string>"
}
],
"published": true,
"warnings": [
{
"code": "no_entry",
"message": "<string>",
"kind": "<string>",
"label": "<string>",
"node_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"outlet": "<string>"
}
],
"error": {
"code": "<string>",
"message": "<string>"
},
"published_revision": 123
}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.
Path Parameters
Response
Published
Errors block publishing; warnings do not. The same shape is returned either way, so the panel reads one document whether the flow went live or was refused.
The new draft, forked from the revision just published.
What stops it publishing; empty when it published.
Show child attributes
Show child attributes
Whether the draft passed validation and is now the published revision.
Things worth fixing that do not stop it.
Show child attributes
Show child attributes
Present only when publishing was refused, so the standard error envelope still applies.
Show child attributes
Show child attributes
The revision now answering calls.