Error Handling
Handle API errors gracefully in your integrations.
Error Response Format
All errors return a consistent JSON structure:
json
{
"success": false,
"error": "Not Found",
"message": "The requested product was not found"
}Validation errors include field-specific details:
json
{
"success": false,
"error": "Validation Error",
"message": "The given data was invalid",
"errors": {
"url": ["The url field is required"],
"events": ["The events field must be an array"]
}
}HTTP Status Codes
Success Codes
| Code | Description |
|---|---|
| 200 | Request succeeded |
| 201 | Resource created |
| 204 | Request succeeded, no content |
Client Error Codes
| Code | Error | Description |
|---|---|---|
| 400 | Bad Request | Malformed request syntax |
| 401 | Unauthorized | Invalid or missing API token |
| 403 | Forbidden | Token lacks required scope |
| 404 | Not Found | Resource doesn't exist |
| 422 | Unprocessable Entity | Validation failed |
| 429 | Too Many Requests | Rate limit exceeded |
Server Error Codes
| Code | Error | Description |
|---|---|---|
| 500 | Internal Server Error | Something went wrong on our end |
| 502 | Bad Gateway | Upstream service error |
| 503 | Service Unavailable | Temporarily unavailable |
Common Errors
401 Unauthorized
json
{
"success": false,
"error": "Unauthorized",
"message": "Invalid or missing API token"
}Causes:
- Missing
Authorizationheader - Malformed header (should be
Bearer {token}) - Invalid or expired token
- Revoked token
Solution: Check your token and header format.
403 Forbidden
json
{
"success": false,
"error": "Forbidden",
"message": "Token does not have required scope: orders:write"
}Cause: Token lacks the permission needed for this endpoint.
Solution: Create a new token with required scopes.
404 Not Found
json
{
"success": false,
"error": "Not Found",
"message": "Product not found"
}Cause: The requested resource doesn't exist.
Solution: Verify the ID or identifier is correct.
422 Validation Error
json
{
"success": false,
"error": "Validation Error",
"message": "The given data was invalid",
"errors": {
"url": ["The url must be a valid URL"],
"events": ["The selected events.0 is invalid"]
}
}Cause: Request data didn't pass validation.
Solution: Fix the indicated fields and retry.
429 Rate Limited
json
{
"success": false,
"error": "Too Many Requests",
"message": "Rate limit exceeded. Retry after 60 seconds",
"retry_after": 60
}Cause: Too many requests in the time window.
Solution: Implement backoff and respect retry_after.
Best Practices
1. Always Check Status Codes
javascript
const response = await client.get('/products');
if (response.status !== 200) {
handleError(response);
return;
}
// Process success response2. Handle Specific Errors
javascript
switch (response.status) {
case 401:
// Re-authenticate or refresh token
break;
case 403:
// Check permissions
break;
case 404:
// Resource not found - handle gracefully
break;
case 429:
// Implement exponential backoff
await sleep(response.data.retry_after * 1000);
break;
case 500:
// Log and retry with backoff
break;
}3. Log Errors
Always log API errors for debugging:
javascript
console.error('API Error:', {
status: response.status,
error: response.data.error,
message: response.data.message,
endpoint: endpoint,
timestamp: new Date().toISOString()
});4. Implement Retries
For transient errors (5xx), implement retry with exponential backoff:
javascript
async function fetchWithRetry(endpoint, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
const response = await client.get(endpoint);
if (response.status < 500) {
return response;
}
// Exponential backoff: 1s, 2s, 4s
await sleep(Math.pow(2, i) * 1000);
}
throw new Error('Max retries exceeded');
}5. Validate Before Sending
Reduce errors by validating data before making requests:
javascript
function createWebhook(url, events) {
if (!url.startsWith('https://')) {
throw new Error('URL must use HTTPS');
}
if (!Array.isArray(events) || events.length === 0) {
throw new Error('Events must be a non-empty array');
}
return client.post('/webhooks', { url, events });
}