IPL 2026 Season Opener: Live Score Coverage & API Demo
Contents

What makes IPL different to cover via an API

Most domestic leagues follow a predictable rhythm: teams play, scores update, and the table moves. IPL has all of that, but the sheer volume of simultaneous engagement means your implementation needs to be tighter.

A few things stand out specifically for IPL data:

Match format. Every game is T20, which means 40 overs maximum, a match that’s over in around three hours, and score changes that come fast. Polling intervals that work fine for a four-day Test will be too slow here.

Scorecard depth. An IPL scoreline isn’t just runs and wickets. Fans expect ball-by-ball progression, strike rates, economy rates, power play splits, and the six-hit count. The API delivers all of it, but only if you’re asking for it correctly with includes.

Two innings in one sitting. Unlike a Test match spread over days, both innings of an IPL game happen live, back-to-back. Your code needs to handle the transition between innings cleanly.

The Sportmonks Cricket API is built for exactly this. It’s a RESTful v2 API returning JSON, with a composable include system that lets you request precisely the data you need without overloading your response.

Step 1: Find the IPL league and season

Before you can pull live match data, you need two things: the IPL league ID and the active season ID. Start by hitting the leagues endpoint:

const API_TOKEN = 'YOUR_API_TOKEN';
const BASE_URL = 'https://cricket.sportmonks.com/api/v2.0';

async function getIPLLeague() {
 const res = await fetch(`${BASE_URL}/leagues?api_token=${API_TOKEN}`);
 const { data } = await res.json();

 const ipl = data.find(league => league.name === 'Indian Premier League');
 console.log(`IPL League ID: ${ipl.id}, Current Season ID: ${ipl.season_id}`);
 return ipl;
}

getIPLLeague();

Note: Your own IPL league ID can also be confirmed in the Sportmonks ID Finder or by browsing the Postman collection. We’ll refer to it as {IPL_LEAGUE_ID} throughout this guide; replace it with your verified IPL league ID.

Once you have the season_id from the league response, you’re ready to pull fixtures.

Step 2: Get the IPL 2026 fixture list

With the season ID in hand, fetch all fixtures for the tournament. The localteam and visitorteam includes the team names and logos alongside match metadata:

async function getIPLFixtures(seasonId) {
 const url = [
   `${BASE_URL}/fixtures`,
   `?api_token=${API_TOKEN}`,
   `&filters=seasonId:${seasonId}`,
   `&include=localteam,visitorteam,venue,stage`,
   `&per_page=50`
 ].join('');

 const res = await fetch(url);
 const { data, meta } = await res.json();

 console.log(`Total fixtures: ${meta.pagination.total}`);

 return data.map(fixture => ({
   id: fixture.id,
   match: `${fixture.localteam.data.name} vs ${fixture.visitorteam.data.name}`,
   stage: fixture.stage?.data?.name,
   venue: fixture.venue?.data?.full_name,
   starting_at: fixture.starting_at,
   status: fixture.status,
 }));
}

The status field is what you’ll use to identify the opener. Before the tournament begins, it’ll be NS (Not Started). As the first match approaches, it transitions from Scheduled to Live, then to Finished. The full list of statuses is in your Statuses and definitions docs.

Step 3: Go live, polling the livescores endpoint

On matchday, switch to the livescores endpoint. This is the core of any real-time cricket integration: it returns all matches currently in progress, and it’s available from 15 minutes before the first ball until 15 minutes after the final wicket falls.

The base request is simple:

async function getLiveScores() {
 const url = `${BASE_URL}/livescores?api_token=${API_TOKEN}`;
 const res = await fetch(url);
 const { data } = await res.json();
 return data;
}

But a raw livescores response only gives you match metadata, IDs, status, toss result, and current scores at the highest level. To build anything useful, you need to add includes.

Step 4: Build the full IPL scorecard request

Here’s where the API earns its keep. The include parameter is how you enrich every livescores or fixtures response. For a complete IPL scorecard, you’ll want this combination:

async function getIPLLiveScorecard() {
 const includes = [
   'runs',       // Score summary: total runs, wickets, overs per inning
   'batting',    // Batting scorecard: runs, balls, 4s, 6s, SR, dismissal
   'bowling',    // Bowling figures: overs, maidens, runs, wickets, economy
   'lineup',     // Playing XI for both teams
   'toss',       // Toss winner and decision (bat/bowl)
   'venue',      // Stadium name and location
   'localteam',  // Home team info
   'visitorteam' // Away team info
 ].join(',');

 const url = `${BASE_URL}/livescores?api_token=${API_TOKEN}&include=${includes}`;
 const res = await fetch(url);
 const { data } = await res.json();

 // Filter to IPL matches only
 return data.filter(match => match.league_id === {IPL_LEAGUE_ID});
}
The response for a live IPL match will look like this (trimmed for clarity):
{
 "id": 59282,
 "league_id": {IPL_LEAGUE_ID},
 "status": "2nd Innings",
 "note": "Mumbai Indians won the toss and elected to bat",
 "localteam_id": 28,
 "visitorteam_id": 31,
 "starting_at": "2026-03-22 14:00:00",
 "runs": [
   { "team_id": 28, "inning": "S1", "score": 187, "wickets": 5, "overs": 20 },
   { "team_id": 31, "inning": "S2", "score": 134, "wickets": 6, "overs": 15.2 }
 ],
 "batting": [
   {
     "player_id": 4401,
     "player_name": "Rohit Sharma",
     "score": 72,
     "ball": 44,
     "four_x": 7,
     "six_x": 3,
     "rate": "163.64",
     "dismissal": "caught"
   }
 ],
 "bowling": [
   {
     "player_id": 5521,
     "player_name": "Jasprit Bumrah",
     "overs": 3,
     "medians": 0,
     "runs": 22,
     "wickets": 2,
     "rate": "7.33"
   }
 ]
}

A few things to note about this structure. The runs array uses the S1 and S2 inning values to differentiate the two T20 innings (S3 and S4 are reserved for Test matches). The batting and bowling arrays contain one object per player per innings; you’ll need to filter by team_id when rendering each team’s scorecard separately.

Step 5: Handle the innings transition

The moment the first innings ends and the second begins is a common breakpoint for live integrations. The status field changes from 1st Innings to Innings Break to 2nd Innings, but crucially, the runs array will already have two objects from the moment the second innings starts, even before any runs are scored.

Here’s a clean helper to always show the correct current batting team:

function getCurrentInnings(match) {
 const inningMap = { '1st Innings': 'S1', '2nd Innings': 'S2' };
 const currentInning = inningMap[match.status];

 if (!currentInning) return null; // Innings break or finished

 const score = match.runs.find(r => r.inning === currentInning);
 const battingTeamId = score?.team_id;

 const battingScorecard = match.batting.filter(
   b => b.team_id === battingTeamId && b.inning === currentInning
 );
 const bowlingScorecard = match.bowling.filter(
   b => b.team_id !== battingTeamId && b.inning === currentInning
 );

 return {
   inning: currentInning,
   score,
   batting: battingScorecard,
   bowling: bowlingScorecard,
 };
}

Step 6: Add ball-by-ball data for deep coverage

If your product needs delivery-level detail, commentary feeds, ball-by-ball trackers, or advanced analytics, include the balls in your fixture request. Note that balls are best fetched per fixture ID rather than via the general livescores endpoint, since it returns a large payload:

async function getBallByBall(fixtureId) {
 const url = [
   `${BASE_URL}/fixtures/${fixtureId}`,
   `?api_token=${API_TOKEN}`,
   `&include=balls,runs,batting,bowling,lineup,manofmatch,tosswon`,
 ].join('');

 const res = await fetch(url);
 const { data } = await res.json();

 // Each ball object contains: over, ball, score, wicket, six, four, commentary
 return data.balls?.data ?? [];
}

Each object in the balls array represents one delivery, including the over number, ball number, runs scored, whether it was a wicket, a four, or a six, and a short commentary string. This is the data layer that powers premium cricket experiences: real-time over-by-over animation, dismissal highlights, and power play breakdowns.

Step 7: Polling strategy for matchday

T20 is fast. An over takes around four minutes, which means score state changes roughly every 25–40 seconds. Here’s a polling setup that balances freshness with rate limit headroom:

const POLLING_INTERVALS = {
 live: 15_000,        // 15 seconds during active innings
 inningsBrBreak: 60_000, // 60 seconds during innings break
 preMatch: 120_000,   // 2 minutes before match starts
 finished: null,      // Stop polling once match ends
};

async function startLivePolling(fixtureId) {
 let interval;

 async function poll() {
   const url = `${BASE_URL}/fixtures/${fixtureId}?api_token=${API_TOKEN}&include=runs,batting,bowling`;
   const res = await fetch(url);
   const { data: match } = await res.json();

   console.log(`Status: ${match.status} | Score: ${match.runs.map(r => `${r.score}/${r.wickets}`).join(' | ')}`);

   // Adjust polling interval based on match state
   const newInterval = POLLING_INTERVALS[match.status] ?? POLLING_INTERVALS.live;

   if (match.status === 'Finished' || match.status === 'Abandoned') {
     clearInterval(interval);
     console.log('Match over. Polling stopped.');
     return;
   }

   if (newInterval !== interval._idleTimeout) {
     clearInterval(interval);
     interval = setInterval(poll, newInterval);
   }
 }

 interval = setInterval(poll, POLLING_INTERVALS.live);
 poll(); // Run immediately on start
}

Keep an eye on your rate limit. The Cricket API has a rate limit tied to your plan; check the X-RateLimit-Remaining header on each response and reduce your polling frequency if you’re approaching the limit ahead of a critical period, such as the final over.

Step 8: Fetch the post-match summary

Once the match ends, the livescores endpoint drops the fixture. Switch to the fixtures endpoint with the same fixture_id to get the full post-match record, including Man of the Match, Man of the Series (if applicable), and the final result:

async function getPostMatchSummary(fixtureId) {
 const url = [
   `${BASE_URL}/fixtures/${fixtureId}`,
   `?api_token=${API_TOKEN}`,
   `&include=runs,batting,bowling,lineup,venue,toss,manofmatch,firstumpire,secondumpire,referee,localteam,visitorteam`,
 ].join('');

 const res = await fetch(url);
 const { data } = await res.json();

 return {
   result: data.note,
   winner_team_id: data.winner_team_id,
   man_of_match: data.manofmatch?.data,
   final_scores: data.runs,
   batting: data.batting,
   bowling: data.bowling,
 };
}

The note field contains a plain-text match result string, something like “Mumbai Indians won by 34 runs”, which you can render directly on your results screen without any additional processing.

What you can build around IPL 2026

The endpoints above cover everything needed for a core live score integration, but the data available opens up more ambitious product surfaces:

Fantasy cricket scoring engines combine the batting and bowling scorecard data with your own points logic. Boundaries, wickets, dot balls, and economy rates are all in the response. Update fantasy points ball-by-ball using the balls include.

Live match centre widgets pull runs, batting, bowling, and balls and render a full match centre: current score, recent overs, fall of wickets, partnership tracker, and projected total.

Historical season archives call GET /fixtures?filters=seasonId:{season_id} for any past IPL season to pull full match records. Cross-reference player IDs with GET /players/{id} to build career stat timelines across multiple IPL seasons.

Team and player form guides use GET /fixtures?filters=teamId:{team_id} to pull a team’s last ten matches and calculate rolling averages for batting totals, powerplay run rates, and death-over economy.

IPL Live Coverage API-asset

Full call sequence (IPL live coverage)

Here’s the complete flow from season discovery to post-match summary:

  1. GET /leagues find the IPL league ID and active season ID
  2. GET /fixtures?filters=seasonId:{season_id} retrieve all IPL 2026 fixtures
  3. GET /livescores?include=runs,batting,bowling,lineup,toss,venue go live on matchday
  4. GET /fixtures/{fixture_id}?include=balls,runs,batting,bowling ball-by-ball during the match
  5. GET /fixtures/{fixture_id}?include=runs,batting,bowling,manofmatch,localteam,visitorteam post-match summary

The switch from livescores to fixture-by-ID is the key transition to understand. Livescores gives you the live feed across all ongoing matches. Fixture-by-ID gives you the depth of all the includes, all the innings data, and all the ball records for a single game.

Ready to power your IPL 2026 coverage?

Start your free trial of the Sportmonks Cricket API and deliver real-time IPL live scores, full scorecards, and ball-by-ball data from the very first ball of the season opener.

FAQs

How do I get the IPL 2026 season ID?
Call the /leagues endpoint and locate the Indian Premier League in the response. The object returned includes the current season_id, which you can then use to fetch all fixtures for IPL 2026.
Which endpoint should I use for live IPL scores?
Use the /livescores endpoint on matchday. Add includes such as runs, batting, bowling, lineup, toss, and venue to build a complete live match centre experience.
How do I get ball-by-ball data for the IPL opener?
Fetch a specific fixture using /fixtures/{fixture_id} and include balls in your request. This returns delivery-level data, such as overs, runs scored, boundaries, wickets, and commentary.
What is the best polling interval for T20 matches?
For live innings, polling every 15 seconds works well for most products. During innings breaks or pre-match phases, you can safely reduce polling frequency to preserve rate limit headroom.

Written by David Jaja

David Jaja is a technical content manager at Sportmonks, where he makes complex football data easier to understand for developers and businesses. With a background in frontend development and technical writing, he helps bridge the gap between technology and sports data. Through clear, insightful content, he ensures Sportmonks' APIs are accessible and easy to use, empowering developers to build standout football applications