9292 API9292.nl ↗
Search Dutch public transport stops, plan multi-modal trips, and retrieve leg-by-leg journey details including fares, platforms, and transfer counts via the 9292.nl API.
What is the 9292 API?
The 9292.nl API exposes 3 endpoints for querying the Dutch public transport network, covering trains, buses, trams, metros, and ferries. Use search_locations to resolve station names or addresses into location IDs, plan_trip to retrieve multiple route options with pricing and operator data, and get_journey_details to pull full leg-by-leg breakdowns including platforms, intermediate stops, and fare class information.
curl -X GET 'https://api.parse.bot/scraper/1f75bb0f-f76b-47f6-9036-0d839252dfe4/search_locations?limit=10&query=Amsterdam+Centraal' \ -H 'X-API-Key: $PARSE_API_KEY'
Typed, relational, agent-ready
A generated client with real types, enums, and the links between objects — the structure a flat JSON response can't carry. Autocompletes in your editor and reads cleanly to coding agents.
- Fully typed · autocompletes
- Objects link to objects
- Typed errors & pagination
Typed Python client. Set up the SDK in your uv project, then pull this API’s typed client:
uv add parse-sdk uv run parse init uv run parse add --marketplace 9292-nl-api
uv run parse add --marketplace pulls a pinned snapshot of this canonical API — it won’t change underneath you. To customize it, subscribe and swap to your own copy.
"""Walkthrough: 9292 Dutch Public Transport SDK — bounded, re-runnable; every call capped."""
from parse_apis.api_9292_nl_api import NinetyTwoNinetyTwo, RequestType, LocationUnknown
client = NinetyTwoNinetyTwo()
# Search for locations to find valid station IDs.
for loc in client.locations.search(query="Utrecht", limit=3):
print(loc.label, loc.category, loc.place)
# Plan a trip between two stations.
origin = client.locations.search(query="Amsterdam Centraal", limit=1).first()
for trip in client.trip_plans.plan(
from_location=origin.id,
to_location="station-rotterdam-centraal",
request_type=RequestType.DEPARTURE,
limit=3,
):
print(trip.departure_time, trip.duration_minutes, "min", trip.price_euro_cents, "ct", trip.operators)
# Get full journey details for the first trip found.
trip = client.trip_plans.plan(
from_location="station-amsterdam-centraal",
to_location="station-rotterdam-centraal",
limit=1,
).first()
try:
detail = client.journey_details.get(journey_id=trip.journey_id)
print(detail.from_, "→", detail.to, "|", detail.duration_minutes, "min")
for leg in detail.legs:
print(" ", leg.departure.name, leg.departure.platform, "→", leg.arrival.name, leg.modality)
except LocationUnknown as e:
print("location not found:", e)
print("exercised: locations.search, trip_plans.plan, journey_details.get")
Search for public transport locations (stations, stops, addresses) by free-text query. Returns matching locations with their unique IDs, which are used as inputs to plan_trip. Results are ranked by relevance to the query.
| Param | Type | Description |
|---|---|---|
| limit | integer | Maximum number of results to return (1-50). |
| queryrequired | string | Free-text search query for a location name, station, stop, or address. |
{
"type": "object",
"fields": {
"locations": "array of location objects with id, label, category, place, lat_long, and location_type"
},
"sample": {
"data": {
"locations": [
{
"id": "station-amsterdam-centraal",
"label": "Amsterdam Centraal",
"place": "Amsterdam",
"category": "Treinstation",
"lat_long": "52.378706,4.900489",
"location_type": "Station"
}
]
},
"status": "success"
}
}About the 9292 API
Location Search and ID Resolution
search_locations accepts a free-text query and returns up to 50 matching results (controlled by the limit parameter). Each result includes an id field — such as station-amsterdam-centraal — along with a human-readable label, a category, a place, lat_long coordinates, and a location_type. These IDs are the required inputs for trip planning, so location search is typically the first call in any workflow.
Trip Planning
plan_trip takes a from and to location ID and returns between 1 and 15 route options (set via the results parameter). The date_time parameter accepts an ISO 8601 UTC datetime so you can plan for future or past times, and request_type specifies whether that timestamp is a departure or arrival time. An extra_interchange_time parameter adds buffer minutes at each transfer. Each trip option in the trips array includes a journey_id, departure and arrival times, total duration, price, the transport modes involved, and the operators running each segment.
Detailed Journey Breakdown
get_journey_details accepts a journey_id from plan_trip and returns the full structure of a trip. The legs array covers each individual segment with departure and arrival station info, platform numbers, modality (e.g. train, tram, bus), and intermediate stops. The fare_info object provides a detailed fare breakdown by class and available reductions. Additional top-level fields include cancelled (boolean), duration_minutes, price_euro_cents, and number_of_changes.
The 9292 API is a managed, monitored endpoint for 9292.nl — not a raw scraper you maintain. Every endpoint is automatically health-checked on a schedule, and when 9292.nl changes and a check fails, the API is automatically queued for repair and re-verified. It is built to keep working as the site underneath it changes.
This isn't an official 9292.nl API — it's an independent, maintained REST wrapper over public data. Where the source has no official API (or only a limited one), Parse gives you a stable contract over a source that never promised one, and keeps it current. Need a new endpoint or field? You can revise it yourself in plain English and the agent rebuilds it against the live site in minutes — contributing the change back to the shared API is free.
Will this API break when the source site changes?+
Is this an official API from the source site?+
Can I fix or extend this API myself if I need a new endpoint or field?+
What happens if I call an endpoint that has an issue?+
- Build a commute planner app that resolves Dutch station names with
search_locationsand surfaces fastest routes viaplan_trip. - Display real-time cancellation status for booked journeys using the
cancelledfield fromget_journey_details. - Calculate travel costs between any two Dutch cities using
price_euro_centsandfare_infofrom detailed journey results. - Show platform numbers and intermediate stops for a specific leg using the
legsarray inget_journey_details. - Compare journey duration and number of transfers across multiple route options returned by
plan_trip. - Identify which transport operators (train, bus, ferry) serve a given route using the
operatorsfield inplan_tripresults. - Automate arrival-time-based trip planning by setting
request_typeto arrival and providing a targetdate_time.
| Tier | Price | Credits/month | Rate limit |
|---|---|---|---|
| Free | $0/mo | 200 | 5 req/min |
| Hobby | $30/mo | 1,000 | 20 req/min |
| Developer | $100/mo | 5,000 | 100 req/min |
| Team | $300/mo | 20,000 | 300 req/min |
| Company | $1,000/mo | 100,000 | 500 req/min |
Each endpoint has a fixed posted price per successful call — most fall between 1 and 10 credits — shown on this API's page before you run it. Exceeding the rate limit returns a 429 response. Authenticate with the X-API-Key header.
Does 9292.nl have an official developer API?+
What does `get_journey_details` return beyond what `plan_trip` already provides?+
plan_trip returns summary data per route option: times, total duration, price, modes, and operators. get_journey_details expands a specific journey_id into individual legs with per-leg departure and arrival stations, platform numbers, intermediate stops, a cancelled boolean, and a fare_info object that breaks down fares by class and available reductions.Can I plan trips outside the Netherlands using this API?+
Does the API return real-time disruption or service alerts for a route?+
cancelled boolean per journey via get_journey_details, but it does not currently expose broader service disruption messages, delay reasons, or network-wide alerts. You can fork this API on Parse and revise it to add an endpoint that surfaces disruption data.How do location IDs work, and do they stay stable over time?+
search_locations as strings like station-rotterdam-centraal. They are used as from and to inputs in plan_trip. IDs follow a predictable naming pattern for major stations, but they should be resolved fresh from search_locations rather than hardcoded, as stop-level IDs for bus stops and tram halts may change when operators restructure their networks.