Flow Client API
Authentication
The Flow Client API allows authorized clients to interact with the platform. Authentication uses Signed JWT Assertions (RS256), which provides high security without ever sharing your Private Key with our servers.
To obtain your Client ID and Private Key, you must first configure a Webhook URL on the Flow Platform. Once you have saved your webhook configuration, the platform will generate and display your unique credentials.
For a step-by-step guide on configuring webhooks, see the Webhooks documentation.
We recommend performing all initial integration tests in the Sandbox environment. This allows you to verify your authentication logic and API calls safely before switching to the Live environment.
Authentication Process
Authentication is a two-step process:
- Exchange a Signed Assertion for a short-lived Bearer Token.
- Use the Bearer Token in the
Authorizationheader for all API calls.
1. Obtain an Access Token
You must generate a JWT locally, sign it with your RSA Private Key, and send it to the token endpoint.
Endpoint: POST access.1flow/v1/clients/token
Assertion Requirements (JWT Claims):
| Claim | Value | Description |
|---|---|---|
iss | YOUR_CLIENT_ID | Your unique Client ID provided by on the Flow Platform. |
sub | YOUR_CLIENT_ID | Same as Client ID. |
iat | Timestamp | Issued At (Current Unix time). |
exp | Timestamp | Expiry. |
Python Authentication Example
import jwt
import time
import requests
CLIENT_ID = "your_client_id"
PRIVATE_KEY = """Your Private key"""
def get_access_token():
now = int(time.time())
payload = {
"iss": CLIENT_ID,
"sub": CLIENT_ID,
"iat": now,
"exp": now + 300 # Valid for 5 minutes
}
# Sign the assertion using RS256
assertion = jwt.encode(payload, PRIVATE_KEY, algorithm="RS256")
# Exchange assertion for a real Bearer Token
response = requests.post(
"(https://access.1flow/v1/clients/token)",
data={
"grant_type": "client_credentials",
"client_assertion_type": "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
"client_assertion": assertion,
"client_id": CLIENT_ID
}
)
if response.status_code == 200:
return response.json()["access_token"]
else:
raise Exception(f"Auth Failed: {response.text}")
# Authenticate once and reuse the token
token = get_access_token()
Customer Lookup
Before initiating a recharge, you can look up a customer to verify their details and the devices associated with them.
Endpoint: POST access.1flow/v1/clients/lookup
Request Examples
- Python
- JSON
headers = {"Authorization": f"Bearer {token}"}
payload = {"phoneNumber": "+254700000000"}
response = requests.post(
'https://access.1flow/v1/clients/lookup',
headers=headers,
json=payload
)
print(response.json())
{
"phoneNumber": "+254700000000"
}
Initiate Recharge
To add water credit to a customer's device, use the Initiate Recharge endpoint. This process is asynchronous.
Endpoint: POST access.1flow/v1/clients/recharge
Request Examples
- Python
- JSON
headers = {"Authorization": f"Bearer {token}"}
payload = {
"deviceId": "68753500140920",
"amount": 100.0
}
response = requests.post(
'https://access.1flow/v1/clients/recharge',
headers=headers,
json=payload
)
print(response.json())
{
"deviceId": "68753500140920",
"amount": 100.0
}
Response
The API will return a 202 Accepted status with a rechargeId. You can use this ID to track the status of the recharge.
{
"success": true,
"timestamp": 1777885301197,
"message": "success",
"data": {
"id": "98466062-2548-4dca-9ef9-f1b4b09c92dc",
"serialNumber": "68753500140920",
"deviceType": "DEVICE",
"status": "PENDING",
"amount": 100.5,
"createdAt": "2026-05-04T09:01:41.197617901Z",
"customer": {
"name": "Jane Doe",
"phoneNumber": "+254712345678"
}
}
}
Verify Recharge
Check the current status of a recharge using its ID.
Endpoint: GET access.1flow/v1/clients/recharge/{id}
Request Examples
- Python
recharge_id = "98466062-2548-4dca-9ef9-f1b4b09c92dc"
headers = {"Authorization": f"Bearer {token}"}
response = requests.get(
f'https://access.1flow/v1/clients/recharge/{recharge_id}',
headers=headers
)
print(response.json())
Response
Returns the current status of the recharge (e.g., PENDING, COMPLETED, FAILED).
{
"success": true,
"timestamp": 1777890516031,
"message": "success",
"data": {
"id": "800cb2a6-1b5f-4e5d-aba0-22550fab12bb",
"serialNumber": "68753500140920",
"deviceType": "DEVICE",
"status": "COMPLETED",
"amount": 100.5,
"currency": "GHS",
"litres": 20.1,
"pricePerLitre": 5,
"balance": 150052,
"createdAt": "2026-05-04T09:36:30.112536Z",
"completedAt": "2026-05-04T09:46:28.331923Z",
"customer": {
"name": "Jane Doe",
"phoneNumber": "+254712345678"
}
}
}