# IRCTC Train Data Scraper (`maximedupre/irctc`) Actor

Search public IRCTC train services between two stations for a journey date, quota, and travel class. Get train schedules, station details, source-provided availability, and fare data in structured dataset rows for travel research and route tools.

- **URL**: https://apify.com/maximedupre/irctc.md
- **Developed by:** [Maxime Dupré](https://apify.com/maximedupre) (community)
- **Categories:** Travel, Developer tools, Automation
- **Stats:** 2 total users, 1 monthly users, 66.7% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$1.00 / 1,000 train services

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

### 🚆 Search Indian rail routes with IRCTC data

For travel planners, rail data teams, and developers, IRCTC searches public train services for one origin, destination, journey date, quota, and travel class. It returns train identity, station details, times, operating days, available classes, source-provided availability, and fare data in structured dataset rows for route research and travel tools.

- Find public services between two stations with **[Trains Between Stations](https://apify.com/maximedupre/irctc/examples/trains-between-stations)**.
- Compare departure, arrival, and travel-day details with **[Train Schedule](https://apify.com/maximedupre/irctc/examples/train-schedule)**.
- Check source-provided seat or berth status with **[Train Availability](https://apify.com/maximedupre/irctc/examples/train-availability)**.
- Review total fares and fare components with **[Train Fare Enquiry](https://apify.com/maximedupre/irctc/examples/train-fare-enquiry)**.
- Start an IRCTC route search by station name or code with **[IRCTC Train](https://apify.com/maximedupre/irctc/examples/irctc-train)**.

#### 📊 Train service rows from public routes

Each dataset item is one train service returned for the submitted route, date, quota, and class. A row keeps the train, route, schedule, available classes, operating days, and source-provided station context. Availability and fare are optional because the source may not provide them for every service.

#### ▶️ Search one Indian rail route

This Actor handles one origin and destination, one journey date, one quota, and one travel class per run. It does not book tickets, take payments, reserve seats, cancel trips, or change an account.

1. Enter the origin and destination by station name or official station code.
2. Choose a journey date in `YYYY-MM-DD` format, a quota code, and a travel class code.
3. Run the Actor and open the `results` link in the Output tab or the default dataset.
4. Review the fields that the source provides. Optional availability and fare fields stay absent when the source does not return them.

#### ⚙️ Input

Use one route, date, quota, and travel class per run. Station names and official station codes are accepted for both endpoints.

**Input fields**

| Field | Type | What it does |
| --- | --- | --- |
| `origin` | string (required) | Sets the departure station by name or official station code. |
| `destination` | string (required) | Sets the arrival station by name or official station code. |
| `journeyDate` | string (required) | Sets the journey date in `YYYY-MM-DD` format. |
| `quota` | string (required) | Chooses a quota code. Common codes include `GN`, `TQ`, and `PT`; other source-supported codes may also work. |
| `travelClass` | string (required) | Chooses a travel class code. Common codes include `SL`, `3A`, `2A`, and `1A`; other source-supported codes may also work. |

**Example input**

This is the exact public input from a successful current-beta default-input run.

```json
{
  "origin": "NDLS",
  "destination": "MMCT",
  "journeyDate": "2026-10-15",
  "quota": "GN",
  "travelClass": "3A"
}
```

#### 🧾 Output

The Output tab exposes `results`, a string link to the train services returned by the run. Open it to view the default dataset.

**Train service fields**

| Field | Type | What it does |
| --- | --- | --- |
| `journeyDate` | string | Gives the journey date used for the service result. |
| `quota` | string | Gives the source quota used for availability and fare details. |
| `travelClass` | string | Gives the source travel class used for availability and fare details. |
| `train` | object | Holds the train identity and source-provided service details. |
| `train.number` | string | Gives the train number returned by the source. |
| `train.name` | string | Gives the train name returned by the source. |
| `train.availableClasses` | string\[] (optional) | Lists travel classes available for the train when supplied by the source. |
| `train.operatingDays` | string\[] (optional) | Lists days on which the train operates when supplied by the source. |
| `route` | object | Holds the source-provided stations and schedule. |
| `route.origin` | object | Holds the canonical origin station. |
| `route.origin.name` | string | Gives the origin station name. |
| `route.origin.code` | string | Gives the origin station code. |
| `route.origin.city` | string (optional) | Gives the origin city when supplied by the source. |
| `route.origin.state` | string (optional) | Gives the origin state or region when supplied by the source. |
| `route.origin.zone` | string (optional) | Gives the origin railway zone or other administrative area when supplied by the source. |
| `route.destination` | object | Holds the canonical destination station. |
| `route.destination.name` | string | Gives the destination station name. |
| `route.destination.code` | string | Gives the destination station code. |
| `route.destination.city` | string (optional) | Gives the destination city when supplied by the source. |
| `route.destination.state` | string (optional) | Gives the destination state or region when supplied by the source. |
| `route.destination.zone` | string (optional) | Gives the destination railway zone or other administrative area when supplied by the source. |
| `route.departureTime` | string | Gives the departure time at the origin station. |
| `route.arrivalTime` | string | Gives the arrival time at the destination station. |
| `route.durationMinutes` | integer (optional) | Gives the journey duration in minutes when available. |
| `route.distanceKm` | number (optional) | Gives the journey distance in kilometers when available. |
| `availability` | object (optional) | Holds source-provided seat or berth availability for the selected service, class, quota, and date. |
| `availability.status` | string (optional) | Gives the availability text or status returned by the source. |
| `availability.seats` | integer (optional) | Gives the available seat count when the source provides it. |
| `availability.berths` | integer (optional) | Gives the available berth count when the source provides it. |
| `fare` | object (optional) | Holds the source-provided total fare and fare components. |
| `fare.total` | number | Gives the total fare returned by the source. |
| `fare.currency` | string (optional) | Gives the fare currency returned by the source. |
| `fare.components` | object\[] (optional) | Lists named fare components returned by the source. |
| `fare.components[].name` | string | Gives the fare component name. |
| `fare.components[].amount` | number | Gives the fare component amount. |

**Example train service row**

This complete row is from the successful current-beta default-input run.

```json
{
  "journeyDate": "2026-10-15",
  "quota": "GN",
  "travelClass": "3A",
  "train": {
    "number": "12952",
    "name": "MMCT TEJAS RAJ",
    "availableClasses": [
      "1A",
      "3A",
      "2A"
    ],
    "operatingDays": [
      "Mon",
      "Tue",
      "Wed",
      "Thu",
      "Fri",
      "Sat",
      "Sun"
    ]
  },
  "route": {
    "origin": {
      "name": "NEW DELHI",
      "code": "NDLS",
      "city": "NEW DELHI",
      "state": "DELHI"
    },
    "destination": {
      "name": "MUMBAI CENTRAL",
      "code": "MMCT",
      "city": "MUMBAI",
      "state": "MAHARASHTRA"
    },
    "departureTime": "16:55",
    "arrivalTime": "08:35",
    "durationMinutes": 940,
    "distanceKm": 1383
  },
  "availability": {
    "status": "AVAILABLE-0217",
    "berths": 217
  },
  "fare": {
    "total": 3165,
    "currency": "INR",
    "components": [
      {
        "name": "baseFare",
        "amount": 1820
      },
      {
        "name": "reservationCharge",
        "amount": 40
      },
      {
        "name": "superfastCharge",
        "amount": 45
      },
      {
        "name": "fuelAmount",
        "amount": 0
      },
      {
        "name": "tatkalFare",
        "amount": 0
      },
      {
        "name": "serviceTax",
        "amount": 132
      },
      {
        "name": "otherCharge",
        "amount": 0
      },
      {
        "name": "cateringCharge",
        "amount": 400
      },
      {
        "name": "dynamicFare",
        "amount": 728
      }
    ]
  }
}
```

#### 💳 Pricing

This Actor uses pay-per-event pricing. The `Train service` event costs `$0.001` for each train service saved to the dataset.

#### 🔌 Integrations

Read the dataset through the Apify API or export it from the run. Open the `results` link in the Output tab to reach the dataset.

https://www.youtube.com/watch?v=bNACk1\_S\_6w\&list=PLObrtcm1Kw6MUrlLNDbK9QRg8VDJg0gOW\&index=4

#### ❓ FAQ

##### Can I search more than one route in one run?

No. Each run uses one origin, one destination, one journey date, one quota, and one travel class. Start another run for another route or date.

##### Can I use a station name instead of a station code?

Yes. Enter a station name or official station code for the origin and destination. The output keeps the canonical station name and code returned by the source.

##### What does the availability field mean?

It contains the source-provided availability status and, when supplied, a seat or berth count for the selected train, class, quota, and journey date.

##### Why might availability or fare be missing?

These fields are optional because the source may not provide them for every train service. Missing source values stay absent from the row.

##### Does this Actor book or cancel tickets?

No. It searches public train services and saves returned schedule, availability, and fare details. It does not book, reserve, pay for, cancel, or change a ticket or account.

##### Does it show PNR status or live train locations?

No. This Actor covers route schedules, source-provided availability, and fares. It does not provide PNR status, live train location tracking, or change alerts.

##### Can I read the data through the Apify API?

Yes. Open the dataset from the `results` link, export it, or read it through the Apify API.

##### What happens when no train matches the search?

No train-service row is saved for a run when the source returns no matching service.

### 📝 Changelog

**v0.0** (28-09-2026)

- Initial release.

### 🆘 Support

For issues, questions, or feature requests, [file a ticket](https://console.apify.com/actors/maximedupre~irctc/issues) and I'll fix or implement it in less than 24h 🫡

### 🔗 Related Actors

- [redBus Scraper](https://apify.com/maximedupre/redbus) compares public bus schedules, fares, and seat availability for road routes.
- [Flight Scraper](https://apify.com/maximedupre/flight-scraper) compares public flight itineraries, prices, and times for trips that may continue by air.
- [Flightpoints & Roame Award Flights Scraper](https://apify.com/maximedupre/award-flights-scraper) checks points-based flight itineraries, seats, cabins, and taxes for travel planning.
- [Ryanair Scraper](https://apify.com/maximedupre/ryanair-scraper) checks public Ryanair fares, flight times, and airport details for a route.
- [EasyJet Scraper](https://apify.com/maximedupre/easyjet-scraper) checks public easyJet fares, flight times, and airport details for a route.

**Made with ❤️ by Maxime Dupré**

# Actor input Schema

## `origin` (type: `string`):

Enter the origin by station name or official station code, such as New Delhi or NDLS.

## `destination` (type: `string`):

Enter the destination by station name or official station code, such as Mumbai Central or BCT.

## `journeyDate` (type: `string`):

Select the date of travel. JSON and API users should send it as YYYY-MM-DD.

## `quota` (type: `string`):

Choose a quota code or enter another quota code supported by the source. GN is General, TQ is Tatkal, and PT is Premium Tatkal.

## `travelClass` (type: `string`):

Choose a travel class code or enter another class code supported by the source. Common codes include SL, 3A, 2A, and 1A.

## Actor input object example

```json
{
  "origin": "NDLS",
  "destination": "MMCT",
  "journeyDate": "2026-10-15",
  "quota": "GN",
  "travelClass": "3A"
}
```

# Actor output Schema

## `results` (type: `string`):

Open the train services returned by this run.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "origin": "NDLS",
    "destination": "MMCT",
    "journeyDate": "2026-10-15",
    "quota": "GN",
    "travelClass": "3A"
};

// Run the Actor and wait for it to finish
const run = await client.actor("maximedupre/irctc").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "origin": "NDLS",
    "destination": "MMCT",
    "journeyDate": "2026-10-15",
    "quota": "GN",
    "travelClass": "3A",
}

# Run the Actor and wait for it to finish
run = client.actor("maximedupre/irctc").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "origin": "NDLS",
  "destination": "MMCT",
  "journeyDate": "2026-10-15",
  "quota": "GN",
  "travelClass": "3A"
}' |
apify call maximedupre/irctc --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,maximedupre/irctc"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/s1nHSDqiKHq57sDja/builds/vl0oje8DbRe6FZI1q/openapi.json
