Error Codes
Complete reference of error codes returned by EasySlip API.
Match on error.code, not the message
For v2, error.code (e.g. SLIP_NOT_FOUND) is the stable contract — match your logic on it. The error.message is a human-readable string that may change without notice. The Description column below explains each code; it is not the literal error.message the API returns. (For v1, the message field carries the code string itself.)
API v2 Error Codes
Authentication Errors (401)
| Code | Description | Cause | Solution |
|---|---|---|---|
MISSING_API_KEY | Authorization header is required | No Authorization header | Add Authorization: Bearer YOUR_API_KEY header |
INVALID_API_KEY | The provided API key is invalid | API key doesn't exist or is malformed | Check API key is correct |
Authorization Errors (403)
| Code | Description | Cause | Solution |
|---|---|---|---|
BRANCH_INACTIVE | This API branch has been deactivated | Branch was deactivated | Reactivate in developer portal |
SERVICE_BANNED | Service has been banned | Violation of terms | Contact support |
SERVICE_EXPIRED | Service has expired | Subscription/plan expired | Renew your plan |
IP_NOT_ALLOWED | Your IP address is not in the allowed list | IP whitelist restriction | Add IP to whitelist |
QUOTA_EXCEEDED | Your API quota has been exceeded | Monthly quota reached | Upgrade plan or wait for reset |
USER_BANNED | User has been banned | User account violation of terms | Contact support |
Validation Errors (400)
| Code | Description | Cause | Solution |
|---|---|---|---|
VALIDATION_ERROR | Validation failed | Invalid request body | Check request format |
URL_PROTOCOL_NOT_ALLOWED | Only HTTP/HTTPS allowed | Non-HTTP URL | Use HTTP or HTTPS URL |
URL_INVALID_IP_RANGE | URL points to restricted IP | Private/internal IP | Use public URL |
IMAGE_URL_UNREACHABLE | Unable to access URL | URL not accessible | Check URL is public |
IMAGE_SIZE_TOO_LARGE | Image exceeds 4MB limit | File too large | Compress image |
INVALID_IMAGE_FORMAT | File is not a valid image | Corrupt or wrong format | Use JPEG, PNG, GIF, WebP |
INVALID_BANK_CODE | The provided bankCode is not supported | bankCode not in bank list | Use a code from GET /banks |
INVALID_EXTRA_VERIFY | extraVerify is not valid for this bank | Value supplied is not in the bank's option list | Use one of the bank's extraVerify values from GET /banks |
INVALID_EXTRA_VERIFY | extraVerify is required for this bank | Bank requires an option but none was supplied (e.g. on a bankCode change) | Supply a valid extraVerify value from GET /banks |
Not Found Errors (404)
| Code | Description | Cause | Solution |
|---|---|---|---|
SLIP_NOT_FOUND | Slip not found or invalid | Invalid slip or no QR | Check slip validity |
SLIP_PENDING | Bangkok Bank slip is pending | Slip transferred within 5 minutes | Wait a few minutes and retry |
BANK_ACCOUNT_NOT_FOUND | Bank account not found | Account doesn't exist or isn't linked to your branch | Check the account id and branch link |
NOT_FOUND | Resource not found | Wrong endpoint | Check endpoint URL |
Conflict Errors (409)
| Code | Description | Cause | Solution |
|---|---|---|---|
BANK_ACCOUNT_DUPLICATE | An active account with the same bank code and number already exists | Duplicate bankCode + bankNumber in your service | Reuse the existing account or use different details |
Rate Limit Errors (429)
| Code | Description | Cause | Solution |
|---|---|---|---|
RATE_LIMIT_EXCEEDED | Too many requests | Verify request rate exceeded | Wait for the Retry-After seconds, then retry — see Rate Limits |
Server Errors (500)
| Code | Description | Cause | Solution |
|---|---|---|---|
API_SERVER_ERROR | Service temporarily unavailable | Temporary processing error | Retry later |
INTERNAL_SERVER_ERROR | Internal server error | Unexpected error | Contact support |
API v1 Error Codes
Authentication Errors (401)
| Code | Description | Cause | Solution |
|---|---|---|---|
unauthorized | Unauthorized | Invalid or missing API key | Check Authorization header |
Authorization Errors (403)
| Code | Description | Cause | Solution |
|---|---|---|---|
access_denied | Access denied | IP not whitelisted | Add IP to whitelist |
application_expired | Application expired | Subscription expired | Renew subscription |
application_deactivated | Application deactivated | App was deactivated | Reactivate in portal |
quota_exceeded | Quota exceeded | Monthly quota reached | Upgrade plan |
Validation Errors (400)
| Code | Description | Cause | Solution |
|---|---|---|---|
invalid_payload | Invalid payload | Malformed QR payload | Check payload format |
invalid_check_duplicate | Invalid checkDuplicate | Wrong boolean format | Use true or false |
invalid_url | Invalid URL | Malformed or unsafe URL | Check URL format |
invalid_image | Invalid image | Not a valid image | Use supported format |
image_size_too_large | Image too large | Exceeds 4MB | Compress image |
invalid_request | Invalid request | Schema validation failed | Check request body |
duplicate_slip | Duplicate slip | Already verified | Check data for details |
Not Found Errors (404)
| Code | Description | Cause | Solution |
|---|---|---|---|
slip_not_found | Slip not found | Invalid or fake slip | Verify slip authenticity |
slip_pending | Bangkok Bank slip is pending | Slip transferred within 5 minutes | Wait a few minutes and retry |
qrcode_not_found | QR code not found | No QR in image | Use clearer image |
not_found | Not found | Wrong endpoint | Check URL |
Rate Limit Errors (429)
| Code | Description | Cause | Solution |
|---|---|---|---|
rate_limit_exceeded | Too many requests | Verify request rate exceeded | Wait for the Retry-After seconds, then retry — see Rate Limits |
Server Errors (500)
| Code | Description | Cause | Solution |
|---|---|---|---|
server_error | Server error | Internal error | Retry later |
api_server_error | Service temporarily unavailable | Temporary processing error | Retry later |
Error Response Format
API v2
{
"success": false,
"error": {
"code": "SLIP_NOT_FOUND",
"message": "The slip could not be found or is invalid"
}
}VALIDATION_ERROR messages
For VALIDATION_ERROR, the message names which field failed and why, e.g. "bankNumber: Too small: expected string to have >=1 characters". When more than one field fails, the failures are joined into one message with ; . The code is always VALIDATION_ERROR (there is no separate details field — match on code, show message to the user).
API v1
{
"status": 404,
"message": "slip_not_found"
}Duplicate Slip (v1)
Returns slip data along with error:
{
"status": 400,
"message": "duplicate_slip",
"data": {
"payload": "...",
"transRef": "...",
"amount": { ... }
}
}Error Handling Best Practices
1. Check Success/Status First
// v2
if (!result.success) {
console.error(`Error [${result.error.code}]: ${result.error.message}`);
}
// v1
if (result.status !== 200) {
console.error(`Error: ${result.message}`);
}2. Handle Specific Errors
switch (result.error.code) {
case 'QUOTA_EXCEEDED':
// Alert user or pause operations
break;
case 'SLIP_NOT_FOUND':
// Ask user to try again
break;
case 'API_SERVER_ERROR':
// Retry with exponential backoff
break;
}3. Implement Retry Logic
async function verifyWithRetry(payload, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
const result = await verify(payload);
if (result.success) return result;
if (result.error.code === 'API_SERVER_ERROR') {
await sleep(1000 * (i + 1)); // Exponential backoff
continue;
}
throw new Error(result.error.message);
}
}4. Log Errors for Debugging
if (!result.success) {
console.error({
timestamp: new Date().toISOString(),
errorCode: result.error.code,
errorMessage: result.error.message,
payload: payload.substring(0, 20) + '...'
});
}