Step 3 — Make API calls
Request structure
Every request has this shape:
// Headers
Content-Type: application/json
x-client-id: <CLIENT_ID>
// Body
{
data: <JWE encrypted token>,
srvc: <CLIENT_SRVC>
}Always include userId
Inside every encrypted payload, include the userId of the end user making the request:
const result = await apiCall('users/details', {
userId: 'the-logged-in-users-id',
...otherFields
})This is how the API tracks per-user activity. Without userId, logs will show null for user identity.
Response structure
Every response follows this shape:
{
ok: true, // boolean — use this to check success
data: { ... }, // the actual response payload
memo: "string", // human-readable message
stat: true, // same as ok
code: 200, // HTTP status code
time: 143, // server processing time ms
trxn: "txn_...", // internal transaction reference
srvc: "...", // service that handled the request
}Error handling
try {
const data = await apiCall('users/details', { userId })
} catch (err) {
console.error(err.message) // human-readable error from memo
console.error(err.status) // HTTP status: 400 / 401 / 403 / 500
console.error(err.txId) // include this when contacting support
}Common error codes
| Error memo | Status | Cause |
|---|---|---|
| Missing x-client-id header | 401 | Header not included |
| Unknown or inactive client | 401 | Wrong CLIENT_ID |
| Token expired | 401 | Token > 5 min old |
| Invalid or tampered token | 400 | Wrong secret / corrupt token |
| Token srvc mismatch | 400 | srvc in token ≠ body srvc |
| Missing data field | 400 | No data field in request body |
| Missing srvc field | 400 | No srvc field in request body |