If you've read our stat explainers and thought "I want to pull these numbers myself," this is where you start. We'll get a free API key, store it safely, and write a short Python script that pulls real college football data from the CollegeFootballData API (CFBD) — the same free, public source much of this site is built on. No prior API experience needed. The complete script is in scripts/cfbd-api-python-tutorial.py; we'll build it here step by step.
Step 1: Get a free API key
CFBD is free, but it asks you to register for a key so usage can be rate-limited fairly. Go to collegefootballdata.com, follow the link to get a key (the free tier is plenty for learning), and you'll receive a long string of characters. That string is a password — treat it like one.
Step 2: Store the key as an environment variable (never in your code)
The single most important habit in this tutorial: do not paste your key into your script. If you do, you'll eventually commit it to GitHub and leak it. Instead, store it in an environment variable your script reads at runtime.
# PowerShell (Windows) — for the current terminal session
$env:CFBD_API_KEY = "paste_your_key_here"
# macOS / Linux (bash or zsh)
export CFBD_API_KEY="paste_your_key_here"
Set the key in your terminal, then run Python from that same terminal.
Step 3: A helper that authenticates for you
CFBD uses "bearer token" authentication: you send the key in an HTTP header named Authorization. Here's a small function — standard library only, so it runs anywhere — that reads the key from the environment and fetches any endpoint:
import os, json, urllib.request
BASE = "https://api.collegefootballdata.com"
def get(path):
key = os.environ.get("CFBD_API_KEY")
if not key:
raise SystemExit("Set CFBD_API_KEY first (see Step 2).")
request = urllib.request.Request(
BASE + path,
headers={
"Authorization": f"Bearer {key}", # the key travels here
"Accept": "application/json",
},
)
with urllib.request.urlopen(request, timeout=25) as response:
return json.loads(response.read())
Notice the key is read from os.environ — it never appears as text in the file.
If you'd rather use the official package, pip install cfbd gives you a typed client; it authenticates the same way (a configuration object holding your key). We use raw HTTP here so there are zero dependencies and you can see exactly what's happening.
Step 4: Pull a team's schedule
Now the fun part. CFBD's /games endpoint returns games filtered by year and team:
games = get("/games?year=2024&team=Michigan&seasonType=regular")
for g in games:
print(f"Wk{g['week']:>2} {g['away_team']} {g.get('away_points','-')} "
f"@ {g['home_team']} {g.get('home_points','-')}")
Each game is a dictionary; we print week, the away team, and the home team.
Run it and you'll see a tidy, week-by-week schedule with scores — pulled live, no copy-pasting from a website. The exact output depends on the season you request, which is the whole point: you're reading the source of truth, not someone's transcription of it.
Step 5: Pull advanced ratings (SP+)
The same helper reaches every endpoint. Here's the top 10 teams by SP+, the rating we break down in our SP+ explainer:
sp = get("/ratings/sp?year=2024")
sp = [s for s in sp if s.get("rating") is not None]
sp.sort(key=lambda s: s["rating"], reverse=True)
for s in sp[:10]:
print(f"{s['team']:<18} {s['rating']:.1f}")
Filter out null ratings, sort high-to-low, print the top 10.
That's the entire workflow: get a key, store it safely, write one helper, and every public CFBD dataset is a function call away — schedules, ratings, drives, play-by-play, recruiting class aggregates, and more.
Be a good API citizen
- Cache responses. If you're going to request the same data repeatedly while developing, save it to a file and read from disk. (Our site's scripts do exactly this — see
scripts/_fetch.py.) It's faster for you and kinder to the free service. - Rate-limit yourself. Don't hammer the API in a tight loop. A short pause between requests is polite and keeps you within the free tier.
- Send a real User-Agent. Identify your script; it helps the maintainers and is just good manners.
- Respect the terms. Use the data for analysis and learning. Don't redistribute proprietary datasets, and credit your sources.
Where to go next
Once you can pull schedules and ratings, try computing something yourself: average scoring margin, a simple strength of schedule (we walk through one in our spreadsheet tutorial), or your own success-rate calculation from the play-by-play endpoint. The leap from "reading stats" to "making stats" is smaller than it looks — and once you've made it, you'll never take a cited number at face value again. You'll just go check it.
Sources & further reading
- CollegeFootballData.com — collegefootballdata.com (API and free key)
- Companion code:
scripts/cfbd-api-python-tutorial.py - Related: Pull basketball data with sportsdataverse · SP+ explained