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

# Overview

> Authenticate requests, send idempotent writes, handle rate limits, and read errors from the Admin API.

The Admin API lets you automate PricePirate workflows from your own tools.

## Base URL

Use this base URL for all Admin API requests:

```text theme={null}
https://app.pricepirate.com/api/v1
```

## Authentication

Create an API key under **Settings → API keys**. The token uses the format `pp_live_<prefix>.<secret>` and is shown only once. Copy it immediately.

Send the token in the `Authorization` header:

```text theme={null}
Authorization: Bearer pp_live_<prefix>.<secret>
```

Missing, invalid, or revoked tokens return `401 UNAUTHORIZED`.

```bash theme={null}
curl https://app.pricepirate.com/api/v1/shop \
  -H "Authorization: Bearer pp_live_<prefix>.<secret>"
```

## Writes and idempotency

Every write request requires an `Idempotency-Key` header. This applies to `POST`, `PUT`, `PATCH`, and `DELETE` requests.

Use a unique key for each logical write operation. A UUID works well.

```bash theme={null}
curl https://app.pricepirate.com/api/v1/tracked-variants/activate \
  -X POST \
  -H "Authorization: Bearer pp_live_<prefix>.<secret>" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 0e43f632-f4c2-4d83-a125-f5b4a5dc8f51" \
  -d '{
    "variantIds": ["gid://shopify/ProductVariant/1234567890"]
  }'
```

If you repeat the same key with the same request body, the API returns the cached response and includes this header:

```text theme={null}
Idempotency-Replayed: true
```

The idempotency cache is kept for 24 hours.

If you reuse the same key with a different request body, the API returns `409 idempotency_key_reuse`. If another request with the same key is still running, the API returns `409 idempotency_key_in_progress`.

## Rate limits

Each API key can send 60 requests per minute.

If you exceed the limit, the API returns `429 TOO_MANY_REQUESTS` and includes a `Retry-After` header with the number of seconds to wait before retrying.

## Errors

Error responses use one JSON shape:

```json theme={null}
{
  "error": {
    "code": "BAD_REQUEST",
    "message": "Request validation failed",
    "details": "Validation details, when available",
    "requestId": "req_123"
  }
}
```

Quote the `requestId` when you contact support about a failed API request.

| HTTP status | Error code                                                         |
| ----------- | ------------------------------------------------------------------ |
| `400`       | `BAD_REQUEST`, `idempotency_key_required`                          |
| `401`       | `UNAUTHORIZED`                                                     |
| `403`       | `FORBIDDEN`                                                        |
| `404`       | `NOT_FOUND`                                                        |
| `409`       | `CONFLICT`, `idempotency_key_reuse`, `idempotency_key_in_progress` |
| `429`       | `TOO_MANY_REQUESTS`                                                |
| `500`       | `INTERNAL_SERVER_ERROR`                                            |

## Pagination

List endpoints use `page` and `perPage` query parameters.

`page` is one-based. Use `page=1` for the first page.

```bash theme={null}
curl "https://app.pricepirate.com/api/v1/tracked-variants?page=1&perPage=50" \
  -H "Authorization: Bearer pp_live_<prefix>.<secret>"
```

## Reference

Use the endpoints in the Admin API navigation for parameters, response schemas, and examples.
