Skip to main content

TacosScore - football analytics from Sofascore. Typed models, DataFrames, and rate-limited API access for analysts.

Project description

TacosScore — Python Football Data Library

TacosScore

Python Football Data Library — typed models, pandas DataFrames, rate-limited API access, and a full CLI built for analysts.

PyPI · GitHub · API Reference · MIT License


Author: Md. Tariquzzamana
Version: 0.1.0
Python: 3.9+

Disclaimer: TacosScore is not affiliated with Sofascore. The Sofascore API is undocumented and may change without notice. Use responsibly for research and personal analysis. See Operational considerations.


Table of contents


Why TacosScore?

Sofascore exposes rich match data — xG, shot maps, heatmaps, action streams, ~60 per-player stats — but the API is reverse-engineered, JSON-heavy, and protected by Akamai. TacosScore gives you:

Problem TacosScore solution
Raw JSON with UI clutter Typed dataclass models + strip_ui_fields()
403 errors from plain HTTP curl_cffi Chrome TLS impersonation
Rate-limit bans Built-in rate limiter + exponential backoff on 429
Inconsistent field names Snake_case Python fields mapped from camelCase API
Notebook / warehouse workflows .to_dataframe() on models + standalone helpers
Discoverability tacoscore help interactive guide + full CLI

Inspired by the breadth of tools like Match ScraperFC, TacosScore focuses on football analytics only — media streams, highlights, betting UI, and comment feeds are intentionally excluded.


Features

  • Sync and async clientsTacosScoreClient and AsyncTacosScoreClient
  • Match-level data — metadata, lineups, team stats, incidents, graph, H2H, pregame form, match shotmap
  • Player-level spatial data — heatmap, action stream (rating-breakdown), per-player shotmap
  • Tournament discovery — rounds, round fixtures, standings, season-wide fetch
  • Profiles — team, player, season stats, transfers, rankings, fixture lists
  • fetch_full_match() — orchestrated multi-endpoint pipeline with smart skips
  • CLI — every major endpoint as a subcommand with --raw, --pretty, --analytics-only
  • Interactive help — arrow-key browser (tacoscore help)
  • 132+ tests — parsers, client, CLI, extraction rules

Installation

From PyPI

pip install tacoscore

With pandas and Jupyter (recommended for analysts)

pip install "tacoscore[analysis]"

From source (development)

git clone https://github.com/Tariq-15/TacosScore.git
cd TacosScore
pip install -e ".[dev,analysis]"

Optional dependency groups

Extra Packages Use case
(default) curl_cffi, httpx Core client + CLI
analysis pandas, jupyter, ipykernel DataFrames and notebooks
dev pytest, ruff, mypy, respx, … Contributing and CI

Quick start

Python — one match

from tacoscore import TacosScoreClient

client = TacosScoreClient()

# Team stats and full lineups (~60 stats per player)
stats = client.event_statistics(15186861)
lineups = client.event_lineups(15186861)

print(f"{lineups.home.formation} vs {lineups.away.formation}")
print(f"Possession: {stats.by_period['ALL']['ballPossession'].home_value}%")

# Spatial data for one player
heatmap = client.player_heatmap(15186861, 868812)
actions = client.player_actions(15186861, 868812)
shots   = client.player_shotmap(15186861, 868812)

for shot in shots.shots:
    if shot.shot_type == "goal":
        print(f"Goal {shot.minute}' — xG={shot.xg:.3f}")

client.close()

Python — full match in one call

match = client.fetch_full_match(15186861)

print(match.event_detail)          # venue, referee, score
print(match.team_statistics)       # by period
print(match.lineups.home.players)  # all home players + stats
print(match.match_shotmap)         # every shot in the match
print(match.player_data[868812])   # heatmap, actions, shotmap per player

CLI — fastest way to inspect JSON

tacoscore lineups 15186861 --pretty
tacoscore event-stats 15186861
tacoscore fetch-match 15186861 --out match.json --pretty
tacoscore help

Import name (TacosScore Client)

from tacoscore import TacosScoreClient

client = TacosScoreClient()

The old names SofascoreClient and AsyncSofascoreClient still work as aliases for backward compatibility, but new code should use TacosScoreClient and AsyncTacosScoreClient.


World Cup 2026 extraction example

Use this ready-to-copy flow to extract World Cup 2026 data using 58210 as requested.

from tacoscore import TacosScoreClient

client = TacosScoreClient()

# World Cup 2026 extraction example
# tournament_id = 16, 58210 used here for World Cup 2026 season data
rounds = client.tournament_rounds(16, 58210)
round_6 = client.round_events(16, 58210, 6, slug="round-of-32")

for match in round_6.events:
    event_id = match.event_id
    full = client.fetch_full_match(
        event_id,
        include_match_shotmap=True,
        include_h2h=True,
        include_pregame_form=True,
    )
    print(
        event_id,
        full.lineups.home.team.name,
        "vs",
        full.lineups.away.team.name,
        "| players:",
        len(full.player_data),
    )

client.close()

CLI version:

tacoscore rounds 16 58210
tacoscore round-events 16 58210 6 --slug round-of-32 --table
tacoscore fetch-match 15186861 --pretty --out wc2026_match.json

Finding matches and IDs

Sofascore uses numeric IDs everywhere. You typically discover event_id values from tournament rounds or team fixture lists.

Common tournament IDs

Tournament tournament_id Example season_id
FIFA World Cup 16 58210 (2026)
Premier League 17 varies by season
UEFA Champions League 7 varies by season

Workflow: list rounds → list matches → fetch match

from tacoscore import TacosScoreClient

client = TacosScoreClient()

# 1. All rounds in a season
rounds = client.tournament_rounds(16, 58210)
print(rounds.current_round)
for r in rounds.rounds:
    print(r.round, r.name, r.slug)

# 2. Matches in a knockout round (slug required for named rounds)
r32 = rounds.by_slug("round-of-32")
matches = client.round_events(16, 58210, r32.round, r32.slug)

for m in matches.events:
    print(m.event_id, m.home_team.name, "vs", m.away_team.name)

# 3. Use event_id for any match endpoint
event_id = matches.events[0].event_id
lineups = client.event_lineups(event_id)

CLI equivalent

tacoscore rounds 16 58210
tacoscore round-events 16 58210 6 --slug round-of-32 --table

The --table flag prints event_id | Home vs Away per line instead of JSON.

Extract event ID from a Sofascore URL

Match URLs look like:

https://www.sofascore.com/scotland-brazil/xxxxx#id:15186861

The number after id: is the event_id.


Client configuration

from tacoscore import TacosScoreClient

client = TacosScoreClient(
    rate_limit_seconds=1.5,   # minimum gap between requests (default 1.5)
    rate_jitter_seconds=0.5,  # random extra delay (default 0.5)
    timeout=30.0,             # per-request timeout in seconds
    max_retries=3,            # retries on HTTP 429 with backoff
    user_agent=None,          # optional custom User-Agent
)
Parameter Default Description
rate_limit_seconds 1.5 Minimum seconds between API calls
rate_jitter_seconds 0.5 Random jitter added to spacing
timeout 30.0 Request timeout
max_retries 3 Retries on rate-limit (429) responses
user_agent built-in Override User-Agent header

Always call client.close() when done (or use AsyncTacosScoreClient as a context manager).


API methods reference

Base URL: https://www.sofascore.com/api/v1

Match endpoints

Python method Returns API path CLI command
event(event_id) EventDetail GET event/{id} tacoscore event ID
event_lineups(event_id) Lineups GET event/{id}/lineups tacoscore lineups ID
event_statistics(event_id) TeamStatistics GET event/{id}/statistics tacoscore event-stats ID
event_incidents(event_id) Incidents GET event/{id}/incidents tacoscore incidents ID
event_graph(event_id) MatchGraph GET event/{id}/graph tacoscore graph ID
event_managers(event_id) EventManagers GET event/{id}/managers tacoscore managers ID
event_shotmap(event_id) Shotmap GET event/{id}/shotmap tacoscore event-shotmap ID
event_h2h(event_id) HeadToHead GET event/{id}/h2h tacoscore h2h ID
event_pregame_form(event_id) PregameForm GET event/{id}/pregame-form tacoscore pregame-form ID

Player endpoints (per match)

Python method Returns API path CLI command
player_heatmap(event_id, player_id) Heatmap GET event/{id}/player/{pid}/heatmap tacoscore heatmap ID PID
player_actions(event_id, player_id) ActionStream GET event/{id}/player/{pid}/rating-breakdown tacoscore actions ID PID
player_shotmap(event_id, player_id) Shotmap GET event/{id}/shotmap/player/{pid} tacoscore shotmap ID PID
player_statistics(event_id, player_id) SinglePlayerStats GET event/{id}/player/{pid}/statistics tacoscore player-stats ID PID

Tip: Prefer event_lineups() when you need stats for the entire squad. player_statistics() returns the same block for one player only.

Tournament and standings

Python method Returns CLI command
tournament_rounds(tournament_id, season_id) RoundList tacoscore rounds TID SID
round_events(tid, sid, round_num, slug=None) MatchList tacoscore round-events TID SID ROUND [--slug]
season_events(tid, sid) dict[int, MatchList] (Python only — one request per round)
tournament_standings(tid, sid, table_type="total") Standings tacoscore standings TID SID [--type]

table_type for standings: "total", "home", or "away".

Profiles and history

Python method Returns CLI command
team(team_id) TeamProfile tacoscore team ID
player(player_id) PlayerProfile tacoscore player ID
player_season_statistics(pid, tid, sid) SeasonPlayerStatistics tacoscore player-season-stats PID TID SID
team_events(team_id, page=0) MatchList tacoscore team-events ID [--page]
team_events_next(team_id, page=0) MatchList (Python only)
team_rankings(team_id) TeamRankings tacoscore team-rankings ID
player_transfer_history(player_id) TransferHistory (Python only)
player_events_last(player_id, page=0) MatchList (Python only)

Low-level access

raw = client.get_raw("event/15186861/lineups")

Any CLI subcommand also supports --raw to bypass parsers and emit original API JSON.


Full-match pipeline

fetch_full_match() implements the recommended analytics order from docs/sofascore-api-reference.md (Section 10).

Fetch order

event → lineups → statistics → incidents → managers → graph
  → h2h → pregame_form → match_shotmap
  → per-player: heatmap → actions → shotmap

Parameters

match = client.fetch_full_match(
    event_id=15186861,
    skip_no_minutes=True,           # skip spatial calls for 0-minute players
    skip_no_shots=True,             # skip shotmap when total_shots == 0
    skip_sparse_heatmap=True,       # skip heatmap when touches <= threshold
    min_touches_for_heatmap=5,      # minimum touches for heatmap
    include_match_shotmap=True,     # fetch event/{id}/shotmap
    include_h2h=True,
    include_pregame_form=True,
)
Parameter Default Effect
skip_no_minutes True No heatmap/actions/shotmap for unused subs
skip_no_shots True No per-player shotmap when total_shots == 0
skip_sparse_heatmap True No heatmap when touches <= min_touches
min_touches_for_heatmap 5 Touch threshold for heatmap
include_match_shotmap True Fetch all shots in the match
include_h2h True Head-to-head aggregates
include_pregame_form True Pre-match form strings

FullMatch structure

match.event_id            # int
match.event_detail        # EventDetail | None
match.team_statistics     # TeamStatistics
match.lineups             # Lineups
match.incidents           # Incidents | None
match.graph               # MatchGraph | None
match.managers            # EventManagers | None
match.head_to_head        # HeadToHead | None
match.pregame_form        # PregameForm | None
match.match_shotmap       # Shotmap | None
match.player_data         # dict[int, PlayerMatchData]

Each PlayerMatchData holds:

pmd = match.player_data[868812]
pmd.player_id   # int
pmd.heatmap     # Heatmap | None
pmd.actions     # ActionStream | None
pmd.shotmap     # Shotmap | None

CLI

tacoscore fetch-match 15186861 --out match.json --pretty
tacoscore fetch-match 15186861 --include-bench --fetch-empty-shotmaps

Data models

All models are immutable-style dataclasses with typed fields. Parsers map Sofascore camelCase JSON to snake_case Python.

Core match models

Model Description
EventDetail Teams, score, status, venue, referee, attendance
Lineups Confirmed flag, home/away LineupSide (formation + players)
LineupEntry Player, shirt number, position, captain, PlayerStats
TeamStatistics Stats keyed by period (ALL, 1ST, 2ND) then stat name
Incidents Goals, cards, subs, period markers
MatchGraph Minute-by-minute attack momentum
Shotmap / Shot xG, coordinates, body part, situation, outcome
Heatmap / HeatmapPoint Normalized touch coordinates
ActionStream / Action Passes, dribbles, defensive actions, carries
HeadToHead Team and manager duel records
PregameForm Form strings and table context

Discovery models

Model Description
RoundList / Round Season rounds with optional knockout slug
MatchList / MatchSummary Fixture lists with event_id
Standings / StandingRow League table rows
TeamProfile / PlayerProfile Bio, market value, venue
SeasonPlayerStatistics Season aggregate stats
TransferHistory / Transfer Career transfers
TeamRankings FIFA-style ranking rows

Accessing raw JSON

Every parsed model stores the original payload:

lineups = client.event_lineups(15186861)
lineups.raw                    # full API dict on Lineups
lineups.home.players[0].stats.raw  # per-player raw stats block

Use --include-raw on the CLI to include raw fields in JSON output.


Player statistics

PlayerStats exposes ~60 fields per player. Sofascore omits zero values in JSON; TacosScore defaults missing fields to 0 / 0.0.

Categories

Category Example fields
Passing total_pass, accurate_pass, key_pass, goal_assist, expected_assists
Shooting total_shots, goals, expected_goals, expected_goals_on_target, big_chance_created
Dribbling total_contest, won_contest, dispossessed
Duels duel_won, duel_lost, aerial_won, aerial_lost
Defending total_tackle, interception_won, ball_recovery, error_lead_to_a_goal
Fouls fouls, was_fouled, total_offside
Goalkeeping saves, goals_prevented, keeper_save_value
Physical top_speed, kilometers_covered, number_of_sprints
Ball carries ball_carries_count, total_progression, progressive_ball_carries_count
Engagement touches, minutes_played, possession_lost_ctrl
Rating rating, shot_value_normalized, pass_value_normalized, goalkeeper_value_normalized

Example — top xG in a match

lineups = client.event_lineups(15186861)

rows = []
for side in (lineups.home, lineups.away):
    for entry in side.players:
        s = entry.stats
        rows.append((entry.player.name, s.expected_goals, s.minutes_played))

for name, xg, mins in sorted(rows, key=lambda r: r[1], reverse=True)[:5]:
    print(f"{name:20s}  xG={xg:.2f}  ({mins} min)")

Pandas and DataFrames

Install the analysis extra:

pip install "tacoscore[analysis]"

Method on models (.to_dataframe())

Most models expose a convenience method:

lineups = client.event_lineups(15186861)
df = lineups.to_dataframe()   # player_id is the first column

stats_df = client.event_statistics(15186861).to_dataframe()  # long format by period
shots_df = client.player_shotmap(15186861, 868812).to_dataframe(player_id=868812)

Module-level helpers

from tacoscore import (
    lineups_to_dataframe,
    team_stats_to_dataframe,
    player_stats_to_dataframe,
    heatmap_to_dataframe,
    actions_to_dataframe,
    shotmap_to_dataframe,
    incidents_to_dataframe,
    graph_to_dataframe,
    matches_to_dataframe,
    rounds_to_dataframe,
    standings_to_dataframe,
    season_player_stats_to_dataframe,
)

df = lineups_to_dataframe(lineups)
Helper Input model Typical use
lineups_to_dataframe Lineups One row per player, all stat columns
team_stats_to_dataframe TeamStatistics Long format: period × stat × home/away
shotmap_to_dataframe Shotmap Shot-level xG, coords, body part
heatmap_to_dataframe Heatmap Touch coordinates
actions_to_dataframe ActionStream Pass/dribble/defensive events
matches_to_dataframe MatchList Fixture discovery tables
standings_to_dataframe Standings League table

Notebook and explore script

jupyter notebook notebooks/tacoscore_methods.ipynb
python scripts/explore_data.py --show-raw

Analytics extraction

The tacoscore.extraction module encodes rules from the Sofascore API Reference — which fields to keep, drop, and when to skip endpoints.

Strip UI-only JSON keys

from tacoscore import strip_ui_fields

clean = strip_ui_fields(client.get_raw("event/15186861/lineups"))

Dropped keys include: fieldTranslations, userCount, teamColors, logo, draw, directStreamUrl, thumbnailUrl, and other web/UI fields. See UI_DROP_KEYS in extraction.py.

Pipeline constants

from tacoscore import MATCH_EXTRACTION_ORDER, ANALYTICS_EVENT_ENDPOINTS

print(MATCH_EXTRACTION_ORDER)
# ('event', 'lineups', 'statistics', 'incidents', 'managers', 'graph', ...)

from tacoscore.extraction import should_fetch_shotmap, should_fetch_heatmap

should_fetch_shotmap(total_shots=0)   # False
should_fetch_heatmap(touches=3)       # False (default min_touches=5)

CLI — analytics-only JSON

tacoscore lineups 15186861 --analytics-only --pretty

This removes UI keys from serialized output before writing to stdout or --out.

Intentionally excluded endpoints

Media and web-only paths are not implemented as typed methods:

Suffix Reason
/media Video streams (m3u8), thumbnails
/highlights Video highlights
/news Editorial content
/tv-channels Broadcast listings
/comments User comments

Use get_raw() only if you explicitly need these; do not use them in analytics pipelines.


Coordinate systems

Sofascore uses two 0–100 grids plus a separate goal-mouth frame. TacosScore documents them in coordinates.py and provides StatsBomb-aligned conversion in statsbomb.py.

System Used by X axis Y axis
A Heatmap, rating-breakdown 0 = own goal → 100 = opposition goal 0/100 = touchlines
B Shotmap playerCoordinates Distance from opposition goal Lateral
Goal mouth goalMouthCoordinates Always 0 (on goal line) Lateral y, height z

StatsBomb 120×80 (recommended for plotting)

Rule Value
Origin (0, 0) = bottom-left corner
Pitch size 120 × 80
Home goal (default) x = 120 when home_attacks_left_to_right=True
from tacoscore import TacosScoreClient
from tacoscore.statsbomb import convert_shotmap_to_statsbomb

client = TacosScoreClient()
shots = client.event_shotmap(15186861)

# Each shot: location (where struck) + end_location (goal mouth)
for spatial in convert_shotmap_to_statsbomb(shots, home_attacks_left_to_right=True):
    print(spatial.location, spatial.end_location)

# DataFrame with sb_x, sb_y, sb_end_x, sb_end_y, sb_end_z columns
df = shots.to_statsbomb_dataframe(home_attacks_left_to_right=True)

Low-level converters:

from tacoscore.statsbomb import (
    system_a_to_statsbomb,   # heatmap / actions
    system_b_to_statsbomb,   # shot take position
    goal_mouth_to_statsbomb,  # goal frame (y, z) -> end_location
)

Metres on FIFA pitch (105×68)

from tacoscore.coordinates import system_a_to_pitch, system_b_to_pitch

px, py = system_a_to_pitch(63.0, 91.0)
px, py = system_b_to_pitch({"x": 8.1, "y": 51}, attack_right=True)

Note: coordinates.to_statsbomb() is a simple scale on System A only. Use tacoscore.statsbomb for shotmap and mixed-team plots.


Command-line interface

After install, tacoscore is on your PATH.

Global options

tacoscore [--version]
        [--rate-limit SEC] [--jitter SEC]
        [--max-retries N] [--timeout SEC]
        [--user-agent UA]
        COMMAND ...

Per-command options

Flag Description
--out PATH Write JSON to file instead of stdout
--raw Emit original API JSON (skip parsers)
--pretty Pretty-print JSON (2-space indent)
--include-raw Include each model's raw field in output
--analytics-only Strip UI-only Sofascore keys from output

All subcommands

# Match
tacoscore event EVENT_ID
tacoscore lineups EVENT_ID
tacoscore event-stats EVENT_ID
tacoscore incidents EVENT_ID
tacoscore graph EVENT_ID
tacoscore managers EVENT_ID
tacoscore h2h EVENT_ID
tacoscore pregame-form EVENT_ID
tacoscore event-shotmap EVENT_ID
tacoscore fetch-match EVENT_ID [--include-bench] [--fetch-empty-shotmaps]

# Player (per match)
tacoscore heatmap EVENT_ID PLAYER_ID
tacoscore actions EVENT_ID PLAYER_ID
tacoscore shotmap EVENT_ID PLAYER_ID
tacoscore player-stats EVENT_ID PLAYER_ID

# Tournament
tacoscore rounds TOURNAMENT_ID SEASON_ID
tacoscore round-events TID SID ROUND [--slug SLUG] [--table]
tacoscore standings TID SID [--type total|home|away]

# Profiles
tacoscore team TEAM_ID
tacoscore player PLAYER_ID
tacoscore player-season-stats PID TID SID
tacoscore team-events TEAM_ID [--page N]
tacoscore team-rankings TEAM_ID

# Help
tacoscore help [TOPIC] [--all] [--no-interactive]

Examples

# Pretty JSON to stdout
tacoscore lineups 15186861 --pretty

# Save full match bundle
tacoscore fetch-match 15186861 --out wc_match.json --pretty

# Raw API passthrough
tacoscore heatmap 15186861 868812 --raw

# List knockout fixtures
tacoscore round-events 16 58210 6 --slug round-of-32 --table

Interactive help

Browse all methods with an arrow-key UI (like an in-terminal notebook index):

tacoscore help
Key Action
↑ / ↓ Navigate list
Enter Open section or method detail
Backspace Go back
q / Esc Quit
# One topic (plain text)
tacoscore help fetch_full_match
tacoscore help player_heatmap

# Full catalog
tacoscore help --all

From Python

from tacoscore import show_help, get_help_entry, list_help_entries

show_help()                        # interactive when run in a TTY
show_help("event_lineups")         # print one entry
show_help(interactive=False)       # print entire catalog

entry = get_help_entry("fetch_full_match")
print(entry.signature)
print(entry.example_cli)

Async client

import asyncio
from tacoscore import AsyncTacosScoreClient

async def main():
    async with AsyncTacosScoreClient() as client:
        stats = await client.event_statistics(15186861)
        lineups = await client.event_lineups(15186861)
        match = await client.fetch_full_match(15186861)

asyncio.run(main())

AsyncTacosScoreClient mirrors every method on TacosScoreClient. Rate limiting is shared per client instance.


Serialization and export

from tacoscore._serialize import to_jsonable

match = client.fetch_full_match(15186861)
payload = to_jsonable(match, include_raw=False, analytics_only=True)

import json
with open("match_clean.json", "w", encoding="utf-8") as f:
    json.dump(payload, f, indent=2, ensure_ascii=False, default=str)

The CLI uses the same serializer internally.


Exceptions

from tacoscore import (
    SofascoreError,   # base class
    APIError,         # HTTP errors (4xx/5xx)
    RateLimitError,   # 429 after retries exhausted
    NotFoundError,    # 404
    ParseError,       # JSON shape unexpected
)

try:
    match = client.fetch_full_match(99999999)
except NotFoundError:
    print("Match not found")
except RateLimitError:
    print("Rate limited — increase rate_limit_seconds")
except SofascoreError as e:
    print(f"API error: {e}")

Project structure

TacosScore/
├── src/tacoscore/
│   ├── client.py              # TacosScoreClient (sync)
│   ├── async_client.py        # AsyncTacosScoreClient
│   ├── cli.py                 # tacoscore CLI entry point
│   ├── extraction.py          # strip_ui_fields, pipeline rules
│   ├── help_catalog.py        # Method documentation catalog
│   ├── interactive_help.py    # Arrow-key help browser
│   ├── dataframe.py           # Pandas export helpers
│   ├── coordinates.py         # Metres + legacy scale-only to_statsbomb
│   ├── statsbomb.py           # StatsBomb 120×80 coordinate conversion
│   ├── _serialize.py          # JSON serialization
│   ├── models/                # Typed dataclasses
│   └── parsers/               # API JSON → models
├── docs/
│   └── sofascore-api-reference.md   # Field catalog + KEEP/DROP rules
├── notebooks/
│   └── tacoscore_methods.ipynb      # Exploration notebook
├── scripts/
│   └── explore_data.py              # Live API exploration
├── tests/                           # pytest suite (132+ tests)
├── pyproject.toml
├── README.md
├── LICENSE
└── TacosScore.png

Development and testing

git clone https://github.com/Tariq-15/TacosScore.git
cd TacosScore
pip install -e ".[dev,analysis]"

# Run tests
pytest

# Lint
ruff check src tests

# Type check
mypy src/tacoscore

Tests use respx to mock HTTP — no live API calls in CI.

Build and publish (maintainers)

pip install build twine
python -m build
twine upload dist/*

Operational considerations

Topic Guidance
Akamai / 403 Plain httpx or requests often get blocked. TacosScore uses curl_cffi with Chrome TLS impersonation by default.
Rate limits Default 1.5 s between requests. Aggressive scraping will get you IP-blocked. Use fetch_full_match() sparingly on large batches.
Undocumented API Field names and shapes can change. Every model keeps .raw for forward compatibility.
Legal / ToS Sofascore's terms may restrict automated access. This library is for research and personal analysis. Not authorized for commercial scraping or redistribution of Sofascore data.
National teams Some team/player sub-endpoints return 404 for certain national-team IDs.

Related documentation

Document Contents
docs/sofascore-api-reference.md Full endpoint catalog, field KEEP/DROP/UNKNOWN tables, pipeline spec
tacoscore help Interactive in-terminal method guide
notebooks/tacoscore_methods.ipynb Hands-on examples

License

MIT License — Copyright (c) 2026 Md. Tariquzzaman.

See LICENSE for full text.


Built for football analysts who want typed data, not raw JSON soup.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tacoscore-0.1.1.tar.gz (146.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

tacoscore-0.1.1-py3-none-any.whl (86.2 kB view details)

Uploaded Python 3

File details

Details for the file tacoscore-0.1.1.tar.gz.

File metadata

  • Download URL: tacoscore-0.1.1.tar.gz
  • Upload date:
  • Size: 146.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.13

File hashes

Hashes for tacoscore-0.1.1.tar.gz
Algorithm Hash digest
SHA256 cfbc41250221cb09aa299336b956825907ba60512e91a958ead8c1e0b7929b81
MD5 bd6bc151c83f57e5e0d289e16dd071f2
BLAKE2b-256 d2cdc0c99bb9f426cdc1c5dbca79f2356284d65e79eae6d09eec1701ab608918

See more details on using hashes here.

File details

Details for the file tacoscore-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: tacoscore-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 86.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.13

File hashes

Hashes for tacoscore-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 197491ead184232a88c9dedf9f6023400f3b246bcb91607e68800e6529af07e7
MD5 1bdeeedc98b6cb9b9a03d9d55f488548
BLAKE2b-256 995400be797c90c011727abcbcb406120c6019c1c1f589135ab037a2116380ef

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page