Error codes
Pry returns structured JSON errors with a stable code field:
{
"type": "/errors/unauthorized",
"title": "Unauthorized",
"status": 401,
"detail": "Invalid or missing API key",
"request_id": "abc123",
"code": "unauthorized"
}
HTTP-level codes
| Status | Code | Meaning | Fix |
|---|---|---|---|
| 401 | unauthorized | Missing/invalid Bearer key, or non-loopback on keyless instance | Send Authorization: Bearer <key> |
| 402 | payment_required | Paid endpoint without payment proof | Pay the challenge in PAYMENT-REQUIRED header, retry |
| 403 | forbidden | Loopback-only surface reached remotely, or missing admin scope | Use loopback or an admin-scope key |
| 404 | - | Unknown path | Check /openapi.json for routes |
| 429 | - | Rate limit exceeded | Honor x-ratelimit-reset |
| 500 | payment_gate_misconfigured | Paid endpoint missing its price entry (fail-closed) | Operator: add pricing; this refuses traffic rather than leaking it free |
Scrape result statuses
Inside scrape payloads, status is one of:
| Status | Meaning |
|---|---|
ok | Content retrieved through one of the 12 tiers |
error | All tiers exhausted; error field explains why |
skipped | (corpus actors) filtered by length/duplicate rules |
Webhook failures
Webhooks are fail-closed: deliveries without a configured signing
secret are refused (refused: true), never sent unsigned. Check
GET /v1/webhooks/dead-letter for failed deliveries after fixing
PRY_WEBHOOK_SECRET.