Check up to 25 train and class combinations.
POST /v1/availability/seats/batch
Scope availability:read · Credits max(5, 2 x item/class combinations) · Plans All plans
Returns independent availability results for every item. Pricing is dynamic based on each requested item and class.
Send your key in the X-RailCore-Key header. This operation requires the availability:read scope. See the authentication guide.
This operation takes no path or query parameters.
| Field | Type | Description |
|---|---|---|
items | AvailabilityInput[] | Array with 1 to 25 items. |
items[].train_number | string | Train number. |
items[].from | string | Boarding station code. |
items[].to | string | Destination station code. |
items[].date | string(date) | Journey date. |
items[].classes | ClassCode[] | Up to 8 classes. Omission prices and checks four default classes. |
items[].quota | Quota | Optional reservation quota. |
Base URL https://ir.railcore.tech/v1. Keep the key in an environment variable and call from a trusted server-side environment.
curl -sS -X POST \
-H "X-RailCore-Key: $RAILCORE_KEY" \
-H "Content-Type: application/json" \
--data '{"items":[{"train_number":"12656","from":"BSL","to":"ADI","date":"2026-08-27","classes":["SL","3A"],"quota":"GN"},{"train_number":"12952","from":"NDLS","to":"BCT","date":"2026-08-28","classes":["2A"],"quota":"TQ"}]}' \
"https://ir.railcore.tech/v1/availability/seats/batch"
const response = await fetch("https://ir.railcore.tech/v1/availability/seats/batch", {
method: "POST",
headers: {
"X-RailCore-Key": process.env.RAILCORE_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
"items": [
{
"train_number": "12656",
"from": "BSL",
"to": "ADI",
"date": "2026-08-27",
"classes": [
"SL",
"3A"
],
"quota": "GN"
},
{
"train_number": "12952",
"from": "NDLS",
"to": "BCT",
"date": "2026-08-28",
"classes": [
"2A"
],
"quota": "TQ"
}
]
}),
});
const body = await response.json();
console.log(response.status, body);
import json
import os
import requests
response = requests.request(
"POST",
"https://ir.railcore.tech/v1/availability/seats/batch",
headers={"X-RailCore-Key": os.environ["RAILCORE_KEY"]},
json=json.loads("{\"items\":[{\"train_number\":\"12656\",\"from\":\"BSL\",\"to\":\"ADI\",\"date\":\"2026-08-27\",\"classes\":[\"SL\",\"3A\"],\"quota\":\"GN\"},{\"train_number\":\"12952\",\"from\":\"NDLS\",\"to\":\"BCT\",\"date\":\"2026-08-28\",\"classes\":[\"2A\"],\"quota\":\"TQ\"}]}"),
timeout=20,
)
print(response.status_code, response.json())
This call costs max(5, 2 x item/class combinations) credits and is available on All plans. Per-minute and daily budgets, and the headers reporting remaining quota, are documented in rate limits and credits and billing.
| Field | Type | Description |
|---|---|---|
results[] | AvailabilityResponse[] | Per-input availability result. |
results[].train_number | string | Train number. |
results[].from_station_code / to_station_code | string | Requested segment. |
results[].journey_date | string(date) | Requested journey date. |
results[].quota | Quota | Applied quota. |
results[].classes[].class_code | ClassCode | Travel class. |
results[].classes[].status | string | AVAILABLE, RAC, WAITLIST, REGRET, NOT_AVAILABLE, TRAIN_CANCELLED, TRAIN_DEPARTED, or UNKNOWN. |
results[].classes[].availability_text | string | Source availability text normalized for display. |
results[].classes[].available_count | integer | Known available berth count. |
results[].classes[].waitlist_count / rac_count | integer | Known waitlist and RAC positions. |
results[].classes[].wl_pool | string | null | GNWL, PQWL, RLWL, RSWL, TQWL, NLWL, or CKWL. |
results[].classes[].fare / total_fare | integer | null | Fare values in INR. |
results[].classes[].confirmation_probability | object | null | Percentage, LOW/MEDIUM/HIGH label, and explanatory text. |
results[].classes[].last_updated_at | string | null | Live source update time. |
{
"success": true,
"data": {
"results": [
{
"train_number": "12656",
"from_station_code": "BSL",
"to_station_code": "ADI",
"journey_date": "2026-08-27",
"quota": "GN",
"classes": [
{
"class_code": "3A",
"status": "AVAILABLE",
"availability_text": "AVAILABLE 24",
"available_count": 24,
"waitlist_count": 0,
"rac_count": 0,
"wl_pool": null,
"fare": 1125,
"total_fare": 1125,
"confirmation_probability": {
"percentage": 96,
"label": "HIGH",
"text": "High confirmation likelihood"
},
"last_updated_at": "2026-08-20T17:12:23.304Z"
}
]
}
]
},
"meta": {
"api_version": "v1",
"request_id": "req_01J5Z7Y8N2K4M6P8R0T2V4X6Z8",
"trace_id": "trc_01J5Z7Y8N2K4M6P8R0T2V4X6Z9",
"timestamp": "2026-08-20T17:12:23.305Z",
"freshness": {
"mode": "live",
"retrieved_at": "2026-08-20T17:12:23.305Z",
"sources": [
{
"confidence": "high"
}
]
}
}
}
| Status | Code | Description | Retry |
|---|---|---|---|
| 400 | VALIDATION_ERROR | A required field is missing or invalid. | Not retryable |
| 401 | MISSING_API_KEY / INVALID_API_KEY | The credential is absent, unknown, disabled, or expired. | Not retryable |
| 403 | SCOPE_MISSING / PLAN_ENDPOINT_DISABLED | The key lacks the required scope or plan entitlement. | Not retryable |
| 402 | CREDITS_EXHAUSTED | The account balance cannot cover this operation. | Not retryable |
| 429 | RATE_LIMITED | Minute or daily request budget is exhausted. Honor Retry-After. | Retryable |
| 410 | API_VERSION_SUNSET | This API version has reached its announced sunset date. Migrate to a supported major version. | Not retryable |
| 502 | UPSTREAM_UNAVAILABLE | Live data could not be retrieved. Retry with backoff. | Retryable |
| 504 | UPSTREAM_TIMEOUT | The live-data request exceeded its deadline. Retry with backoff. | Retryable |
| 503 | METERING_UNAVAILABLE | Credit settlement is temporarily unavailable and no data was returned. | Retryable |
All RailCore Indian Railways API endpoints · Quickstart · Rate limits