Configuration
Pry is configured through environment variables. All PRY_* variables are
auto-loaded. Copy .env.example to .env, adjust values, and restart.
cp .env.example .env
Per the security contract, no secrets live in .env in production — .env
is for local dev and CI only. Production secrets go in the secrets manager
(gopass by default) — see Secrets backend.
Secrets backend
Pry resolves secrets via secrets_backend.get_secret(name). The default
backend is gopass, reading under pry/<name>.
| Variable | Default | Meaning |
|---|---|---|
PRY_SECRET_BACKEND | auto | gopass (default) — reads from the gopass store under pry/<name>; env — reads os.environ (PRY_<NAME> or PRY_<name>); file — reads from PRY_ENV_FILE (default $PRY_DATA_DIR/.env); auto — tries gopass, falls back to env |
PRY_ENV_FILE | $PRY_DATA_DIR/.env | .env file path for the file backend |
PRY_DATA_DIR | ~/.pry | Root directory for on-disk data (quality, monitors, sessions, vault, etc.). Override for production (e.g. /var/lib/pry) or tests (e.g. /tmp/pry-test) |
PRY_WEBSHARE_GOPASS_PATH | pry/webshare_proxy_list | gopass path used as fallback for the Webshare proxy list |
Seed initial secrets (one time):
gopass insert -m pry/jwt_secret # opens editor, paste a strong random value
gopass insert -m pry/api_key
gopass insert -m pry/x402_wallet # your receiving EVM/Solana address
gopass insert -m pry/x402_facilitator # https://x402.org/facilitator or your own
Core
| Variable | Default | Description |
|---|---|---|
PRY_HOST | 127.0.0.1 | Bind address for the API server |
PRY_PORT | 8002 | Bind port (container port — Docker publishes 8005 → 8002) |
PRY_URL | http://localhost:8002 | API endpoint used by the CLI |
PRY_TIMEOUT | 60 | Default request timeout (seconds) |
Authentication (fail-closed)
| Variable | Default | Description |
|---|---|---|
PRY_API_KEY | (unset) | API key for endpoint authentication. Set → every request (loopback or remote) must send Authorization: Bearer <key> (or an rmi JWT); requests without a valid credential get 401. Unset → the API is only reachable from the loopback interface; every non-loopback request is rejected with 401, so a keyless instance is never exposed to the internet |
# Generate a strong key
python -c "import secrets; print(secrets.token_urlsafe(48))"
Proxy/Tor configuration endpoints follow the same rule and are guarded
explicitly in addition to the middleware: /v1/proxy/configure,
POST /v1/config, and /v1/config/profile/tor reject remote clients that
cannot present the key.
LLM / AI
| Variable | Default | Description |
|---|---|---|
PRY_OLLAMA_URL | http://100.100.18.18:11434 | Ollama endpoint (used for summarization, categorization, extraction) |
PRY_OPENROUTER_API_KEY | — | OpenRouter API key (optional — used for vision model queries with 5-model auto-fallback) |
Web scraping
| Variable | Default | Description |
|---|---|---|
PRY_FLARESOLVERR_URL | http://flaresolverr:8191/v1 | FlareSolverr endpoint for Cloudflare bypass |
Webhook
| Variable | Default | Description |
|---|---|---|
PRY_WEBHOOK_SECRET | — | Secret used to sign job-completion webhooks |
Proxy / Tor
| Variable | Default | Description |
|---|---|---|
PRY_PROXY_URL | — | HTTP/SOCKS proxy URL (e.g. http://proxy:8080) |
PRY_PROXY_TYPE | http | Proxy type (http, socks5, …) |
PRY_PROXY_USERNAME | — | Proxy username |
PRY_PROXY_PASSWORD | — | Proxy password |
PRY_TOR_ENABLED | false | Enable Tor routing |
PRY_TOR_SOCKS5_HOST | tor | Tor SOCKS5 host |
PRY_TOR_SOCKS5_PORT | 9050 | Tor SOCKS5 port |
Webshare residential proxy pool
| Variable | Default | Description |
|---|---|---|
WEBSHARE_PROXY_LIST | — | Space-separated Webshare residential proxies (http://user:pass@host:port). Loaded by webshare_proxy.py and exposed to the ProxyManager pool/rotation (provider tag webshare). If unset, falls back to the secrets manager (gopass) at PRY_WEBSHARE_GOPASS_PATH |
WEBSHARE_PROXY_LIST="http://user:pass@proxy1.webshare.io:80 http://user:pass@proxy2.webshare.io:80"
Never commit real credentials here — this is a format example only.
Rotation / retry
| Variable | Default | Description |
|---|---|---|
PRY_IP_ROTATION | — | IP rotation mode |
PRY_MAX_RETRIES | 3 | Max retries per scrape |
PRY_MIN_QUALITY | 50 | Minimum content-quality score to accept a scrape |
PRY_RATE_LIMIT_RPM | 120 | Requests per minute (token bucket, per IP) |
Redis
| Variable | Default | Description |
|---|---|---|
PRY_REDIS_URL | redis://localhost:6379/0 | Redis URL (cache backend with TTL-based invalidation) |
Database
| Variable | Default | Description |
|---|---|---|
PRY_DATABASE_URL | postgresql+asyncpg://pry:pry@localhost/pry | Async SQLAlchemy database URL |
Stealth / anti-detection
| Variable | Default | Description |
|---|---|---|
PRY_STEALTH_ENABLED | true | Enable the stealth engine |
PRY_RANDOM_USER_AGENT | true | Rotate user agents |
PRY_WEBDRIVER_OVERRIDE | true | Hide the navigator.webdriver flag |
PRY_CANVAS_NOISE | true | Inject canvas fingerprint noise |
PRY_WEBRTC_DISABLE | true | Disable WebRTC IP leaks |
PRY_GEOLOCATION_SPOOF | true | Spoof geolocation |
PRY_MIN_DELAY_MS | 500 | Minimum human-like delay between actions |
PRY_MAX_DELAY_MS | 3000 | Maximum human-like delay between actions |
Output
| Variable | Default | Description |
|---|---|---|
PRY_DEFAULT_FORMAT | markdown | Default scrape output format |
PRY_MAX_CHARS | 100000 | Maximum characters returned per scrape |
PRY_INCLUDE_LINKS | true | Include extracted links in output |
x402 / MCP
| Variable | Default | Description |
|---|---|---|
PRY_X402_ENABLED | false | Enable x402 pay-per-call gating |
PRY_X402_PAY_TO | — | Receiving wallet for x402 payments |
PRY_X402_WALLET | pry-default-wallet | Wallet override (gopass pry/x402_wallet is preferred — persistent across restarts) |
PRY_X402_FACILITATOR | https://x402.org/facilitator | x402 facilitator router (or your own) |
PRY_X402_ASSET | USDC | Default payment asset |
PRY_X402_PAYMENT_TTL | 3600 | Seconds a verified payment_id stays valid for replay |
PRY_X402_TIMEOUT | 15 | Facilitator timeout (seconds) |
PRY_MCP_ENABLED | true | Enable the MCP server |
PRY_X402_OFFLINE=true is a dev-only bypass that makes every verify/settle
succeed without a facilitator. It requires DEBUG=true (or PRY_DEBUG=true)
and must never be active in production.
Data layout
On bare metal, all data is stored under ~/.pry/ (or PRY_DATA_DIR):
| Directory | Purpose |
|---|---|
~/.pry/quality/ | Quality check history |
~/.pry/reviews/ | Human review queue |
~/.pry/intel/ | Competitive intelligence snapshots |
~/.pry/costing/ | Usage tracking |
~/.pry/freshness/ | Content fingerprints |
~/.pry/structure/ | Page structure monitor history |
~/.pry/seo/ | SEO snapshot history |
~/.pry/monitors/ | Scheduled monitors |
~/.pry/vault/ | Encrypted credentials |
~/.pry/accounts/ | Registered account pool |
~/.pry/reports/ | Generated client reports |
~/.pry/training/ | AI training datasets |
~/.pry/pipelines/ | Saved pipeline definitions |
~/.pry/gdpr/ | Consent records, deletion requests |
~/.pry/agency/ | Agency/client management |
Next steps
- Docker Compose — how the compose file wires these vars
- API Overview — auth, rate limits, error format
- Production Deployment — secrets in production