Roanuz CricketAPI v5 — Complete API Reference
Compiled: 2026-03-27 Source: https://www.cricketapi.com/v5/docs/ + Hannibal integration code Support: support@sports.roanuz.com | Sales: +91 90030 21362
Table of Contents
- Architecture Overview
- Authentication
- Data Model & Resource Keys
- Match Endpoints
- Ball-by-Ball & Live Data
- WebSocket / Real-Time Streaming
- Scorecard & Commentary
- Overs Summary
- Tournament Endpoints
- Association & Reference Data
- Odds Endpoints
- Statistics Endpoints
- Visualization Endpoints
- Fantasy Endpoints
- News & Insights
- Refresh Intervals
- Caching Best Practices
- Error Handling
- Pricing & Rate Limits
- Coverage
- Hannibal Integration Status
1. Architecture Overview
Delivery Methods
- HTTP REST — Standard pull-based API (primary)
- Socket.IO WebSocket — Real-time push for live matches
- WebHook — Push notifications to your endpoint (available for match updates, fantasy points)
- Firebase — Google Firebase integration (available for match updates, fantasy points)
Base URLs
| Purpose | URL |
|---|---|
| REST API | https://api.sports.roanuz.com |
| WebSocket | http://socket.sports.roanuz.com/cricket (HTTP, NOT HTTPS) |
| WebSocket Path | /v5/websocket |
| Console | https://console.roanuz.com |
URL Pattern
All REST endpoints follow: GET /v5/cricket/{project_key}/{endpoint}/
Exception: Auth is POST /v5/core/{project_key}/auth/
Exception: Country flags use GET /v5/cricket/proj_key/{project_key}/country/{code}/flags/
2. Authentication
Create Token
POST https://api.sports.roanuz.com/v5/core/{project_key}/auth/
Request:
{ "api_key": "YOUR_API_KEY" }
Response:
{
"status_code": 200,
"data": {
"token": "eyJhbG...",
"expires": "1711234567.89"
}
}
Token Usage
- Pass via
rs-tokenheader on all subsequent requests expiresis a Unix timestamp (float) indicating token expiry- Tokens valid for ~24 hours
- One token supports multiple concurrent requests
- Refresh before expiry (Hannibal refreshes when < 5 minutes remain)
- On
A-401-0error, immediately refresh the token
Hannibal Implementation
RoanuzDataAdapter.refreshToken()— POST to auth endpointRoanuzDataAdapter.ensureValidToken()— Auto-refresh if < 5min remainingRoanuzDataAdapter.makeRequest()— Addsrs-tokenheaderRoanuzWebSocketManager.updateToken()— Updates WS manager + re-subscribes
3. Data Model & Resource Keys
Hierarchy
Country
-> Association (ICC, BCCI, ECB, etc.)
-> Competition (recurring series, e.g., "ICC Cricket World Cup")
-> Tournament (specific edition, e.g., "ICC CWC 2019")
-> Match (individual game)
-> Teams -> Players
Players are independent resources — accessible directly without traversing the hierarchy.
Resource Key Types
| Type | Format | Examples |
|---|---|---|
| Country Code | ISO-like string | in, au, eng, wi |
| Association Key | string | icc, bcci, ecb, c.board.bcci.b13f0 |
| Tournament Key | string | ipl_2026, wc_2026_odi, ausind_2020 |
| Match Key | string | ipl_2026_t20_01, rsaeng_2020_t20_03 |
| Team Key | string | csk, mi, ind, aus |
| Player Key (long) | c__player__{first}_{last}__{hash} | c__player__virat_kohli__abc12 |
| Player Key (short) | {initial}_{surname} | p_salt, s_samson, shi_dube |
Innings Identifiers
Format: {team}_{innings_number} — e.g., a_1 = team A innings 1, b_2 = team B innings 2
Over Key Format
Format: {innings}_{over_number} — e.g., b_1_11 = team B, innings 1, over 11
4. Match Endpoints
4.1 Featured Matches
GET /v5/cricket/{project_key}/featured-matches-2/
Manually curated list of high-demand matches. Includes live scores, venues, start dates, match status, team scores, Player of the Match, and more.
Response:
{
"status_code": 200,
"data": {
"matches": {
"<match_key>": {
"key": "ipl_2026_t20_01",
"name": "CSK vs MI, 1st Match",
"status": "started",
"format": "t20i",
"start_at": 1711234567,
"teams": {
"a": { "key": "csk", "name": "Chennai Super Kings", "short_name": "CSK", "logo_url": "..." },
"b": { "key": "mi", "name": "Mumbai Indians", "short_name": "MI", "logo_url": "..." }
},
"tournament": { "key": "ipl_2026", "name": "IPL 2026", "short_name": "IPL 2026" },
"venue": { "key": "chepauk", "name": "MA Chidambaram Stadium", "city": "Chennai", "country": "India" },
"score": {
"a": { "runs": 185, "wickets": 4, "overs": 20 },
"b": { "runs": 120, "wickets": 3, "overs": 15.2 }
},
"result": "CSK won by 65 runs",
"winner": { "key": "csk", "name": "Chennai Super Kings" }
}
},
"cache": { "key": "featured-matches-2", "expires": 300, "max_age": 60, "etag": "abc123" },
"schema": { "major": 5, "minor": 2 }
}
}
Key fields: key, name, status (not_started/started/completed/cancelled), format (t20i/odi/test/t10), start_at (Unix timestamp), teams.a/teams.b, tournament, venue, score, result, winner.
4.2 Fixtures
GET /v5/cricket/{project_key}/fixtures/
GET /v5/cricket/{project_key}/fixtures/mg/MG101/date/{YYYY-MM}/page/{page}/
All matches (past, present, future). Default endpoint (MG100) vs paginated by month (MG101).
Response:
{
"data": {
"months": {
"2026-03": {
"matches": {
"<match_key>": { /* same structure as featured matches */ }
}
}
},
"cache": { "key": "fixtures", "expires": 10800, "max_age": 3600 }
}
}
Two response shapes: data.months (grouped by month) or data.matches (flat list).
4.3 Match Details
GET /v5/cricket/{project_key}/match/{match_key}/
Delivery: HTTP REST, WebHook, WebSocket, Firebase Refresh: Varies by match time (5s for MG100 live)
Returns comprehensive match data including real-time scorecard, lineups, toss, live play state, related balls, innings, and result.
Response:
{
"data": {
"key": "ipl_2026_t20_01",
"name": "CSK vs MI, 1st Match",
"status": "started",
"format": "t20i",
"start_at": 1711234567,
"teams": {
"a": { "key": "csk", "name": "...", "short_name": "CSK", "players": { ... } },
"b": { ... }
},
"tournament": { "key": "ipl_2026", "name": "IPL 2026" },
"venue": { "key": "chepauk", "name": "MA Chidambaram Stadium" },
"toss": {
"winner": { "key": "csk", "name": "Chennai Super Kings" },
"decision": "bat"
},
"play": {
"live": {
"runs": 156, "wickets": 3, "overs": [14, 6],
"target": null, "batting_team": "a"
},
"related_balls": {
"529536": { /* ball object */ },
"529792": { /* ball object */ }
},
"first_batting": "a",
"target": { "runs": 186 }
},
"innings": {
"a_1": { "runs": 185, "wickets": 4, "overs": 20, "batting": [...], "bowling": [...] },
"b_1": { ... }
},
"score": {
"a": { "runs": 185, "wickets": 4, "overs": 20 },
"b": { "runs": 120, "wickets": 3, "overs": 15.2 }
},
"result": "CSK won by 65 runs",
"winner": { "key": "csk", "name": "Chennai Super Kings" }
}
}
Key fields:
| Field | Type | Description |
|---|---|---|
status | string | not_started, started, completed, cancelled |
teams.a / teams.b | Object | Team data with players |
toss.winner | Object/string | Varies: {key, name}, 'a'/'b', or team key |
toss.decision | string | bat or bowl |
play.live | Object | Current live score state |
play.related_balls | Object | Recent ball events (numeric keys) |
play.first_batting | string | "a" or "b" |
play.target | Object | { runs: number } target if chasing |
innings | Object | Keyed as a_1, b_1, a_2, b_2 |
score.a / score.b | Object | { runs, wickets, overs } |
5. Ball-by-Ball & Live Data
5.1 Ball-by-Ball API
GET /v5/cricket/{project_key}/match/{match_key}/ball-by-ball/
GET /v5/cricket/{project_key}/match/{match_key}/ball-by-ball/FIRST-OVER/
GET /v5/cricket/{project_key}/match/{match_key}/ball-by-ball/{over_key}/
Refresh: Every 5 seconds (MG100 matches only, current over only) Delivery: HTTP REST, WebHook (Match Updates), WebHook (Match Detail)
Over key format: {innings}_{over_number} — e.g., b_1_11
Ball Object Structure
{
"key": "529536",
"overs": [14, 6],
"innings": "a_1",
"batsman": {
"player_key": "c__player__virat_kohli__abc12",
"name": "Virat Kohli",
"runs": 4,
"is_four": true,
"is_six": false,
"is_dot_ball": false
},
"bowler": {
"player_key": "c__player__jasprit_bumrah__def34",
"name": "Jasprit Bumrah"
},
"runs": 4,
"batsman_runs": 4,
"extras": {
"total": 0,
"wides": 0, "wide": 0,
"no_balls": 0, "no_ball": 0,
"byes": 0, "bye": 0,
"leg_byes": 0, "leg_bye": 0
},
"wicket": null,
"score": { "runs": 156, "wickets": 3, "overs": [14, 6] },
"four": true,
"six": false,
"comment": "FOUR! Short and wide outside off...",
"commentary": "FOUR! Short and wide outside off...",
"timestamp": 1711234567
}
Ball Fields
| Field | Type | Description |
|---|---|---|
key | string | Unique ball identifier |
overs | number[] | [over_number, ball_number] |
innings | string | a_1, b_1, a_2, b_2 |
batsman.player_key | string | Roanuz player key |
batsman.name | string | Batsman name |
batsman.runs | number | Runs scored on this ball |
batsman.is_four | boolean | Boundary four |
batsman.is_six | boolean | Boundary six |
batsman.is_dot_ball | boolean | Dot ball |
bowler.player_key | string | Bowler key |
bowler.name | string | Bowler name |
runs | number | Total runs (including extras) |
batsman_runs | number | Runs off bat only |
extras | Object | Extras breakdown (both singular/plural forms) |
wicket | Object/null | Wicket details if fell |
score | Object | Team score after this ball |
four / six | boolean | Boundary indicators |
comment / commentary | string | Ball commentary text |
timestamp | number | Unix timestamp |
Wicket Object
{
"type": "caught",
"how_out": "caught",
"player": {
"player_key": "c__player__...",
"key": "...",
"name": "Player Name"
}
}
Dismissal types: bowled, caught, lbw, run_out, stumped, hit_wicket, retired_hurt, etc.
5.2 Related Balls (from Match Endpoint)
For live matches, play.related_balls from the match endpoint is preferred over the dedicated ball-by-ball API because:
- One API call instead of two
- Includes current score context
- Same format as WebSocket updates
- Object with numeric keys -> ball objects
6. WebSocket / Real-Time Streaming
Protocol
- Socket.IO (NOT raw WebSocket)
- URL:
http://socket.sports.roanuz.com/cricket - Path:
/v5/websocket - Max connections: 20 per project
- Data format: Gzipped JSON (decompress with
gunzipSync) - Duplicate subscriptions: Do NOT charge twice or send duplicate updates
Connection Flow
Step 1: Subscribe via HTTP POST
POST https://api.sports.roanuz.com/v5/cricket/{project_key}/match/{match_key}/subscribe/
Headers: rs-token: <token>, Content-Type: application/json
Body: { "method": "web_socket" }
Step 2: Connect via Socket.IO
const socket = io('http://socket.sports.roanuz.com/cricket', {
path: '/v5/websocket',
transports: ['websocket'],
});
Step 3: Join Match Room
socket.on('connect', () => {
socket.emit('connect_to_match', {
token: accessToken,
match_key: matchKey,
});
});
Step 4: Handle Events
| Event | Description |
|---|---|
on_match_joined | Server confirms subscription to match |
on_match_update | Real-time match data update (gzipped) |
on_error | Error (e.g., match not subscribed) |
Step 5: Decompress & Parse Updates
socket.on('on_match_update', (data) => {
let parsed;
if (Buffer.isBuffer(data)) {
const decompressed = gunzipSync(data);
parsed = JSON.parse(decompressed.toString());
} else {
parsed = typeof data === 'string' ? JSON.parse(data) : data;
}
});
Step 6: Unsubscribe
POST /v5/cricket/{project_key}/match/{match_key}/unsubscribe/
Headers: rs-token: <token>, Content-Type: application/json
Match Update Data Structure
Same as Match Details endpoint:
play.live— Current live score stateplay.related_balls— Recent ball eventsplay.first_batting— Which team batted firstplay.target— Target scoreteams.a/teams.b— Team infoinnings— Innings datatoss— Toss informationstatus— Match status
Hannibal Implementation (RoanuzWebSocketManager.ts)
- Single Socket.IO connection, multiplexed match subscriptions
- Exponential backoff reconnection: 1s -> 60s, max 10 attempts
- 30s heartbeat, 2min stale threshold
- Ball ID deduplication (tracks
processedBallIdsper match) - Token refresh triggers re-subscription of all active matches
- Gzip decompression for all
on_match_updatedata
Coverage Limitation
WebSocket is only available for MG100 matches (high-demand/featured). MG101 matches get 15-minute REST polling only.
7. Scorecard & Commentary
7.1 Scorecard
GET /v5/cricket/{project_key}/match/{match_key}/scorecard/
Full scorecard with innings-level batting and bowling performances.
Hannibal caching:
- Live: 30s TTL
- Completed: 1hr TTL
7.2 Commentary
GET /v5/cricket/{project_key}/match/{match_key}/commentary/
Ball-by-ball text commentary entries. Also available inline via ball.comment / ball.commentary in ball-by-ball data.
Hannibal: Default limit of 50 entries.
8. Overs Summary
GET /v5/cricket/{project_key}/match/{match_key}/over-summary/
GET /v5/cricket/{project_key}/match/{match_key}/over-summary/{page_key}/
Refresh: Every 5 seconds (MG100 live matches)
Page key format: {innings}_{over_number} — e.g., b_1_11
Returns:
- Runs scored per over
- Wickets in each over
- Current batsmen on crease
- Current bowler statistics
- Match score at end of each over
Hannibal status: NOT currently used. Useful for over-by-over visualization and momentum tracking.
9. Tournament Endpoints
9.1 Featured Tournaments
GET /v5/cricket/{project_key}/featured-tournaments/
Curated high-demand tournaments.
Response:
{
"data": {
"tournaments": {
"<tournament_key>": {
"key": "ipl_2026",
"name": "Indian Premier League 2026",
"short_name": "IPL 2026",
"association": { "key": "bcci", "name": "BCCI" },
"format": "t20i",
"status": "in_progress",
"start_date": 1711234567,
"end_date": 1713826567,
"teams_count": 10,
"matches_count": 74
}
}
}
}
9.2 Tournament Details
GET /v5/cricket/{project_key}/tournament/{tournament_key}/
Name, host countries, start date, competition details, participating teams, match keys.
9.3 Tournament Fixtures
GET /v5/cricket/{project_key}/tournament/{tournament_key}/fixtures/
All matches for a specific tournament.
9.4 Tournament Featured Matches
GET /v5/cricket/{project_key}/tournament/{tournament_key}/featured-matches/
High-demand matches within a tournament.
9.5 Points Table
GET /v5/cricket/{project_key}/tournament/{tournament_key}/points/
Response:
{
"data": {
"groups": {
"default": {
"teams": [
{
"team": { "key": "csk", "name": "Chennai Super Kings" },
"played": 10, "won": 7, "lost": 3, "no_result": 0,
"points": 14, "nrr": 0.845
}
]
}
}
}
}
9.6 Team Squad
GET /v5/cricket/{project_key}/tournament/{tournament_key}/team/{team_key}/
Response:
{
"data": {
"team": {
"key": "csk",
"name": "Chennai Super Kings",
"players": {
"<player_key>": {
"player_key": "c__player__ms_dhoni__abc12",
"name": "MS Dhoni",
"role": "wicket_keeper_batsman",
"batting_style": "right_handed",
"bowling_style": "right_arm_medium"
}
}
}
}
}
Refresh: Every 3 hours (live/upcoming within 5 days), once daily at 8 PM GMT (others).
Hannibal status: NOT currently used. High value for points tables, team squads, tournament navigation.
10. Association & Reference Data
Associations List
GET /v5/cricket/{project_key}/association/list/
GET /v5/cricket/{project_key}/association/list/{page_key}/
Returns: key, name, country, parent, type (international/domestic).
Association Featured Tournaments
GET /v5/cricket/{project_key}/association/{association_key}/featured-tournaments/
Refresh: Every 3 hours.
Associations by Country
GET /v5/cricket/{project_key}/associations-by-country/{country_code}/
Country List
GET /v5/cricket/{project_key}/country/list/
GET /v5/cricket/{project_key}/country/list/{page_key}/
Refresh: 24 hours.
Country Flag
GET /v5/cricket/proj_key/{project_key}/country/{country_code}/flags/
NOTE: URL includes literal proj_key/ — differs from all other endpoints.
Refresh: Never (static).
Venue List
GET /v5/cricket/{project_key}/venue/list/{page_key}/
Refresh: 24 hours. Requires pagination.
11. Odds Endpoints
11.1 Live Match Odds
GET /v5/cricket/{project_key}/match/{match_key}/odds/live/
or (alternate URL from docs):
GET /v5/cricket/{project_key}/match/{match_key}/live-match-odds/
Refresh: Every 5 seconds (MG100 live matches) Data: AI-powered live match odds in Decimal and Fractions, winning probability percentages.
11.2 Pre-Match Odds
GET /v5/cricket/{project_key}/match/{match_key}/odds/pre-match/
or:
GET /v5/cricket/{project_key}/match/{match_key}/pre-match-odds/
Refresh: Once daily (before match day), every 3 hours (match day) Data: AI-powered pre-match odds in Decimal and Fractions, winning probability percentages.
IMPORTANT: These are aggregated AI-powered odds, NOT exchange odds. They should NOT be used for bet placement or settlement. Hannibal uses Bifrost/Betfair for actual betting. Roanuz odds are useful for comparison/reference only.
12. Statistics Endpoints
12.1 Tournament Stats
GET /v5/cricket/{project_key}/tournament/{tournament_key}/stats/
Refresh: Every 10 minutes (live match), one final sync post-match.
Returns:
- Best batting performances
- Best bowling performances
- Top fielders
- Highest/lowest team totals
- Largest/smallest margins of victory
- Most sixes
12.2 Tournament Player Stats
GET /v5/cricket/{project_key}/tournament/{tournament_key}/player/{player_key}/stats/
Refresh: Every 10 minutes (live match), sync post-match.
Returns per-player stats within a tournament:
- Batting: runs, average, strike rate, 50s, 100s, highest score, matches played
- Bowling: wickets, average, economy, best figures
- Fielding: catches, stumpings, run-outs
Hannibal status: NOT currently used. High value for AI analysis, player prop markets, tournament leaderboards.
13. Visualization Endpoints
13.1 Worm Chart
GET /v5/cricket/{project_key}/match/{match_key}/worm/
Cumulative run progression — "worm" chart comparing innings.
{
"innings": {
"a_1": [
{ "over": 1, "runs": 8 },
{ "over": 2, "runs": 15 }
],
"b_1": [...]
}
}
13.2 Manhattan Chart
GET /v5/cricket/{project_key}/match/{match_key}/manhattan/
Runs per over (bar chart / "skyline").
{
"innings": {
"a_1": [
{ "over": 1, "runs": 8, "wickets": 0 },
{ "over": 2, "runs": 12, "wickets": 1 }
]
}
}
13.3 Run Rate Chart
GET /v5/cricket/{project_key}/match/{match_key}/run-rate/
Current vs required run rate.
{
"current_run_rate": 8.5,
"required_run_rate": 10.2,
"progression": [
{ "over": 1, "current_rr": 8.0, "required_rr": 9.3 }
]
}
13.4 Wagon Zone (Batter)
GET /v5/cricket/{project_key}/match/{match_key}/innings/{innings_key}/wagon-zone/
13.5 Wagon Zone (Bowler)
GET /v5/cricket/{project_key}/match/{match_key}/innings/{innings_key}/wagon-zone/bowlers/
Shot/run distribution by ground zone.
{
"zones": {
"fine_leg": { "runs": 24, "shots": 8 },
"square_leg": { "runs": 18, "shots": 6 },
"mid_wicket": { "runs": 32, "shots": 10 },
"long_on": { "runs": 28, "shots": 7 },
"long_off": { "runs": 15, "shots": 5 },
"cover": { "runs": 22, "shots": 8 },
"point": { "runs": 12, "shots": 4 },
"third_man": { "runs": 10, "shots": 3 }
}
}
Note: Wagon Zone is specifically mentioned as IPL-related in docs navigation.
Hannibal status: NOT currently used. High value for live match UI charts, AI momentum analysis, player weakness/strength analysis.
14. Fantasy Endpoints
14.1 Fantasy Match Credits
GET /v5/cricket/{project_key}/fantasy-match-credits/{match_key}/
Player credit values for fantasy team building. AI algorithm considers overall + recent performance.
Refresh: Every 3 hours (today/tomorrow), daily at 4 PM GMT (2-5 days out).
14.2 Fantasy Match Points
GET /v5/cricket/{project_key}/fantasy-match-points/{match_key}/
Real-time fantasy points using Roanuz AI Intelligent Scoring. Customizable scoring supported.
Delivery: HTTP REST, Webhook, WebSocket, Firebase Refresh: Every 5 seconds (MG100), every 15 minutes (MG101).
Hannibal status: NOT currently used. Could inform player value analysis.
15. News & Insights
15.1 News Aggregator
GET /v5/cricket/{project_key}/news-aggregation/
Aggregated cricket news from trusted sources.
15.2 Match Insights
GET /v5/cricket/{project_key}/match/{match_key}/insights/
AI-ready match insights including:
- Last 5 head-to-head results between the two teams in the current tournament
- Scores, winners, key player details
- Team form (recent results)
- Squad availability
- Recent top performers
- Pitch conditions
- Competition data only (no external sources)
Refresh: Varies by match time.
Hannibal status: NOT currently used. HIGH VALUE — provides exactly the data our cricketAnalysisService manually constructs by fetching multiple endpoints.
16. Refresh Intervals
Authentication
Refresh every 24 hours, or instantly on A-401-0 error.
Static Endpoints
| Endpoint | Refresh |
|---|---|
| Associations, Country, Venue Lists | 24 hours |
| Country Flags | Never (static) |
| Featured Tournaments | 3 hours |
Tournament Endpoints
| Condition | Refresh |
|---|---|
| Live or starting within 5 days | Every 3 hours |
| All other tournaments | Once daily at 8 PM GMT |
Match Endpoints
| Condition | Refresh |
|---|---|
| Live Match (MG100) | Every 5 seconds (or via Push API) |
| Live Match (MG101) | Every 15 minutes (or via Push API) |
| Match Day (today's matches) | Every 1 hour |
| Matches within 1 day | Every 3 hours |
| Matches in 2-5 days | Daily at 4 PM GMT |
Ball-by-Ball & Overs Summary
MG100 matches only. Live: every 5 seconds (current over only).
Match Odds
| Endpoint | Condition | Refresh |
|---|---|---|
| Live Match Odds | MG100 live | Every 5 seconds |
| Pre-Match Odds | Before match day | Once daily |
| Pre-Match Odds | Match day | Every 3 hours |
Tournament Stats
| Condition | Refresh |
|---|---|
| Live match | Every 10 minutes |
| Post-match | One final sync |
Fantasy
| Endpoint | Condition | Refresh |
|---|---|---|
| Fantasy Points | MG100 | Every 5 seconds |
| Fantasy Points | MG101 | Every 15 minutes |
| Fantasy Credits | Today/tomorrow | Every 3 hours |
| Fantasy Credits | 2-5 days | Daily at 4 PM GMT |
MG100 vs MG101
- MG100 = High-demand/featured matches — full ball-by-ball, 5s refresh, WebSocket eligible
- MG101 = Lower-tier matches — 15-minute refresh, no ball-by-ball, no WebSocket
Post-Match Validation
After match conclusion, one additional validation run finalizes: final scores, overs, player stats, points tables, and fantasy points.
17. Caching Best Practices
Cache Object (in every response)
Every API response includes:
{
"cache": {
"key": "recommended-cache-key",
"expires": 300,
"max_age": 60,
"etag": "abc123"
}
}
| Field | Description |
|---|---|
cache.key | Recommended cache key for your storage |
cache.expires | Maximum seconds to cache (hard limit) |
cache.max_age | Seconds before checking for updates (always < expires) |
cache.etag | ETag for HTTP conditional requests |
ETag Caching
- Store the
etagfrom response - On next request, send
If-None-Match: <etag>header - If unchanged: server returns
304 Not Modified(no body) — bandwidth savings - If changed: server returns
200with new data and new etag
Hannibal Caching vs Roanuz Recommendations
| Data | Hannibal TTL | Roanuz Recommendation |
|---|---|---|
| Fixtures | 5min | ~3 hours |
| Match state (live) | 1min | Seconds |
| Match state (completed) | 1hr | Hours/days |
| Scorecard (live) | 30s | Seconds |
| Scorecard (completed) | 1hr | Hours/days |
| Ball-by-ball | 10s | 5s |
| Commentary | 30s | ~5s |
| Venue stats | 24hr | N/A (computed) |
Note: Hannibal caches slightly longer than recommended for live data because WebSocket provides real-time updates. REST is fallback/initial load.
18. Error Handling
Error Response Format
{
"status_code": 400,
"error": {
"msg": "Human-readable error message",
"code": "ERROR_CODE"
}
}
Error Codes
| Code | HTTP | Message | Action |
|---|---|---|---|
A-400-0 | 400 | Invalid input to process | Verify inputs (match keys, etc.) |
A-400-2 | 400 | Invalid Project Key provided | Check project key in console |
A-400-3 | 400 | Invalid Page Key provided | Use page_key from current response |
A-400-4 | 400 | Invalid API Key provided | Check API key in request body |
A-401-0 | 401 | Invalid access token to process | Token expired — refresh and retry |
A-402-0 | 402 | Project is inactive | Renew Roanuz subscription |
A-403-0 | 403 | Access limited to specific user groups | Upgrade plan or check permissions |
A-404-0 | 404 | Resource not found | Resource doesn't exist |
C-400-1 | 400 | Invalid country code provided | Check country code format |
P-400-1 | 400 | Subscription not configured | Configure delivery method |
P-400-2 | 400 | Invalid push delivery method | Use valid delivery method |
P-400-3 | 400 | Delivery method unsupported | Method not available |
P-400-4 | 400 | Resource already subscribed | Already subscribed (not an error — just skip) |
P-403-1 | 403 | Subscription disabled on project | Enable push services on account |
P-403-2 | 403 | Subscription not authorized | Push unavailable for this resource |
UN-500-0 | 500 | Unknown error | Retry after a few seconds |
Best Practices
- On
A-401-0: Immediately refresh token and retry - On
UN-500-0: Retry with exponential backoff - On
P-400-4: Safe to ignore — duplicate subscription is harmless - On
A-402-0/A-403-0: Alert ops — subscription/plan issue
19. Pricing & Rate Limits
Plans
| Feature | Essential | Business | Business+ | Enterprise |
|---|---|---|---|---|
| Price (annual/mo) | ~15,902/mo | ~27,999/mo | ~47,999/mo | Custom |
| Matches/month | 100 | 200 | Unlimited | Custom |
| API requests/month | 400,000 | 800,000 | 1,600,000 | Custom |
| APIs available | 14 | 21 | 25+ | All |
| Active tokens | 100 | 300 | 500 | Custom |
| Concurrent req/token | 32 | 64 | 128 | Custom |
| Historic data | None | 1 month | 3 months | Custom |
| Cricket Widget | No | No | Yes | Yes |
| News Aggregator | No | No | Yes | Yes |
| Data push (AWS) | No | No | No | Yes |
All prices in INR. Single app per subscription (all tiers).
Rate Limits (derived from plan)
- Essential: 400K req/month, 32 concurrent per token, 100 tokens
- Business: 800K req/month, 64 concurrent per token, 300 tokens
- Business+: 1.6M req/month, 128 concurrent per token, 500 tokens
WebSocket Limit
- 20 connections per project (across all plans)
- Duplicate subscriptions to same match do NOT consume an additional slot
20. Coverage
Match Groups
- MG100 — High-demand/featured matches: full ball-by-ball (5s refresh), WebSocket, live odds, fantasy points (5s)
- MG101 — Lower-tier matches: 15-minute refresh, no ball-by-ball, no WebSocket, fantasy (15min)
Known Coverage Areas
Based on the API's tournament/association structure:
- International: ICC events (World Cups, Champions Trophy, T20 World Cups)
- Franchise T20: IPL, BBL, CPL, PSL, SA20, The Hundred, MLC, ILT20
- Bilateral: Test series, ODI series, T20I series between nations
- Domestic: Coverage varies — check featured matches/tournaments endpoints
What Determines MG100 vs MG101
Not fully documented publicly. Appears to be based on:
- Match demand/popularity
- League tier
- Roanuz editorial curation ("manually curated list of matches expected to create high demand")
Checking Coverage
Use GET /featured-matches-2/ to see which matches are currently MG100 (featured).
Use GET /fixtures/ to see all available matches.
21. Hannibal Integration Status
Currently Used
| Roanuz Endpoint | Hannibal Code | Purpose |
|---|---|---|
POST /v5/core/{key}/auth/ | RoanuzDataAdapter.refreshToken() | Token management |
GET /featured-matches-2/ | RoanuzDataAdapter.getMatches() | Live/curated match list |
GET /fixtures/ | RoanuzDataAdapter.getMatches() | Scheduled/upcoming matches |
GET /match/{id}/ | getMatchState(), getRelatedBalls(), getVenueStatistics() | Match details, live state, related balls |
GET /match/{id}/ball-by-ball/ | getBallByBall() | Ball-by-ball data (REST fallback) |
GET /match/{id}/commentary/ | getCommentary() | Commentary entries |
GET /match/{id}/scorecard/ | getScorecard() | Full scorecard |
| WebSocket (Socket.IO) | RoanuzWebSocketManager | Real-time match updates |
Not Used Yet (Available & Valuable)
| Endpoint | Value | Potential Use |
|---|---|---|
| Match Insights | CRITICAL | Pre-built H2H, form, pitch data — replaces manual multi-fetch in cricketAnalysisService |
| Tournament Points Table | HIGH | IPL standings display |
| Tournament Player Stats | HIGH | Player form for AI, player prop markets |
| Tournament Stats | HIGH | Orange/Purple Cap, leaderboards |
| Team Squad | HIGH | Player lists for AI analysis |
| Worm/Manhattan/Run Rate | HIGH | Live match UI charts |
| Wagon Zone | MEDIUM | Batting zone analysis for AI commentary |
| Overs Summary | MEDIUM | Over-by-over run rate visualization |
| Live/Pre-Match Odds | LOW | Cross-reference (NOT for bet placement) |
| News Aggregator | LOW | Cricket news feed |
| Fantasy Credits/Points | LOW | Player value analysis |
| Venue List | LOW | Venue database improvement |
Key Integration Files
backend/src/
├── config/index.ts — ROANUZ_* env vars
├── exchanges/adapters/roanuz/
│ ├── index.ts — Module exports
│ ├── RoanuzDataAdapter.ts — IDataProvider (REST)
│ └── RoanuzWebSocketManager.ts — Socket.IO real-time
├── services/cricket/
│ ├── ballByBallService.ts — AI commentary on balls
│ ├── cricketAnalysisService.ts — Match analysis
│ ├── cricketIdResolver.ts — Betfair<->Roanuz ID mapping
│ ├── tossAnalysisService.ts — Toss analysis
│ └── sessionBettingService.ts — Session betting analysis
├── services/clientWs.ts — WebSocket relay to frontend
└── routes/cricket.ts — Cricket API routes
Environment Variables
ROANUZ_ENABLED=true
ROANUZ_PROJECT_KEY=<project_key>
ROANUZ_API_KEY=<api_key>
ROANUZ_BASE_URL=https://api.sports.roanuz.com
ROANUZ_WS_URL=wss://api.sports.roanuz.com
ROANUZ_TIMEOUT=10000
ROANUZ_RATE_LIMIT=100