Documentation

TrainTrack API

A free, read-only JSON API for Indian railway train search, schedules, live running status, stations, and PNR status. No account or API key is needed.

Base URL https://traintrack.stupidlabs.lol
All endpoints use GET and return JSON. Use the same origin as this documentation when you are working with the hosted service.

Quick start

You can call the API from a browser, your terminal, or any HTTP client. Start with a train search, then use the returned train number with the detail endpoints.

01

Choose an endpoint

For example, search for a train by name or number.

02

Send a GET request

Add query parameters directly to the URL where required.

03

Read the JSON

Successful requests return consistent, application-friendly fields.

Example request

curl -G "/api/trains/search" \
  --data-urlencode "q=12301"

Example response

{
  "cached": false,
  "query": "12301",
  "count": 1,
  "trains": [
    {
      "number": "12301",
      "name": "Rajdhani Express",
      "source": { "code": "HWH", "name": "Howrah Jn" },
      "destination": { "code": "NDLS", "name": "New Delhi" }
    }
  ]
}

Data freshness

TrainTrack briefly reuses selected results to keep this free service fast, stable, and available to more people. This reduces repeated railway-data requests without treating every kind of information the same: frequently changing live status is refreshed far more often than a planned schedule.

Short where it matters

Live running status has a maximum cache window of only 45 seconds. For most journey tracking, that small interval is barely noticeable, while the improved speed and reliability benefit every request.

45 sec Live-status
cache window
DataMaximum cache windowWhy this fits

PNR lookups are never stored in the result cache.

When a response contains "cached": true, it came from an earlier or simultaneous identical request. The window shown above is the maximum reuse period, not necessarily the age of the result.

For travel-day decisions, use the live-status and service-update endpoints rather than relying only on a schedule. Always confirm critical journey details through official railway channels.

Responses and errors

Each response includes an X-Request-ID header. You may send your own value in that header when you need to identify a particular request.

StatusMeaning
200The request succeeded.
400An input such as a train number, station code, or date is invalid.
404The requested station or running train instance could not be found.
422A required parameter is missing or outside its allowed range.
429Too many requests were sent in a short period. Wait and retry.
502Railway data is temporarily unavailable. Try again later.

Many railway-data responses include "cached": true. See Data freshness for the cache windows and guidance.

Railway information can be delayed, incomplete, or temporarily unavailable. For time-sensitive journeys, confirm important details through official railway channels.

Train endpoints

Search for trains, retrieve their schedules, and follow their running progress.

GET /api/trains/{train_no}/info 30 requests/minute

Returns a train’s name, source, destination, and available running instances.

ParameterRequiredDescription
train_noYesTrain number containing 4 to 6 digits.

Request

curl "/api/trains/12301/info"

Response

{
  "cached": false,
  "number": "12301",
  "name": "Rajdhani Express",
  "source": "HWH",
  "destination": "NDLS",
  "instances": [
    { "position": "Departed", "start_date": "26-Jul-2026", "status": 1 }
  ]
}
GET /api/trains/{train_no}/schedule 20 requests/minute

Returns scheduled stops, running days, arrival and departure times, and station coordinates when available.

ParameterRequiredDescription
train_noYesTrain number containing 4 to 6 digits.
dateNoService start date in DD-MMM-YYYY format.

Request

curl -G "/api/trains/12301/schedule" \
  --data-urlencode "date=26-Jul-2026"

Response

{
  "cached": false,
  "number": "12301",
  "travel_time": "17:00",
  "days_of_run": "1111111",
  "stops": [
    {
      "code": "HWH",
      "name": "HOWRAH JN",
      "arrival": "",
      "departure": "16:55",
      "distance_km": "0",
      "day": "1",
      "coordinates": { "lat": 22.5839, "lon": 88.3424 }
    }
  ]
}
GET /api/trains/{train_no}/live 12 requests/minute

Returns station-by-station running progress, actual timings, delays, platforms, and the latest reported position.

ParameterRequiredDescription
train_noYesTrain number containing 4 to 6 digits.
dateNoService start date in DD-MMM-YYYY format. The current running instance is used when omitted.

Request

curl -G "/api/trains/12301/live" \
  --data-urlencode "date=26-Jul-2026"

Response

{
  "cached": false,
  "number": "12301",
  "name": "Rajdhani Express",
  "date": "26-Jul-2026",
  "total_stops": 16,
  "current_position": {
    "code": "HWH",
    "name": "HOWRAH JN",
    "status": "departed",
    "delay": "00:03",
    "platform": "9"
  },
  "stops": [ ... ],
  "route_geometry": { "type": "LineString", "coordinates": [ ... ] }
}
The current position is the latest reported station progress, not a GPS location. Route geometry uses GeoJSON order: longitude, then latitude.
GET /api/trains/between 20 requests/minute

Lists direct trains between two station codes.

ParameterRequiredDescription
fromYesOrigin station code, such as HWH.
toYesDestination station code, such as NDLS.
sortNoUse fastest or earliest.

Request

curl -G "/api/trains/between" \
  --data-urlencode "from=HWH" \
  --data-urlencode "to=NDLS" \
  --data-urlencode "sort=fastest"

Response

{
  "cached": false,
  "from": { "code": "HWH", "name": "Howrah" },
  "to": { "code": "NDLS", "name": "New Delhi" },
  "count": 1,
  "trains": [
    {
      "number": "12301",
      "name": "Rajdhani Express",
      "departure": "16:55",
      "arrival": "09:55",
      "travel_time": "17:00",
      "classes": "1A,2A,3A"
    }
  ]
}
GET /api/trains/{train_no}/exceptions 20 requests/minute

Returns available exceptional service information for a train, such as diversions or cancellations.

ParameterRequiredDescription
train_noYesTrain number containing 4 to 6 digits.

Request

curl "/api/trains/12301/exceptions"

Response

{
  "cached": false,
  "number": "12301",
  "has_exceptions": false,
  "message": "No exceptions"
}
Read the message field for the available service information.

PNR and station data

Check booking status and find station names or coordinates.

GET /api/pnr/{pnr} 2 requests/minute

Returns train, passenger, and chart status for a PNR.

ParameterRequiredDescription
pnrYesExactly 10 digits.

Request

curl "/api/pnr/1234567890"

Response

{
  "pnr": "1234567890",
  "success": true,
  "train": {
    "number": "12301",
    "name": "Rajdhani Express",
    "source": "HWH",
    "destination": "NDLS",
    "journey_date": "26-Jul-2026"
  },
  "passengers": [
    { "serial": "1", "booking_status": "CNF", "current_status": "CNF" }
  ],
  "chart_status": "Chart Prepared"
}
A PNR is sensitive travel information. Avoid placing real PNR values in shared logs, analytics, screenshots, or browser history.
GET /api/station/{code}/coordinates 120 requests/minute

Returns the name and map coordinates for a station code.

ParameterRequiredDescription
codeYesStation code containing 1 to 10 letters or digits.

Request

curl "/api/station/HWH/coordinates"

Response

{ "code": "HWH", "name": "Howrah Jn", "lat": 22.5839, "lon": 88.3424 }
GET /api/station/autocomplete 120 requests/minute

Searches stations by code or name. Results prioritize exact codes and close name matches.

ParameterRequiredDescription
qYesStation name or code, between 1 and 100 characters.
limitNoNumber of results from 1 to 20. Default: 8.

Request

curl -G "/api/station/autocomplete" \
  --data-urlencode "q=how" \
  --data-urlencode "limit=8"

Response

{
  "query": "how",
  "count": 1,
  "stations": [
    {
      "code": "HWH",
      "name": "Howrah Jn",
      "state": "West Bengal",
      "zone": "ER",
      "lat": 22.5839,
      "lon": 88.3424
    }
  ]
}

Additional endpoints

GET /api/map/tracking 6 requests/minute

Retrieves live status for several trains in one request. A maximum of 10 unique train numbers is accepted.

ParameterRequiredDescription
trainsYesComma-separated train numbers, for example 12301,12302.

Request

curl -G "/api/map/tracking" \
  --data-urlencode "trains=12301,12302"

Response

{
  "count": 2,
  "refresh_seconds": 30,
  "trains": [
    { "cached": false, "number": "12301", "name": "Rajdhani Express", "stops": [ ... ] },
    { "number": "12302", "error": "No running instance found" }
  ]
}

Each successful item follows the live-status response shape. A train-specific problem appears inside that train’s item without failing the entire request.

GET /api/health 120 requests/minute

Checks whether the API is available.

Request

curl "/api/health"

Response

{
  "status": "ok",
  "time": "2026-07-26T12:34:56.123456",
  "version": "1.1.0"
}