Skip to main content

A session, step by step

One USSD session from dial to close. A customer of Kpelle MFI repays a loan in four turns. For each turn you see the request Ponitor sends, the response your webhook returns, and the screen the phone shows.

For how sessions work in general, see How USSD works.

  1. 1The subscriber dials *123#start turn
    Ponitor sends
    {
      "sessionId": "a3f1c9e2-7b44-4e91-9c3a-1d8f0b2e6c77",
      "msisdn": "231770000000",
      "serviceCode": "*123#",
      "carrier": "orange",
      "type": "start",
      "timestamp": "2026-09-14T19:30:52.924Z",
      "input": null
    }
    
    You return
    {
      "action": "continue",
      "screen": "Welcome to Kpelle MFI",
      "options": [
        { "label": "Check balance" },
        { "label": "Repay loan" }
      ]
    }
    
    Welcome to Kpelle MFI
    1. Check balance
    2. Repay loan
    2
    CancelSend

    Every turn of the session carries the same sessionId. Key your own state on it.

  2. 2The subscriber picks 2, Repay loaninput turn
    Ponitor sends
    {
      "sessionId": "a3f1c9e2-7b44-4e91-9c3a-1d8f0b2e6c77",
      "msisdn": "231770000000",
      "serviceCode": "*123#",
      "carrier": "orange",
      "type": "input",
      "timestamp": "2026-09-14T19:31:01.310Z",
      "input": "2"
    }
    
    You return
    {
      "action": "continue",
      "screen": "Amount to repay (LRD)",
      "form": { "type": "digits" }
    }
    
    Amount to repay (LRD)
    4500
    CancelSend

    A menu choice comes back as the option's position, starting at 1.

  3. 3The subscriber types 4500input turn
    Ponitor sends
    {
      "sessionId": "a3f1c9e2-7b44-4e91-9c3a-1d8f0b2e6c77",
      "msisdn": "231770000000",
      "serviceCode": "*123#",
      "carrier": "orange",
      "type": "input",
      "timestamp": "2026-09-14T19:31:09.552Z",
      "input": "4500"
    }
    
    You return
    {
      "action": "continue",
      "screen": "Enter your PIN to pay LRD 4,500",
      "form": { "type": "digits", "sensitive": true }
    }
    
    Enter your PIN to pay LRD 4,500
    ••••
    CancelSend

    sensitive marks the next answer as a PIN, so Ponitor won't store it.

  4. 4The subscriber types their PINinput turn
    Ponitor sends
    {
      "sessionId": "a3f1c9e2-7b44-4e91-9c3a-1d8f0b2e6c77",
      "msisdn": "231770000000",
      "serviceCode": "*123#",
      "carrier": "orange",
      "type": "input",
      "timestamp": "2026-09-14T19:31:18.047Z",
      "input": "2580"
    }
    
    You return
    {
      "action": "end",
      "screen": "Paid LRD 4,500. Thank you for using Kpelle MFI."
    }
    
    Paid LRD 4,500. Thank you for using Kpelle MFI.
    Session closed

    Your webhook gets the real PIN. The session history shows "[redacted]". end shows the screen and closes the session.

What to take from it​

  • Key your state on sessionId. It's the same on every turn.
  • Treat every input as the answer to the last screen you returned for that session.
  • Reset your state when a start turn arrives. The subscriber can press 00 to go home mid-session.
  • Validate what the subscriber types. Ask again with another continue if it isn't valid.
  • Mark PIN and password prompts sensitive, so Ponitor doesn't store the answer.

For every field and the signature check, see the USSD webhook reference.