Validate a flow
curl --request POST \
--url https://sandbox.voice.miraiminds.co/v2/agents/flow/validate \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"nodes": [
{
"id": "persona",
"type": "globalNode",
"data": {
"name": "Persona and rules",
"prompt": "You are Ashu, a service advisor at Mirai Motors.\nSpeak everyday Hindi in Devanagari; common English words such as service, slot and workshop are fine.\nSay one or two short sentences, then listen.\nNever promise a discount, a price or a pickup.\nWhen the condition of one of your functions is met, call it at once without saying anything first."
}
},
{
"id": "identity",
"type": "startCall",
"data": {
"name": "Confirm the customer",
"greeting": "नमस्ते, मैं मिराई मोटर्स से आशु बोल रहा हूं. क्या मेरी बात {{name}} जी से हो रही है?",
"prompt": "You have asked whether you are speaking with {{name}}. Wait for the answer.\nIf they confirm, call confirmed_identity.\nIf it is someone else or a wrong number, call wrong_person.\nDo not mention the car or the service before they confirm."
}
},
{
"id": "offer_slot",
"type": "agentNode",
"data": {
"name": "Book the service",
"prompt": "Tell them their {{vehicle}} is due for service on {{due_date}}, and ask which day they can bring it to the workshop.\nWhen they name a day, read it back once and call slot_booked.\nIf they do not want to book now, call not_now.",
"extraction_enabled": true,
"extraction_variables": [
{
"name": "preferred_day",
"type": "string",
"prompt": "The day the customer chose for the service, in their words, for example Saturday or 20 August."
}
]
}
},
{
"id": "goodbye",
"type": "endCall",
"data": {
"name": "Close",
"prompt": "In one sentence, repeat what was agreed. Thank them and say goodbye. Do not ask anything else.",
"allow_interrupt": false
}
},
{
"id": "not_customer",
"type": "endCall",
"data": {
"name": "Wrong person",
"prompt": "Apologise for the trouble and say goodbye. Do not mention the car or the service."
}
}
],
"edges": [
{
"id": "e1",
"source": "identity",
"target": "offer_slot",
"data": {
"label": "confirmed_identity",
"condition": "The caller confirmed they are the customer you asked for."
}
},
{
"id": "e2",
"source": "identity",
"target": "not_customer",
"data": {
"label": "wrong_person",
"condition": "The caller is someone else, or says it is a wrong number."
}
},
{
"id": "e3",
"source": "offer_slot",
"target": "goodbye",
"data": {
"label": "slot_booked",
"condition": "The customer named a day for the service and you read it back."
}
},
{
"id": "e4",
"source": "offer_slot",
"target": "goodbye",
"data": {
"label": "not_now",
"condition": "The customer does not want to book the service now."
}
}
]
}
'import requests
url = "https://sandbox.voice.miraiminds.co/v2/agents/flow/validate"
payload = {
"nodes": [
{
"id": "persona",
"type": "globalNode",
"data": {
"name": "Persona and rules",
"prompt": "You are Ashu, a service advisor at Mirai Motors.
Speak everyday Hindi in Devanagari; common English words such as service, slot and workshop are fine.
Say one or two short sentences, then listen.
Never promise a discount, a price or a pickup.
When the condition of one of your functions is met, call it at once without saying anything first."
}
},
{
"id": "identity",
"type": "startCall",
"data": {
"name": "Confirm the customer",
"greeting": "नमस्ते, मैं मिराई मोटर्स से आशु बोल रहा हूं. क्या मेरी बात {{name}} जी से हो रही है?",
"prompt": "You have asked whether you are speaking with {{name}}. Wait for the answer.
If they confirm, call confirmed_identity.
If it is someone else or a wrong number, call wrong_person.
Do not mention the car or the service before they confirm."
}
},
{
"id": "offer_slot",
"type": "agentNode",
"data": {
"name": "Book the service",
"prompt": "Tell them their {{vehicle}} is due for service on {{due_date}}, and ask which day they can bring it to the workshop.
When they name a day, read it back once and call slot_booked.
If they do not want to book now, call not_now.",
"extraction_enabled": True,
"extraction_variables": [
{
"name": "preferred_day",
"type": "string",
"prompt": "The day the customer chose for the service, in their words, for example Saturday or 20 August."
}
]
}
},
{
"id": "goodbye",
"type": "endCall",
"data": {
"name": "Close",
"prompt": "In one sentence, repeat what was agreed. Thank them and say goodbye. Do not ask anything else.",
"allow_interrupt": False
}
},
{
"id": "not_customer",
"type": "endCall",
"data": {
"name": "Wrong person",
"prompt": "Apologise for the trouble and say goodbye. Do not mention the car or the service."
}
}
],
"edges": [
{
"id": "e1",
"source": "identity",
"target": "offer_slot",
"data": {
"label": "confirmed_identity",
"condition": "The caller confirmed they are the customer you asked for."
}
},
{
"id": "e2",
"source": "identity",
"target": "not_customer",
"data": {
"label": "wrong_person",
"condition": "The caller is someone else, or says it is a wrong number."
}
},
{
"id": "e3",
"source": "offer_slot",
"target": "goodbye",
"data": {
"label": "slot_booked",
"condition": "The customer named a day for the service and you read it back."
}
},
{
"id": "e4",
"source": "offer_slot",
"target": "goodbye",
"data": {
"label": "not_now",
"condition": "The customer does not want to book the service now."
}
}
]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const url = 'https://sandbox.voice.miraiminds.co/v2/agents/flow/validate';
const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
nodes: [
{
id: 'persona',
type: 'globalNode',
data: {
name: 'Persona and rules',
prompt: 'You are Ashu, a service advisor at Mirai Motors.\nSpeak everyday Hindi in Devanagari; common English words such as service, slot and workshop are fine.\nSay one or two short sentences, then listen.\nNever promise a discount, a price or a pickup.\nWhen the condition of one of your functions is met, call it at once without saying anything first.'
}
},
{
id: 'identity',
type: 'startCall',
data: {
name: 'Confirm the customer',
greeting: 'नमस्ते, मैं मिराई मोटर्स से आशु बोल रहा हूं. क्या मेरी बात {{name}} जी से हो रही है?',
prompt: 'You have asked whether you are speaking with {{name}}. Wait for the answer.\nIf they confirm, call confirmed_identity.\nIf it is someone else or a wrong number, call wrong_person.\nDo not mention the car or the service before they confirm.'
}
},
{
id: 'offer_slot',
type: 'agentNode',
data: {
name: 'Book the service',
prompt: 'Tell them their {{vehicle}} is due for service on {{due_date}}, and ask which day they can bring it to the workshop.\nWhen they name a day, read it back once and call slot_booked.\nIf they do not want to book now, call not_now.',
extraction_enabled: true,
extraction_variables: [
{
name: 'preferred_day',
type: 'string',
prompt: 'The day the customer chose for the service, in their words, for example Saturday or 20 August.'
}
]
}
},
{
id: 'goodbye',
type: 'endCall',
data: {
name: 'Close',
prompt: 'In one sentence, repeat what was agreed. Thank them and say goodbye. Do not ask anything else.',
allow_interrupt: false
}
},
{
id: 'not_customer',
type: 'endCall',
data: {
name: 'Wrong person',
prompt: 'Apologise for the trouble and say goodbye. Do not mention the car or the service.'
}
}
],
edges: [
{
id: 'e1',
source: 'identity',
target: 'offer_slot',
data: {
label: 'confirmed_identity',
condition: 'The caller confirmed they are the customer you asked for.'
}
},
{
id: 'e2',
source: 'identity',
target: 'not_customer',
data: {
label: 'wrong_person',
condition: 'The caller is someone else, or says it is a wrong number.'
}
},
{
id: 'e3',
source: 'offer_slot',
target: 'goodbye',
data: {
label: 'slot_booked',
condition: 'The customer named a day for the service and you read it back.'
}
},
{
id: 'e4',
source: 'offer_slot',
target: 'goodbye',
data: {
label: 'not_now',
condition: 'The customer does not want to book the service now.'
}
}
]
})
};
fetch(url, options)
.then(res => res.json())
.then(json => console.log(json))
.catch(err => console.error(err));{
"edges": 4,
"flow_revision": "2c0eccdffdf0edca4e0a",
"nodes": 5,
"ok": true
}{
"details": [
{
"path": "flow.edges[2].data.label",
"message": "must be a function name: a letter or underscore, then letters, digits or underscores (at most 64)"
},
{
"path": "flow.edges[3].data.condition",
"message": "is required: describe when the model should take this transition"
}
],
"error": "invalid_flow"
}Flows
Validate a flow
Checks a graph against every rule without saving it: node and transition counts, ids and labels, that every node can be reached and can reach an end, and that your tier’s model can run flows. Free, and it calls no one. The body is the graph itself.
Every problem comes back at once, each with the path to the field. Whether the graph’s variables and node tools exist on a particular agent is checked when you save it on that agent.
POST
/
v2
/
agents
/
flow
/
validate
Validate a flow
curl --request POST \
--url https://sandbox.voice.miraiminds.co/v2/agents/flow/validate \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"nodes": [
{
"id": "persona",
"type": "globalNode",
"data": {
"name": "Persona and rules",
"prompt": "You are Ashu, a service advisor at Mirai Motors.\nSpeak everyday Hindi in Devanagari; common English words such as service, slot and workshop are fine.\nSay one or two short sentences, then listen.\nNever promise a discount, a price or a pickup.\nWhen the condition of one of your functions is met, call it at once without saying anything first."
}
},
{
"id": "identity",
"type": "startCall",
"data": {
"name": "Confirm the customer",
"greeting": "नमस्ते, मैं मिराई मोटर्स से आशु बोल रहा हूं. क्या मेरी बात {{name}} जी से हो रही है?",
"prompt": "You have asked whether you are speaking with {{name}}. Wait for the answer.\nIf they confirm, call confirmed_identity.\nIf it is someone else or a wrong number, call wrong_person.\nDo not mention the car or the service before they confirm."
}
},
{
"id": "offer_slot",
"type": "agentNode",
"data": {
"name": "Book the service",
"prompt": "Tell them their {{vehicle}} is due for service on {{due_date}}, and ask which day they can bring it to the workshop.\nWhen they name a day, read it back once and call slot_booked.\nIf they do not want to book now, call not_now.",
"extraction_enabled": true,
"extraction_variables": [
{
"name": "preferred_day",
"type": "string",
"prompt": "The day the customer chose for the service, in their words, for example Saturday or 20 August."
}
]
}
},
{
"id": "goodbye",
"type": "endCall",
"data": {
"name": "Close",
"prompt": "In one sentence, repeat what was agreed. Thank them and say goodbye. Do not ask anything else.",
"allow_interrupt": false
}
},
{
"id": "not_customer",
"type": "endCall",
"data": {
"name": "Wrong person",
"prompt": "Apologise for the trouble and say goodbye. Do not mention the car or the service."
}
}
],
"edges": [
{
"id": "e1",
"source": "identity",
"target": "offer_slot",
"data": {
"label": "confirmed_identity",
"condition": "The caller confirmed they are the customer you asked for."
}
},
{
"id": "e2",
"source": "identity",
"target": "not_customer",
"data": {
"label": "wrong_person",
"condition": "The caller is someone else, or says it is a wrong number."
}
},
{
"id": "e3",
"source": "offer_slot",
"target": "goodbye",
"data": {
"label": "slot_booked",
"condition": "The customer named a day for the service and you read it back."
}
},
{
"id": "e4",
"source": "offer_slot",
"target": "goodbye",
"data": {
"label": "not_now",
"condition": "The customer does not want to book the service now."
}
}
]
}
'import requests
url = "https://sandbox.voice.miraiminds.co/v2/agents/flow/validate"
payload = {
"nodes": [
{
"id": "persona",
"type": "globalNode",
"data": {
"name": "Persona and rules",
"prompt": "You are Ashu, a service advisor at Mirai Motors.
Speak everyday Hindi in Devanagari; common English words such as service, slot and workshop are fine.
Say one or two short sentences, then listen.
Never promise a discount, a price or a pickup.
When the condition of one of your functions is met, call it at once without saying anything first."
}
},
{
"id": "identity",
"type": "startCall",
"data": {
"name": "Confirm the customer",
"greeting": "नमस्ते, मैं मिराई मोटर्स से आशु बोल रहा हूं. क्या मेरी बात {{name}} जी से हो रही है?",
"prompt": "You have asked whether you are speaking with {{name}}. Wait for the answer.
If they confirm, call confirmed_identity.
If it is someone else or a wrong number, call wrong_person.
Do not mention the car or the service before they confirm."
}
},
{
"id": "offer_slot",
"type": "agentNode",
"data": {
"name": "Book the service",
"prompt": "Tell them their {{vehicle}} is due for service on {{due_date}}, and ask which day they can bring it to the workshop.
When they name a day, read it back once and call slot_booked.
If they do not want to book now, call not_now.",
"extraction_enabled": True,
"extraction_variables": [
{
"name": "preferred_day",
"type": "string",
"prompt": "The day the customer chose for the service, in their words, for example Saturday or 20 August."
}
]
}
},
{
"id": "goodbye",
"type": "endCall",
"data": {
"name": "Close",
"prompt": "In one sentence, repeat what was agreed. Thank them and say goodbye. Do not ask anything else.",
"allow_interrupt": False
}
},
{
"id": "not_customer",
"type": "endCall",
"data": {
"name": "Wrong person",
"prompt": "Apologise for the trouble and say goodbye. Do not mention the car or the service."
}
}
],
"edges": [
{
"id": "e1",
"source": "identity",
"target": "offer_slot",
"data": {
"label": "confirmed_identity",
"condition": "The caller confirmed they are the customer you asked for."
}
},
{
"id": "e2",
"source": "identity",
"target": "not_customer",
"data": {
"label": "wrong_person",
"condition": "The caller is someone else, or says it is a wrong number."
}
},
{
"id": "e3",
"source": "offer_slot",
"target": "goodbye",
"data": {
"label": "slot_booked",
"condition": "The customer named a day for the service and you read it back."
}
},
{
"id": "e4",
"source": "offer_slot",
"target": "goodbye",
"data": {
"label": "not_now",
"condition": "The customer does not want to book the service now."
}
}
]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const url = 'https://sandbox.voice.miraiminds.co/v2/agents/flow/validate';
const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
nodes: [
{
id: 'persona',
type: 'globalNode',
data: {
name: 'Persona and rules',
prompt: 'You are Ashu, a service advisor at Mirai Motors.\nSpeak everyday Hindi in Devanagari; common English words such as service, slot and workshop are fine.\nSay one or two short sentences, then listen.\nNever promise a discount, a price or a pickup.\nWhen the condition of one of your functions is met, call it at once without saying anything first.'
}
},
{
id: 'identity',
type: 'startCall',
data: {
name: 'Confirm the customer',
greeting: 'नमस्ते, मैं मिराई मोटर्स से आशु बोल रहा हूं. क्या मेरी बात {{name}} जी से हो रही है?',
prompt: 'You have asked whether you are speaking with {{name}}. Wait for the answer.\nIf they confirm, call confirmed_identity.\nIf it is someone else or a wrong number, call wrong_person.\nDo not mention the car or the service before they confirm.'
}
},
{
id: 'offer_slot',
type: 'agentNode',
data: {
name: 'Book the service',
prompt: 'Tell them their {{vehicle}} is due for service on {{due_date}}, and ask which day they can bring it to the workshop.\nWhen they name a day, read it back once and call slot_booked.\nIf they do not want to book now, call not_now.',
extraction_enabled: true,
extraction_variables: [
{
name: 'preferred_day',
type: 'string',
prompt: 'The day the customer chose for the service, in their words, for example Saturday or 20 August.'
}
]
}
},
{
id: 'goodbye',
type: 'endCall',
data: {
name: 'Close',
prompt: 'In one sentence, repeat what was agreed. Thank them and say goodbye. Do not ask anything else.',
allow_interrupt: false
}
},
{
id: 'not_customer',
type: 'endCall',
data: {
name: 'Wrong person',
prompt: 'Apologise for the trouble and say goodbye. Do not mention the car or the service.'
}
}
],
edges: [
{
id: 'e1',
source: 'identity',
target: 'offer_slot',
data: {
label: 'confirmed_identity',
condition: 'The caller confirmed they are the customer you asked for.'
}
},
{
id: 'e2',
source: 'identity',
target: 'not_customer',
data: {
label: 'wrong_person',
condition: 'The caller is someone else, or says it is a wrong number.'
}
},
{
id: 'e3',
source: 'offer_slot',
target: 'goodbye',
data: {
label: 'slot_booked',
condition: 'The customer named a day for the service and you read it back.'
}
},
{
id: 'e4',
source: 'offer_slot',
target: 'goodbye',
data: {
label: 'not_now',
condition: 'The customer does not want to book the service now.'
}
}
]
})
};
fetch(url, options)
.then(res => res.json())
.then(json => console.log(json))
.catch(err => console.error(err));{
"edges": 4,
"flow_revision": "2c0eccdffdf0edca4e0a",
"nodes": 5,
"ok": true
}{
"details": [
{
"path": "flow.edges[2].data.label",
"message": "must be a function name: a letter or underscore, then letters, digits or underscores (at most 64)"
},
{
"path": "flow.edges[3].data.condition",
"message": "is required: describe when the model should take this transition"
}
],
"error": "invalid_flow"
}Authorizations
Your workspace secret key, sk_live_ followed by 32 hex characters. Create one in the console under Developers.
Body
application/json
A node graph: the conversation as nodes with their own instructions and transitions between them. See x-semantics.flow for the rules.
⌘I