API calls and data
Call your own systems from a flow, decide what happens next from the answer, and list choices from data.
Calling an API
A route can run an API call before it decides where to go.
transitions:
- actions:
- type: http
method: POST
url: "{{api_base}}/auth/verify"
body:
phone: "{{phone_number}}"
pin: "{{pin}}"
store_as: auth
timeout_secs: 8
on_error: error_screen
guards:
- when: "auth.status == 200"
next: show_balance
- when: "auth.status == 403"
next: locked_screen
default: auth_failed
- Address and body can use any name in reach, such as
{{api_base}}and{{pin}}. - Save its answer as names the answer. The whole answer lands under that name, so
auth.statusis the HTTP status andauth.balanceis a field of the body. - If the call fails, go to names a screen for when the API cannot be reached or takes too long.
Conditions
After the actions, the route goes to the first condition that holds, else to its fallback. Conditions compare a name with a value: auth.status == 200, account.kind == "agent", input|int <= 500.
Keep calls quick
An aggregator hangs up after about 10 seconds. Set each call's timeout to 8 seconds or less and give it an on-error screen, so a slow answer still ends politely.
Test answers
The phone in the editor does not call your API. Each call has a test answer instead: the JSON your API would give, kept under Network in the dock. Test answers are what make the phone, scenarios and the Callers see preview show real data.
A call without a test answer gets a canned 200.
-
POSTMocked 200 200403500Fail the call
{{api_base}}/auth/verifyenter_pin
{
"status": 200,
"balance": "250.00"
}
Choices from data
A menu can list entries from an API, such as a farmer's programs or a customer's accounts. Open Choices from data on the menu:
- Where the data comes from. Give the address to call and a name to save its answer under. The call runs each time a caller reaches the menu. Leave the address blank if an earlier screen already fetched the data.
- What to list from it. Say where the list sits inside the answer, such as
programs.items, what each choice shows, such as{{ item.name }}, and what choosing it stores.
Paste what the API answers into Paste what the API answers and save it as the test answer. The form then offers the lists it found and the fields of an entry, so you pick instead of typing.
pick_program:
type: menu
text:
en: "Choose a program"
list:
fetch: { url: "{{api_base}}/programs", store_as: programs }
items: programs.items
text: "{{ item.name }}"
value: "{{ item }}"
store_as: program
next: farm_size
on_empty: no_programs
options:
- { text: "Back", next: main_menu, input_value: "*" }
Entries from data are numbered first. Options you type, such as Back, are numbered after them, so give those a key of their own: how many entries there are changes from call to call.
If there is nothing to list, go to sends the caller somewhere useful when the list comes back empty.