SNCF Train Ticket and Connection Scraper avatar

SNCF Train Ticket and Connection Scraper

Pricing

from $1.50 / 1,000 trips

Go to Apify Store
SNCF Train Ticket and Connection Scraper

SNCF Train Ticket and Connection Scraper

Scrape live SNCF train connections, schedules, ticket prices, transfers, delays, and fares across France and Europe. Extract structured SNCF timetable data for travel apps, price monitoring, analytics, and AI agents.

Pricing

from $1.50 / 1,000 trips

Rating

5.0

(3)

Developer

Jindřich Bär

Jindřich Bär

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 days ago

Last modified

Share

SNCF train tickets & connections scraper

Search SNCF Connect train journeys across France (TGV INOUI, OUIGO, Intercités, TER, and connecting services) and get back a structured dataset of routes, times, transfers, and live ticket prices — ready to plug into spreadsheets, databases, dashboards, or AI agents.

Pulls data straight from SNCF Connect (sncf-connect.com), so you get the same trains, schedules, and fares a passenger sees when booking.

What you can do with it

  • Compare ticket prices between any two French stations in real time — Paris to Marseille, Lyon to Bordeaux, Lille to Nice, and every other route SNCF Connect covers.
  • See fares by class — cheapest 2nd-class and 1st-class prices, plus the discount-card price when one is offered.
  • Inspect each journey's legs — train type and number, transfer points, per-leg times.
  • Monitor fares over time by scheduling the actor to run daily / hourly and writing results to your own datastore.
  • Build a travel-planning assistant — feed the JSON output into an LLM agent that answers "what's the cheapest train from Paris to Marseille next Saturday morning".

Typical use cases: travel comparison sites, price-monitoring tools, business-trip planners, journalists covering transport, and AI agents that need a structured French rail-data source.

Input

FieldRequiredDefaultDescription
fromyesDeparture station or city (e.g. "Paris", "Marseille Saint-Charles", "Lyon Part Dieu")
toyesDestination station or city
datenotodayDeparture date (date picker, ISO YYYY-MM-DD), Paris local time
timenonowDeparture time (HH:MM, 24-hour, Paris local time)
adultsno1Number of adult passengers — prices are quoted for this group (1–9)
maxResultsno20Maximum number of journeys to push to the dataset (1–100)

Station and city names are matched against SNCF Connect's autocomplete; the actor picks the best matching station (or city) automatically.

Example input

{
"from": "Marseille",
"to": "Paris",
"date": "2026-06-15",
"time": "08:00",
"adults": 1,
"maxResults": 20
}

Output

Each item in the dataset describes one proposed journey.

Example item

{
"id": "51148c3f-fa2e-44f2-b24f-25b24672995e",
"from": "Marseille Saint-Charles",
"to": "PARIS - GARE DE LYON - HALL 1 & 2",
"departure": "2026-06-15T07:57:00+02:00",
"arrival": "2026-06-15T11:16:00+02:00",
"departureTime": "7:57 AM",
"arrivalTime": "11:16 AM",
"durationLabel": "3h 19min",
"transfers": 0,
"transporter": "Direct OUIGO",
"priceAmount": 109,
"priceCurrency": "EUR",
"priceLabel": "€109",
"priceWithDiscountCardAmount": null,
"firstClassPriceAmount": null,
"secondClassPriceAmount": 109,
"legs": [
{
"line": "OUIGO",
"trainNumber": "7822",
"from": "Marseille Saint-Charles",
"to": "PARIS - GARE DE LYON - HALL 1 & 2",
"departure": "2026-06-15T07:57:00+02:00",
"arrival": "2026-06-15T11:16:00+02:00",
"departureTime": "7:57 AM",
"arrivalTime": "11:16 AM",
"durationLabel": "3h 19min"
}
]
}

Field reference

FieldTypeDescription
idstringIdentifier for the proposed journey
from / tostringOrigin / destination station labels
departure / arrivalISO 8601 datetimeScheduled times with Paris offset (e.g. +02:00 in summer); arrival rolls to a later day on overnight journeys
departureTime / arrivalTimestringHuman-readable time labels as shown in the app (e.g. "7:57 AM")
durationLabelstringTotal travel time (e.g. "3h 19min")
transfersintegerNumber of transfers (0 = direct)
transporterstringService summary (e.g. "Direct TGV INOUI", "1 connection")
priceAmountnumber or nullCheapest 2nd-class fare for the requested passengers, in priceCurrency. Null when no bookable fare is shown
priceCurrencystring or nullISO 4217 ("EUR")
priceLabelstring or nullRaw price label as shown in the app (e.g. "€109")
priceWithDiscountCardAmountnumber or nullCheapest fare with a discount card applied, when offered
firstClassPriceAmount / secondClassPriceAmountnumber or nullCheapest 1st- / 2nd-class fares, when shown
legs[]arrayPer-leg breakdown: line (TGV INOUI, OUIGO, Intercités, TER…), train number, stations, times

priceAmount is null on journeys that aren't currently bookable (sold out, or not yet on sale). The journey is still returned with full timing and leg details — only the price is missing.

Pricing

Pay-per-event — one search-result event is charged for each journey pushed to the dataset. A query with maxResults: 10 charges for at most ten events, regardless of how many requests the actor makes under the hood.

Using the API

Trigger runs from your own code via the Apify API. With your Apify API token, a POST request runs the actor synchronously and returns the dataset items:

curl -X POST "https://api.apify.com/v2/acts/jindrich.bar~sncf-train-ticket-scraper/run-sync-get-dataset-items?token=<APIFY_TOKEN>" \
-H "Content-Type: application/json" \
-d '{"from": "Marseille", "to": "Paris", "maxResults": 10}'

Or run asynchronously and poll for status / dataset items:

# Start a run
curl -X POST "https://api.apify.com/v2/acts/jindrich.bar~sncf-train-ticket-scraper/runs?token=<APIFY_TOKEN>" \
-H "Content-Type: application/json" \
-d '{"from": "Marseille", "to": "Paris"}'
# When it's done, read the dataset
curl "https://api.apify.com/v2/datasets/<DATASET_ID>/items?token=<APIFY_TOKEN>"

Official client libraries are available for JavaScript / TypeScript, Python, and via the Apify REST API directly.

Scheduling

Run the actor on a cron schedule from the Schedules tab in the Apify console — daily, hourly, or any custom cron expression. Common patterns:

  • Daily price snapshot at 09:00 — track fare changes for a fixed Paris → Marseille route and chart the trend over weeks.
  • Hourly refresh for a launch week — keep a real-time price board for a route during a promotional campaign.
  • Weekly market scan — compare a basket of intercity routes (Paris↔Lyon, Paris↔Bordeaux, Lyon↔Marseille) for week-over-week price changes.

Schedules can fan out into multiple datasets, push to a webhook, or trigger downstream actors when the run finishes.

Use with AI Agents (Apify MCP)

This actor is exposed through the Apify Model Context Protocol (MCP) server, so any AI agent that speaks MCP — Claude, ChatGPT custom agents, OpenAI Agents SDK, Cursor, etc. — can call it directly to fetch live SNCF ticket prices and connection options.

Once the Apify MCP server is connected, the agent picks up the actor's input schema automatically. Typical prompts that work out of the box:

  • "What's the cheapest train from Paris to Marseille tomorrow morning?"
  • "Find me a direct TGV from Paris to Lyon on 2026-06-15."
  • "How long does the train from Paris to Bordeaux take, and what does it cost?"
  • "List the next five trains from Lyon to Marseille."

The agent fills the input, runs the actor, and reads the structured dataset items back — no scraping, no HTML parsing, no scheduling logic on the agent side.

Why this works well for agents

  • Typed input schema — every field has a title, type, default, and validation rules, so an agent can call the actor without trial-and-error prompting.
  • Typed outputdeparture, arrival, transfers, priceAmount are numbers / ISO timestamps, ready to be diffed, sorted, or compared directly.
  • Predictable results — journeys come back in departure order with full leg breakdowns.

Troubleshooting & support

Most issues come from date/time formatting or sparsely-served routes. Try the fixes below before opening an issue.

Common problems

No results returned

  • The departure date is in the past, or beyond the SNCF Connect booking horizon. Pick a date within the next few months.
  • The route genuinely has no service on the requested day. Try shifting the date.

priceAmount is null on some / all journeys

  • The journey isn't currently bookable (sold out, or not yet on sale). The connection is still returned with full timing and leg details — only the price is missing.

Fewer results than maxResults

  • On sparsely-served routes or late departures, the timetable simply may not have enough matching trains after the requested time. Try an earlier departure time or a larger nearby station.

Invalid time error

  • date must be YYYY-MM-DD (e.g. 2026-06-15). time must be HH:MM in 24-hour format (e.g. 08:00, not 8 AM). Both fields are optional — leave them empty to use "now".

Different prices than the SNCF Connect site shows in a browser

  • The actor returns the cheapest available fare for the requested passengers. Loyalty discounts and promo codes that require a logged-in account aren't applied.

FAQs

Can I search by station ID instead of name? from and to accept station or city names; the actor resolves them to the best-matching SNCF station automatically.

Does it cover metro, trams, or buses? Mainline rail (TGV INOUI, OUIGO, Intercités, TER) and the connecting services SNCF Connect surfaces. Urban transit is largely out of scope. For long-distance buses, see the Flixbus actor below.

Can I get seat availability or book a ticket? No — the actor returns timetable and fare data only. Booking requires SNCF Connect's checkout flow.

Support

Open an issue on the actor's Issues tab in the Apify console. Include the full input JSON, the run ID (visible in the run URL), and the expected vs. actual output — that lets the maintainer pull the exact logs and reproduce the issue quickly.

Need a different data source?

If you're scraping connections across multiple operators, check our companion actors:

All these actors emit a comparable schema (from, to, departure, arrival, price, leg-level breakdown), so an aggregator agent can merge their outputs into a single multi-modal travel search.