hkjc_race_results_core
Hong Kong horse racing results and form guide (core columns)
Download a file
CSV · Excel · Parquet · JSON. Filtered exports.
See pricingQuery with SQL
DBeaver, DuckDB, MotherDuck, or HTTPS. Sub-second latency.
Open connection detailsConnect to AI
MCP for Claude Desktop, Cursor, ChatGPT, Goose. 1-line install.
See setupHong Kong horse racing results and form guide — the Starter column set: identifiers, result, race specifications, connections, horse attributes, pedigree, performance flags, and the horse's career record. The premium race-grain analytics (in-running positions, sectional and final-800m 200m-split times, pace deltas, and the as-of-race rating) are in the Pro dataset, hkjc_race_results.
Evaluate it in full below: the evidence and a working sample are open to everyone. Buy or subscribe to unlock the complete dataset — your account is created automatically at checkout.
The evidence
Rows over time
monthSchema & column quality (59 columns)
Scroll table sideways to see more columns →
| Column | Type | Description | Populated | Distinct |
|---|---|---|---|---|
| horse_id | String | Unique horse identifier (e.g., 'HK_2020_E403') | 100.0% | 16,551 |
| race_date | DateTime | Date of the race (YYYY-MM-DD) | 100.0% | 3,587 |
| race_number | Int64 | Race number within the meeting (1-11) | 100.0% | 11 |
| race_index | Nullable(String) | Original HKJC race identifier within the meeting (1-10). Use this for matching with external HKJC data sources. NULL for modern data (Sept 2025+). | — | — |
| race_id | Nullable(String) | Unique race identifier (format: ST_20250928_R01) | — | — |
| horse_name | String | Horse's name in English | — | — |
| horse_number | Nullable(Int64) | Horse's saddle/barrier number for the race | — | — |
| finishing_position | Int64 | Final finishing position (1, 2, 3, etc.). 0 for non-starters — see non_starter. | — | — |
| non_starter | Nullable(Bool) | TRUE when the horse was entered but did not start the race (scratched, withdrawn, or a standby/reserve that never ran). For these rows finishing_position is not meaningful (0). Filter on non_starter = false for finishing-position calculations; keep them for withdrawal and pre-race analysis. | — | — |
| result_status | Nullable(String) | Result classification. 'PLACED' = a completed run with a numeric finishing_position (any position, not the racing sense of "placed in the money"). Codes present in the data: PU = pulled up (started, retired mid-race, no placing); WV = withdrawn on veterinary advice; WXNR = declared a non-runner. WV and WXNR are non-runners (the horse did not start), so they are always flagged non_starter = true. non_starter = false therefore cleanly means the horse ran; for a set restricted to placed runners (excluding a PU or a future DISQ that ran but did not place) filter result_status = 'PLACED'. DISQ (disqualified) is decoded but does not yet appear: HKJC publishes disqualifications weeks after the race, after our re-scrape window closes, so the provisional placing stays frozen. When a DISQ is ingested the runner did start and HKJC renumbers the field, so finishing_position reflects the official result. See result_status_label for decoded wording. NULL for non-starters with no recorded code and entries with no outcome. | — | — |
| result_status_label | Nullable(String) | Human-readable form of result_status (Finished, Pulled Up, Withdrawn (Vet), Non-runner; Disqualified once ingested). Unmapped codes pass through verbatim. | — | — |
| finishing_time_seconds | Nullable(Float64) | Finishing time converted to total seconds | — | — |
| finishing_time | Nullable(String) | Finishing time (MM:SS.ss format) | — | — |
| margin | Nullable(String) | Margin from winner (lengths, head, neck, short head, etc.) | — | — |
| margin_lengths | Nullable(Float64) | Margin converted to numeric lengths | — | — |
| draw | Nullable(Int64) | Starting gate/barrier position (same as horse_number in HK flat racing) | — | — |
| odds | Nullable(Float64) | Win odds as a decimal number (e.g. 4.5 = 9/2) | — | — |
| venue_code | String | Venue code (ST/HV) | — | — |
| venue | Nullable(String) | Race venue (Sha Tin / Happy Valley) | — | — |
| surface_type | Nullable(String) | Track surface type: 'Turf' or 'AWT' (All Weather Track) | — | — |
| course_config | Nullable(String) | Course configuration (A, B, C, C+3, etc.) - different track layouts at same venue | — | — |
| distance | Nullable(Int64) | Race distance in meters (1000-2400m typical) | — | — |
| distance_category | String | Distance category (Sprint/Mile/Middle/Long) | — | — |
| race_name | Nullable(String) | Name of the race (e.g., 'FAT CHOI HANDICAP') | — | — |
| race_class | Nullable(String) | Race class (Class 1-5, Group 1/2/3, Griffin, etc.) | — | — |
| track_condition | Nullable(String) | Track going condition (Good/Good to Firm/Yielding/etc.) | — | — |
| field_size | Int64 | Number of horses in the race | — | — |
| jockey | String | Jockey name | — | — |
| jockey_allowance | Nullable(Int64) | Weight allowance for apprentice jockeys (0/2/5 lbs). NULL for historical races. | — | — |
| trainer | String | Trainer name | — | — |
| owner | String | Owner name | — | — |
| horse_colour | Nullable(String) | Horse's coat colour (Bay, Chestnut, Grey, etc.) | — | — |
| horse_sex | Nullable(String) | Horse's sex (G=Gelding, C=Colt, F=Filly, M=Mare, H=Horse) | — | — |
| horse_age | Nullable(Int64) | Horse's age in years | — | — |
| horse_origin | String | Country of origin (AUS, NZ, IRE, GB, etc.) | — | — |
| import_type | String | Import classification (PP, PPG, ISG, etc.) | — | — |
| import_date | Nullable(DateTime) | Date imported to Hong Kong | — | — |
| declared_horse_weight | Nullable(Int32) | Horse's declared body weight before racing (in lbs, typically 1000-1200). Useful for tracking fitness/condition changes. | — | — |
| sire | String | Sire (father) | — | — |
| dam | String | Dam (mother) | — | — |
| dam_sire | String | Dam's sire (maternal grandfather) | — | — |
| is_winner | Nullable(UInt8) | True if horse won the race | — | — |
| is_top_three | Nullable(UInt8) | True if horse finished in top 3 (excludes scratched entries) | — | — |
| dead_heat | Nullable(Bool) | True if horse tied for position. FALSE by default for historical races. | — | — |
| weight | Nullable(Int32) | Weight carried by the horse, in pounds (e.g. 126) | — | — |
| gear | Nullable(String) | Equipment used (B=Blinkers, TT=Tongue Tie, H=Hood, SR=Shadow Roll, etc.). '--' means no gear. See gear_label for the decoded form. | — | — |
| gear_label | Nullable(String) | Equipment decoded to words, e.g. 'Visor (removed) / Blinkers (2nd time) / Tongue Tie'. 'No gear' where the raw code is '--'. Codes are HKJC's own (Equipment Register, racing.hkjc.com/en-us/local/page/reg-approved-gear); a trailing 1/2 means first/second time worn and a trailing '-' means removed this start. Unrecognised codes pass through unchanged. | — | — |
| total_stakes | Nullable(Float64) | Total career prize money (HKD) | — | — |
| season_stakes | Nullable(Float64) | Current season prize money (HKD) | — | — |
| no_of_starts | Nullable(String) | Career record (format: wins-seconds-thirds-total) | — | — |
| career_wins | Nullable(Int32) | Career wins in Hong Kong | — | — |
| career_seconds | Nullable(Int32) | Career second places | — | — |
| career_thirds | Nullable(Int32) | Career third places | — | — |
| career_total_starts | Nullable(Int32) | Total career starts | — | — |
| career_win_rate | Nullable(Float64) | Career win percentage (0-1) | — | — |
| race_url | String | Source URL for the race page | — | — |
| video_replay_url | String | Direct URL to watch race video replay for this specific horse | — | — |
| updated_at | Nullable(DateTime) | Timestamp when record was last updated | — | — |
| id | String | Stable unique identifier for this row — the last column of every export. Use it to deduplicate, to key an incremental load, or to reference one specific row. It is additive: the entity and join keys you already use (race_id, horse_id, and the like) are unchanged. | — | — |
Last 12 months of race results across every meeting — the core columns (result, race specs, connections, form, career record). The premium sectional / in-running / pace columns are in the Pro dataset.
Choose your access
A Pass gives you freshness within a rolling window. The Full Archive gives you the full history we hold for the dataset, frozen at purchase. They solve different problems, and they work together.
- Access window
- Most recent 24 months, rolling
- Updates
- Continuous, within hours of the source
- Delivery
- API, SQL and downloads
- Exports
- 120,000 rows/month included
Included Datasets
- Access window
- Most recent 24 months, rolling
- Updates
- Continuous, within hours of the source
- Delivery
- API, SQL and downloads
- Exports
- 1,000,000 rows/month included
Included Datasets
- Access window
- Most recent 24 months, rolling
- Updates
- Continuous, within hours of the source
- Delivery
- API, SQL and downloads
- Exports
- Uncapped
Included Datasets
Get notified when this dataset is updated.
Questions about this data?
Our data experts are ready to help clarify any aspects of this dataset.
Contact Our Team