Skip to main content

API Error Handling

This document describes how the CO2Trust API handles errors and how to properly handle them in your application.

Error Response Format

All API errors follow a consistent format:

{
"detail": "Error message describing what went wrong",
"status_code": 400
}

HTTP Status Codes

The API uses standard HTTP status codes to indicate the type of error:

2xx Success

  • 200 OK: Request succeeded
  • 201 Created: Resource created successfully

4xx Client Errors

  • 400 Bad Request: Invalid request parameters or body
  • 401 Unauthorized: Authentication required or token invalid
  • 403 Forbidden: User lacks required permissions
  • 404 Not Found: Requested resource does not exist
  • 422 Unprocessable Entity: Validation error

5xx Server Errors

  • 500 Internal Server Error: Unexpected server error
  • 503 Service Unavailable: Service temporarily unavailable

Common Error Scenarios

Authentication Errors

Invalid Token

{
"detail": "Could not validate credentials"
}

Status Code: 401

Solution: Re-authenticate to get a new access token.

Missing Token

{
"detail": "Not authenticated"
}

Status Code: 401

Solution: Include the Authorization: Bearer <token> header in your request.

Invalid Backend Secret Key

{
"detail": "Invalid key"
}

Status Code: 401

Solution: Ensure the X-Backend-Secret-Key header matches the configured backend secret key.

Validation Errors

Invalid Request Body

{
"detail": [
{
"loc": ["body", "email"],
"msg": "field required",
"type": "value_error.missing"
}
]
}

Status Code: 422

Solution: Review the request body and ensure all required fields are provided with valid values.

Invalid Query Parameters

{
"detail": "Invalid query parameter: page must be >= 1"
}

Status Code: 400

Solution: Check query parameter values and ensure they meet the API requirements.

Resource Errors

Resource Not Found

{
"detail": "Product not found"
}

Status Code: 404

Solution: Verify the resource ID exists and you have access to it.

Duplicate Resource

{
"detail": "Resource already exists"
}

Status Code: 400

Solution: Check if the resource already exists before creating it.

Permission Errors

Insufficient Permissions

{
"detail": "Insufficient permissions"
}

Status Code: 403

Solution: Ensure your user account has the required role (admin, approver, etc.).

Server Errors

Internal Server Error

{
"detail": "Internal server error"
}

Status Code: 500

Solution: This indicates a server-side issue. Check API status and retry the request. If the issue persists, contact support.

Service Unavailable

{
"detail": "Service temporarily unavailable"
}

Status Code: 503

Solution: The service is temporarily down. Retry the request after a short delay.

Error Handling Best Practices

1. Always Check Status Codes

const response = await fetch('/api/endpoint');
if (!response.ok) {
const error = await response.json();
// Handle error based on status code
switch (response.status) {
case 401:
// Re-authenticate
break;
case 404:
// Resource not found
break;
case 500:
// Server error - retry or report
break;
}
}

2. Implement Retry Logic

For transient errors (5xx), implement exponential backoff:

async function fetchWithRetry(url, options, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
const response = await fetch(url, options);
if (response.ok) return response;

if (response.status >= 500 && i < maxRetries - 1) {
await new Promise(resolve => setTimeout(resolve, Math.pow(2, i) * 1000));
continue;
}

throw new Error(`Request failed: ${response.status}`);
} catch (error) {
if (i === maxRetries - 1) throw error;
await new Promise(resolve => setTimeout(resolve, Math.pow(2, i) * 1000));
}
}
}

3. Handle Token Expiration

async function authenticatedFetch(url, options = {}) {
let token = getStoredToken();

const response = await fetch(url, {
...options,
headers: {
...options.headers,
'Authorization': `Bearer ${token}`
}
});

if (response.status === 401) {
// Token expired, re-authenticate
token = await reAuthenticate();
// Retry request with new token
return fetch(url, {
...options,
headers: {
...options.headers,
'Authorization': `Bearer ${token}`
}
});
}

return response;
}

4. Validate Input Before Sending

Validate data on the client side before making API requests to reduce validation errors:

function validateOrderData(data) {
const errors = [];

if (!data.product_id) {
errors.push('product_id is required');
}

if (data.amount <= 0) {
errors.push('amount must be greater than 0');
}

return errors;
}

5. Provide User-Friendly Error Messages

Translate technical error messages into user-friendly messages:

function getUserFriendlyError(error) {
const errorMap = {
'Could not validate credentials': 'Your session has expired. Please log in again.',
'Product not found': 'The requested product is no longer available.',
'Insufficient permissions': 'You do not have permission to perform this action.'
};

return errorMap[error.detail] || error.detail || 'An unexpected error occurred';
}

Rate Limiting

If rate limiting is enabled, you may receive:

{
"detail": "Rate limit exceeded"
}

Status Code: 429

Response Headers:

  • X-RateLimit-Limit: Maximum requests allowed
  • X-RateLimit-Remaining: Remaining requests
  • X-RateLimit-Reset: Time when limit resets

Solution: Implement request throttling and respect the rate limits.

Debugging Tips

  1. Check Response Headers: Additional error information may be in response headers
  2. Log Full Error Response: Include the full error object in logs for debugging
  3. Use OpenAPI Docs: Reference the interactive API documentation for expected request/response formats
  4. Test with curl: Use curl to test endpoints directly and see raw responses
  5. Check API Status: Verify the API is operational before troubleshooting

Support

If you encounter persistent errors or need assistance:

Next Steps