Deutsche Bahn Train Tickets Scraper - Fares & Timetables
Pricing
from $2.00 / 1,000 train connections
Deutsche Bahn Train Tickets Scraper - Fares & Timetables
Scrape Deutsche Bahn train tickets: connections, ICE and regional timetables, Sparpreis fares, BahnCard prices and delays. $4 per 1,000 connections.
Pricing
from $2.00 / 1,000 train connections
Rating
0.0
(0)
Developer
Muhammad Afzal
Maintained by CommunityActor stats
0
Bookmarked
4
Total users
2
Monthly active users
11 days ago
Last modified
Categories
Security
Limited permissionsShare
Deutsche Bahn Train Tickets Scraper returns Deutsche Bahn train connections between any two DB stations, with departure and arrival times, changes, ICE, IC and regional products, platforms, delays, and current ticket offers such as Super Sparpreis, Sparpreis and Flexpreis in EUR. It is built for travel apps, fare-monitoring dashboards, mobility researchers and AI agents, and costs $4.00 per 1,000 connections on the Apify Free plan plus a $0.005 start fee per run.
The Actor reads Deutsche Bahn's public journey data, handles data access itself, and saves one validated row per connection. It never books, reserves or buys tickets, and it charges only for connections it actually saves.
What Deutsche Bahn train ticket data does it return?
Each dataset row is one connection (one journey option from origin to destination).
| Field | What it holds |
|---|---|
connectionId | Stable 20-character ID for deduplication |
origin, destination, originId, destinationId | Resolved station names and DB station IDs |
departureTime, arrivalTime | Current departure and arrival, ISO 8601 with offset |
plannedDepartureTime, plannedArrivalTime | Timetable times, so you can compute delays |
durationMinutes, changes, direct, cancelled | Journey summary |
price, currency, partialFare | Lowest fare Deutsche Bahn returned for the journey, or null when none was offered |
ticketOffers | Each fare's name, price, currency, class, partial-fare flag and conditions |
products, operators | Train types (ICE, IC, RE, RB, S-Bahn, bus) and operating companies |
legs | Per-leg stations, times, delay seconds, platforms, line, operator, load factor and notices |
remarks | Service notices for the whole journey |
adults, travelClass, bahnCard, searchedOrigin, searchedDestination, searchedAt | The search that produced the row |
source, sourceProfile, sourceUrl | Provenance |
Every run also writes an OUTPUT record in the key-value store. Its outcome is DATA, EMPTY, REJECTED, BLOCKED or FAILED, with delivered and charged counts, resolved stations and warnings, so you can tell a real empty timetable from an access problem.
When should you use it, and when not?
Use it when you need:
- DB train tickets, fares and timetables for specific routes and dates, for example Berlin Hbf to München Hbf tomorrow at 08:00;
- German train ticket prices for second or first class, with or without a BahnCard 25, 50 or 100;
- a fare monitor that checks the same route on a schedule and records Sparpreis changes;
- structured connections for an AI travel assistant or a comparison page.
Do not use it when:
- you want to book or pay for a ticket. The Actor is read-only;
- the trip is in Italy. Use Trenitalia Train Tickets Scraper or Italo Train Scraper;
- the trip is in Great Britain. Use National Rail Tickets Scraper;
- you need long-distance buses. Use FlixBus Tickets Scraper in Europe or Greyhound Bus Tickets, Megabus & Amtrak Scraper in the US;
- you need a full station departure board or a bulk timetable export. This Actor searches one A-to-B route per run and returns at most 20 connections.
How do I search Deutsche Bahn connections and fares?
Enter two station names and, optionally, a date and time. Station names such as Berlin Hbf, München Hbf or Frankfurt(Main)Hbf work best; the Actor picks the exact name match, otherwise the first station DB suggests.
travelDateisYYYY-MM-DDin Germany time. Leave it empty to search tomorrow, which keeps saved Tasks and schedules evergreen. Words such as "tomorrow" are not accepted; dates in the past or more than 365 days ahead are rejected.travelTime(default08:00) withsearchByset todeparture(leave at or after) orarrival(arrive by).adults(1-5) andadultAge(18-99),travelClass(secondorfirst) andbahnCard(none,bahncard25,bahncard50,bahncard100) shape the fares.directOnly,includeLocalTransport(S-Bahn, U-Bahn, tram, bus and ferry legs) andbikefilter the connections.includeTicketOffers(default on) fetches every fare for each connection. Turn it off when the lowest price is enough.maxResultscaps the rows, from 1 to 20 (default 5).
{"origin": "Berlin Hbf","destination": "München Hbf","travelTime": "08:00","searchBy": "departure","adults": 1,"travelClass": "second","bahnCard": "bahncard25","includeTicketOffers": true,"maxResults": 5}
Use it from an AI assistant
Deutsche Bahn Train Tickets Scraper works from Claude, ChatGPT, Cursor or any other MCP client through Apify's MCP server. Add https://mcp.apify.com/?tools=muhammadafzal/deutsche-bahn-train-tickets-connections-scraper as a server, and the assistant can call the Actor as a single tool. Example prompt: "Find the five earliest Deutsche Bahn trains from Hamburg Hbf to Köln Hbf next Friday after 07:00 and list the cheapest second-class fare for each."
How do I run it from code?
JavaScript (apify-client):
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('muhammadafzal/deutsche-bahn-train-tickets-connections-scraper').call({origin: 'Berlin Hbf',destination: 'München Hbf',travelTime: '08:00',maxResults: 5,});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items.map((c) => `${c.departureTime} ${c.products.join('/')} ${c.price} ${c.currency}`));
Python (apify-client 3.x):
import osfrom apify_client import ApifyClientclient = ApifyClient(os.environ["APIFY_TOKEN"])run = client.actor("muhammadafzal/deutsche-bahn-train-tickets-connections-scraper").call(run_input={"origin": "Berlin Hbf", "destination": "München Hbf", "travelTime": "08:00", "maxResults": 5})for item in client.dataset(run.default_dataset_id).iterate_items():print(item["departureTime"], item["changes"], item["price"], item["currency"])
What does the output look like?
Two connections from a default run (Berlin Hbf to München Hbf, searched 2026-10-26), shortened: legs and the long fare conditions are trimmed.
[{"connectionId": "273d7daa274ac4bd318b","origin": "Berlin Hbf","destination": "München Hbf","departureTime": "2026-10-27T08:29:00+01:00","arrivalTime": "2026-10-27T13:08:00+01:00","durationMinutes": 279,"changes": 0,"direct": true,"cancelled": false,"price": 107.99,"currency": "EUR","products": ["ICE"],"operators": ["DB Fernverkehr AG"],"ticketOffers": [{ "name": "Super Sparpreis", "price": 107.99, "currency": "EUR", "firstClass": false, "partialFare": false, "conditions": ["Train selection. Cancellation. No City-Ticket"] },{ "name": "Flexpreis", "price": 178.9, "currency": "EUR", "firstClass": false, "partialFare": false, "conditions": ["Train selection. Cancellation. City-Ticket"] }],"legs": [{ "line": "ICE 505", "departurePlatform": "3", "arrivalPlatform": "20", "loadFactor": "high" }],"travelClass": "second","bahnCard": "none","source": "Deutsche Bahn"},{"connectionId": "28507d977bc881082540","departureTime": "2026-10-27T08:43:00+01:00","arrivalTime": "2026-10-27T13:08:00+01:00","durationMinutes": 265,"changes": 1,"direct": false,"price": 83.99,"currency": "EUR","products": ["ICE"],"legs": [{ "line": "ICE 371", "origin": "Berlin Hbf", "destination": "Erfurt Hbf" },{ "line": null, "origin": "Erfurt Hbf", "destination": "Erfurt Hbf", "walking": true },{ "line": "ICE 505", "origin": "Erfurt Hbf", "destination": "München Hbf" }]}]
Pricing: how much does a Deutsche Bahn search cost?
You pay per connection saved, plus a small start fee. Platform usage is included in these prices.
| Event | FREE | BRONZE | SILVER | GOLD |
|---|---|---|---|---|
| Train connection (primary event, per saved row) | $0.004 | $0.004 | $0.004 | $0.002 |
| Actor start (per started GB of allocated memory) | $0.005 | $0.005 | $0.005 | $0.005 |
PLATINUM and DIAMOND plans pay the GOLD price. The default memory is 256 MB, so a normal run pays one start event.
Worked totals on the Free plan:
- Default run, 5 connections: $0.005 + 5 × $0.004 = $0.025.
- Maximum run, 20 connections: $0.005 + 20 × $0.004 = $0.085 (GOLD: $0.045).
Rejected inputs, empty searches and blocked runs save no rows and charge no connection events; only the start fee applies. If you set a maximum cost per run, the Actor stops cleanly when it is reached.
How reliable is it, and what are its limits?
- The default run (Berlin Hbf to München Hbf, 5 connections) finished in about 17 seconds on 2026-10-26 and saved 5 connections with fares.
- Up to four result pages are read per search, and at most 20 connections are saved per run.
- Ticket offers are fetched for every returned connection in small parallel batches. If one fare lookup fails, the connection is still saved and a warning goes to
OUTPUT. - Prices and seats change constantly. Each row is a snapshot at
searchedAt; confirm on the official DB site before you travel. - The Actor handles data access itself. If Deutsche Bahn refuses every attempt, the run ends
BLOCKEDwith no connection charges.
FAQ
Does it buy or reserve Deutsche Bahn tickets?
No. It only reads public connection and fare data. Booking, seat reservation and payment stay on the official Deutsche Bahn website or app.
How far ahead can I search, and what date is used by default?
Any date from today up to 365 days ahead, in YYYY-MM-DD format. With no date, the Actor searches tomorrow in Germany time, so a saved Task always looks one day ahead.
Can I get BahnCard and first-class prices?
Yes. Set bahnCard to 25, 50 or 100 and travelClass to first or second. The same discount and age apply to every adult in the search.
Why is price empty for some connections?
price is null when Deutsche Bahn returns no fare for that journey. The schedule fields are still filled, and ticketOffers is then usually empty too.
Does it include regional trains, S-Bahn and buses?
Regional and long-distance trains are always searched. includeLocalTransport (on by default) adds S-Bahn, U-Bahn, tram, bus and ferry legs; turn it off for rail-only results.
Are delays and platforms included?
Yes, when Deutsche Bahn publishes them. Compare departureTime with plannedDepartureTime, or read departureDelaySeconds and the platform fields on each leg.
What happens if the route has no trains?
The run ends with outcome: "EMPTY" in OUTPUT, saves no rows and charges no connection events.
Related Actors
- Trenitalia Train Tickets Scraper: Frecciarossa, Intercity and regional fares in Italy.
- Italo Train Scraper: Italo high-speed fares by class.
- National Rail Tickets Scraper: UK train times and fares.
- FlixBus Tickets Scraper: FlixBus schedules, prices and seats.
- Greyhound Bus Tickets, Megabus & Amtrak Scraper: US intercity bus fares and Amtrak schedules.
- SNCF Scraper and SJ Train Tickets Scraper: French and Swedish trains.
Legal and responsible use
Deutsche Bahn data is subject to Deutsche Bahn's terms, database rights and local law. Use it for research and planning at a reasonable volume, get any permission your commercial use requires, and do not present scraped fares as guaranteed or as a booking. This Actor is independent and not affiliated with or endorsed by Deutsche Bahn AG.
Last verified: 2026-10-27