> ## Documentation Index
> Fetch the complete documentation index at: https://docs.swiftpay.cx/llms.txt
> Use this file to discover all available pages before exploring further.

# Errors

> Understanding and handling API errors

# Error Handling

SwiftPay uses conventional HTTP response codes to indicate the success or failure of an API request.

## HTTP Status Codes

| Code  | Description                                           |
| ----- | ----------------------------------------------------- |
| `200` | Success - The request completed successfully          |
| `201` | Created - A new resource was created                  |
| `400` | Bad Request - Invalid request parameters              |
| `401` | Unauthorized - Invalid or missing API key             |
| `403` | Forbidden - Valid key but insufficient permissions    |
| `404` | Not Found - The requested resource doesn't exist      |
| `409` | Conflict - The request conflicts with current state   |
| `422` | Validation Error - The request body failed validation |
| `429` | Rate Limited - Too many requests                      |
| `500` | Server Error - Something went wrong on our end        |

## Error Response Format

All error responses follow a consistent format:

```json theme={null}
{
   "success": false,
   "error": {
      "type": "validation_error",
      "message": "Request validation failed",
      "requestId": "req_abc123xyz",
      "fields": {
         "email": "Invalid email format",
         "amount": "Amount must be greater than 0"
      }
   }
}
```

### Error Object Properties

<ResponseField name="type" type="string" required>
  The type of error. One of: - `unauthenticated` - Invalid or missing API key -
  `unauthorized` - Insufficient permissions - `validation_error` - Invalid
  request parameters - `not_found` - Resource not found - `conflict` - Resource
  state conflict - `rate_limit_exceeded` - Too many requests -
  `internal_server_error` - Internal server error - `external_service_error` -
  External service error - `database_error` - Database error
</ResponseField>

<ResponseField name="message" type="string" required>
  A human-readable description of the error.
</ResponseField>

<ResponseField name="requestId" type="string" required>
  A unique identifier for this request. Include this when contacting support.
</ResponseField>

<ResponseField name="fields" type="object">
  For validation errors, an object containing field-specific error messages.
</ResponseField>

## Error Types

### Authentication Error

Returned when the API key is missing or invalid.

```json theme={null}
{
   "success": false,
   "error": {
      "type": "unauthenticated",
      "message": "Invalid API key provided",
      "requestId": "req_abc123"
   }
}
```

### Validation Error

Returned when request parameters fail validation.

```json theme={null}
{
   "success": false,
   "error": {
      "type": "validation_error",
      "message": "Request validation failed",
      "requestId": "req_abc123",
      "fields": {
         "items": "At least one item is required",
         "customer.email": "Invalid email format"
      }
   }
}
```

### Not Found Error

Returned when the requested resource doesn't exist.

```json theme={null}
{
   "success": false,
   "error": {
      "type": "not_found",
      "message": "Checkout session not found",
      "requestId": "req_abc123"
   }
}
```

### Conflict Error

Returned when the request conflicts with the current state.

```json theme={null}
{
   "success": false,
   "error": {
      "type": "conflict",
      "message": "This checkout session has already been paid",
      "requestId": "req_abc123"
   }
}
```

## Handling Errors

<CodeGroup>
  ```javascript JavaScript theme={null}
  async function createCheckoutSession(data) {
    try {
      const response = await fetch('https://api.swiftpay.cx/api/checkout/sessions', {
        method: 'POST',
        headers: {
          'Authorization': 'Bearer mp_live_your_api_key',
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(data)
      });
      
      const result = await response.json();
      
      if (!result.success) {
        // Handle specific error types
        switch (result.error.type) {
          case 'validation_error':
            console.error('Validation failed:', result.error.fields);
            break;
          case 'unauthenticated':
            console.error('Check your API key');
            break;
          default:
            console.error('Error:', result.error.message);
        }
        return null;
      }
      
      return result.data;
    } catch (error) {
      console.error('Network error:', error);
      return null;
    }
  }
  ```

  ```python Python theme={null}
  import requests

  def create_checkout_session(data):
      try:
          response = requests.post(
              'https://api.swiftpay.cx/api/checkout/sessions',
              headers={
                  'Authorization': 'Bearer mp_live_your_api_key',
                  'Content-Type': 'application/json'
              },
              json=data
          )

          result = response.json()

          if not result.get('success'):
              error = result.get('error', {})
              error_type = error.get('type')

              if error_type == 'validation_error':
                  print(f"Validation failed: {error.get('fields')}")
              elif error_type == 'unauthenticated':
                  print("Check your API key")
              else:
                  print(f"Error: {error.get('message')}")

              return None

          return result.get('data')
      except requests.RequestException as e:
          print(f"Network error: {e}")
          return None
  ```
</CodeGroup>

## Best Practices

<CardGroup cols={2}>
  <Card title="Log Request IDs" icon="clipboard">
    Always log the `requestId` from error responses. This helps our support
    team debug issues quickly.
  </Card>

  <Card title="Retry on 5xx" icon="rotate">
    Server errors (5xx) are usually temporary. Implement exponential backoff
    and retry logic.
  </Card>

  <Card title="Validate Locally" icon="check">
    Validate request data before sending to reduce validation errors.
  </Card>

  <Card title="Handle Edge Cases" icon="shield">
    Always handle error responses gracefully to provide a good user
    experience.
  </Card>
</CardGroup>
