HTTP status codes and error handling for the Precium API.
HTTP Status Codes
| Code | Type | Description |
|---|---|---|
200 | Successful | Request processed successfully |
201 | Created | Resource created successfully |
204 | No Content | Request processed, resource removed |
400 | Bad Request | Invalid request structure or data |
401 | Unauthorized | Invalid or expired access token |
403 | Forbidden | Insufficient permissions |
404 | Not Found | Requested resource not found |
409 | Conflict | Resource conflict (e.g., duplicate reference) |
500 | Internal Server Error | Server error - contact Precium support |
Success Responses
200 OK
Returned for successful GET requests and updates.
{
"id": "8f4a6b0f-fa9b-4f45-8e19-b75c1a70432a",
"status": "COMPLETED",
...
}201 Created
Returned when a resource is successfully created.
{
"id": "new-resource-id",
"status": "PENDING",
...
}204 No Content
Returned when a resource is successfully deleted. No response body.
Error Responses
400 Bad Request
Invalid request data. Check required fields and formats.
{
"value": {
"Message": "Validation error: field 'accountNumber' is required"
},
"statusCode": 400
}Common causes:
- Missing required fields
- Invalid field formats
- Invalid enum values
- Business rule violations
401 Unauthorized
Invalid or expired access token.
{
"message": "Unauthorized"
}Resolution: Request a new access token.
403 Forbidden
Insufficient permissions for the requested operation.
{
"message": "Forbidden"
}Resolution: Contact Precium support to verify account permissions.
404 Not Found
Requested resource does not exist.
{
"message": "Resource not found"
}Common causes:
- Invalid resource ID
- Resource deleted or expired
409 Conflict
Resource conflict, typically duplicate data.
{
"message": "Duplicate external reference"
}Common causes:
- Duplicate
externalReference - Duplicate
contractReference
500 Internal Server Error
Server-side error.
{
"message": "Internal server error"
}Resolution: Contact Precium support with request details.
Mandate Status Codes
EFT Mandate Statuses
| Status | Description |
|---|---|
ACTIVE | Mandate is active and can be used for collections |
SUSPENDED | Mandate temporarily suspended |
CANCELLED | Mandate cancelled, no further collections |
EXPIRED | Mandate has expired |
DebiCheck Mandate Statuses
| Status | Description |
|---|---|
NEW | Mandate created, not yet submitted |
PENDING_AUTHENTICATION | Awaiting customer authentication |
COMPLETED | Successfully authenticated |
AUTH_FAILURE | Authentication failed or rejected |
CANCELLED | Mandate cancelled |
SUSPENDED | Mandate temporarily suspended |
Collection Status Codes
| Status | Description |
|---|---|
PENDING | Collection submitted, awaiting processing |
PROCESSING | Being processed by bank |
COMPLETED | Collection successful |
UNPAID | Collection failed |
DISPUTED | Customer disputed the collection |
CANCELLED | Collection cancelled before processing |
Unpaid Reason Codes
When a collection returns UNPAID, additional information may include:
| Code | Description |
|---|---|
INSUFFICIENT_FUNDS | Not enough funds in account |
ACCOUNT_CLOSED | Account has been closed |
ACCOUNT_NOT_FOUND | Account does not exist |
PAYMENT_STOPPED | Customer stopped the payment |
NOT_PROVIDED_FOR | Account holder rejected debit |
Payment Status Codes
| Status | Description |
|---|---|
PENDING | Payment submitted, awaiting processing |
PROCESSING | Being processed by bank |
COMPLETED | Payment successful |
FAILED | Payment failed |
CANCELLED | Payment cancelled |
Bank Account Verification Codes
When verifyAccount: true fails:
{
"value": {
"Message": "Debtor account verification failure: details={\"AccountExists\":true,\"AccountIsOpen\":false,\"AccountTypeMatches\":null,\"IdNumberMatches\":null,\"AccountAcceptsDebits\":null}"
},
"statusCode": 400
}| Field | Description |
|---|---|
AccountExists | Account number exists at bank |
AccountIsOpen | Account is active/open |
AccountTypeMatches | Provided type matches actual |
AccountAcceptsDebits | Account can receive debits |
IdNumberMatches | ID matches account holder |
Error Handling Best Practices
Retry Logic
async function apiRequest(options, maxRetries = 3) {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
const response = await fetch(options.url, options);
if (response.status === 401) {
// Refresh token and retry
await refreshToken();
continue;
}
if (response.status >= 500) {
// Server error - wait and retry
await sleep(attempt * 1000);
continue;
}
return response;
} catch (error) {
if (attempt === maxRetries) throw error;
await sleep(attempt * 1000);
}
}
}Logging
Log all API responses for debugging:
console.log({
timestamp: new Date().toISOString(),
endpoint: response.url,
status: response.status,
requestId: response.headers.get('x-request-id'),
body: await response.json()
});Error Mapping
Map API errors to user-friendly messages:
const errorMessages = {
400: 'Invalid request data. Please check your input.',
401: 'Session expired. Please log in again.',
403: 'You do not have permission for this action.',
404: 'The requested resource was not found.',
409: 'This reference already exists.',
500: 'An unexpected error occurred. Please try again later.'
};Contact Support
If you encounter a 500 status code or persistent errors:
- Note the request details (endpoint, payload, timestamp)
- Check for any
x-request-idin response headers - Contact Precium support with this information
Email: support@precium.com