Tutorial: Build a Community Bank

A complete, build-along USSD app that ties together the core node types — start, input, condition, menu, API, database and end.

What you'll build

A bank short-code where a caller enters a PIN, then picks from a menu to check their balance (external API), make a deposit (payment API → database) or leave feedback(stored in your tables). By the end you'll have wired up every core node.

NodeWhere it's used
startEntry screen
inputPIN, amount and comment capture
conditionValidate the PIN and the amount
menuBalance / Deposit / Feedback
apiFetch the balance & submit the deposit
databaseRecord deposits & feedback
endClose each branch

Before you start

Create two tables in Database deposits and feedback. The deposit step posts to a payment API, so have that endpoint's URL handy.

1 · Start and capture the PIN

Drop a start node, then an input node to capture the PIN into a variable. Wire start → pin.

start · data
{ "prompt": "Welcome to Community Bank" }
input (pin) · data
{
  "prompt": "Enter your 4-digit PIN:",
  "variable": "pin"            // → {{pin}}
}

2 · Validate the PIN

Add a condition node after the PIN input. The single branch checks that a PIN was entered; connect b1 to the menu and the else handle to an "invalid PIN" end node.

condition (validate pin) · data
{
  "branches": [
    { "id": "b1", "variable": "pin", "operator": "notEmpty", "value": "" }
  ]
}
In production you'd verify the PIN with an api node and branch on eq against the response — the same pattern.

3 · The main menu

Add a menu node. Each option exposes a handle named after its key — wire option 1 → balance, 2 → amount (deposit) and 3 → comment (feedback).

menu · data
{
  "prompt": "Community Bank",
  "options": [
    { "key": "1", "label": "Check Balance" },
    { "key": "2", "label": "Deposit" },
    { "key": "3", "label": "Feedback" }
  ]
}

4 · Check balance with the API node

For option 1, add an api node that fetches the balance and saves it. Wire its next handle to an end screen that shows {{balance}}, and its errorhandle to a "try again later" end.

api (get balance) · data
{
  "method": "GET",
  "url": "https://api.example.com/balance?msisdn={{msisdn}}",
  "headers": { "Authorization": "Bearer {{token}}" },
  "saveAs": "balance"
}
end (show balance) · data
{ "message": "Your balance is GHS {{balance}}." }

5 · Take a deposit (amount → condition → payment API)

For option 2, capture the amount, validate it with another condition (gt 0), then collect it by posting to your payment API with an apinode. Save the provider's reference so the next step can store it.

input (amount) · data
{ "prompt": "Enter amount (GHS):", "variable": "amount" }
condition (valid amount) · data
{
  "branches": [
    { "id": "b1", "variable": "amount", "operator": "gt", "value": "0" }
  ]
}
api (collect deposit) · data
{
  "method": "POST",
  "url": "https://api.example.com/payments",
  "body": { "amount": "{{amount}}", "msisdn": "{{msisdn}}" },
  "timeoutMs": 8000,
  "saveAs": "paymentReference"   // provider ref → {{paymentReference}}
}

Wire the condition's b1 api and else→ an "invalid amount" end. The API node exposes two handles:

HandleWire it to
nextThe database node (step 6)
errorA 'payment failed' end

6 · Record the deposit

On next, write the deposit to your table (capturing {{paymentReference}}), then an end confirms it.

database (write deposit) · data
{
  "operation": "write",
  "collection": "deposits",
  "assignments": {
    "amount": "{{amount}}",
    "msisdn": "{{msisdn}}",
    "reference": "{{paymentReference}}"
  },
  "saveAs": "depositId"
}
end (deposited) · data
{ "message": "Deposit of GHS {{amount}} received. Ref {{paymentReference}}." }

For option 3 (Feedback), capture a comment into comment and reuse a database write into the feedback table — the same node, a different table.

7 · Test, then publish

Open the simulator and dial through each branch. API calls are mocked, so you can verify the next → database path without hitting a live provider. When it looks right, publish and deploy (see Deployments).

Shortcut

The Mobile Banking and Savings Deposittemplates in the Studio's "New from template" picker already wire up most of this — start from one and adapt.