Rate limits + credit costs

Everything you need to size your integration. Per-tier rate limits, credit cost per endpoint, what the 429 + 403 responses look like, and which response headers to read. Machine-readable version at /v1/meta/limits.

Tier comparison

Tier Price / mo Credits / mo Rate / min Burst / sec WebSocket SSE Support
Free $0 1,000 30 1 , , Community
Starter $5 20,000 no rate limit 5 , Email
Pro $20 100,000 no rate limit 10 , Email
Business $40 1,000,000 no rate limit 20 Email · 1-day SLA
Enterprise $100 5,000,000 no rate limit 50 Email + Slack · 4-hr SLA
Scale $200 50,000,000 no rate limit 100 ✓ sub-1s Email + Slack · 1-hr SLA
Enterprise Contact sales Custom Custom Custom Dedicated · 99.95% SLA

Annual pricing: 10% discount (15% on Enterprise). See /pricing for the full breakdown and the cost projector at /cost for your specific polling frequency.

Credit cost per endpoint

Each request costs a fixed number of credits, charged on success. The amount is returned in the X-Credits-Cost response header. Free /v1/try/* and /v1/meta/* endpoints cost 0 credits but are IP-rate-limited at 60 req/h regardless of tier.

Endpoint familyCost (credits)Notes
/v1/sports/{sport}/odds?markets=h2h1Moneyline only
/v1/sports/{sport}/odds?markets=h2h,spreads,totals2Full game-line
/v1/sports/{sport}/odds?markets=player_*5Player props (any market)
/v1/sports/{sport}/arbitrage3Per scan
/v1/sports/{sport}/ev3Per scan
/v1/sports/{sport}/middles3Per scan
/v1/sgp/price10 + 5/legMin 15
/v1/clv/history1/betBatch endpoint; counts per graded bet
/v1/historical/closing-lines.csv1Per day downloaded
/v1/inplay/*2Per snapshot
/v1/meta/*0Public metadata, no auth required
/v1/try/*0Free no-auth demos, IP-rate-limited at 60/h
/v1/ws/* (WebSocket)0/msgSubscription is tier-gated, not credit-charged

Response headers (every authenticated request)

HeaderMeaning
X-Credits-CostCredits charged for this request
X-Credits-RemainingCredits remaining in your monthly allowance
X-Rate-Limit-RemainingRequests remaining in current minute window
X-Rate-Limit-ResetUnix timestamp when the window resets
X-Request-IDPer-request UUID; include in support tickets

What 429 (rate limit) looks like

HTTP/1.1 429 Too Many Requests
Retry-After: 60
Content-Type: application/json

{
  "error": "rate_limit",
  "message": "Rate limit exceeded. Retry after 60 seconds.",
  "retry_after_seconds": 60,
  "request_id": "01HPK8...EXAMPLE",
  "docs_url": "https://parlay-api.com/limits"
}
Always honor Retry-After. Our reference clients (Python, JS, Go, Ruby, Java, PHP, C#, Rust) do this automatically with capped exponential backoff. If you're writing your own client, parse Retry-After as seconds and sleep before retry. Retrying immediately on 429 wastes credits and gets your account flagged.

What 403 (credit exhausted) looks like

HTTP/1.1 403 Forbidden
Content-Type: application/json

{
  "error": "credit_limit_exceeded",
  "message": "Monthly credit allowance exhausted. Upgrade tier or wait for the next billing period.",
  "credits_used": 100000,
  "credits_allowance": 100000,
  "next_reset_at": "2026-06-01T00:00:00Z",
  "request_id": "01HPK8...EXAMPLE",
  "upgrade_url": "https://parlay-api.com/pricing"
}
Credit exhaustion doesn't kill WebSocket sessions. Existing WebSocket connections continue receiving updates through the end of the billing period; new REST requests will 403 but the streaming feed stays live. WebSocket bandwidth itself doesn't draw down credits.

Common patterns

Check remaining credits

curl -sI 'https://parlay-api.com/v1/sports/baseball_mlb/odds?regions=us&markets=h2h' \
  -H "X-API-Key: $PARLAY_API_KEY" | grep -i x-credits

Estimate monthly cost

If you poll the full-markets odds endpoint every 5 seconds across MLB (during a 6-month season), that's roughly:

2 credits × (60 / 5) requests/min × 60 min/hr × 18 hr/day × 180 days = 7.78M credits

That's a Scale-tier ($200/mo) workload. WebSocket on Business ($40/mo) would be cheaper and faster. Use /cost for an interactive projector.

Reference client handles all this for you

# Python (and 7 other languages at /docs/sdks)
from parlay_api_client import Client
client = Client(api_key="pak_live_...")
odds = client.odds("baseball_mlb", regions="us", markets="h2h,spreads,totals")
# Retries 429 with Retry-After automatically; surfaces X-Request-ID
# on errors; supports idempotency keys on POST endpoints.

What "rate limit" actually means

Two independent meters:

The two meters protect against different abuse patterns. Burst stops a single bad cron from saturating; per-minute stops a slow-but-relentless leak.

Related

/pricing · /cost (interactive projector) · /v1/meta/limits (JSON) · /docs/best-practices (retry / idempotency / WebSocket reconnect) · /docs/sdks (reference clients in 8 languages)