Skip to main content

🏈 CFL SDK

Ruff

A modern Python SDK for the Canadian Football League API using httpx.

Features · Installation · Quick Start · API Reference · Built with CFL SDK · Contributing


Features

  • Full type hints using modern Python typing
  • Comprehensive API coverage (most endpoints supported)
  • Error handling and logging

Installation

pip install cfl-sdk

With Poetry

poetry add cfl-sdk

Quick Start

from cfl import CFLClient

client = CFLClient()

# Get all teams
teams = client.get_teams()
for team in teams:
    print(f"{team['name']} ({team['abbreviation']})")

# Get fixtures for a season
fixtures = client.get_fixtures(season_id=75)  # 2026 season

# Get players filtered by position
qbs = client.get_players(position="QB", limit=20)

API Reference

Teams · Venues · Players · Seasons · Fixtures · Rosters · Roster Players · Colleges · Ledger · Team Stats · Player Stats · Standings · Leaderboard


Teams

# Get all teams
teams = client.get_teams()

# Get a specific team
team = client.get_team(team_id=1)

# Get a team's full current roster
roster = client.get_team_roster(team_id=1)

Venues

# Get all venues
venues = client.get_venues()

# Get specific venue
venue = client.get_venue(venue_id=1)

Players

# Get players (filterable)
players = client.get_players(limit=50)
players = client.get_players(position="QB")
players = client.get_players(college_id=295)
players = client.get_players(sort_by="lastname", sort_order="asc", page=2, limit=25)

# Get a specific player
player = client.get_player(player_id=183186)

# Embed college details in the response
player = client.get_player(player_id=183186, with_college=True)
# player["relations"]["college"] -> college object

# Search players by name pattern
results = client.search_players("mitchell")  # returns [{ID, name}, ...]

# Get all position definitions
positions = client.get_player_positions()

Seasons

# Get all seasons (with optional pagination)
seasons = client.get_seasons(page=1, limit=50)

# Get specific season
season = client.get_season(season_id=75)  # 2026 season

Fixtures (Games)

# Get fixtures (with optional filters and pagination)
fixtures = client.get_fixtures(limit=50)
fixtures = client.get_fixtures(season_id=75)  # 2026 season
fixtures = client.get_fixtures(home_team_id=1)
fixtures = client.get_fixtures(away_team_id=1)
fixtures = client.get_fixtures(venue_id=1)

# Get a specific fixture
fixture = client.get_fixture(fixture_id=6555)

# Embed related objects
fixture = client.get_fixture(fixture_id=6555, with_venue=True)
fixture = client.get_fixture(fixture_id=6555, with_season=True)
# fixture["relations"]["venue"] -> venue object

Rosters

# Get all rosters
rosters = client.get_rosters()

# Get specific roster
roster = client.get_roster(roster_id=1)

# Get per-team roster state and nationality counts
summary = client.get_rosters_summary()

Roster Players

# Get all roster player entries
roster_players = client.get_roster_players(limit=50)

# Filter to a specific player's entry
entries = client.get_roster_players(player_id=183186)

# Embed full player object
entries = client.get_roster_players(with_player=True, limit=25)
# entries[0]["relations"]["player"] -> full player object

# Get a specific roster player entry
rp = client.get_roster_player(rosterplayer_id=26733)
rp = client.get_roster_player(rosterplayer_id=26733, with_player=True)

# Get all valid roster states
states = client.get_roster_player_states()

Colleges

# Get all colleges
colleges = client.get_colleges(limit=50)

# Filter by name
colleges = client.get_colleges(name="laval")

# Sort and paginate
colleges = client.get_colleges(sort_by="name", sort_order="asc", page=1, limit=25)

# Get a specific college
college = client.get_college(college_id=295)

Ledger (Transactions)

# Get transactions for a year
transactions = client.get_ledger(year=2026)

Team Stats

# Get team stats
team_stats = client.get_team_stats()

# Get team stats for a season
team_stats = client.get_team_stats(season_id=75)  # 2026 season

# Get specific team stats
team_stat = client.get_team_stat(team_stats_id=122345)

Player Stats

# Get player stats (with optional pagination and season filter)
player_stats = client.get_player_stats(season_id=75, page=1, limit=50)

# Get specific player stats
player_stat = client.get_player_stat(player_stats_id=1629968)

# Get player stats with photo URL
player_stat = client.get_player_pims(player_id=168507)

Standings

# Get standings for a year (2016-2026 supported)
standings = client.get_standings(year=2026)

standings["week"]      # week the standings reflect
standings["east"]      # list of team rows for the East division
standings["west"]      # list of team rows for the West division
standings["unified"]   # combined table (available from 2020 on)

row = standings["west"][0]
row["place"], row["abbreviation"], row["wins"], row["losses"], row["ties"]

Leaderboard

# Get league leaders for every stat category (2016-2026 supported)
leaders = client.get_leaderboards(season=2026)

# Return more players per category (1-25, default 3)
leaders = client.get_leaderboards(season=2026, count=10)

leaders["offence"]        # [{"category": "passing", "leaders": [...]}, ...]
leaders["defence"]        # [{"category": "tackles", "leaders": [...]}, ...]
leaders["special_teams"]  # [{"category": "fieldGoalsSucceeded", "leaders": [...]}, ...]

top_passer = leaders["offence"][0]["leaders"][0]
top_passer["firstname"], top_passer["lastname"], top_passer["statValue"]

Error Handling

The SDK provides specific error types:

  • CFLAPIConnectionError: For connection issues
  • CFLAPITimeoutError: For request timeouts
  • CFLAPINotFoundError: For 404 responses
  • CFLAPIAuthenticationError: For auth issues
  • CFLAPIValidationError: For invalid requests
  • CFLAPIServerError: For server errors
from cfl import CFLClient, CFLAPINotFoundError

client = CFLClient()

try:
    team = client.get_team(team_id=999999)
except CFLAPINotFoundError:
    print("Team not found")

Using with Context Manager

with CFLClient() as client:
    teams = client.get_teams()
    # Client will be closed automatically

Acknowledgements & Disclaimer

Thank you to the Canadian Football League (CFL) for providing a public API.

This is an unofficial SDK and is not affiliated with, endorsed, or sponsored by the Canadian Football League (CFL).

Built with CFL SDK

Using this SDK in a project? Open a PR to add it here!

Project Description
Your project here Open a PR to add yours

Contributing

Contributions are welcome! Please feel free to submit a pull request or open an issue for any bugs or feature requests.

License

This project is licensed under the MIT License. See the LICENSE file for more details.

Metadata

Release files for cfl-sdk 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for cfl-sdk 0.1.0
File Size Uploaded
cfl_sdk-0.1.0.tar.gz 16.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for cfl-sdk 0.1.0
File Interpreter ABI Platform
cfl_sdk-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 34.6 kB

Release files / cfl_sdk-0.1.0.tar.gz

Download URL cfl_sdk-0.1.0.tar.gz
Size 16.0 kB
Tags Source
SHA-256 checksum
How to use checksums
61bd0f8e049a8daf2e028ad4b10cb960627f566a4e840facb6de819dc788c210
BLAKE2b-256 checksum
How to use checksums
fb93ed3c9973256179f54a00a8524ea1594585aaa5c88c508902538a8ff67a4c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 3, 2026.

Transparency log

Release files / cfl_sdk-0.1.0-py3-none-any.whl

Download URL cfl_sdk-0.1.0-py3-none-any.whl
Size 18.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
82a51ec20425203d0076880a91983c4d45f17ef683710ddb7e855b7c228c208d
BLAKE2b-256 checksum
How to use checksums
14a182d12333f6b94b1c5c70fab2e2fe26c769bf50fa38fda4f6848390d8295d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 3, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

0.0.3

2 release files

0.0.2

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page