railworks · OpenAPI 3.1

Irish Rail engineering works API

railworks reads Iarnród Éireann's planned engineering works page every 6 hours and turns it into structured, queryable data: which days, which stations, what happens there, and how that changed over time. It's read-only, unauthenticated and cacheable.

railworks is not affiliated with or endorsed by Iarnród Éireann. The data is machine-read from their page and may be wrong: check the source before travelling.

Quick start

Subscribe a calendar to one station. One all-day event per affected day, e.g. "No trains at Woodbrook":

webcal://railworks.paddez.com/v1/feeds/notices.ics?station=WBROK

Ask whether a station is affected, and when:

curl https://railworks.paddez.com/v1/stations/WBROK/days

List what's planned (today to 90 days ahead by default):

curl "https://railworks.paddez.com/v1/notices?line=dart"

Follow every change without missing any: see Polling for changes.

Concepts

Term Meaning
Works Notice One dated block of engineering works, as published under one Service Group: a set of days, the published text, and what it does to the service. Identified across page updates by a stable id.
Service Group A heading on the works page ("DART Services", "Rosslare Services") under which notices are published.
Line The stations one Service Group's trains serve, in order along its branches, named after the group (dart, northern-commuters, …).
Build One published version of the works page, identified by when upstream built it (built_at).
Revision A change to a notice's published text between builds, identity unchanged. A trim is a revision that drops days that have passed.
Works Segment A track section where works take place ("between Dromod and Sligo"), expanded to every station in between.
Effect A station- or section-level consequence: no_service, station_closed, bus_replacement, reduced_service, other.
Service Alteration A change to one train (cancelled, bus-replaced, terminating short, …).
Station Day One date a station is affected, with the strongest effect there. The same closure published under DART and Rosslare is one Station Day.
Expired / Withdrawn A notice leaves the page when its days pass (expired, the normal end of life) or while it still had days to come (withdrawn). Nothing is ever deleted.

How notices are read

Polling for changes

/v1/changes is an append-only log of created, revised (with trim), expired, withdrawn and extracted events behind an opaque cursor. Start with ?since= once, then always pass the previous response's next:

cursor=$(curl -s "https://railworks.paddez.com/v1/changes?since=2026-09-01T00:00:00Z" | jq -r .next)
# later, and forever after:
curl -s "https://railworks.paddez.com/v1/changes?after=$cursor" | jq '.events[], .next'

Each event names a notice_id: fetch /v1/notices/{id} for its current state. Treat the cursor as opaque.

Freshness, caching and errors

Reference

Notices

Works Notices, their history, and the change log.

GET /v1/changes Follow the change log

Events after an opaque cursor, oldest first. Pass after (a previous next), or since for a first call only. Each event is returned exactly once when you follow next; an empty page means you're up to date (keep the same next).

GET /v1/notices List Works Notices

Works Notices with any day in the window, unmerged across Service Groups (the same closure published under DART and Rosslare is two notices; use Station Days for one answer per date). Lists leave out day_sections, detail, alterations and revisions: fetch a single notice for those.

GET /v1/notices/{id} Get one Works Notice

The notice in full, with its Day Sections, text, per-train Service Alterations and revision history. Works for any status.

GET /v1/notices/{id}/raw Get a notice's upstream HTML

The verbatim upstream HTML of every revision, oldest first, so you can check railworks' reading against the source.

Stations

Stations, their Lines, and Station Days.

GET /v1/stations List stations

Every Irish Rail station served by timetabled trains, with its Lines and position on each. Refreshed daily from the TFI GTFS feed and Irish Rail's station list.

GET /v1/stations/{code} Get one station

Alias codes (other Irish Rail codes for the same station, e.g. ADAMF) redirect to the canonical code.

GET /v1/stations/{code}/days Is this station affected, and when?

One Station Day per affected date in the window, deduplicated across Service Groups, with the strongest effect at the station (no_service > station_closed > bus_replacement > reduced_service > other), any stated time scope, and the notices behind it. A station reached only by a works segment gets other. Withdrawn notices don't count.

Feeds

Calendar (ICS) subscriptions.

GET /v1/feeds/notices.ics Calendar feed

An iCalendar (RFC 5545) feed to subscribe to. All events are all-day; a stated time of day goes in the title.

UIDs are stable across rewording and trims (days that have passed stay as history), and SEQUENCE rises with each change. Withdrawn events become STATUS:CANCELLED with a "Cancelled: " title and leave the feed a week after their dates. Expired events stay as ordinary past events. The feed covers 90 days back (from overrides) and asks clients to refresh every 6 hours. The calendar is named after the filters ("Rail works · Woodbrook · DART").

Service

Health and this documentation.

GET / Home page

Subscribe to a station's calendar, see its upcoming affected days, and what's planned in the next four weeks. Built on this API.

GET /docs This documentation, rendered

GET /v1/health Health and things needing a human

Freshness, the last failure, the extraction backlog, and anything railworks couldn't resolve by itself.

GET /v1/openapi.yaml This document

Site

Files for browsers, crawlers and tools.

GET /favicon.svg Favicon

The site icon.

GET /llms.txt LLM summary

A plain-Markdown summary of the API for AI tools (llmstxt.org).

GET /og.png Social card

The 1200×630 image shown when the site is shared.

GET /robots.txt Robots rules

Lets crawlers index the pages and keeps them off the API.

GET /sitemap.xml Sitemap

The pages, with the home page's last change.