Try Live
Add Docs
Rankings
Pricing
Enterprise
Docs
Install
Install
Docs
Pricing
Enterprise
More...
More...
Try Live
Rankings
Add Docs
HKJC API
https://github.com/alextsang1991-debug/hkjc-api
Admin
A Node.js package for communicating with the Hong Kong Jockey Club GraphQL API, providing access to
...
Tokens:
12,288
Snippets:
52
Trust Score:
2
Update:
2 months ago
Context
Skills
Chat
Benchmark
85.5
Suggestions
Latest
Show doc for...
Code
Info
Show Results
Context Summary (auto-generated)
Raw
Copy
Link
# HKJC API HKJC API is a Node.js/TypeScript package for communicating with the Hong Kong Jockey Club (HKJC) GraphQL API. It provides a clean, typed interface for accessing real-time data for horse racing and football betting, including race meetings, runners, odds, pool investments, match details, and various betting types. The package offers two main API modules: `HorseRacingAPI` for accessing horse racing data including active meetings, race information, runners, odds (WIN, PLA, QIN, QPL, etc.), and pool investments; and `FootballAPI` for retrieving football match data with comprehensive odds types (HAD, HHA, CRS, etc.). Both APIs support simplified usage with automatic client creation or advanced usage with custom GraphQL clients. ## Installation ```bash npm install @gikndue/hkjc-api ``` ## HKJCClient - GraphQL Client The base GraphQL client that connects to the HKJC GraphQL endpoint. Can be used directly for custom queries or passed to API modules for advanced configuration. ```typescript import { HKJCClient } from 'hkjc-api'; // Create a custom client (optional - APIs create their own by default) const client = new HKJCClient(); // Or use a custom endpoint const customClient = new HKJCClient('https://custom-endpoint.example.com/graphql'); // Execute custom GraphQL queries const result = await client.request<MyType>(` query { raceMeetings { id venueCode date } } `); console.log(result); ``` ## HorseRacingAPI - Initialize Horse Racing API The main class for accessing horse racing data. Can be initialized with default settings or a custom client. ```typescript import { HorseRacingAPI, HKJCClient } from 'hkjc-api'; // Simplified setup - client created automatically (Recommended) const horseRacingAPI = new HorseRacingAPI(); // Advanced setup - use custom client const client = new HKJCClient(); const horseRacingAPICustom = new HorseRacingAPI(client); ``` ## HorseRacingAPI.getActiveMeetings() - Get Active Race Meetings Retrieves a list of currently active race meetings with basic information including venue code, date, status, and race summaries. ```typescript import { HorseRacingAPI } from 'hkjc-api'; const horseRacingAPI = new HorseRacingAPI(); const activeMeetings = await horseRacingAPI.getActiveMeetings(); console.log(`Found ${activeMeetings.length} active meetings`); activeMeetings.forEach(meeting => { console.log(`Meeting: ${meeting.venueCode} on ${meeting.date}`); console.log(`Status: ${meeting.status}`); console.log(`Races:`, meeting.races.map(r => `Race ${r.no} at ${r.postTime}`)); }); // Example output: // Found 1 active meetings // Meeting: ST on 2025-01-26 // Status: ACTIVE // Races: [ 'Race 1 at 13:00', 'Race 2 at 13:30', ... ] ``` ## HorseRacingAPI.getAllRaces() - Get All Race Meetings with Full Details Retrieves all race meetings with comprehensive details including runners, jockeys, trainers, and pool information. ```typescript import { HorseRacingAPI } from 'hkjc-api'; const horseRacingAPI = new HorseRacingAPI(); const raceMeetings = await horseRacingAPI.getAllRaces(); raceMeetings.forEach(meeting => { console.log(`\n=== ${meeting.venueCode} - ${meeting.date} ===`); console.log(`Total Races: ${meeting.totalNumberOfRace}`); console.log(`Total Investment: $${meeting.totalInvestment?.toLocaleString()}`); meeting.races.forEach(race => { console.log(`\nRace ${race.no}: ${race.raceName_en}`); console.log(`Distance: ${race.distance}m | Class: ${race.raceClass_en}`); console.log(`Post Time: ${race.postTime}`); console.log(`Track: ${race.raceTrack?.description_en}`); console.log(`Runners: ${race.runners?.length || 0}`); }); }); ``` ## HorseRacingAPI.getRace() - Get Single Race Details Retrieves detailed information for a specific race by race number from the first active meeting. ```typescript import { HorseRacingAPI } from 'hkjc-api'; const horseRacingAPI = new HorseRacingAPI(); // Get race #3 from today's meeting const race = await horseRacingAPI.getRace(3); if (race) { console.log(`Race: ${race.raceName_en}`); console.log(`Distance: ${race.distance}m`); console.log(`Class: ${race.raceClass_en}`); console.log(`Post Time: ${race.postTime}`); console.log(`Track: ${race.raceTrack?.description_en}`); console.log(`Course: ${race.raceCourse?.description_en}`); console.log('\nRunners:'); race.runners?.forEach(runner => { console.log(` ${runner.no}. ${runner.name_en}`); console.log(` Jockey: ${runner.jockey?.name_en}`); console.log(` Trainer: ${runner.trainer?.name_en}`); console.log(` Weight: ${runner.handicapWeight}lb | Draw: ${runner.barrierDrawNumber}`); console.log(` Last 6 runs: ${runner.last6run}`); console.log(` Win Odds: ${runner.winOdds}`); }); } else { console.log('Race not found'); } ``` ## HorseRacingAPI.getRaceWithDateAndVenueCode() - Get Race by Date and Venue Retrieves a specific race using date, venue code, and race number for precise lookups. ```typescript import { HorseRacingAPI } from 'hkjc-api'; const horseRacingAPI = new HorseRacingAPI(); // Get race #5 at Sha Tin on a specific date const race = await horseRacingAPI.getRaceWithDateAndVenueCode( '2025-01-26', // Date 'ST', // Venue code: ST (Sha Tin), HV (Happy Valley) 5 // Race number ); if (race) { console.log(`Race ${race.no}: ${race.raceName_en}`); console.log(`Venue: ${race.raceCourse?.displayCode}`); console.log(`Distance: ${race.distance}m on ${race.raceTrack?.description_en}`); console.log(`Field Size: ${race.wageringFieldSize} runners`); } else { console.log('Race not found for specified date/venue'); } ``` ## HorseRacingAPI.getRaceOdds() - Get Race Odds Retrieves odds information for a specific race with specified odds types. Supports various odds types including WIN, PLA, QIN, QPL, FCT, TCE, TRI, and more. ```typescript import { HorseRacingAPI, OddsType } from 'hkjc-api'; const horseRacingAPI = new HorseRacingAPI(); // Get WIN and PLA odds for race #1 const odds = await horseRacingAPI.getRaceOdds(1, ['WIN', 'PLA']); odds.forEach(pool => { console.log(`\n${pool.oddsType} Pool:`); console.log(`Status: ${pool.status}`); console.log(`Last Update: ${pool.lastUpdateTime}`); pool.oddsNodes?.forEach((node: any) => { console.log(` Horse ${node.combString}: ${node.oddsValue}`); if (node.hotFavourite) console.log(' ★ Hot Favourite'); }); }); // Get exotic odds (Quinella, Forecast, Tierce) const exoticOdds = await horseRacingAPI.getRaceOdds(1, ['QIN', 'FCT', 'TCE']); exoticOdds.forEach(pool => { console.log(`\n${pool.name_en} (${pool.oddsType}):`); console.log(`Min Ticket Cost: $${pool.minTicketCost}`); console.log(`Guarantee: $${pool.guarantee?.toLocaleString()}`); }); ``` ## HorseRacingAPI.getRaceOddsWithDateAndVenueCode() - Get Odds by Date and Venue Retrieves odds for a specific race using date and venue code parameters. ```typescript import { HorseRacingAPI } from 'hkjc-api'; const horseRacingAPI = new HorseRacingAPI(); // Get odds for race #3 at Happy Valley on a specific date const odds = await horseRacingAPI.getRaceOddsWithDateAndVenueCode( '2025-01-22', // Date 'HV', // Venue code (Happy Valley) 3, // Race number ['WIN', 'PLA', 'QIN'] // Odds types ); console.log(`Retrieved odds for ${odds.length} pool types`); odds.forEach(pool => { console.log(`${pool.oddsType}: ${pool.oddsNodes?.length || 0} combinations`); }); ``` ## HorseRacingAPI.getRacePools() - Get Pool Investment Data Retrieves pool investment information showing the total money wagered in each betting pool. ```typescript import { HorseRacingAPI } from 'hkjc-api'; const horseRacingAPI = new HorseRacingAPI(); // Get pool investments for race #1 const pools = await horseRacingAPI.getRacePools(1, ['WIN', 'PLA', 'QIN', 'QPL']); pools.forEach(pool => { console.log(`${pool.oddsType} Pool:`); console.log(` Investment: $${pool.investment?.toLocaleString()}`); console.log(` Status: ${pool.status}`); console.log(` Sell Status: ${pool.sellStatus}`); console.log(` Last Update: ${pool.lastUpdateTime}`); }); // Example output: // WIN Pool: // Investment: $15,234,567 // Status: SELLING // Sell Status: AVAILABLE // Last Update: 2025-01-26T12:45:00Z ``` ## HorseRacingAPI.getRacePoolsWithDateAndVenueCode() - Get Pool Data by Date and Venue Retrieves pool investment data for a specific race at a given date and venue. ```typescript import { HorseRacingAPI } from 'hkjc-api'; const horseRacingAPI = new HorseRacingAPI(); const pools = await horseRacingAPI.getRacePoolsWithDateAndVenueCode( '2025-01-24', 'ST', 1, ['WIN', 'PLA', 'TRI', 'FF'] ); let totalInvestment = 0; pools.forEach(pool => { totalInvestment += pool.investment || 0; console.log(`${pool.oddsType}: $${pool.investment?.toLocaleString()}`); }); console.log(`\nTotal across selected pools: $${totalInvestment.toLocaleString()}`); ``` ## FootballAPI - Initialize Football API The main class for accessing football betting data including matches, odds, and live scores. ```typescript import { FootballAPI, HKJCClient } from 'hkjc-api'; // Simplified setup - client created automatically (Recommended) const footballAPI = new FootballAPI(); // Advanced setup - use custom client const client = new HKJCClient(); const footballAPICustom = new FootballAPI(client); ``` ## FootballAPI.getAllFootballMatches() - Get All Football Matches Retrieves all available football matches with optional filtering by date, tournament, and odds types. ```typescript import { FootballAPI } from 'hkjc-api'; const footballAPI = new FootballAPI(); // Get all available matches const allMatches = await footballAPI.getAllFootballMatches(); console.log(`Total matches available: ${allMatches.length}`); // Get matches with filters const filteredMatches = await footballAPI.getAllFootballMatches({ startDate: '2025-04-30', endDate: '2025-05-07', tournIds: ['50046423'], // Specific tournament IDs oddsTypes: ['HAD', 'HHA', 'CRS'], // Specific odds types featuredMatchesOnly: true, // Only featured matches showAllMatch: false, earlySettlementOnly: false }); filteredMatches.forEach(match => { console.log(`\n${match.homeTeam?.name_en} vs ${match.awayTeam?.name_en}`); console.log(`Tournament: ${match.tournament?.name_en}`); console.log(`Date: ${match.matchDate} | Kickoff: ${match.kickOffTime}`); console.log(`Status: ${match.status}`); // Display running score if match is in play if (match.runningResult) { console.log(`Score: ${match.runningResult.homeScore} - ${match.runningResult.awayScore}`); console.log(`Corners: ${match.runningResult.homeCorner} - ${match.runningResult.awayCorner}`); } // Display available odds pools console.log(`Available pools: ${match.poolInfo?.sellingPools?.join(', ')}`); }); ``` ## FootballAPI.getFootballMatchDetails() - Get Match Details Retrieves comprehensive details for a specific match including all odds types and live information. ```typescript import { FootballAPI } from 'hkjc-api'; const footballAPI = new FootballAPI(); // Get details for a specific match const matchDetails = await footballAPI.getFootballMatchDetails('50047131'); if (matchDetails) { console.log('=== Match Details ==='); console.log(`${matchDetails.homeTeam?.name_en} vs ${matchDetails.awayTeam?.name_en}`); console.log(`Tournament: ${matchDetails.tournament?.name_en}`); console.log(`Match ID: ${matchDetails.id} (Frontend: ${matchDetails.frontEndId})`); console.log(`Date: ${matchDetails.matchDate}`); console.log(`Kickoff: ${matchDetails.kickOffTime}`); console.log(`Status: ${matchDetails.status}`); // Display odds for each pool matchDetails.foPools?.forEach(pool => { console.log(`\n${pool.name_en} (${pool.oddsType}):`); pool.lines?.forEach(line => { if (line.main) { line.combinations?.forEach(combo => { console.log(` ${combo.str}: ${combo.currentOdds}`); }); } }); }); } else { console.log('Match not found'); } // Get match with specific odds types only const matchWithSpecificOdds = await footballAPI.getFootballMatchDetails( '50047131', ['HAD', 'HHA', 'HIL', 'CRS'] ); ``` ## Available Odds Types ### Horse Racing Odds Types ```typescript import { OddsType } from 'hkjc-api'; // Available horse racing odds types const horseOddsTypes: OddsType[] = [ 'WIN', // Win (獨贏) 'PLA', // Place (位置) 'QIN', // Quinella (連贏) 'QPL', // Quinella Place (位置Q) 'CWA', // Composite Win A 'CWB', // Composite Win B 'CWC', // Composite Win C 'IWN', // Investment Win 'FCT', // Forecast (二重彩) 'TCE', // Tierce (三重彩) 'TRI', // Trio (單T) 'FF', // First Four (四連環) 'QTT', // Quartet (四重彩) 'DBL', // Double (孖寶) 'TBL', // Treble (三寶) 'DT', // Double Trio (孖T) 'TT', // Triple Trio (三T) 'SixUP' // Six Up (六環彩) ]; ``` ### Football Odds Types ```typescript import { FootballOddsType } from 'hkjc-api'; // Available football odds types const footballOddsTypes: FootballOddsType[] = [ 'HAD', // Home/Away/Draw (主客和) 'EHA', // Early Home/Away 'FHA', // First Half Home/Away/Draw 'HHA', // Handicap Home/Away (讓球主客) 'HDC', // Handicap (讓球) 'EDC', // Early Handicap 'EHH', // Early Handicap Home/Away 'FHH', // First Half Handicap 'HIL', // Hi/Lo Over/Under (大細) 'EHL', // Early Hi/Lo 'FHL', // First Half Hi/Lo 'CHL', // Corner Hi/Lo 'ECH', // Early Corner Hi/Lo 'FCH', // First Half Corner Hi/Lo 'CHD', // Corner Handicap 'ECD', // Early Corner Handicap 'FHC', // First Half Corner 'CRS', // Correct Score (波膽) 'ECS', // Early Correct Score 'FCS', // First Half Correct Score 'FTS', // First Team to Score 'TTG', // Total Goals 'ETG', // Early Total Goals 'OOE', // Odd/Even 'FGS', // First Goalscorer 'HFT', // Halftime/Fulltime 'MSP', // Multi-Scoring 'NTS', // Anytime Goalscorer 'ENT', // Early Anytime Goalscorer 'AGS', // Anytime Goalscorer 'LGS', // Last Goalscorer 'SGA', // Special Group A 'CHP', // Championship 'TQL' // To Qualify ]; ``` ## Error Handling Both APIs include proper error handling with null returns for missing data and exceptions for API errors. ```typescript import { HorseRacingAPI, FootballAPI } from 'hkjc-api'; const horseRacingAPI = new HorseRacingAPI(); const footballAPI = new FootballAPI(); // Horse Racing error handling try { const race = await horseRacingAPI.getRace(99); // Non-existent race if (race === null) { console.log('Race not found - no racing meeting active or invalid race number'); } } catch (error) { console.error('API error:', error); } // Football error handling try { const match = await footballAPI.getFootballMatchDetails('invalid-id'); if (match === null) { console.log('Match not found'); } } catch (error) { if (error instanceof Error) { console.error('Error fetching match:', error.message); } } // Football matches returns empty array on error const matches = await footballAPI.getAllFootballMatches(); if (matches.length === 0) { console.log('No matches available or API error occurred'); } ``` ## Complete Working Example ```typescript import { HorseRacingAPI, FootballAPI } from 'hkjc-api'; async function main() { // Initialize APIs const horseAPI = new HorseRacingAPI(); const footballAPI = new FootballAPI(); // === Horse Racing === console.log('🏇 HORSE RACING'); const activeMeetings = await horseAPI.getActiveMeetings(); console.log(`Active meetings: ${activeMeetings.length}`); if (activeMeetings.length > 0) { const race = await horseAPI.getRace(1); if (race) { console.log(`First race: ${race.raceName_en}`); console.log(`Runners: ${race.runners?.length}`); // Get top 3 runners with best odds const sortedRunners = [...(race.runners || [])] .filter(r => r.winOdds > 0) .sort((a, b) => a.winOdds - b.winOdds) .slice(0, 3); console.log('Top 3 favorites:'); sortedRunners.forEach(r => { console.log(` ${r.name_en}: ${r.winOdds}`); }); } const odds = await horseAPI.getRaceOdds(1, ['WIN', 'PLA']); console.log(`Odds pools retrieved: ${odds.length}`); } // === Football === console.log('\n⚽ FOOTBALL'); const matches = await footballAPI.getAllFootballMatches({ featuredMatchesOnly: true, oddsTypes: ['HAD', 'HHA'] }); console.log(`Featured matches: ${matches.length}`); if (matches.length > 0) { const match = matches[0]; console.log(`Next match: ${match.homeTeam?.name_en} vs ${match.awayTeam?.name_en}`); // Get HAD odds const hadPool = match.foPools?.find(p => p.oddsType === 'HAD'); if (hadPool) { const mainLine = hadPool.lines?.find(l => l.main); console.log('HAD Odds:'); mainLine?.combinations?.forEach(c => { console.log(` ${c.str}: ${c.currentOdds}`); }); } } } main().catch(console.error); ``` ## Summary The HKJC API package provides a comprehensive TypeScript interface for accessing Hong Kong Jockey Club betting data. The primary use cases include building horse racing applications that need real-time race cards, runner information, and odds tracking; football betting applications requiring match listings, live scores, and odds comparisons; and data analysis tools for tracking pool investments and betting patterns. The APIs are designed for both simple integrations where default settings suffice and advanced use cases requiring custom GraphQL clients. Integration patterns typically involve initializing the API classes once and reusing them throughout the application lifecycle. For horse racing, the workflow involves calling `getActiveMeetings()` to check for live events, then drilling down with `getRace()` or `getAllRaces()` for details, and finally using `getRaceOdds()` and `getRacePools()` for betting data. For football, `getAllFootballMatches()` provides an overview with optional filtering, while `getFootballMatchDetails()` offers deep data for specific matches. Both APIs return typed responses with proper null handling, making them suitable for TypeScript applications requiring type safety and predictable error handling.