Table of contents

Response codes

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.

JSON

{
 "id": "8f4a6b0f-fa9b-4f45-8e19-b75c1a70432a",
 "status": "COMPLETED",
 ...
}

201 Created

Returned when a resource is successfully created.

JSON

{
 "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.

JSON

{
 "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.

JSON

{
 "message": "Unauthorized"
}

Resolution: Request a new access token.

403 Forbidden

Insufficient permissions for the requested operation.

JSON

{
 "message": "Forbidden"
}

Resolution: Contact Precium support to verify account permissions.

404 Not Found

Requested resource does not exist.

JSON

{
 "message": "Resource not found"
}

Common causes:

  • Invalid resource ID
  • Resource deleted or expired

409 Conflict

Resource conflict, typically duplicate data.

JSON

{
 "message": "Duplicate external reference"
}

Common causes:

  • Duplicate externalReference
  • Duplicate contractReference

500 Internal Server Error

Server-side error.

JSON

{
 "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:

JSON

{
 "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

JSX

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:

JSX

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:

JSX

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:

  1. Note the request details (endpoint, payload, timestamp)
  2. Check for any x-request-id in response headers
  3. Contact Precium support with this information

Email: support@precium.com