Flowwithlit Docs
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

CodeNameMeaningWhat to do
200OK Request succeeded Process data normally
400Bad Request A required field is missing, has the wrong type, or fails validation Read message — it names the offending field
401Unauthorized Missing or invalid API key / JWT token Check your Authorization header; re-authenticate if token expired
402Payment Required Insufficient wallet balance for the operation Fund your wallet first
403Forbidden Authenticated but not authorised (wrong role, KYC not complete, etc.) Complete KYC or check account permissions
404Not Found The resource doesn't exist or doesn't belong to your account Verify the ID / reference is correct
409Conflict Duplicate transaction reference or unique constraint violation Use a different ref for each transaction
429Too Many Requests Rate limit exceeded Implement exponential back-off; slow down your request rate
501Not Implemented Feature not yet available (e.g. live card charging) Contact support for availability
500Internal 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();