# Formula 1 Live Timing & Telemetry Scraper (OpenF1, No API Key) (`ninhothedev/f1-openf1-scraper`) Actor

$0.35/1K 🔥 Formula 1 session scraper! Lap times, pit stops, positions & track weather via OpenF1. No key. JSON, CSV, Excel or API in seconds. Power F1 analytics & fantasy leagues ⚡

- **URL**: https://apify.com/ninhothedev/f1-openf1-scraper.md
- **Developed by:** [ninhothedev](https://apify.com/ninhothedev) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.35 / 1,000 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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Formula 1 Live Timing & Telemetry Scraper (OpenF1, No API Key)

Scrape **session-level Formula 1 data** — lap times, sector splits, pit stops, speed traps and track weather — straight from the free [OpenF1](https://openf1.org/) API. No API key, no login, no proxy, no browser. Every row comes out flat and analysis-ready, with driver names and team names already joined in.

If you have ever tried to build an F1 dashboard, a fantasy-league tool or a race-strategy model, you know the pain: the official data is locked behind broadcast feeds, and most public sources only give you the final classification. This actor gives you what actually happened **during** the session — every lap by every driver, every pit stop with its stationary time, and the track temperature that explains why the tyres fell apart on lap 34.

***

### How is this different from `f1-scraper`?

We publish two Formula 1 actors. They do **not** overlap:

| | [`f1-scraper`](https://apify.com/ninhothedev/f1-scraper) | **`f1-openf1-scraper`** (this one) |
|---|---|---|
| **Data source** | Ergast / jolpica F1 API | OpenF1 API |
| **Granularity** | Season & race level — **historical results** | **Session level** — what happened lap by lap |
| **Typical rows** | Race winners, championship standings, constructor points, driver careers | Individual laps, sector times, pit stops, weather readings |
| **Time range** | 1950 → today (full F1 history) | 2023 → today |
| **Answers** | "Who won the 1988 Monaco GP?" "How many points did Ferrari score in 2010?" | "What was Norris's sector 2 on lap 41?" "How long was Bottas stationary in the pits?" |
| **Best for** | History, records, career stats, all-time comparisons | Timing analysis, strategy modelling, live-ish dashboards, telemetry |

**Rule of thumb:** want *results and history* → use `f1-scraper`. Want *what happened inside a session* → use this one. Many users run both and join them on race name / year.

***

### What you get

Four modes, one actor:

#### `sessions` — every session of a season

Lists all practice, qualifying, sprint and race sessions of a year, each with its `session_key`. **Run this first** to find the session you want to dig into.

#### `laps` — lap & sector times per driver

Every lap of a session for all 20 drivers: lap time, the three sector durations, speed-trap and intermediate speeds, and a pit-out-lap flag so you can filter out in/out laps before computing race pace.

#### `pit` — pit stops

Every stop with the full pit-lane duration **and** the stationary time — the two numbers strategists actually care about.

#### `weather` — track conditions

A time series of air temperature, track temperature, humidity, pressure, rainfall, wind speed and wind direction throughout the session.

***

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `mode` | select | `sessions` | `sessions`, `laps`, `pit` or `weather` |
| `year` | integer | `2024` | Season to scrape. OpenF1 data starts in 2023. |
| `sessionKey` | string | *(empty)* | OpenF1 `session_key`, e.g. `9662`. Leave empty to auto-pick the **latest race of that season**. |
| `maxItems` | integer | `500` | Row cap, max 5000. |

```json
{
  "mode": "laps",
  "year": 2024,
  "sessionKey": "9662",
  "maxItems": 500
}
```

***

### Output samples

**`sessions`**

```json
{
  "type": "session",
  "session_key": 9662,
  "session_name": "Race",
  "session_type": "Race",
  "meeting_key": 1252,
  "year": 2024,
  "location": "Yas Island",
  "country_name": "United Arab Emirates",
  "circuit": "Yas Marina Circuit",
  "date_start": "2024-12-08T13:00:00+00:00",
  "date_end": "2024-12-08T15:00:00+00:00",
  "source": "openf1",
  "scraped_at": "2026-07-28T14:12:03+00:00"
}
```

**`laps`**

```json
{
  "type": "lap",
  "session_key": 9662,
  "driver_number": 1,
  "driver_name": "Max VERSTAPPEN",
  "team_name": "Red Bull Racing",
  "lap_number": 1,
  "lap_duration_s": 99.877,
  "sector1_s": 25.002,
  "sector2_s": 39.931,
  "sector3_s": 34.944,
  "speed_trap_kmh": 289,
  "i1_speed": 290,
  "i2_speed": 302,
  "is_pit_out_lap": false,
  "date_start": "2024-12-08T13:03:35.033000+00:00",
  "source": "openf1",
  "scraped_at": "2026-07-28T14:12:03+00:00"
}
```

**`pit`**

```json
{
  "type": "pit",
  "session_key": 9662,
  "driver_number": 77,
  "driver_name": "Valtteri BOTTAS",
  "team_name": "Kick Sauber",
  "lap_number": 6,
  "pit_duration_s": 41.144,
  "stop_duration_s": 21.5,
  "date": "2024-12-08T13:14:05.238000+00:00",
  "source": "openf1",
  "scraped_at": "2026-07-28T14:12:03+00:00"
}
```

**`weather`**

```json
{
  "type": "weather",
  "session_key": 9662,
  "date": "2024-12-08T12:07:44.039000+00:00",
  "air_temperature_c": 27.8,
  "track_temperature_c": 37.2,
  "humidity_pct": 42.0,
  "pressure_mbar": 1017.3,
  "rainfall": 0,
  "wind_direction_deg": 292,
  "wind_speed_ms": 1.0,
  "source": "openf1",
  "scraped_at": "2026-07-28T14:12:03+00:00"
}
```

Export as JSON, CSV, Excel, XML or via the Apify API. All fields are nullable — missing upstream values come back as `null`, never as a crash.

***

### Use cases

- **F1 analytics** — build race-pace models, stint analysis and tyre-degradation curves from real lap and sector times.
- **Fantasy leagues** — score drivers on true pace instead of finishing position, and spot undervalued midfielders before the deadline.
- **Race dashboards** — power a live-ish timing board, a Discord bot or a Grafana panel with session data refreshed on a schedule.
- **Betting research** — quantify pit-lane efficiency by team, correlate track temperature with lap-time deltas, and backtest strategy edges.

***

### How to find a session key

1. Run the actor with `mode: "sessions"` and your `year`.
2. Find the row you want in the dataset — filter by `circuit` and `session_type`.
3. Copy its `session_key` into the `sessionKey` input and switch mode to `laps`, `pit` or `weather`.

Or just leave `sessionKey` empty: the actor automatically picks the **latest race of the season**.

***

### Pricing

Roughly **$0.5 per 1,000 items**. A full race session of lap data (~1,000 laps) costs about half a dollar. The `sessions` mode for a whole season is ~123 rows — a few cents.

***

### Notes & limits

- OpenF1 covers the **2023 season onwards**. For anything older, use [`f1-scraper`](https://apify.com/ninhothedev/f1-scraper).
- Data is unofficial and community-maintained. It is not affiliated with, endorsed by, or connected to Formula 1, the FIA or any team.
- Live sessions have a short delay; historical sessions are complete and stable.
- The actor retries transient errors automatically and fails loudly (`RuntimeError`) if a run would produce zero rows, so you never get a silently empty dataset.

***

### Related actors

- [F1 Scraper (Ergast historical results)](https://apify.com/ninhothedev/f1-scraper) — full F1 history since 1950: results, standings, constructors.
- [ESPN Scores Scraper](https://apify.com/ninhothedev/espn-scores-scraper) — live scores and schedules across major leagues.
- [Sports Scraper](https://apify.com/ninhothedev/sports-scraper) — multi-sport fixtures, results and tables.
- [OpenLigaDB Scraper](https://apify.com/ninhothedev/openligadb-scraper) — German football (Bundesliga & more), free and keyless.

***

### Legal

This actor reads a public, keyless, community API. Only publicly available sporting data is collected — no personal data, no authentication, no scraping of gated content. "Formula 1", "F1" and related marks are trademarks of Formula One Licensing BV; this project is an independent tool and is not affiliated with them.

# Actor input Schema

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

What to scrape. 'sessions' lists every session of a season (practice, qualifying, sprint, race) with its session\_key. 'laps' returns per-driver lap and sector times for one session. 'pit' returns every pit stop with its duration. 'weather' returns the track/air condition time series of one session.

## `year` (type: `integer`):

Formula 1 season to scrape, e.g. 2024. Used directly in 'sessions' mode, and to find the latest race when 'Session key' is left empty. OpenF1 data starts with the 2023 season.

## `sessionKey` (type: `string`):

OpenF1 session\_key of the session to scrape in 'laps', 'pit' and 'weather' mode, e.g. 9662 for the 2024 Abu Dhabi Grand Prix race. Leave empty to automatically use the latest race session of the selected season. Ignored in 'sessions' mode. Get valid keys by running 'sessions' mode first.

## `maxItems` (type: `integer`):

Hard cap on how many rows are pushed to the dataset. One row equals one session, one lap, one pit stop or one weather reading. Default 500, maximum 5000.

## Actor input object example

```json
{
  "mode": "sessions",
  "year": 2024,
  "sessionKey": "",
  "maxItems": 500
}
```

# Actor output Schema

## `results` (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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("ninhothedev/f1-openf1-scraper").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 = {}

# Run the Actor and wait for it to finish
run = client.actor("ninhothedev/f1-openf1-scraper").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 '{}' |
apify call ninhothedev/f1-openf1-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,ninhothedev/f1-openf1-scraper"
        }
    }
}
```

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/Ou9XyflNjyHhXJhD6/builds/E5hUsY0xgnmud3eAj/openapi.json
