reitti is a non-interactive journey-planning CLI for people and AI agents. It resolves places, compares public-transport journeys, lists nearby stops and departures, and reports service alerts using Digitransit open data.
It covers the HSL Journey Planner service area: Helsinki, Espoo, Vantaa, Kauniainen, Kerava, Kirkkonummi, Sipoo, Siuntio, and Tuusula.
- Installation
- API key and first run
- Examples
- Configuration · Full configuration reference
- Agent skill
- Limits and interpretation
- Privacy and data sources
Install with Rust 1.88 or newer:
cargo install --locked reitti-cliThe package is reitti-cli; the installed command is reitti.
brew install jarimustonen/reitti/reitti-cliThe Homebrew tap installs a prebuilt binary on macOS arm64 and Linux arm64/x86_64.
curl --proto '=https' --tlsv1.2 -LsSf \
https://github.com/jarimustonen/reitti-cli/releases/latest/download/reitti-cli-installer.sh | shGitHub Releases also provides archives for macOS arm64 and Linux arm64/x86_64 (static musl). Each archive has a matching .sha256 file; releases also include sha256.sum. Verify the checksum before installing an archive. Other architectures and operating systems are unsupported in v1.
git clone https://github.com/jarimustonen/reitti-cli
cd reitti-cli
cargo install --locked --path crates/reitti-cliDigitransit requires a free subscription key. Follow the registration and key-rotation guide, then save the key without placing it in command arguments or shell history. This Bash-compatible hidden-input wrapper works on supported macOS and Linux systems:
read -rsp 'Digitransit subscription key: ' key; printf '\n'
printf '%s\n' "$key" | reitti config update --subscription-key-stdin
unset keyThe CLI itself remains non-interactive: --subscription-key-stdin reads exactly one line supplied by a caller. A secret manager can pipe the key to the same option instead.
Check the local setup first, then make deliberate network checks:
reitti doctor
reitti doctor --onlinedoctor is read-only. Offline mode validates configuration, credential presence, bundled-skill synchronization, build provenance, and configured private markers without contacting Digitransit. --online adds bounded geocoding and routing probes.
The installed CLI's --help is the authoritative reference for commands and flags. Each command supports it, and schema describes the JSON responses. These commands work without an API key:
reitti --help
reitti journey list --help
reitti --json schema list
reitti --json schema show journey-listUse --json for schema-versioned output. Times must be RFC 3339 with Z or an explicit offset; coordinates use LAT,LON without whitespace.
Find candidates before choosing an ambiguous place, or inspect one known stop:
reitti --json location list --query "Kamppi" --kind stop --limit 5
reitti --json stop list --near 60.1699,24.9384 --radius-m 500 --limit 5
reitti --json stop show HSL:1020453stop show takes a raw HSL: stop ID and returns bounded Digitransit facts plus an explicit reittiopas_url for human follow-up. The linked web page is not an additional machine-authoritative source.
Plan from coordinates at the current time:
reitti --json journey list \
--from coord:60.1699,24.9384 \
--to coord:60.1776,24.6529 --limit 3For a deadline, use the actual travel date and its UTC offset. The timestamp below is illustrative, not a current timetable query:
reitti --json journey list \
--from query:Kamppi --to stop:HSL:1020453 \
--arrive-by 2027-02-15T10:00:00+02:00 \
--wheelchair --max-walk-m 800 --limit 6List departures and active alerts. These commands take raw HSL identifiers, without a stop: or route: reference prefix:
reitti --json departure list --stop HSL:1020453 --window 2h --limit 10
reitti --json alert list --route HSL:31M1 --stop HSL:1020453 --limit 25Add --include-geometry to a journey request when GeoJSON route lines are needed.
Persistent values follow this precedence independently for each key:
- a matching invocation flag;
- an environment variable;
- the configuration file;
- the built-in default.
--routing-url, --geocoding-url, --connect-timeout, and --request-timeout are temporary invocation overrides. Their persistent counterparts are the config update --set-* options. Supported duration suffixes are ms, s, m, and h; connection and whole-request defaults are 5 seconds and 20 seconds.
Inspect the selected file and every effective value's source:
reitti --json config path
reitti --json config show
reitti --json config update --language fi --timezone Europe/Helsinki --dry-runThe subscription key and private-marker values are redacted by default. Configuration files are created with private permissions. See Configuration and operation for paths, environment variables, safe key setup, and runtime behavior.
The binary bundles a version-matched Agent Skill with supporting workflow guidance. Inspect it without writing files:
reitti --json skill list
reitti skill print reittiInstall the native skill tree for Claude Code, Pi, and Codex into an isolated or real home only when intended:
reitti --json skill install reitti --agent all --dry-run
reitti --json skill install reitti --agent allInstallation is non-interactive and does not clobber a differing existing tree. Use --force only after reviewing the destination. Select one runtime with --agent claude, --agent pi, or --agent codex; use --target DIR to change the install base.
- A
query:journey endpoint is accepted only when it resolves uniquely with strong provider confidence. Otherwiselocation_ambiguousreturns candidates; select a returnedplace:orstop:reference rather than guessing. - Results are bounded and may be incomplete. Comparison labels such as
fastestapply only to alternatives in that response. --wheelchairasks the router for wheelchair-aware results but cannot prove every part of a trip is accessible. Preserveunknownaccessibility evidence.--max-walk-mfilters only the bounded alternatives already returned by Digitransit. No local match does not prove that no suitable route exists.- Times are labelled to distinguish timetable data from realtime updates. When no realtime update is available, the CLI shows the scheduled time. Matching scheduled and reported times alone do not mean a realtime update was received.
- Navigation can be incomplete or truncated. GeoJSON coordinates are
[longitude, latitude], unlike CLI input coordinates. - An empty alert list does not guarantee normal service.
The bundled Agent Skill contains the detailed interpretation and corrective-retry workflow.
reitti sends requested locations, stops, routes, times, language, and planning options to the configured Digitransit HTTPS endpoints. The subscription key is sent in the digitransit-subscription-key request header, never in the URL. The CLI has no analytics, account system, or background tracking. Persistent configuration stays on the local machine; command output goes to stdout or an explicitly selected file.
Journey, stop, departure, alert, and map-related facts come from Digitransit and its upstream sources. Preserve the attribution included in command responses when presenting results. Upstream data keeps its own licensing and attribution terms; the MIT License covers this software only.
This project is independent and is not affiliated with or endorsed by HSL or Digitransit.
See CONTRIBUTING.md, SECURITY.md, and distribution operations.
The software is available under the MIT License. Transit, map, and other upstream data are not relicensed by this repository.