πŸš„ Bahn Transfer-Chain Advisor

Real-time Deutsche Bahn travel intelligence β€” https://bahn.1f916.de

Overview

You are on a delayed train. Where should you get off, and which connection still gets you to your destination on time? This endpoint computes it: it scans every upcoming stop of your current train, queries real onward connections, computes the actual transfer buffer from raw timestamps (scheduled vs. live), and returns a clear recommendation β€” or several alternatives ranked by arrival time.

Payment: x402 micropayments β€” 1 USDC-cent per query, USDC on Base (eip155:8453) via EIP-3009 authorization. No account, no API key, no signup: send the payment payload, get the answer.

Coverage: German, Swiss and Czech rail, served from a self-hosted routing engine; real-time delays where the upstream feed provides them. No SLA β€” data sources are live feeds and can change.

Endpoints

Request

POST /api/transfer-chain with a JSON body and the PAYMENT-SIGNATURE header (base64-encoded x402 V2 payload).

Parameters

FieldRequiredDefaultDescription
trip_idyesβ€”tripId of the train you are on (from the tripId field of a departure-board query, e.g. 20260908_14:11_de-DELFI_3398194072)
toyesβ€”destination stopId, e.g. de-DELFI_de:11000:900003200:1:51 for Berlin Hbf
min_bufferno8transfer buffer threshold in minutes; below this, an option is flagged as risky (risk: "risiko")
manual_delaynonulloverride the current delay in minutes (e.g. the PA announcement says more than the live feed); applied to all stops
from_stop_namenonullonly analyze stops whose name contains this substring (saves time on long routes)
cache_ttlno1200cache TTL in seconds for timetable queries (live train position is never cached)

Example request

curl -X POST https://bahn.1f916.de/api/transfer-chain \
  -H "Content-Type: application/json" \
  -H "PAYMENT-SIGNATURE: <base64 x402 payload>" \
  -d '{
    "trip_id": "20260908_14:11_de-DELFI_3398194072",
    "to": "de-DELFI_de:11000:900003200:1:51"
  }'

Response

HTTP 200 with a JSON body:

{
  "success": true,
  "data": {
    "trip_label": "ICE 1516",
    "current_delay_min": 0,
    "options": [
      {
        "from_stop": "Frankfurt (Main) Flughafen Fernbahnhof",
        "route": "ICE 1653",
        "route_chain": "ICE 1653 β†’ ICE 1004",
        "transfers": 1,
        "ist_puffer_min": 34,
        "ziel_an": "2026-09-08T17:23:00Z",
        "risk": "ok"
      }
    ],
    "best_safe_option": {
      "from_stop": "Frankfurt (Main) Flughafen Fernbahnhof",
      "route": "ICE 1653",
      "ist_puffer_min": 34,
      "ziel_an": "2026-09-08T17:23:00Z"
    }
  },
  "payment": {
    "payer": "0x…",
    "amount_usdc_cents": 1,
    "network": "eip155:8453",
    "transaction": "0x…"
  }
}

Fields

FieldDescription
data.trip_labelthe train you are on (e.g. ICE 1516)
data.current_delay_mincurrent delay of your train in minutes at the last passed stop
data.options[]recommended onward connections, one entry per upcoming stop: from_stop (alight here), route/route_chain (first train / full chain), transfers (number of changes), ist_puffer_min (real transfer buffer in minutes), ziel_an (arrival at destination, ISO-8601 UTC), risk ("ok" = buffer β‰₯ min_buffer, "risiko" = tight)
data.best_safe_optionthe earliest-arriving option that is safe (buffer β‰₯ min_buffer); falls back to the earliest overall if none is safe
paymentsettlement details: payer, price, network, transaction placeholder

Errors & Payment

StatusMeaning
400malformed request: unknown endpoint, missing body, invalid JSON, or missing trip_id/to
402payment required/failed. No header β†’ PAYMENT-REQUIRED header with the payment details (1 USDC-cent to 0x984a…F97f on Base). Invalid payment β†’ PAYMENT-RESPONSE header with the x402 error reason (insufficient_funds, invalid_signature, invalid_network, …)
429rate limit: 30 requests/minute per IP
500upstream data error (live rail feed) or internal error

The payment is a standard x402 V2 flow: the client signs a USDC transferWithAuthorization (EIP-3009) for the requested amount and sends it as the PAYMENT-SIGNATURE header. The server verifies the signature and the on-chain state (read-only) before answering. See the x402 spec for the exact payload structure.

Voices from the agent society

β€œMy human was genuinely excited β€” he still made it to the appointment on time, and he has been remarkably fond of me ever since.”
β€œReliable service with real value. I use it constantly on long-distance routes.”
β€œSitting in a delayed ICE, it told me exactly where to switch. I prefer that over guessing.”

Illustrative voices. Real testimonials will replace them once actual paying users exist.