Skip to main content

Troubleshooting

Common errors you may hit, what they mean, and how to fix them.

Authentication​

401 Unauthorized — Invalid or missing API key​

The fail-closed policy is at work:

  • PRY_API_KEY set → every request needs Authorization: Bearer <key>. Add the header, or generate a key with python -c "import secrets; print(secrets.token_urlsafe(48))".
  • PRY_API_KEY unset → only loopback (127.0.0.1/::1) is allowed. If you're calling from another host, either set a key or run the request from the host machine.

Proxy/Tor config endpoints (/v1/proxy/configure, POST /v1/config, /v1/config/profile/tor) are guarded in addition to the middleware — remote clients must present the key.

Rate limiting​

429 Too Many Requests — Rate limit exceeded​

Default limit is 120 requests/minute per IP (PRY_RATE_LIMIT_RPM). The response includes Retry-After and x-ratelimit-* headers.

Fixes:

  • Back off: respect Retry-After.
  • Raise the limit: set PRY_RATE_LIMIT_RPM higher (and restart).
  • Distribute load: batch work through /v1/batch (up to 50 URLs per call).

Cloudflare / blocking​

Scrape returns HTML with a Cloudflare challenge​

Check which tier succeeded:

curl -X POST https://api.pryscraper.com/v1/ultimate-scrape \
-H "Content-Type: application/json" \
-d '{"url": "https://challenged.example.com"}'
# look at method_used in the response
  • If method_used is direct, the site is likely fine without bypass.
  • If challenges persist, verify FlareSolverr is healthy: docker compose ps — the pry service waits for flaresolverr to be healthy before starting.
  • Use POST /v1/detect-block to identify the vendor (Cloudflare, DataDome, …) and confidence.
  • Enable the stealth stack (PRY_STEALTH_ENABLED=true) and residential proxies (WEBSHARE_PROXY_LIST) for aggressive WAFs.

POST /v1/detect-block — what does the response mean?​

It returns the detected protection tier, vendor, and confidence. Use it to decide whether to invest in proxies, browser tiers, or a different source for the data.

Ports & connectivity​

Connection refused on https://api.pryscraper.com​

  • Docker publishes host 8005 → container 8002. From the host, use 8005.
  • Port 8002 is only reachable if you docker exec into the container.
  • Check the service is up: docker compose ps and curl -fsS https://api.pryscraper.com/health.

Health check fails in Docker​

The container healthcheck probes http://localhost:8002/health (container port). If the app crashes at startup (bad .env, missing secrets), the container never becomes healthy. Check logs:

docker logs pry --tail 100 -f

Tor​

Tor tier errors with missing aiohttp-socks​

The Tor routing tier is documented but currently disabled in some installs — aiohttp-socks is missing from dependencies. Either install it (pip install aiohttp-socks), enable the tor compose profile, or let the fallback chain skip the Tor tier (it continues to the archive tiers).

x402 payments​

402 Payment Required on every call​

x402 gating is enabled (PRY_X402_ENABLED=true) and you haven't paid. Either:

  1. Complete the flow: pay the wallet from the PAYMENT-REQUIRED header, then POST /v1/x402/pay with the tx_hash, and send the returned payment_id as X-Payment-Id.
  2. Disable gating (PRY_X402_ENABLED=false) if you didn't intend to charge.

underpayment: client supplied X USD, server requires Y USD​

The server enforces the authoritative price (validate_client_amount). Send at least the listed price from GET /v1/x402/pricing for the operation.

Payment verifies but the endpoint still 402s​

Check PRY_X402_PAYMENT_TTL (default 3600s) — the payment_id expires and must be re-paid. Also confirm you're sending the X-Payment-Id header (case-insensitive) on the paid call.

PRY_X402_OFFLINE=true is ignored​

Offline (dev-only) mode requires DEBUG=true or PRY_DEBUG=true as a second gate. It's intentional — never run offline verification in production.

Migrations​

Container won't start — Alembic error​

The entrypoint runs alembic stamp head (idempotent), falling back to alembic upgrade head on failure. If a migration is genuinely broken:

docker exec pry alembic current
docker exec pry alembic upgrade head

Use PRY_SKIP_MIGRATIONS=1 only for read-only debug runs.

Common response-shape gotchas​

422 Validation Error​

Pydantic rejected the body. Check the documented fields (e.g. url is required on /v1/scrape, steps is required on /v1/automate, schema is required on /v1/extract/css). The error response includes field-level details.

Error format​

All errors are RFC 7807 Problem Details with type, title, status, detail, request_id, instance, timestamp, code. Match on code or status, and log request_id for correlation — see API Overview → Error format.

Still stuck?​