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

# HTTP error codes and error response format

> InfraAudit returns JSON errors with a code and message field. Reference the HTTP status codes, machine-readable error codes, and error handling patterns.

Every error response from the InfraAudit API follows a consistent JSON structure so you can handle errors programmatically regardless of the endpoint.

## Error response format

```json theme={null}
{
  "error": "resource not found",
  "code": "NOT_FOUND",
  "details": "drift with id 99 does not exist"
}
```

<ResponseField name="error" type="string" required>
  A human-readable message describing what went wrong. Suitable for logging but not for display to end users.
</ResponseField>

<ResponseField name="code" type="string">
  A machine-readable error code. Use this field for programmatic error handling. May be absent on some error types.
</ResponseField>

<ResponseField name="details" type="string">
  Additional context about the error, such as which field failed validation or which resource was not found. Optional.
</ResponseField>

## HTTP status codes

| Status                      | When it is returned                                                                   |
| --------------------------- | ------------------------------------------------------------------------------------- |
| `200 OK`                    | Request succeeded.                                                                    |
| `201 Created`               | Resource was created successfully.                                                    |
| `204 No Content`            | Request succeeded with no response body (typical for DELETE).                         |
| `400 Bad Request`           | Malformed JSON, missing required fields, or invalid parameter values.                 |
| `401 Unauthorized`          | Missing, expired, or invalid auth token.                                              |
| `403 Forbidden`             | Token is valid but the user lacks permission.                                         |
| `404 Not Found`             | The requested resource does not exist.                                                |
| `409 Conflict`              | State conflict — for example, trying to connect a provider that is already connected. |
| `422 Unprocessable Entity`  | Request is valid JSON but fails business-logic validation.                            |
| `429 Too Many Requests`     | Rate limit exceeded. See [Rate limiting](/api/rate-limiting).                         |
| `500 Internal Server Error` | Unexpected server-side error.                                                         |

## Handling errors

<CodeGroup>
  ```bash curl theme={null}
  response=$(curl -s -w "\n%{http_code}" \
    https://api.infraaudit.dev/v1/drifts/99 \
    -H "Authorization: Bearer $TOKEN")

  http_code=$(echo "$response" | tail -1)
  body=$(echo "$response" | head -1)

  if [ "$http_code" -ne 200 ]; then
    echo "Error $http_code: $(echo $body | jq -r '.error')"
  fi
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch('https://api.infraaudit.dev/v1/drifts/99', {
    headers: { Authorization: `Bearer ${token}` },
  })

  if (!response.ok) {
    const err = await response.json()
    console.error(`${response.status}: ${err.error}`)
    // Use err.code for programmatic handling
  }
  ```

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

  resp = requests.get(
      'https://api.infraaudit.dev/v1/drifts/99',
      headers={'Authorization': f'Bearer {token}'},
  )

  if not resp.ok:
      err = resp.json()
      print(f"{resp.status_code}: {err['error']}")
  ```
</CodeGroup>

## Common error codes

| Code               | HTTP status | Meaning                                                     |
| ------------------ | ----------- | ----------------------------------------------------------- |
| `NOT_FOUND`        | 404         | The resource ID does not exist.                             |
| `UNAUTHORIZED`     | 401         | Token missing or invalid.                                   |
| `FORBIDDEN`        | 403         | Insufficient permissions.                                   |
| `VALIDATION_ERROR` | 422         | A field failed business-logic validation.                   |
| `CONFLICT`         | 409         | Resource already exists or is in a conflicting state.       |
| `RATE_LIMITED`     | 429         | Too many requests. Check `retryAfter` in the response body. |

<Note>
  The `code` field is not present on all error responses. Always fall back to the HTTP status code for error handling.
</Note>
