Skip to content
Scouting & Strategy·Lesson 20 of 32

Project 3: Pull Live Data with the TBA and Statbotics APIs

Write real Python that fetches an event's matches and OPRs from The Blue Alliance and EPA ratings from Statbotics, the foundation of any automated analysis.

Sign in to track progress, earn XP, and save lessons.

Goal

A short Python script that, given an event key, pulls (a) the qualification schedule and results from The Blue Alliance (TBA) and (b) Statbotics EPA ratings, so your analysis sheet can refresh itself instead of being retyped.

Get a TBA Read API key

Go to your TBA account dashboard and generate a key under Read API Keys. Every direct request to the base URL https://www.thebluealliance.com/api/v3 must include the header X-TBA-Auth-Key. Event keys look like 2025cc (the 2025 Chezy Champs off-season event; the event code is the part after the year in the event URL, e.g. thebluealliance.com/event/2025cc).

TBA with the tbapy wrapper

pip3 install tbapy
import tbapy

tba = tbapy.TBA('YOUR_TBA_KEY')
event = '2025cc'

# Every match at the event (objects with alliances + score_breakdown)
matches = tba.event_matches(event)

# OPR / DPR / CCWM that TBA already computed
oprs = tba.event_oprs(event)         # dict with 'oprs', 'dprs', 'ccwms'
rankings = tba.event_rankings(event) # qualification ranking + RP

for m in matches:
    if m['comp_level'] != 'qm':
        continue
    red = m['alliances']['red']['team_keys']      # e.g. ['frc254','frc1678','frc2713']
    red_score = m['alliances']['red']['score']
    print(m['key'], red, red_score)

The score_breakdown on each match is gold: for REEFSCAPE it splits out auto vs teleop coral counts by level, algae, and barge points, which you can feed straight into component OPR (Project 2).

Statbotics for EPA

EPA (Expected Points Added) is Statbotics' rating; it was built to replace OPR/Elo and is designed to be predictive, expressed in point units, and split into auto/teleop/endgame component EPAs.

pip install statbotics==3.0.0
import statbotics

sb = statbotics.Statbotics()

print(sb.get_team(254))                     # team profile incl. EPA summary
print(sb.get_team_year(254, 2025))          # one team's 2025 EPA
ty = sb.get_team_event(254, '2025cc')       # EPA at a specific event
ms = sb.get_matches(team=254, year=2025)    # match-level EPA records

Use the fields parameter (e.g. sb.get_team(254, fields=['team','norm_epa'])) to request only what you need so responses stay small.

Putting it together

A practical pattern: pull TBA event_rankings for ranking-point standings, TBA event_oprs for a no-scouting power baseline, and Statbotics get_team_event for predictive EPA, then join all three on team number in a DataFrame. When TBA OPR and Statbotics EPA agree with your own scouting averages, you have high confidence; when they disagree, that team is worth a super-scout's eyes. Cache responses (TBA returns an ETag; send it back as If-None-Match to get a cheap 304 Not Modified) so you are polite to the API and fast on refresh.

Key takeaways

  • TBA requires the X-TBA-Auth-Key header; tbapy wraps event_matches, event_oprs, and event_rankings into one-line calls.
  • TBA score_breakdown gives per-phase REEFSCAPE counts (auto vs teleop coral by level) you can feed into component OPR.
  • Statbotics v3 (pip install statbotics==3.0.0) exposes get_team, get_team_year, get_team_event, and get_matches for predictive EPA with auto/teleop/endgame components.

Lesson quiz

Required

Answer all 3 questions correctly to complete this lesson.

1.How do you authenticate a request to The Blue Alliance Read API v3?

2.Which correctly describes the TBA API v3 base URL and request style?

3.Compared with TBA, what is distinctive about pulling team data from the Statbotics Python API?

Answer every question to submit.