# MotoGP Riders, Results & Standings (`scrapermaster/motogp-riders-results-standings`) Actor

MotoGP, Moto2, Moto3 and MotoE data: season calendar, session results, rider/team/constructor standings and rider profiles with career stats. Export to JSON, CSV or Excel.

- **URL**: https://apify.com/scrapermaster/motogp-riders-results-standings.md
- **Developed by:** [Scraper Master](https://apify.com/scrapermaster) (community)
- **Categories:** Sports, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.71 / 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.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## MotoGP Riders, Results & Standings

Collect structured motorcycle Grand Prix data for **MotoGP, Moto2, Moto3 and MotoE**: the season calendar, the classification of every session, the championship tables and detailed rider profiles. Everything comes from the public JSON feed that the official motogp.com website itself reads, so there is no HTML scraping and no login.

### What you can do

| Mode | You get |
| --- | --- |
| `calendar` | One row per event: dates, circuit, country and status. |
| `results` | One row per rider per session: position, rider, number, team, constructor, points, time, gap, laps and result status. |
| `standings` | Rider, team or constructor championship table for a season and class. |
| `riders` | One row per rider: identity, birth data, team and number for the season, and optional career statistics. |

Every mode honors `maxItems`. If a request fails (after several retries) the run keeps going and writes an error row (`error: true`) instead.

### Input examples

Calendar of the 2025 MotoGP season:

```json
{ "mode": "calendar", "year": 2025, "category": "MotoGP", "maxItems": 30 }
```

Race result of the Thai Grand Prix, MotoGP class:

```json
{ "mode": "results", "year": 2025, "category": "MotoGP", "event": "THA", "sessionType": "RAC", "maxItems": 30 }
```

Qualifying (both parts) for two events in Moto3:

```json
{ "mode": "results", "year": 2025, "category": "Moto3", "event": "ARG,ITA", "sessionType": "Q", "maxItems": 100 }
```

Constructor championship:

```json
{ "mode": "standings", "year": 2025, "category": "MotoGP", "standingsType": "constructor" }
```

All Moto2 riders of 2026 with career statistics:

```json
{ "mode": "riders", "year": 2026, "category": "Moto2", "includeCareerStats": true, "maxItems": 40 }
```

Specific riders by id:

```json
{ "mode": "riders", "riderIds": ["23e50438-a657-4fb0-a190-3262b5472f29", "8688"], "year": 2025 }
```

#### Input fields

| Field | Meaning |
| --- | --- |
| `mode` | `calendar`, `results`, `standings` or `riders`. |
| `year` | Season, e.g. `2025`. |
| `category` | `MotoGP`, `Moto2`, `Moto3`, `MotoE` (and `ALL` in calendar mode). |
| `event` | Optional comma separated filter: event code (`THA`, `ARG`, `ITA`), part of an event or circuit name, or an event id. |
| `sessionType` | Results mode: `RAC`, `SPR`, `Q2`, `Q1`, `Q` (both), `FP1`, `FP2`, `FP` (all), `PR`, `WUP`, `ALL`. |
| `standingsType` | `rider`, `team` or `constructor`. |
| `riderIds` | Riders mode: rider UUIDs or numeric legacy ids of current riders. |
| `includeCareerStats` | Riders mode: add career totals (one extra request per rider). Default on. |
| `includeBiography` | Riders mode: add the English biography as plain text. Default off. |
| `maxItems` | Upper limit of result rows. Error rows are not counted. |

### Output fields

Rows are flat JSON objects; the `mode` field tells which table a row belongs to.

**Calendar**

| Field | Description |
| --- | --- |
| `season`, `category` | Season year and class filter (null when `ALL`). |
| `eventId`, `eventCode`, `eventName`, `sponsoredName` | Event identifiers and names. |
| `dateStart`, `dateEnd` | Event dates (YYYY-MM-DD). |
| `circuit`, `circuitPlace`, `circuitNation`, `country`, `countryIso` | Where it takes place. |
| `status` | `FINISHED`, `CURRENT` or `NOT-STARTED`. |
| `isTest` | True for pre-season and in-season tests. |
| `circuitInfoPdf` | Link to the circuit information sheet. |

**Results**

| Field | Description |
| --- | --- |
| `season`, `category`, `eventCode`, `eventName`, `circuit`, `country` | Event context. |
| `sessionType`, `sessionNumber`, `sessionName`, `sessionDate`, `weather`, `trackCondition` | Session context. |
| `position`, `classified`, `resultStatus` | Finishing position (null if not classified), and the feed's status code (`INSTND` classified, `OUTSTND` retired/not classified, and others). |
| `riderId`, `riderLegacyId`, `riderName`, `riderNumber`, `riderCountry`, `riderCountryIso` | Rider. |
| `team`, `constructor` | Team and bike manufacturer. |
| `points` | Points awarded (races and sprints). |
| `time` | Race time of the rider (races and sprints). |
| `bestLapTime`, `bestLapNumber`, `topSpeedKmh` | Practice and qualifying sessions. |
| `gapToFirst`, `gapToPrevious`, `lapsBehind` | Gaps; for retirements `lapsBehind` is the number of laps not completed. |
| `laps`, `averageSpeedKmh` | Laps completed and average speed. |

**Standings**

| Field | Description |
| --- | --- |
| `standingsType`, `season`, `category`, `position` | Table identity and rank. |
| `name` | Rider, team or constructor name. |
| `riderId`, `riderLegacyId`, `riderNumber`, `country`, `team`, `constructor` | Rider table only. |
| `points`, `raceWins`, `podiums`, `sprintWins`, `sprintPodiums` | Totals (`sprintPodiums` in rider table only). |
| `eventsCounted`, `riders`, `teams`, `computedFromSessions` | Team and constructor tables only. |

**Riders**

| Field | Description |
| --- | --- |
| `riderId`, `riderLegacyId`, `fullName`, `firstName`, `lastName`, `nickname` | Identity. |
| `riderNumber`, `shortCode`, `team`, `sponsoredTeam`, `constructor`, `inGrid`, `riderType` | Team and number for the chosen season. |
| `nationality`, `nationalityIso`, `birthDate`, `birthPlace`, `age`, `heightCm`, `weightKg` | Personal data. |
| `firstSeason`, `retired`, `retiredYear`, `careerSeasons` | Career span. |
| `careerStats` | Object: `raceStarts`, `grandPrixWins`, `sprintWins`, `podiums`, `poles`, `raceFastestLaps`, `worldTitles`, `winsByCategory`, `titlesByCategory`, `firstGrandPrix`. |
| `profilePicture`, `socialMedia`, `biography` | Extras (biography only when requested). |

### Notes and limitations

- The feed publishes only the **rider** championship table. Team and constructor tables are calculated by this Actor from the race and sprint classifications of the season (teams add up all their riders, constructors score with their best-placed rider in each session). They match the official logic in normal seasons but may differ in rare edge cases such as penalties applied after a race, so treat them as derived data. They need one request per session, so they take longer than the rider table.
- `riders` mode lists the current roster for the current season; for older seasons the rider list comes from that season's standings. Career statistics always cover the whole career.
- Test events are returned by `calendar` (flagged `isTest`) but skipped by `results` and the derived tables.
- Rows for future sessions do not exist; unfinished events are skipped.
- MotoE is only present in seasons in which it was run, and a few classes have several races per event (shown as Race 1 / Race 2).
- Requests are made politely: at most 3 at a time, with short random pauses and automatic retry with backoff on rate limits and server errors.
- Only public sporting data is collected. Please respect the terms of use of the data source when you reuse it.

### Pricing

Each returned data row is one billable result item. Error rows are free. The run stops cleanly when the spending limit you set is reached.

### Running locally

```bash
npm install
./run-test.sh '{"mode":"standings","year":2025,"category":"MotoGP","maxItems":5}'
```

# Actor input Schema

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

calendar = events of a season; results = session classifications; standings = championship tables; riders = rider profiles.

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

Championship season, for example 2025. The data goes back to the 1949 world championship; leave the default for a recent complete season.

## `category` (type: `string`):

Racing class. In calendar mode, ALL returns every event of the season. MotoE is only available in seasons where it was held.

## `event` (type: `string`):

Optional. Comma separated list of event codes (THA, ARG, ITA ...), event name fragments or circuit names. Empty means every event of the season. Used by calendar, results and the team/constructor standings.

## `sessionType` (type: `string`):

Which sessions to return: RAC race, SPR sprint, Q2 / Q1 qualifying parts, Q both, FP1 / FP2 free practice, FP all free practice, PR practice, WUP warm up, or ALL.

## `standingsType` (type: `string`):

rider = official rider championship. team and constructor are computed from the season's race and sprint classifications (constructors score with their best-placed rider in each session).

## `riderIds` (type: `array`):

Optional. Rider UUIDs (as returned in the riderId field of other modes) or numeric legacy IDs of current riders. When set, year and class only select which season's team/number is shown.

## `includeCareerStats` (type: `boolean`):

Adds career totals (starts, wins, podiums, poles, titles ...). Costs one extra request per rider.

## `includeBiography` (type: `boolean`):

Adds the English biography as plain text. Makes rows much longer.

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

Maximum number of result rows to return. Error rows do not count.

## Actor input object example

```json
{
  "mode": "standings",
  "year": 2025,
  "category": "MotoGP",
  "sessionType": "RAC",
  "standingsType": "rider",
  "includeCareerStats": true,
  "includeBiography": false,
  "maxItems": 30
}
```

# 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 = {
    "mode": "standings",
    "year": 2025,
    "category": "MotoGP",
    "sessionType": "RAC",
    "standingsType": "rider",
    "maxItems": 30
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapermaster/motogp-riders-results-standings").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": "standings",
    "year": 2025,
    "category": "MotoGP",
    "sessionType": "RAC",
    "standingsType": "rider",
    "maxItems": 30,
}

# Run the Actor and wait for it to finish
run = client.actor("scrapermaster/motogp-riders-results-standings").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": "standings",
  "year": 2025,
  "category": "MotoGP",
  "sessionType": "RAC",
  "standingsType": "rider",
  "maxItems": 30
}' |
apify call scrapermaster/motogp-riders-results-standings --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scrapermaster/motogp-riders-results-standings"
        }
    }
}
```

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/HwkRc3fMYDHm79j7c/builds/3MK58XXrMrCw6Y8Du/openapi.json
