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

# Errors

> API error codes and handling

# Error Handling

The API uses standard HTTP status codes and returns detailed error information in a consistent format.

## Error Response Format

All errors return a JSON object with the following structure:

```json theme={null}
{
  "error": {
    "code": "error_code",
    "message": "Human-readable error message",
    "request_id": "req_abc123def456",
    "details": {}
  }
}
```

<Tip>
  Save the `request_id` from error responses. When contacting support, include this ID for faster troubleshooting.
</Tip>

## HTTP Status Codes

| Status | Description                                                               |
| ------ | ------------------------------------------------------------------------- |
| 200    | Success                                                                   |
| 201    | Created - Resource successfully created                                   |
| 400    | Bad Request - Invalid parameters or validation failed                     |
| 401    | Unauthorized - Invalid, missing, or expired API key                       |
| 403    | Forbidden - Insufficient permissions or scope                             |
| 404    | Not Found - Requested resource doesn't exist                              |
| 429    | Too Many Requests - Rate limit exceeded (see [Rate Limits](/rate-limits)) |
| 500    | Internal Server Error - Unexpected server error                           |

## Error Codes Reference

### Authentication Errors (401)

| Code                     | Description                                           |
| ------------------------ | ----------------------------------------------------- |
| `missing_api_key`        | No API key provided in the Authorization header       |
| `invalid_auth_format`    | Authorization header not using Bearer scheme          |
| `invalid_api_key`        | API key format is invalid or key doesn't exist        |
| `api_key_revoked`        | API key has been revoked                              |
| `api_key_expired`        | API key has expired                                   |
| `organization_not_found` | Organization associated with API key no longer exists |

### OAuth Errors (401/403)

| Code                       | Description                                          |
| -------------------------- | ---------------------------------------------------- |
| `oauth_invalid_token`      | OAuth access token is invalid, expired, or revoked   |
| `oauth_insufficient_scope` | Token doesn't have required scopes for this endpoint |

### Device Auth Errors (400)

| Code                    | Description                                      |
| ----------------------- | ------------------------------------------------ |
| `authorization_pending` | User hasn't approved/denied yet (keep polling)   |
| `slow_down`             | Polling too fast. Increase interval by 5 seconds |
| `access_denied`         | User denied the authorization request            |
| `expired_token`         | Device code has expired. Start a new flow        |

### Validation Errors (400)

| Code               | Description                                            |
| ------------------ | ------------------------------------------------------ |
| `validation_error` | Request body failed validation. Check `details.issues` |
| `invalid_request`  | Request format is invalid                              |

### Server Errors (500)

| Code             | Description             |
| ---------------- | ----------------------- |
| `internal_error` | Unexpected server error |

## Handling Errors

### JavaScript/TypeScript

```typescript theme={null}
try {
  const response = await fetch('https://api.v2.dealmachine.com/v1/account', {
    headers: {
      'Authorization': `Bearer ${apiKey}`,
    },
  });

  if (!response.ok) {
    const { error } = await response.json();

    switch (error.code) {
      case 'invalid_api_key':
        console.error('Check your API key');
        break;
      case 'validation_error':
        console.error('Validation issues:', error.details?.issues);
        break;
      default:
        console.error('Error:', error.message);
    }
    return;
  }

  const data = await response.json();
} catch (err) {
  console.error('Network error:', err);
}
```

### Python

```python theme={null}
import requests

response = requests.get(
    'https://api.v2.dealmachine.com/v1/account',
    headers={'Authorization': f'Bearer {api_key}'}
)

if not response.ok:
    error = response.json()['error']

    if error['code'] == 'invalid_api_key':
        print('Check your API key')
    elif error['code'] == 'validation_error':
        for issue in error.get('details', {}).get('issues', []):
            print(f"Validation error in {issue['path']}: {issue['message']}")
    else:
        print(f"Error: {error['message']}")
```

## Validation Error Details

When you receive a `validation_error`, the `details.issues` array contains specific validation failures:

```json theme={null}
{
  "error": {
    "code": "validation_error",
    "message": "Validation failed",
    "request_id": "req_7f8a9b0c1d2e3f4g",
    "details": {
      "issues": [
        {
          "path": "client_id",
          "message": "Required"
        }
      ]
    }
  }
}
```

## Response Headers

Every response includes:

| Header         | Description                                 |
| -------------- | ------------------------------------------- |
| `X-Request-Id` | Unique request ID for debugging and support |
