# Error Handling Easypay uses standard HTTP response status codes to indicate the success or failure of API requests. ## HTTP Status Codes The API uses three main ranges of status codes: - **2xx Success**: Your request was successful - **4xx Client Error**: There was an error with the information you provided - **5xx Server Error**: An error occurred on Easypay's servers (rare) ## Common Status Codes | Status Code | Meaning | What to Do | | --- | --- | --- | | `200 OK` | Request successful | Process the response | | `201 Created` | Resource created successfully | Process the newly created resource | | `204 No Content` | Request successful, no content to return | Continue normally | | `400 Bad Request` | Invalid request parameters | Check your request payload | | `403 Forbidden` | Authentication failed | Verify your credentials | | `404 Not Found` | Resource doesn't exist | Check the resource ID | | `409 Conflict` | Request conflicts with current state | Review the conflict details | | `429 Too Many Requests` | Rate limit exceeded | Slow down your requests | | `500 Internal Server Error` | Server error | Retry or contact support | | `502 Bad Gateway` | Temporary server issue | Retry the request | | `503 Service Unavailable` | Service temporarily unavailable | Retry the request | ## Error Response Format When an error occurs, the API returns a JSON response with error details: ```json { "status": "error", "message": "Error description", "code": "ERROR_CODE", "doc_url": "https://docs.easypay.pt/errors/ERROR_CODE" } ``` ## Error Types ### Authentication Error (403) **Possible Causes**: - Missing or invalid `AccountId` or `ApiKey` headers - Account has been blocked - Insufficient permissions for the requested action **Example**: ```json { "status": "error", "message": "Authentication Error: Invalid AccountId or ApiKey", "code": "AUTHENTICATION_ERROR" } ``` **Resolution**: Verify your credentials and ensure your account is active. ### Invalid Content Type Error (415) **Cause**: You provided an invalid or unsupported `Content-Type` header. **Example**: ```json { "status": "error", "message": "Invalid Content Type Error: Unsupported content type", "code": "INVALID_CONTENT_TYPE" } ``` **Resolution**: Set the `Content-Type` header to `application/json`. ### Invalid JSON Error (400) **Cause**: The request body contains malformed JSON. **Example**: ```json { "status": "error", "message": "Invalid JSON Error: Unexpected token", "code": "INVALID_JSON" } ``` **Resolution**: Validate your JSON payload before sending the request. ### Invalid Params Error (400) **Cause**: Required parameters are missing or invalid. **Example**: ```json { "status": "error", "message": "Invalid Params Error: Field 'value' is required", "code": "INVALID_PARAMS", "doc_url": "https://docs.easypay.pt/errors/INVALID_PARAMS" } ``` **Resolution**: Review the error message and ensure all required parameters are provided with valid values. ### Internal Error (500) **Cause**: An unexpected error occurred on Easypay's servers. **Example**: ```json { "status": "error", "message": "Internal Error: An unexpected error occurred", "code": "INTERNAL_ERROR" } ``` **Resolution**: Retry the request. If the problem persists, contact support. ## Retry Logic Some errors are safe to retry, while others are not. The API includes an `X-Easypay-Should-Retry` header to help you decide: ``` X-Easypay-Should-Retry: true ``` ### When to Retry **Safe to Retry** (when `X-Easypay-Should-Retry: true` or for these status codes): - `409 Conflict` - May indicate the original request is still in transit - `429 Too Many Requests` - Wait and retry - `502 Bad Gateway` - Temporary server issue - `503 Service Unavailable` - Service temporarily down **Do NOT Retry**: - `400 Bad Request` - Fix your request first - `403 Forbidden` - Fix authentication first - `404 Not Found` - Resource doesn't exist - `422 Unprocessable Entity` - Fix validation errors first ### Retry Strategy If the `X-Easypay-Should-Retry` header is not present, use this strategy: 1. **No response received**: Retry the request 2. **Status code 409, 429, 502, or 503**: Retry the request 3. **Status code 500** on non-POST requests: Retry the request 4. **Status code 500** on POST requests: Do NOT retry (may duplicate resources) 5. **All other errors**: Do NOT retry ### Example Retry Implementation ```javascript async function retryableRequest(url, options, maxRetries = 3) { for (let i = 0; i < maxRetries; i++) { try { const response = await fetch(url, options); // Check if we should retry const shouldRetry = response.headers.get('X-Easypay-Should-Retry'); if (shouldRetry === 'true' || [409, 429, 502, 503].includes(response.status)) { if (i < maxRetries - 1) { await sleep(Math.pow(2, i) * 1000); // Exponential backoff continue; } } return response; } catch (error) { if (i < maxRetries - 1) { await sleep(Math.pow(2, i) * 1000); continue; } throw error; } } } ``` ## Best Practices 1. **Always Check Status Codes**: Don't assume requests succeed 2. **Log Errors**: Keep detailed logs of errors for debugging 3. **Handle Errors Gracefully**: Provide meaningful feedback to users 4. **Use Idempotency**: Use idempotency keys for safe retries (see [Idempotency](/docs/idempotency)) 5. **Implement Exponential Backoff**: When retrying, increase wait time between attempts 6. **Monitor Error Rates**: Track error rates to identify issues early 7. **Respect Rate Limits**: Implement rate limiting to avoid 429 errors ## Next Steps - [Idempotency](/docs/idempotency) - Learn about safe retries with idempotency keys - [Authentication](/docs/authentication) - Fix authentication errors - [Quick Start](/docs/quickstart) - Make your first successful API call