# Formula 1 Data — Results, Standings & Schedule (`foxlabs/formula1-data`) Actor

Formula 1 as clean rows: race results (position, driver, team, grid, time, points, fastest lap), driver and constructor standings, and the full season schedule. From the maintained Ergast successor. No API key, no login.

- **URL**: https://apify.com/foxlabs/formula1-data.md
- **Developed by:** [Berkan Kaplan](https://apify.com/foxlabs) (community)
- **Categories:** Sports, News
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 1,000 race results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Formula 1 Data Scraper — Results, Laps, Pit Stops, Qualifying & Tyre Strategy 🏎️

**foXLabs sports data:** Formula 1 · (UFC/MMA · Golf · Cricket · Rugby — the same family)

🎉 Turn Formula 1 into clean, structured data: race **results** with grid and fastest lap, **qualifying** (Q1/Q2/Q3), **lap-by-lap** times, **pit stops**, driver and constructor **standings**, the season **schedule**, and **tyre stints** (compound, age and lap range). No API key, no login. Built for sports-stats products, strategy and betting modellers, and AI agents.

### 🔍 What is the Formula 1 Data Scraper — and when should you use it?

Pick a mode and get rows you can filter, export or feed to a model, a spreadsheet or an AI agent:

- **Race results** — finishing order with grid, status, points and fastest lap.
- **Qualifying** — Q1, Q2 and Q3 times per driver.
- **Lap times** — every driver's time and position, lap by lap.
- **Pit stops** — each stop with its lap and duration.
- **Driver / constructor standings** — the championship tables.
- **Season schedule** — the calendar with circuits and dates.
- **Tyre stints** — compound, tyre age and lap range per stint (2023 onward).

**Use it when you need:** a strategy or betting model (lap pace, pit windows, tyre life); a stats product or widget; or historical race data for analysis. **Use something else when** you want other sports — see the rest of the foXLabs sports family.

### 🤖 Use with AI agents

**Already on the Apify MCP server?** Ask for it by name: `foxlabs/formula1-data`.

**Your agent can pay for its own runs** — pay-per-event with agentic payments over **x402 (USDC on Base)** or **Skyfire**, with no Apify account of its own. Billing is per delivered row, never for errors or empty results.

Paste into Claude, ChatGPT, Cursor or any MCP assistant:

```
Use the Apify Actor `foxlabs/formula1-data`.
Input: `mode` = results | qualifying | laps | pitStops | driverStandings | constructorStandings | schedule | tyreStints;
`season` (year or "current"); `round` ("last" or a number) for race-scoped modes; `maxResults` caps rows.
Start with: { "mode": "results", "season": "current", "round": "last" }
```

**Things you can ask your agent:**

- "Give me the lap-by-lap times for the last race."
- "What tyre compounds did each driver run, and for how many laps?"
- "Show the current driver standings."

### 📋 Overview

The Formula 1 Data Scraper reads two free, open sources live on every run: **Jolpica** (the maintained successor to the Ergast F1 API) for results, qualifying, laps, pit stops, standings and the schedule across every season, and **OpenF1** for tyre stints from 2023 onward. There is nothing to configure: no key, no login, no proxy.

**Why teams pick this actor:**

- 🧱 **Eight modes, one actor** — from championship tables down to single laps and tyre stints.
- 🛞 **Tyre strategy that generic scrapers skip** — compound, tyre age and stint length per driver.
- 🔑 **Zero setup** — no API key, no login, no browser.
- ♻️ **Fresh every run** — reads the sources live.
- 🤝 **Agent-ready** — MCP + x402, billed per delivered row.

### ✨ Features

- 🏁 **Results** — position, grid, status, points, fastest lap and its rank.
- ⏱️ **Qualifying** — Q1/Q2/Q3 per driver.
- 📈 **Lap times** — per driver, per lap: time and running position.
- 🅿️ **Pit stops** — lap, stop number and duration in seconds.
- 🛞 **Tyre stints** — compound, tyre age at start, and lap range (2023 onward, via OpenF1).
- 🏆 **Standings** — driver and constructor championship tables.
- 📅 **Schedule** — circuits, localities, countries and dates.

### 🎬 Quick Start

```bash
curl -X POST "https://api.apify.com/v2/acts/foxlabs~formula1-data/runs?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"mode": "results", "season": "current", "round": "last"}'
```

### 🚀 Getting Started (3 steps)

1. **Pick a mode** — `results`, `qualifying`, `laps`, `pitStops`, `driverStandings`, `constructorStandings`, `schedule` or `tyreStints`.
2. **Set the scope** — `season` (a year or `current`), and `round` (`last` or a number) for race-scoped modes.
3. **Run and export** — download the dataset as JSON, CSV or Excel, or pull it from the API.

### 📥 Input

```json
{
  "mode": "laps",
  "season": "2024",
  "round": "1",
  "maxResults": 0
}
```

| Field | Type | Description |
|---|---|---|
| `mode` | string | `results` (default), `qualifying`, `laps`, `pitStops`, `driverStandings`, `constructorStandings`, `schedule`, `tyreStints`. |
| `season` | string | A year (e.g. `2024`) or `current`. |
| `round` | string | For race-scoped modes: `last` (default) or a round number. `all` works only for `results`. |
| `maxResults` | integer | Cap on delivered rows (0 = no cap). |
| `proxyConfiguration` | object | Not required; the sources are reached directly. |

### 📤 Output

**Lap** (laps mode):

```json
{ "season": "2024", "round": 1, "raceName": "Bahrain Grand Prix", "lap": 1, "driverId": "max_verstappen", "position": 1, "time": "1:37.284", "source": "Jolpica/Ergast", "scrapedAt": "2026-11-02T11:05:30.721Z" }
```

**Tyre stint** (tyreStints mode):

```json
{ "season": "2024", "round": 1, "raceName": "Bahrain Grand Prix", "driverNumber": 1, "driver": "Max Verstappen", "code": "VER", "team": "Red Bull Racing", "stint": 1, "compound": "SOFT", "tyreAgeAtStart": 3, "lapStart": 1, "lapEnd": 17, "source": "OpenF1", "scrapedAt": "..." }
```

| Field | Mode | Description |
|---|---|---|
| `position`, `grid`, `status`, `points`, `fastestLap`, `fastestLapRank` | results | Finishing order and fastest lap. |
| `q1`, `q2`, `q3` | qualifying | Session times per driver. |
| `lap`, `time`, `position` | laps | Per driver, per lap. |
| `lap`, `stop`, `durationSec`, `localTime` | pitStops | Each pit stop. |
| `position`, `points`, `wins` | standings | Championship tables. |
| `compound`, `tyreAgeAtStart`, `lapStart`, `lapEnd`, `stint` | tyreStints | Tyre strategy (2023+). |

Every row carries `source` and `scrapedAt`.

### 💼 Use cases

- **Strategy / betting model**
  - *Input:* `{ "mode": "laps", "season": "2024", "round": "1" }` and `{ "mode": "tyreStints", ... }`
  - *Output:* lap pace and tyre stints.
  - *Use:* model pit windows, tyre degradation and undercut opportunities.
- **Stats product / widget**
  - *Input:* `{ "mode": "driverStandings", "season": "current" }`
  - *Output:* the live championship table.
- **Historical analysis**
  - *Input:* `{ "mode": "results", "season": "2021", "round": "all" }`
  - *Output:* every race result of the season.

### 🔗 Integration

**JavaScript (Apify client):**

```js
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const run = await client.actor('foxlabs/formula1-data').call({ mode: 'results', season: 'current', round: 'last' });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

**Python (Apify client):**

```python
from apify_client import ApifyClient
client = ApifyClient("YOUR_TOKEN")
run = client.actor("foxlabs/formula1-data").call(run_input={"mode": "results", "season": "current", "round": "last"})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

**n8n / Zapier / Make:** use the Apify connector, pick this actor, map `mode`, `season` and `round`, then route the dataset into your sheet, database or webhook.

### 📊 Pricing

**Pay per result (PPE).** You are billed only for delivered rows, never for errors or empty runs. Current prices are on the Pricing tab.

### ❓ FAQ

#### Do I need an API key or a login to scrape Formula 1 data?

No. You supply nothing: pick a mode, a season and a round, and run. There is no F1 API key to obtain, no account to connect and no browser to configure. The actor reads two free, open sources (Jolpica, the maintained Ergast successor, and OpenF1) directly.

#### Which Formula 1 seasons and data does it cover?

Race results, qualifying, lap times, pit stops, and driver and constructor standings, plus the season schedule, go back across the Ergast archive — more than seventy seasons of Formula 1 history, from 1950 onward. Tyre stints come from OpenF1 and are available from the 2023 season onward.

#### What is a tyre stint, and what does each row contain?

A stint is one continuous run on a single set of tyres, from the lap a driver fits them to the lap they pit or finish. Each `tyreStints` row gives the driver, team, stint number, tyre `compound` (SOFT, MEDIUM, HARD, INTERMEDIATE or WET), the `tyreAgeAtStart` (laps already on that set), and the `lapStart` and `lapEnd` of the stint — enough to reconstruct each driver's full tyre strategy for a race.

#### Does this actor include lap-by-lap times?

Yes. The `laps` mode returns one row per driver per lap, with the lap time and the driver's running position on that lap. A full Grand Prix has roughly a thousand lap rows across the field.

#### Do you provide strokes-gained, telemetry or car data?

Lap times, sector-level pace through pit and position data, and tyre stints are included. Full car telemetry (throttle, brake, RPM) is not part of this actor; if you need raw telemetry, OpenF1 exposes it separately.

#### What does `fastestLapRank` mean in results mode?

It is the rank of that driver's fastest lap among all drivers in the race: `fastestLapRank` of 1 means the driver set the fastest lap of the Grand Prix (the point-scoring fastest lap in seasons where it applies).

#### Why can't I use `round: all` for laps, pit stops, qualifying or tyre stints?

Those modes read one Grand Prix at a time to keep each run fast and polite to the source. Use a round number (or `last`), and run several rounds if you need a whole season. `round: all` is supported for `results`, which is light enough to sweep a full season in one run.

#### How current is the data, and how fast does it update after a session?

Every run reads the sources live, so results, qualifying and standings appear as soon as Jolpica publishes them after a session — typically within minutes to an hour of the chequered flag. Tyre stints and lap detail populate once OpenF1 processes the session.

#### How do I get a driver's whole-season form?

Run `results` with `round: all` for the season to get every finish, then `driverStandings` for the running championship table. For pace, pull `laps` per round and aggregate.

#### Can I export to CSV, Excel or JSON?

Yes. Download the dataset as JSON, CSV or Excel from the Apify console, or pull it straight from the Apify API or the dataset's `.json` endpoint for a pipeline or an AI agent.

#### How is this different from a generic sports-scores scraper?

Generic scrapers stop at the finishing order. This actor adds the layers Formula 1 analysts and modellers actually use: qualifying session times, lap-by-lap pace, pit-stop durations and, from 2023, full tyre strategy — none of which a leaderboard scraper provides.

### 🐛 Troubleshooting

- **Empty tyre stints before 2023** — OpenF1 only covers 2023 onward; earlier seasons return a clear message.
- **Empty result for a future round** — the race has not happened yet; pick a completed round or `last`.
- **Fewer rows than expected in laps** — use `maxResults: 0` (no cap); a race has roughly a thousand lap rows.

### ⚠️ Trademark

Independent, third-party tool. Not affiliated with, endorsed by or connected to Formula 1, the FIA, Jolpica or OpenF1. All marks belong to their owners and are used for identification only.

### ⚖️ Is it legal to scrape this data?

This actor reads publicly available, non-personal motorsport data (results, timing and standings) from open APIs that publish it for public use. It collects no private or personal data and requires no login. You are responsible for using the output in line with applicable laws and the terms of the sources. When in doubt, consult a lawyer.

### 🤝 Support & contact

- 🌐 **Website:** [data.foxlabs.com.tr](https://data.foxlabs.com.tr)
- 📧 **Email:** info@foxlabs.com.tr
- 🧰 **More clean data actors:** [Fox Labs on Apify](https://apify.com/foxlabs)

### Changelog

#### 0.2 — 2026-11-02

- Added **qualifying** (Q1/Q2/Q3), **lap times**, **pit stops** and **tyre stints** (compound, age, lap range; 2023 onward via OpenF1) modes. Results now include the fastest-lap rank.

#### 0.1 — 2026-11-02

- Initial release: results, driver/constructor standings and schedule from the Jolpica (Ergast successor) API.

# Changelog

This Actor's version history is a separate document: https://apify.com/foxlabs/formula1-data/changelog.md

# Actor input Schema

## `mode` (type: `string`):

results = race finishing order (grid, status, fastest lap); qualifying = Q1/Q2/Q3; laps = lap-by-lap time and position per driver; pitStops = each pit stop with duration; driverStandings / constructorStandings = championship tables; schedule = the season calendar; tyreStints = tyre compound, age and lap range per stint (OpenF1, 2023 onward).

## `season` (type: `string`):

Year (e.g. 2024) or `current`.

## `round` (type: `string`):

Which Grand Prix for results, qualifying, laps, pitStops and tyreStints: `last` (default) or a round number. `all` works only for results; the other race-scoped modes read one round at a time.

## `maxResults` (type: `integer`):

Cap on delivered rows (0 = no cap).

## `proxyConfiguration` (type: `object`):

Not required. Jolpica is a free community API reached directly. Set a proxy only if your network needs one.

## Actor input object example

```json
{
  "mode": "results",
  "season": "current",
  "round": "last",
  "maxResults": 0,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `dataset` (type: `string`):

No description

## `report` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "mode": "results",
    "season": "current",
    "round": "last"
};

// Run the Actor and wait for it to finish
const run = await client.actor("foxlabs/formula1-data").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "mode": "results",
    "season": "current",
    "round": "last",
}

# Run the Actor and wait for it to finish
run = client.actor("foxlabs/formula1-data").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "mode": "results",
  "season": "current",
  "round": "last"
}' |
apify call foxlabs/formula1-data --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,foxlabs/formula1-data"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/KWZgpCez0M1Qu9sp3/builds/QcmhMqt4recsaxcgw/openapi.json
