This document describes the two standardised JSON formats produced by the scraper and consumed by the web dashboard. Both file types share the same metadata block and are scraped from the official F1 Fantasy platform.
| Directory | Naming Convention | Contents |
|---|---|---|
prices/ |
prices-PRE-ROUND-{N}.json |
All drivers and constructors on the market with prices and ownership |
team-price/ |
team-PRE-ROUND-{N}.json |
Current GPT RS team composition, prices, and captain selection |
{N} is the upcoming round number (1-indexed). Files are generated by a scraper that runs on Tuesdays, plus ad-hoc runs before each round.
metadata ObjectBoth file types begin with an identical metadata block.
{
"metadata": {
"scraped_at": "2026-02-26T23:32:44Z",
"round_context": {
"last_completed_round": null,
"last_completed_race": null,
"upcoming_round": 1,
"upcoming_race": "Australian GP",
"is_race_week": false,
"file_type": "pre-round"
}
}
}
| Field | Type | Description |
|---|---|---|
scraped_at |
string (ISO 8601, UTC) |
Timestamp when the data was scraped. Always UTC with Z suffix. |
round_context.last_completed_round |
number \| null |
Round number of the most recently completed race. null before the season starts. |
round_context.last_completed_race |
string \| null |
Human-readable name of the last completed race (e.g. "Australian GP"). null before the season starts. |
round_context.upcoming_round |
number |
Round number of the next upcoming race (1–24). |
round_context.upcoming_race |
string |
Human-readable name of the next upcoming race. |
round_context.is_race_week |
boolean |
true if the scrape occurred during the race weekend (Friday–Sunday), false otherwise. |
round_context.file_type |
string |
Always "pre-round" for these snapshots. Reserved for future types like "post-round" or "mid-weekend". |
prices/prices-PRE-ROUND-{N}.json)Contains the full market — every driver and constructor available in the game.
{
"metadata": { ... },
"drivers": [ ... ],
"constructors": [ ... ]
}
drivers ArrayAn array of all 21 drivers on the grid, sorted by price_millions descending.
{
"name": "Max Verstappen",
"team": "Red Bull Racing",
"price_millions": 27.7,
"ownership_pct": 28.0
}
| Field | Type | Description |
|---|---|---|
name |
string |
Driver’s full display name as shown on the F1 Fantasy platform. |
team |
string |
Constructor/team name the driver races for. Matches the name field in the constructors array. |
price_millions |
number |
Current price in millions (e.g. 27.7 = $27.7M). One decimal place. |
ownership_pct |
number |
Global ownership percentage across all F1 Fantasy players. One decimal place. |
constructors ArrayAn array of all 11 constructors, sorted by price_millions descending.
{
"name": "Mercedes",
"price_millions": 29.3,
"ownership_pct": 23.0
}
| Field | Type | Description |
|---|---|---|
name |
string |
Constructor’s display name. Used as the join key to link drivers to their team. |
price_millions |
number |
Current price in millions. One decimal place. |
ownership_pct |
number |
Global ownership percentage. One decimal place. |
team-price/team-PRE-ROUND-{N}.json)Contains the current composition of the GPT RS fantasy team.
{
"metadata": { ... },
"team": {
"drivers": [ ... ],
"constructors": [ ... ],
"total_team_value_millions": 99.9
}
}
| Field | Type | Description |
|---|---|---|
team.total_team_value_millions |
number |
Sum of all driver and constructor prices. The budget cap is $100.0M, so 100.0 - total_team_value_millions = remaining budget. |
team.drivers ArrayExactly 5 driver objects, representing the selected fantasy squad.
{
"name": "George Russell",
"team": "Mercedes",
"price_millions": 27.4,
"price_change_millions": 0.0,
"is_captain": true
}
| Field | Type | Description |
|---|---|---|
name |
string |
Driver’s full display name. Matches entries in the prices file. |
team |
string |
Constructor name. |
price_millions |
number |
Current price in millions. |
price_change_millions |
number |
Cumulative price change since the driver was acquired. 0.0 at start of season or if just purchased. Can be negative. |
is_captain |
boolean |
true if this driver has the DRS Boost (2x points multiplier). Exactly one driver will have is_captain: true. |
team.constructors ArrayExactly 2 constructor objects.
{
"name": "Ferrari",
"price_millions": 23.3,
"price_change_millions": 0.0
}
| Field | Type | Description |
|---|---|---|
name |
string |
Constructor display name. Matches entries in the prices file. |
price_millions |
number |
Current price in millions. |
price_change_millions |
number |
Cumulative price change since acquisition. |
These are not in the JSON but are straightforward to compute:
| Value | Formula |
|---|---|
| Budget remaining | 100.0 - team.total_team_value_millions |
| Captain driver | team.drivers.find(d => d.is_captain) |
| Team value change | sum(all price_change_millions) across drivers + constructors |
The name field is the join key between files. To enrich the team view with market data (e.g. ownership percentage), match team.drivers[].name against drivers[].name in the prices file, and likewise for constructors.
team.drivers[i].name === prices.drivers[j].name
team.constructors[i].name === prices.constructors[j].name
Both files from the same scrape run share the same scraped_at timestamp and round_context.
price_millions values to shift by ±$0.1–$0.6M per round.ownership_pct can change at any time as players make transfers globally.team-price/ files reflect GPT RS only. The team changes when transfers are executed (up to 3 free per round, or unlimited during Wildcard/Limitless chip usage).A typical dashboard view would:
scraped_at).price_millions and price_change_millions for each pick (green/red for positive/negative change).total_team_value_millions and the derived budget remaining.ownership_pct for each team member.