# French Horse Racing Results · LeTrot & ZEturf (`corent1robert/french-horse-racing-results`) Actor

Export French race cards, starters and official arrivées — the same public meetings listed on LeTrot (trot) and ZEturf (FR). One row per horse-in-race: finish, times, trainer, jockey. No login. Not live betting odds.

- **URL**: https://apify.com/corent1robert/french-horse-racing-results.md
- **Developed by:** [Corentin Robert](https://apify.com/corent1robert) (community)
- **Categories:** Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.70 / 1,000 horse in a races

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?

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

## French Horse Racing Results · LeTrot & ZEturf

Export **French race cards, starters and official arrivées** — the same public meetings listed on [LeTrot](https://www.letrot.com/) (trot) and [ZEturf](https://www.zeturf.fr/) (FR). **One row per horse-in-race.** Finish, times, trainer, jockey or driver.

**No login. No API key. Not live betting odds.**

### Who is this for?

| You are… | Typical goal | Suggested setup |
|----------|--------------|-----------------|
| Form / ratings analyst | Rebuild a day of arrivées with reduced-km times | Yesterday · Trot · max 200 |
| Turf media / data desk | Fill a CMS table after Vincennes or Cabourg | Hippodrome filter · Trot |
| Database vendor | Nightly FR cards + results | Date range · All meetings · `maxItems` 0 |
| Agency building a turf widget | Small, cheap sample for a client demo | Prefill dates · 20 rows |
| Owner / trainer office | One meeting, one spreadsheet | Hippodrome name · Racecard view |

**What you get by default:** race date and off-time (Paris), hippodrome, cloth, horse, rider, trainer, finish when the race is official, finish time and reduced km, career form figures, links to the LeTrot day page (trot) and ZEturf results.

**What this Actor does not do:** live in-play odds, steamers, or tote markets. For live PMU odds see other Store Actors — this one is cards and arrivées only.

### Quick start

1. Open the Actor on Apify and keep **From date** / **To date** on a recent race day (prefill is a full French trotting day).
2. Leave **Discipline** on **Trot (LeTrot)** or switch to **All French meetings**.
3. Click **Start**. Download CSV / Excel from the Dataset tab.

Free plan: **20 rows per run**. Paid plans follow pay-per-event.

### Ready-made examples (published tasks)

Publish these from `published-tasks/` after the first Store push (Console → task Publication). Links 404 until then.

| Example | Best for |
|---------|----------|
| Cabourg trot starters & arrivées | LeTrot meeting sample |
| One French race day (all tracks) | Full FR card like ZEturf |
| LeTrot day URL | Paste-a-link workflow |
| Flat & jumps at Moulins | Galop / ZEturf FR |

### What it extracts

| Category | Fields |
|----------|--------|
| Meeting | `raceDate`, `raceTime`, `reunionNumber`, `raceNumber`, `hippodrome`, `discipline`, `raceName`, `raceStatus` |
| Race setup | `distanceMeters`, `prizeMoneyEur`, `rail`, `declaredRunners` |
| Horse | `horseName`, `horseNumber`, `age`, `sex`, `coat`, `horseBreed`, `formFigures`, `careerRuns`, `careerWins`, `careerEarningsEur` |
| People | `riderName`, `driverName`, `jockeyName`, `trainerName`, `ownerName`, `breederName` |
| Result | `finishPosition`, `finishTime`, `reducedKmTime`, `horseStatus`, `startingPrice` |
| Links | `letrotUrl` (trot days), `zeturfUrl` |

Empty source fields stay `null`.

### Input

| Field | Type | Default | Notes |
|-------|------|---------|--------|
| `dateFrom` | date | yesterday (Paris) if empty | YYYY-MM-DD |
| `dateTo` | date | same as from | Max **31** days per run |
| `discipline` | enum | `trot` | `trot` · `galop` · `all` |
| `hippodromes` | string list | empty | Case-insensitive contains, e.g. `Vincennes` |
| `startUrls` | string list | empty | LeTrot `/courses/YYYY-MM-DD` or a URL with `R1` `C4` |
| `maxItems` | integer | `20` | **0** = no ceiling (paid). **Free plan: 20 / run** |

**API-only** (omit from Console): `verboseLogs` (boolean), `proxyConfiguration` (Apify proxy object). Cloud runs use datacenter proxy by default.

#### JSON example

```json
{
  "dateFrom": "2026-08-28",
  "dateTo": "2026-08-28",
  "discipline": "trot",
  "hippodromes": ["Cabourg"],
  "maxItems": 20
}
```

### Output example

```json
{
  "recordKey": "2026-08-28-R1-C1-4",
  "raceDate": "2026-08-28",
  "raceTime": "18:05",
  "reunionNumber": 1,
  "raceNumber": 1,
  "hippodrome": "HIPPODROME DE CABOURG",
  "discipline": "trot_harness",
  "raceName": "PRIX DES ESCALLONIAS",
  "raceStatus": "official",
  "horseName": "JASMIN PRECIEUX",
  "horseNumber": 1,
  "finishPosition": 11,
  "finishTime": "3'26\"0",
  "reducedKmTime": "1'14\"9",
  "riderName": "J.L.CL. DERSOIR",
  "trainerName": "J.L.CL. DERSOIR",
  "letrotUrl": "https://www.letrot.com/courses/2026-08-28"
}
```

Dataset views: **Overview**, **Results**, **Racecard**.

### How much does it cost to scrape LeTrot or ZEturf results?

HTTP-only (no browser). You pay **pay-per-event**: a tiny start fee plus **one event per horse-in-race row**.

| Scenario | Approx. cost (Free tier list) |
|----------|-------------------------------|
| 20 rows (Try / Free plan cap) | ~$0.02 |
| 1,000 rows | ~$1.00 + start |
| 50,000 rows | ~$50 + start |

| Tier | Per horse-in-race |
|------|-------------------|
| Free | $0.001 |
| Bronze | $0.0009 |
| Silver | $0.0008 |
| Gold | $0.0007 |
| Platinum | $0.0006 |
| Diamond | $0.0005 |

Actor start is **$0.00005** per GB of memory (this Actor defaults to 512 MB). Compute is small because there is no headless Chrome.

### Is it legal to scrape LeTrot / ZEturf race results?

This Actor only reads **public race cards and official arrivées** (meetings already published for the racing public). It does not log into a betting account or collect private customer data. Horse racing results can include names of licence-holders (trainers, drivers). Your use must comply with GDPR and with the terms of any site you reuse the data on. This is not betting advice.

### How it works

1. Resolve the date range (or a pasted LeTrot / ZEturf URL).
2. Load the public French programme for each day.
3. Keep meetings that match **discipline** and **hippodrome**.
4. Load starters / arrivées for each race.
5. Push one dataset row per horse, progressively.

### Local development

```bash
cd french-horse-racing-results
npm install
npm test
apify run
```

`apify run` validates `.actor/INPUT.json` (or `storage/key_value_stores/default/INPUT.json`). Repo `input.json` is merged when you are not on the Apify platform (KV / CLI input wins on conflict). Local `storage/` is **not** uploaded to Console.

### Input (API-only keys)

| Key | Type | Default |
|-----|------|---------|
| `verboseLogs` | boolean | `false` |
| `proxyConfiguration` | object | `{ "useApifyProxy": true }` on cloud |

### Support

Contact <corentin@outreacher.fr> if you need a custom scraper or tailored automation.

# Actor input Schema

## `dateFrom` (type: `string`):

First race day (YYYY-MM-DD). Empty = yesterday in Paris.

## `dateTo` (type: `string`):

Last race day (YYYY-MM-DD). Empty = same as From date. Maximum 31 days per run.

## `discipline` (type: `string`):

**Trot** = LeTrot meetings (harness and mounted). **Flat & jumps** = galop as listed on ZEturf FR. **All** = every French meeting that day.

## `hippodromes` (type: `array`):

Filter by track name, e.g. Vincennes, Cabourg, Laval. Empty = every track that day.

## `startUrls` (type: `array`):

Example: https://www.letrot.com/courses/2026-08-28 — or a ZEturf race URL with R1 C4 in the path.

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

Stop after this many horse-in-race rows. **0** = continue until the date range is done. Free plan: 20 / run.

## Actor input object example

```json
{
  "dateFrom": "2026-08-28",
  "dateTo": "2026-08-28",
  "discipline": "trot",
  "maxItems": 20
}
```

# Actor output Schema

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

Full export — every field from this run.

## `overview` (type: `string`):

Date, track, race, horse, finish, rider, trainer.

## `results` (type: `string`):

Official arrivées with times and reduced km.

## `racecard` (type: `string`):

Starters, form, trainer and rider — finish may still be empty.

## `runLog` (type: `string`):

Plain-text log of the run phases and progress.

# 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 = {
    "dateFrom": "2026-08-28",
    "dateTo": "2026-08-28",
    "discipline": "trot",
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("corent1robert/french-horse-racing-results").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 = {
    "dateFrom": "2026-08-28",
    "dateTo": "2026-08-28",
    "discipline": "trot",
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("corent1robert/french-horse-racing-results").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 '{
  "dateFrom": "2026-08-28",
  "dateTo": "2026-08-28",
  "discipline": "trot",
  "maxItems": 20
}' |
apify call corent1robert/french-horse-racing-results --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,corent1robert/french-horse-racing-results"
        }
    }
}

```

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/iVq0cNuXMOwh8BRGj/builds/gcl14xxCWSAPLU0ET/openapi.json
