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

# Error Handling

> Standard error responses in the V2 Vendor API

<Note>
  **V2 Preview** — This error format is part of the V2 API preview. Breaking changes may occur.
</Note>

## Overview

All V2 API endpoints return a consistent error format. Errors always include `success: false` and an `error` object with a human-readable `message` and a machine-readable `code`.

## Error Response Format

```json theme={null}
{
  "success": false,
  "error": {
    "message": "Invalid API key",
    "code": "UNAUTHORIZED"
  }
}
```

## Error Codes

| Code                    | HTTP Status | Description                                                                | Retry?                                 |
| ----------------------- | ----------- | -------------------------------------------------------------------------- | -------------------------------------- |
| `UNAUTHORIZED`          | 401         | Invalid API key, expired token, revoked key, or inactive shop              | No — re-authenticate or fix the key    |
| `FORBIDDEN`             | 403         | Accessing another vendor's data, unapproved account, or insufficient scope | No — check your permissions            |
| `NOT_FOUND`             | 404         | Requested resource does not exist                                          | No — verify the resource ID            |
| `VALIDATION_ERROR`      | 400         | Request body or query parameters failed validation                         | No — fix the request                   |
| `FULFILLMENT_FAILED`    | 400         | Fulfillment creation failed (e.g., invalid line items)                     | No — fix the request                   |
| `CONFLICT`              | 409         | Resource creation/update conflict                                          | No — check resource state              |
| `RATE_LIMITED`          | 429         | Exceeded 100 requests/minute per IP                                        | Yes — exponential backoff              |
| `INTERNAL_SERVER_ERROR` | 500         | Unexpected server error                                                    | Yes — retry up to 3 times with backoff |

## HTTP Status Codes

| Status  | Description                                                       |
| ------- | ----------------------------------------------------------------- |
| **200** | Success                                                           |
| **201** | Resource created                                                  |
| **400** | Bad request — invalid parameters or missing required fields       |
| **401** | Unauthorized — missing, invalid, or expired token                 |
| **403** | Forbidden — accessing another vendor's data or insufficient scope |
| **404** | Not found — resource does not exist                               |
| **409** | Conflict — resource creation/update conflict                      |
| **429** | Too many requests — rate limit exceeded                           |
| **500** | Internal server error                                             |

## Validation Errors

When request validation fails, the `message` field describes which fields are invalid:

```json theme={null}
{
  "success": false,
  "error": {
    "message": "createdAtMin must be a valid ISO 8601 date",
    "code": "VALIDATION_ERROR"
  }
}
```

## Rate Limiting

The API allows **100 requests per minute per IP address**. The limit is per IP, not per API key. The API returns standard `RateLimit-*` headers on every response.

When you exceed the limit:

```json theme={null}
{
  "success": false,
  "error": {
    "message": "Too many requests, please try again later",
    "code": "RATE_LIMITED"
  }
}
```

Implement exponential backoff — wait 1s, then 2s, then 4s between retries.

## Retry Guidance

| Status                      | Should Retry? | Strategy                                                                     |
| --------------------------- | ------------- | ---------------------------------------------------------------------------- |
| **400, 401, 403, 404, 409** | No            | Fix the request — these are client errors                                    |
| **429**                     | Yes           | Exponential backoff. Check `RateLimit-*` response headers                    |
| **500**                     | Yes           | Retry up to 3 times with exponential backoff. If persistent, contact support |
