Skip to content

Creates a customer session

POST
/session
curl --request POST \
--url https://api.pipevest.com/v1/ussd/session \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'X-Idempotency-Key: 2489E9AD-2EE2-8E00-8EC9-32D5F69181C0' \
--header 'x-client-id: <x-client-id>' \
--data '{ "customerId": "clx0a1b2c3d4e5f6g7h8i9j0k" }'

Opens a USSD session for a customer and returns the HOME menu.

What the customer sees:

Select an investment option:

1. Stocks
2. My Portfolio
X-Idempotency-Key
required
string format: uuid

Idempotency key (UUID) scoped to your credential. Mandatory on both USSD endpoints in Sandbox (UAT) and Production alike — a request without one is rejected with 400. Retrying with the same key replays the stored response verbatim rather than re-running the operation.

The customer to open a USSD session for.

Media typeapplication/json
object
customerId
required

Unique customer identifier (CUID string).

string
Example
clx0a1b2c3d4e5f6g7h8i9j0k

Error state. An unexpected internal failure while building the menu does NOT produce a 4xx/5xx: a session is opened in ERROR state and returned with HTTP 200, so the handset shows a readable message. data is the same Session shape as the 201 — currentState and menu.state are "ERROR". Detect it on the payload, not the status.

Media typeapplication/json
object
message
required
string
data
required
object
data
required

The USSD session response data (HOME menu).

object
sessionId
required

Unique session identifier.

string
currentState
required
string
menu
required

The menu structure with state, text, options, and end state flag.

object
state
required
string
text
required
string
options
required
Array<object>

A menu option with key, label, optional next state, and optional data.

object
key
required

The option key (e.g. “1”, “2”, or a search term).

string
label
required

The display label for the option.

string
nextState

The next state to transition to (some options, like “Next”, omit this).

string
action

An operation the option performs rather than a plain navigation. Mutually exclusive with nextState; most options carry neither. Today the only option that carries it is “Yes, cancel” in the CANCEL_REQUEST_CONFIRMATION menu.

string
data

Optional additional data associated with the option (e.g. stock information).

object
stockId
string
symbol
string
name
string
isEndState
required
boolean
ussdText
required
string
expiresAt
required
string format: date-time
Example
{
"message": "USSD session created with error state",
"data": {
"sessionId": "ussd_3278668b308502f3a562950fc8043028",
"currentState": "ERROR",
"menu": {
"state": "ERROR",
"text": "Sorry, something went wrong. Please try again later.",
"options": [
{
"key": "0",
"label": "Home",
"nextState": "HOME"
}
],
"isEndState": false
},
"ussdText": "Sorry, something went wrong. Please try again later.\n\n0. Home",
"expiresAt": "2025-11-06T14:38:12.202Z"
}
}

Customer session created successfully

Media typeapplication/json
object
message
required
string
data
required
object
data
required

The USSD session response data (HOME menu).

object
sessionId
required

Unique session identifier.

string
currentState
required
string
menu
required

The menu structure with state, text, options, and end state flag.

object
state
required
string
text
required
string
options
required
Array<object>

A menu option with key, label, optional next state, and optional data.

object
key
required

The option key (e.g. “1”, “2”, or a search term).

string
label
required

The display label for the option.

string
nextState

The next state to transition to (some options, like “Next”, omit this).

string
action

An operation the option performs rather than a plain navigation. Mutually exclusive with nextState; most options carry neither. Today the only option that carries it is “Yes, cancel” in the CANCEL_REQUEST_CONFIRMATION menu.

string
data

Optional additional data associated with the option (e.g. stock information).

object
stockId
string
symbol
string
name
string
isEndState
required
boolean
ussdText
required
string
expiresAt
required
string format: date-time
Example
{
"message": "Success",
"data": {
"sessionId": "ussd_3278668b308502f3a562950fc8043028",
"currentState": "HOME",
"menu": {
"state": "HOME",
"text": "Select an investment option:",
"options": [
{
"key": "1",
"label": "Stocks",
"nextState": "STOCKS",
"action": "CANCEL_ORDER",
"data": {
"stockId": "cmhkp4jkw0005zxfok9m0kiwg",
"symbol": "AAPL",
"name": "Apple Inc."
}
}
],
"isEndState": false
},
"ussdText": "Select an investment option:\n\n1. Stocks\n2. My Portfolio",
"expiresAt": "2025-11-06T14:38:12.202Z"
}
}

Request failed schema validation, or the mandatory X-Idempotency-Key header is missing.

Media typeapplication/json
One of:
object
error
string
details
Array<object>
object
field
string
message
string
Examples
{
"error": "Validation failed",
"details": [
{
"field": "customerId",
"message": "Invalid customer ID format"
}
]
}

Missing, invalid, expired or revoked token; x-client-id missing or not matching the token; or the request signature / Content-Digest failed verification.

Media typeapplication/json
object
error
required
string
message
required
string
Example
{
"error": "Unauthorized",
"message": "Organization authentication token is required"
}

Client IP is outside the credential’s allowlist

Media typeapplication/json
object
error
required
string
message
required
string
Example
{
"error": "Forbidden",
"message": "Client IP not allowed"
}

Customer not found, or not a customer of your organization

Media typeapplication/json
object
error
required
string
message
required
string
Example
{
"error": "CUSTOMER_NOT_FOUND",
"message": "Customer not found or does not belong to this organization"
}

A request with this X-Idempotency-Key is still in progress

Media typeapplication/json
object
error
required
string
message
required
string
Example
{
"error": "Conflict",
"message": "A request with this X-Idempotency-Key is already in progress"
}

The X-Idempotency-Key was already used with a different body

Media typeapplication/json
object
error
required
string
message
required
string
Example
{
"error": "Unprocessable Entity",
"message": "X-Idempotency-Key was already used with a different request payload"
}

Rate limit exceeded

Media typeapplication/json
object
error
required
string
message
required
string
Example
{
"error": "Too Many Requests",
"message": "Too many requests. Please slow down and try again shortly."
}