Error Reference
The Borderbolt API uses conventional HTTP status codes and structured error responses to indicate the success or failure of requests.
HTTP Status Codes
| Status Code | Meaning |
|---|---|
200 OK | Request succeeded |
201 Created | Resource created successfully |
204 No Content | Request succeeded with no response body (e.g., DELETE) |
400 Bad Request | Invalid request format or parameters |
401 Unauthorized | Invalid or missing authentication token |
403 Forbidden | Insufficient permissions/scopes |
404 Not Found | Resource not found |
422 Unprocessable Entity | Validation error or business logic failure |
429 Too Many Requests | Rate limit exceeded |
500 Internal Server Error | Server error |
503 Service Unavailable | Temporary service outage |
Error Response Format
All error responses follow this structure:
{
"error": "error_code",
"error_description": "Human-readable error message",
"errors": {
"field_name": [
"Detailed validation error message"
]
}
}Fields
| Field | Description |
|---|---|
error | Machine-readable error code |
error_description | Human-readable error message |
errors | Detailed validation errors (field-level, only for 422 responses) |
Common Error Codes
400 Bad Request
invalid_request
The request is malformed or missing required parameters.
{
"error": "invalid_request",
"error_description": "The request is missing required parameters or contains invalid values.",
"errors": {
"grant_type": [
"The grant_type field is required."
]
}
}Common Causes:
- Missing required fields
- Invalid JSON format
- Invalid parameter types
Solution: Review the API documentation and ensure all required fields are present with correct types.
401 Unauthorized
invalid_token
The access token is invalid, expired, or revoked.
{
"error": "invalid_token",
"error_description": "The access token is invalid or has expired.",
"message": "Unauthenticated."
}Common Causes:
- Token expired (tokens are valid for 1 hour)
- Token revoked
- Invalid token format
Solution: Request a new access token using your client credentials.
invalid_client
Client authentication failed (invalid client ID or secret).
{
"error": "invalid_client",
"error_description": "Client authentication failed",
"message": "Client authentication failed"
}Common Causes:
- Incorrect client ID or secret
- Client credentials revoked
Solution: Verify your client credentials in Settings → API Documentation.
403 Forbidden
insufficient_scope
The access token lacks the required scope for this operation.
{
"error": "insufficient_scope",
"error_description": "The access token does not have the required scope: declarations:write",
"required_scope": "declarations:write",
"token_scopes": ["declarations:read"]
}Common Causes:
- Token requested without necessary scopes
- OAuth client not granted required scopes
Solution: Request a new token with the required scope or contact your admin to grant the scope to your OAuth client.
404 Not Found
not_found
The requested resource does not exist.
{
"error": "not_found",
"error_description": "The requested resource was not found.",
"message": "The requested declaration was not found."
}Common Causes:
- Invalid resource ID
- Resource deleted
- Accessing another organization’s resource
Solution: Verify the resource ID and ensure you have access to it.
422 Unprocessable Entity
validation_error
Request validation failed.
{
"error": "validation_error",
"error_description": "The given data was invalid.",
"errors": {
"declaration.office": [
"The office field is required."
],
"declaration.items.0.hs_code": [
"The hs code must be between 8 and 10 digits."
],
"declaration.items.1.invoice_value": [
"The invoice value must be greater than 0."
]
}
}Common Causes:
- Missing required fields
- Invalid field values (format, range, etc.)
- Business logic constraints
Solution: Review the errors object for field-level details and correct the invalid data.
SKU_RESOLUTION_FAILED
One or more SKU codes could not be resolved from the Item Master.
{
"error": "SKU_RESOLUTION_FAILED",
"error_description": "One or more SKU codes could not be resolved from the Item Master.",
"errors": {
"skus.0.sku_code": [
"SKU 'PROD-999' not found in Item Master."
],
"skus.1.sku_code": [
"SKU 'PROD-888' is inactive."
]
}
}Common Causes:
- SKU code doesn’t exist in Item Master
- SKU is inactive
- Typo in SKU code
Solution: Verify SKU codes exist and are active in the Item Master.
invalid_status
Operation not allowed for the resource’s current status.
{
"error": "invalid_status",
"error_description": "This operation is not allowed for declarations with status 'REL'.",
"current_status": "REL",
"allowed_statuses": ["DRF", "ERR"]
}Common Causes:
- Attempting to update a finalized declaration
- Attempting to delete a submitted declaration
- Attempting to submit a declaration that’s already submitted
Solution: Check the resource’s current status and ensure the operation is valid for that status.
429 Too Many Requests
rate_limit_exceeded
You have exceeded the rate limit for API requests.
{
"error": "rate_limit_exceeded",
"error_description": "You have exceeded the rate limit. Please try again later.",
"retry_after": 60
}Rate Limits:
- General: 60 requests per minute per OAuth client
- Reports Export: 10 exports per minute per OAuth client
Solution: Wait for the retry_after period (in seconds) before retrying.
500 Internal Server Error
server_error
An unexpected error occurred on the server.
{
"error": "server_error",
"error_description": "An unexpected error occurred. Please try again later.",
"reference": "ERR-2026-03-25-12345"
}Common Causes:
- Database connection issues
- External service unavailable
- Application bug
Solution:
- Retry the request after a short delay
- If the error persists, contact support with the error reference
Rate Limiting
The API uses rate limiting to prevent abuse and ensure fair usage.
Rate Limit Headers
Every API response includes rate limit headers:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1711371600| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum requests per window |
X-RateLimit-Remaining | Remaining requests in current window |
X-RateLimit-Reset | Unix timestamp when the window resets |
Handling Rate Limits
const response = await fetch('https://app.borderbolt.com/api/v1/declarations', {
headers: { 'Authorization': `Bearer ${token}` }
});
if (response.status === 429) {
const retryAfter = response.headers.get('Retry-After');
console.log(`Rate limited. Retry after ${retryAfter} seconds.`);
// Wait and retry
await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
// Retry request...
}Validation Error Examples
Declaration Validation
{
"error": "validation_error",
"error_description": "The given data was invalid.",
"errors": {
"declaration.parties.consignee.eori": [
"The EORI field is required for EU consignees."
],
"declaration.items.0.hs_code": [
"The HS code must be between 8 and 10 digits."
],
"declaration.items.0.gross_mass": [
"The gross mass must be greater than or equal to net mass."
],
"declaration.transport_mode": [
"The selected transport mode is invalid."
]
}
}Customer Validation
{
"error": "validation_error",
"error_description": "The given data was invalid.",
"errors": {
"code": [
"The code has already been taken."
],
"eori": [
"The EORI format is invalid. Expected format: NL + 12 digits."
],
"country": [
"The country must be a valid ISO 3166-1 alpha-2 code."
]
}
}Invoice Validation
{
"error": "validation_error",
"error_description": "The given data was invalid.",
"errors": {
"invoice_date": [
"The invoice date must be a date before or equal to today."
],
"lines.0.unit_price": [
"The unit price must be greater than 0."
],
"lines.1.vat_rate": [
"The vat rate must be between 0 and 100."
]
}
}Debugging Tips
1. Enable Verbose Logging
Log all API requests and responses:
// Log API requests for debugging
error_log('Borderbolt API Request: POST /api/v1/declarations/import');
error_log('Request headers: ' . json_encode($headers));
error_log('Request body: ' . json_encode($requestBody));
// Log API responses
error_log('Borderbolt API Response status: ' . $response->status());
error_log('Response body: ' . json_encode($response->json()));2. Check Field-Level Errors
For 422 validation errors, inspect the errors object:
if (response.status === 422) {
const { errors } = await response.json();
// Iterate over field errors
for (const [field, messages] of Object.entries(errors)) {
console.error(`${field}: ${messages.join(', ')}`);
}
}3. Validate Before Submitting
Use the validation endpoints to check data before submission:
curl -X POST "https://app.borderbolt.com/api/v1/declarations/import/validate" \
-H "Authorization: Bearer your-access-token" \
-H "Content-Type: application/json" \
-d @declaration.json4. Monitor Rate Limits
Track rate limit headers to avoid hitting limits:
const remaining = parseInt(response.headers.get('X-RateLimit-Remaining'));
const reset = parseInt(response.headers.get('X-RateLimit-Reset'));
if (remaining < 5) {
console.warn(`Only ${remaining} requests remaining until ${new Date(reset * 1000)}`);
}Support
If you encounter persistent errors:
- Check Status Page: Visit https://status.borderbolt.com for service status
- Review Documentation: Ensure you’re using the correct API format
- Contact Support: Email support@borderbolt.com with:
- Error reference (if provided)
- Request/response logs
- Steps to reproduce
Next Steps
- Authentication - Obtaining access tokens
- Declarations API - Declaration endpoints
- Webhooks - Real-time event notifications