Building a Real-Time Match Monitor
A step-by-step guide to building a CLI tool that monitors live Valorant matches, tracks scores, and alerts on key events using VLRdevAPI.
This guide walks through building a real-time match monitor that polls for live matches, displays scores, and tracks team performance. By the end, you'll have a working CLI tool you can extend for your own use cases.
Prerequisites
Before you begin, make sure you have:
- Python 3.11 or later installed
- The
vlrdevapipackage installed:pip install vlrdevapi - Basic familiarity with Python and the command line
Project Setup
Create a project directory and virtual environment
mkdir match-monitor
cd match-monitor
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install vlrdevapiCreate the main script
Create a file called monitor.py — we'll build it up step by step throughout this guide.
Step 1: Fetch Live Matches
The first thing our monitor needs is the ability to fetch currently live matches from VLR.gg.
Use vlrdevapi.matches.live() to get all ongoing matches. Each entry has match_id, event, stage, and team1/team2 objects.
import vlrdevapi
try:
page = vlrdevapi.matches.live()
matches = page.matches
print(f"Live matches: {len(matches)}")
if matches:
for m in matches:
print(f" Match #{m.match_id} — {m.event}")
else:
print("No matches currently live — this is normal.")
except Exception as e:
print(f"Error: {e}")Step 2: Display Match Status
Raw match objects aren't human-readable. Let's build a formatter and a display function.
Formatting a single match
import vlrdevapi
def format_match(m):
"""Format a match entry into a readable string."""
t1 = m.team1.name if m.team1 else "TBD"
t2 = m.team2.name if m.team2 else "TBD"
return f"{t1} vs {t2} | {m.event} | {m.stage}"
def show_matches(matches):
"""Print a formatted list of matches."""
if not matches:
print("No live matches at this time.")
return
print(f"\n{'='*60}")
print(f" LIVE MATCHES ({len(matches)})")
print(f"{'='*60}")
for m in matches:
print(f" {format_match(m)}")
print(f"{'='*60}\n")
page = vlrdevapi.matches.live()
show_matches(page.matches)Match object fields
Each match exposes:
match_id— unique match identifierteam1/team2—TeamInLiveMatchobjects with.name,.tag,.id,.country_nameevent— tournament name (e.g. "VCT 2025: Masters Madrid")stage— stage within the event (e.g. "Playoffs")status— always"live"
Step 3: Build a Polling Snapshot
A real-time monitor polls the API and alerts when new matches appear. The key is tracking match_id values in a set.
import vlrdevapi
import time
def poll(seen=None, interval=30):
"""Poll for live matches and alert on new ones."""
if seen is None:
seen = set()
print(f"Polling every {interval}s — checking for new matches")
for _ in range(3): # run a few cycles for demonstration
try:
page = vlrdevapi.matches.live()
current = page.matches
except Exception as e:
print(f" Poll error: {e}")
time.sleep(interval)
continue
new_matches = [m for m in current if m.match_id not in seen]
for m in new_matches:
seen.add(m.match_id)
t1 = m.team1.name if m.team1 else "TBD"
t2 = m.team2.name if m.team2 else "TBD"
print(f" [NEW] {t1} vs {t2} just went live!")
if not new_matches:
print(f" [{time.strftime('%H:%M:%S')}] No new matches — continuing...")
time.sleep(interval)
poll(interval=1)To run this continuously (not just 3 cycles), replace the for loop with while True. Interrupt the process with Ctrl+C to stop.
Step 4: Enrich Matches with Team Details
When a new match appears, use vlrdevapi.team(id) to fetch each team's full info and roster.
import vlrdevapi
def show_team_details(match):
"""Fetch and display detailed team rosters."""
for team in [match.team1, match.team2]:
if not team:
continue
try:
obj = vlrdevapi.team(team.id)
info = obj.info()
roster = obj.roster()
print(f"\n {info.name} (ID: {team.id})")
for p in roster.players:
roles = ", ".join(p.roles)
print(f" {p.ign} — {roles}")
except Exception as e:
print(f" Could not fetch team {team.id}: {e}")
page = vlrdevapi.matches.live()
if page.matches:
show_team_details(page.matches[0])
else:
print("No live matches to inspect right now.")Step 5: Track Completed Matches
Use vlrdevapi.matches.completed() to fetch finished matches and see final scores.
import vlrdevapi
def show_completed():
"""Fetch and display recently completed match results."""
try:
results = vlrdevapi.matches.completed(page=1)
except Exception as e:
print(f"Error: {e}")
return
if not results.matches:
print("No completed matches found.")
return
for m in results.matches[:5]:
t1, t2 = m.team1, m.team2
if t1 and t2:
winner = t1 if t1.is_winner else t2
print(f" {t1.name} {t1.score} - {t2.score} {t2.name}")
print(f" Winner: {winner.name}")
show_completed()Completed matches expose these additional fields on each team:
score— number of maps wonis_winner— whether the team won the match
Step 6: Putting It All Together
This final script combines everything into a standalone snapshot tool:
import vlrdevapi
def format_match(m):
t1 = m.team1.name if m.team1 else "TBD"
t2 = m.team2.name if m.team2 else "TBD"
return f"{t1} vs {t2} | {m.event} | {m.stage}"
def show_team_details(match):
for team in [match.team1, match.team2]:
if not team:
continue
try:
obj = vlrdevapi.team(team.id)
info = obj.info()
roster = obj.roster()
print(f"\n {info.name}")
for p in roster.players:
roles = ", ".join(p.roles)
print(f" {p.ign} — {roles}")
except Exception as e:
print(f" Could not fetch team {team.id}: {e}")
print("=== CURRENT LIVE MATCHES ===\n")
try:
page = vlrdevapi.matches.live()
if page.matches:
for m in page.matches:
print(format_match(m))
print(f"\n--- Team details for first match ---")
show_team_details(page.matches[0])
else:
print("No live matches right now.")
except Exception as e:
print(f"Error fetching matches: {e}")Save this as monitor.py and run it directly: python monitor.py.
Next Steps
- Check the API Reference for all available endpoints
- Learn about pagination for browsing large match lists
- Explore error handling patterns for production use
- Read about the async client for non-blocking monitoring
Ready to build with VLRdevAPI?
Install the Python SDK and start fetching Valorant esports data in minutes. No API key required.