PRIZEPICKSAPI.

Python integration

Use the PrizePicks API with Python.

Fetch player-prop observations with Python’s standard library. Start with a clearly labeled fictional dataset, then use the same parser with your API key.

Run the example without installing a client library

Save the program below as prizepicks.py and run it with Python 3. It uses urllib.request to make an HTTPS request and json to decode the response. No third-party package or unofficial scraping client is required. Without an API key, the program uses the separate demo endpoint and prints “fictional demo” before any records.

import json
import os
import time
from urllib.error import HTTPError, URLError
from urllib.parse import urlencode
from urllib.request import Request, urlopen

API_KEY = os.environ.get("PRIZEPICKS_API_KEY")
BASE = "https://prizepicksapi.com"
PATH = "/api/v1/projections" if API_KEY else "/api/v1/demo/projections"
HEADERS = {"Accept": "application/json"}
if API_KEY:
    HEADERS["Authorization"] = "Bearer " + API_KEY


def projections(league="NBA", stat=None):
    cursor = None
    seen_cursors = set()
    while True:
        params = {"league": league, "limit": 100}
        if stat:
            params["stat"] = stat
        if cursor:
            params["cursor"] = cursor
        request = Request(BASE + PATH + "?" + urlencode(params), headers=HEADERS)
        try:
            with urlopen(request, timeout=20) as response:
                page = json.load(response)
        except HTTPError as error:
            detail = error.read().decode("utf-8", errors="replace")
            raise RuntimeError(f"HTTP {error.code}: {detail}") from None
        except URLError as error:
            raise RuntimeError(f"Request failed: {error.reason}") from None

        meta = page["meta"]
        print("Source:", meta["source_status"], "Observed:", meta["observed_at"])
        for projection in page["data"]:
            if API_KEY and projection.get("is_demo"):
                raise RuntimeError("Unexpected demo record in live response")
            yield projection

        cursor = meta.get("next_cursor")
        if not cursor:
            return
        if cursor in seen_cursors:
            raise RuntimeError("Repeated pagination cursor")
        seen_cursors.add(cursor)
        time.sleep(6.1)  # Pace serial page requests below the Free minute limit.


if __name__ == "__main__":
    print("Mode:", "authenticated observations" if API_KEY else "fictional demo")
    for item in projections():
        print(item["id"], item["player"]["name"], item["market"]["stat"], item["line"])

Run python3 prizepicks.py for the sample dataset. To read stored live-source observations, set PRIZEPICKS_API_KEY in the process environment using your own secret manager or terminal, then run the same file. Do not paste the token into the source file or commit it to Git. The code sends the token in the Authorization header only when it is present.

Understand the pagination loop

The API returns an array under data and page information under meta. A response is not necessarily the entire board. The generator yields each record, then follows meta.next_cursor with the same league and optional stat filter. It stops only when the continuation cursor is absent or null. A repeated-cursor check prevents a malformed response from trapping a client in a loop.

The example asks for 100 records per page. The supported maximum is 200; the default is 50. Keeping the filters constant matters: a cursor is a continuation through a filtered collection, not a portable offset that can be reused after switching from Points to Rebounds. The six-second pause limits this one serial loop’s request frequency; it cannot account for other processes sharing the account.

Keep the data types intact

Python valueMeaning in a projection
item["line"]Numeric provider base line. It is not a sportsbook price.
item["player"]["name"]Display name. Use item["id"] as the projection identifier.
item["selections"]More/Less availability, tiers, and any supplied payout multiplier.
NoneAn unknown or unavailable field value. Do not automatically replace it with zero.

Names can contain accents, and combo markets can name more than one player. Python’s JSON decoder handles Unicode strings, so keep those strings intact instead of splitting on spaces or stripping punctuation. A single player can have many projection IDs because the market, period, and offer variant are different.

Handle errors before scheduling the script

The runnable example exits with a useful error rather than retrying forever. A production worker should distinguish 400 validation errors, 401 authentication failures, 429 rate or monthly-quota errors, and temporary 503 responses. A monthly-quota failure will not be solved by waiting a few seconds. For minute-limit or transient failures, use bounded retry backoff and honor a Retry-After header when supplied.

The timeout prevents an individual request from waiting indefinitely. For a long-running integration, save data incrementally and record the final successfully processed cursor in durable storage. A projection refresh and a change-feed consumer have different jobs: the former reads current stored state, while the latter replays recorded events. Avoid repeatedly fetching a complete board separately for every user of your application.

Check freshness independently of HTTP success

Every page prints source_status and observed_at so stale or partial observations stay visible. A 200 response confirms that the API served the request; it does not certify that an upstream collection is complete or that a line is current enough for your use case. Inspect observation_age_seconds, preserve the original timestamps in your dataset, and choose a freshness rule appropriate to your application.

References

Current API documentation ↗Machine-readable OpenAPI contract ↗Python: urllib.request ↗Python: JSON decoding ↗

PrizePicks API is an independent data service. It is not affiliated with or endorsed by PrizePicks. Observations, completeness, and freshness are separate claims; consult source status before relying on a stored line.