REFERENCE
Errors & Status Codes
Every Flowwithlit API response uses a consistent envelope. On error, success is
false and message explains what went wrong.
Error Response Format
JSON — error envelope
{
"success": false,
"message": "Invalid public key",
"data": null
}
HTTP Status Codes
| Code | Name | Meaning | What to do |
|---|---|---|---|
200 | OK | Request succeeded | Process data normally |
400 | Bad Request | A required field is missing, has the wrong type, or fails validation | Read message — it names the offending field |
401 | Unauthorized | Missing or invalid API key / JWT token | Check your Authorization header; re-authenticate if token expired |
402 | Payment Required | Insufficient wallet balance for the operation | Fund your wallet first |
403 | Forbidden | Authenticated but not authorised (wrong role, KYC not complete, etc.) | Complete KYC or check account permissions |
404 | Not Found | The resource doesn't exist or doesn't belong to your account | Verify the ID / reference is correct |
409 | Conflict | Duplicate transaction reference or unique constraint violation | Use a different ref for each transaction |
429 | Too Many Requests | Rate limit exceeded | Implement exponential back-off; slow down your request rate |
501 | Not Implemented | Feature not yet available (e.g. live card charging) | Contact support for availability |
500 | Internal Server Error | Unexpected error on our end | Retry after a short delay; contact support if it persists |
Handling Errors in Code
$ch = curl_init('https://api.flowwithlit.com/user/transfers/bank');
// ... set options ...
$body = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$res = json_decode($body, true);
if ($code === 200 && $res['success']) {
// Handle success
$ref = $res['data']['reference'];
} elseif ($code === 402) {
// Insufficient balance
throw new RuntimeException('Insufficient balance: ' . $res['message']);
} elseif ($code === 400) {
// Validation error
throw new InvalidArgumentException($res['message']);
} else {
// Generic error
throw new RuntimeException("API error $code: " . $res['message']);
}
const res = await fetch('https://api.flowwithlit.com/user/transfers/bank', options);
const data = await res.json();
if (!res.ok || !data.success) {
if (res.status === 402) {
throw new Error('Insufficient balance: ' + data.message);
}
if (res.status === 401) {
// Re-authenticate: token expired
await refreshToken();
return initiateTransfer(); // retry
}
throw new Error(`API ${res.status}: ${data.message}`);
}
return data.data; // success
import requests
resp = requests.post('https://api.flowwithlit.com/user/transfers/bank', **opts)
data = resp.json()
if not resp.ok or not data.get('success'):
if resp.status_code == 402:
raise ValueError(f"Insufficient balance: {data['message']}")
if resp.status_code == 401:
raise PermissionError("Invalid or expired token")
raise RuntimeError(f"API {resp.status_code}: {data.get('message')}")
return data['data']
Idempotency
For transfer and payment endpoints, always supply a unique ref (reference) field
per operation. If you retry a failed request with the same ref, the server will
detect the duplicate and avoid double-charging.
JavaScript — generating a unique ref
// Combine order ID + timestamp for uniqueness
const ref = `ORDER_${orderId}_${Date.now()}`;
// Or use a UUID library:
// import { v4 as uuidv4 } from 'uuid';
// const ref = uuidv4();