场景
适用场景
这个接口适合用在什么地方?下面的场景可以帮你判断它是不是你要找的那个。
- 做一个列车详情页,展示某车次今天从始发到终点的全部经停信息。
- 结合 referenceModels 展示该车次可能使用的车型。
- 展示车次所在的交路(circulation),让用户知道这列车当天还跑哪些车次。
问答
常见问题
接入时最常遇到的疑问,先看看这里能不能解答。
stops 里 stationTrainCode 为什么是对象?
v2 用 { prefix, number } 表示结构化车次号,例如 G2492 就是 { prefix: "G", number: 2492 },方便程序处理而不需要解析字符串。
有些站的 distance 或 platformNo 没有返回?
这两个字段是可选的:没有数据时字段会直接省略,而不是返回 null,这也是 v2 的通用约定。
扣费
扣费规则
每次请求按固定额度扣费,不随返回条数变化。
固定 1 点额度/次
实际扣费以响应头 x-api-cost 为准。
请求说明
参数
路径参数
trainCodestring 必填
要查询的车次号,例如 G2492、D2212 或 C2001。字母大小写都可以,服务端会做标准化处理。
示例:G2492
响应说明
状态码与响应格式
200
当前日期下的完整车次时刻表。
响应头
x-api-remainx-api-costRetry-After
application/jsonobject
响应结构
{
"type": "object",
"required": [
"ok",
"data",
"error"
],
"properties": {
"ok": {
"type": "true",
"required": true,
"enum": [
true
]
},
"data": {
"type": "object",
"required": true,
"shape": {
"type": "object",
"required": [
"internalCode",
"allCodes",
"bureauCode",
"bureauName",
"trainDepartment",
"passengerDepartment",
"referenceModels",
"startStation",
"endStation",
"startAt",
"endAt",
"stops",
"serviceDay"
],
"properties": {
"updatedAt": {
"type": "integer"
},
"requestTrainCode": {
"type": "object",
"shape": {
"type": "object",
"required": [
"prefix",
"number"
],
"properties": {
"prefix": {
"type": "string",
"required": true
},
"number": {
"type": "integer",
"required": true
}
}
}
},
"trainCode": {
"type": "object",
"shape": {
"type": "object",
"required": [
"prefix",
"number"
],
"properties": {
"prefix": {
"type": "string",
"required": true
},
"number": {
"type": "integer",
"required": true
}
}
}
},
"internalCode": {
"type": "string",
"required": true
},
"allCodes": {
"type": "array<object>",
"required": true,
"shape": {
"type": "array",
"items": {
"type": "object",
"required": [
"prefix",
"number"
],
"properties": {
"prefix": {
"type": "string",
"required": true
},
"number": {
"type": "integer",
"required": true
}
}
}
}
},
"bureauCode": {
"type": "string",
"required": true
},
"bureauName": {
"type": "string",
"required": true
},
"trainDepartment": {
"type": "string",
"required": true
},
"passengerDepartment": {
"type": "string",
"required": true
},
"referenceModels": {
"type": "array<object>",
"required": true,
"shape": {
"type": "array",
"items": {
"type": "object",
"required": [
"model",
"weightedShare"
],
"properties": {
"model": {
"type": "string",
"required": true
},
"weightedShare": {
"type": "number",
"required": true
}
}
}
}
},
"startStation": {
"type": "string",
"required": true
},
"endStation": {
"type": "string",
"required": true
},
"startAt": {
"type": "integer",
"required": true
},
"endAt": {
"type": "integer",
"required": true
},
"circulation": {
"type": "object",
"shape": {
"type": "object",
"required": [
"source",
"nodes"
],
"properties": {
"source": {
"type": "unspecified | official | inferred",
"required": true,
"enum": [
"unspecified",
"official",
"inferred"
]
},
"refreshAt": {
"type": "integer"
},
"nodes": {
"type": "array<object>",
"required": true,
"shape": {
"type": "array",
"items": {
"type": "object",
"required": [
"internalCode",
"allCodes",
"startStation",
"endStation",
"startAt",
"endAt"
],
"properties": {
"internalCode": {
"type": "string",
"required": true
},
"allCodes": {
"type": "array<object>",
"required": true,
"shape": {
"type": "array",
"items": {
"type": "object",
"required": [
"prefix",
"number"
],
"properties": {
"prefix": {
"type": "string",
"required": true
},
"number": {
"type": "integer",
"required": true
}
}
}
}
},
"startStation": {
"type": "string",
"required": true
},
"endStation": {
"type": "string",
"required": true
},
"startAt": {
"type": "integer",
"required": true
},
"endAt": {
"type": "integer",
"required": true
}
}
}
}
},
"metadata": {
"type": "object",
"shape": {
"type": "object",
"properties": {
"routeId": {
"type": "string"
},
"windowStart": {
"type": "integer"
},
"windowEnd": {
"type": "integer"
},
"threshold": {
"type": "number"
},
"lowestLinkWeight": {
"type": "number"
},
"lowestLinkSupportCount": {
"type": "integer"
},
"containsLoopBreak": {
"type": "boolean"
},
"validationState": {
"type": "unspecified | raw_official | split_official | unmatched_official",
"enum": [
"unspecified",
"raw_official",
"split_official",
"unmatched_official"
]
},
"originalOfficialEntryKey": {
"type": "string"
},
"splitSegmentIndex": {
"type": "integer"
},
"splitSegmentCount": {
"type": "integer"
},
"matchedInferredRouteId": {
"type": "string"
},
"candidateInferredCirculation": {
"type": "object",
"shape": {
"type": "object",
"required": [
"nodes"
],
"properties": {
"refreshAt": {
"type": "integer"
},
"nodes": {
"type": "array<object>",
"required": true,
"shape": {
"type": "array",
"items": {
"type": "object",
"required": [
"internalCode",
"allCodes",
"startStation",
"endStation",
"startAt",
"endAt"
],
"properties": {
"internalCode": {
"type": "string",
"required": true
},
"allCodes": {
"type": "array<object>",
"required": true,
"shape": {
"type": "array",
"items": {
"type": "object",
"required": [
"prefix",
"number"
],
"properties": {
"prefix": {
"type": "string",
"required": true
},
"number": {
"type": "integer",
"required": true
}
}
}
}
},
"startStation": {
"type": "string",
"required": true
},
"endStation": {
"type": "string",
"required": true
},
"startAt": {
"type": "integer",
"required": true
},
"endAt": {
"type": "integer",
"required": true
}
}
}
}
},
"metadata": {
"type": "object",
"shape": {
"type": "object",
"required": [
"routeId",
"windowStart",
"windowEnd",
"threshold",
"containsLoopBreak"
],
"properties": {
"routeId": {
"type": "string",
"required": true
},
"windowStart": {
"type": "integer",
"required": true
},
"windowEnd": {
"type": "integer",
"required": true
},
"threshold": {
"type": "number",
"required": true
},
"lowestLinkWeight": {
"type": "number"
},
"lowestLinkSupportCount": {
"type": "integer"
},
"containsLoopBreak": {
"type": "boolean",
"required": true
}
}
}
}
}
}
}
}
}
}
}
}
},
"stops": {
"type": "array<object>",
"required": true,
"shape": {
"type": "array",
"items": {
"type": "object",
"required": [
"stationNo",
"stationName",
"wicket",
"isStart",
"isEnd"
],
"properties": {
"stationNo": {
"type": "integer",
"required": true
},
"stationName": {
"type": "string",
"required": true
},
"arriveAt": {
"type": "integer"
},
"departAt": {
"type": "integer"
},
"stationTrainCode": {
"type": "object",
"shape": {
"type": "object",
"required": [
"prefix",
"number"
],
"properties": {
"prefix": {
"type": "string",
"required": true
},
"number": {
"type": "integer",
"required": true
}
}
}
},
"wicket": {
"type": "string",
"required": true
},
"distance": {
"type": "number"
},
"platformNo": {
"type": "integer"
},
"isStart": {
"type": "boolean",
"required": true
},
"isEnd": {
"type": "boolean",
"required": true
}
}
}
}
},
"serviceDay": {
"type": "integer",
"required": true
}
}
}
},
"error": {
"type": "",
"required": true,
"enum": [
""
]
}
}
}示例响应
{
"ok": true,
"data": {
"updatedAt": 1787838393,
"requestTrainCode": {
"prefix": "G",
"number": 2492
},
"trainCode": {
"prefix": "G",
"number": 2492
},
"internalCode": "33000G249204",
"allCodes": [
{
"prefix": "G",
"number": 2492
}
],
"bureauCode": "C",
"bureauName": "呼和浩特局集团",
"trainDepartment": "包头车辆段",
"passengerDepartment": "包头客运段",
"referenceModels": [
{
"model": "CR400BF-G",
"weightedShare": 1
}
],
"startStation": "包头",
"endStation": "北京北",
"startAt": 1787873520,
"endAt": 1787885400,
"circulation": {
"source": "official",
"refreshAt": 1787825543,
"nodes": [
{
"internalCode": "33000G249204",
"allCodes": [
{
"prefix": "G",
"number": 2492
}
],
"startStation": "包头",
"endStation": "北京北",
"startAt": 27120,
"endAt": 39000
},
{
"internalCode": "24000G249307",
"allCodes": [
{
"prefix": "G",
"number": 2493
}
],
"startStation": "北京北",
"endStation": "包头",
"startAt": 42840,
"endAt": 56220
},
{
"internalCode": "33000G249608",
"allCodes": [
{
"prefix": "G",
"number": 2496
}
],
"startStation": "包头",
"endStation": "北京北",
"startAt": 58560,
"endAt": 73080
},
{
"internalCode": "24000G249109",
"allCodes": [
{
"prefix": "G",
"number": 2491
}
],
"startStation": "北京北",
"endStation": "包头",
"startAt": 117120,
"endAt": 130020
},
{
"internalCode": "33000G249408",
"allCodes": [
{
"prefix": "G",
"number": 2494
}
],
"startStation": "包头",
"endStation": "北京北",
"startAt": 131640,
"endAt": 145560
},
{
"internalCode": "24000G249505",
"allCodes": [
{
"prefix": "G",
"number": 2495
}
],
"startStation": "北京北",
"endStation": "包头",
"startAt": 147300,
"endAt": 159120
},
{
"internalCode": "33000D67580J",
"allCodes": [
{
"prefix": "D",
"number": 6758
}
],
"startStation": "包头",
"endStation": "呼和浩特东",
"startAt": 160680,
"endAt": 165300
}
],
"metadata": {
"validationState": "raw_official",
"originalOfficialEntryKey": "33000G249608",
"matchedInferredRouteId": "circulation_fb7bd969"
}
},
"stops": [
{
"stationNo": 1,
"stationName": "包头",
"departAt": 1787873520,
"stationTrainCode": {
"prefix": "G",
"number": 2492
},
"wicket": "一层1检票口,一层2检票口",
"distance": 0,
"platformNo": 1,
"isStart": true,
"isEnd": false
},
{
"stationNo": 2,
"stationName": "呼和浩特",
"arriveAt": 1787877060,
"departAt": 1787877360,
"stationTrainCode": {
"prefix": "G",
"number": 2492
},
"wicket": "3检票口,4检票口",
"distance": 165,
"platformNo": 2,
"isStart": false,
"isEnd": false
},
{
"stationNo": 3,
"stationName": "北京北",
"arriveAt": 1787885400,
"stationTrainCode": {
"prefix": "G",
"number": 2492
},
"wicket": "",
"distance": 633,
"platformNo": 4,
"isStart": false,
"isEnd": true
}
],
"serviceDay": 20693
},
"error": ""
}401
请求未携带有效的认证信息,或提供的 API Key 已失效。
响应头
x-api-remainx-api-costRetry-After
application/jsonobject
响应结构
{
"type": "object",
"required": [
"ok",
"data",
"error"
],
"properties": {
"ok": {
"type": "false",
"required": true,
"enum": [
false
]
},
"data": {
"type": "string",
"required": true
},
"error": {
"type": "string",
"required": true
}
}
}示例响应
{
"ok": false,
"data": "API Key 无效或已过期",
"error": "invalid_api_key"
}403
账号已被封禁。;当前凭证缺少调用该接口所需的 scope。;当前身份的额度上限低于接口最低调用成本。
响应头
x-api-remainx-api-costRetry-After
application/jsonobject
响应结构
{
"type": "object",
"required": [
"ok",
"data",
"error"
],
"properties": {
"ok": {
"type": "false",
"required": true,
"enum": [
false
]
},
"data": {
"type": "string",
"required": true
},
"error": {
"type": "string",
"required": true
}
}
}账号已被封禁。
{
"ok": false,
"data": "账号已被封禁",
"error": "account_banned"
}当前凭证缺少调用该接口所需的 scope。
{
"ok": false,
"data": "当前 API Key 缺乏访问该接口的权限",
"error": "forbidden_scope"
}当前身份的额度上限低于接口最低调用成本。
{
"ok": false,
"data": "当前身份额度上限不足,无法调用该接口",
"error": "cost_exceeds_quota_limit"
}404
当前时刻表暂不可用。
响应头
x-api-remainx-api-costRetry-After
application/jsonobject
响应结构
{
"type": "object",
"required": [
"ok",
"data",
"error"
],
"properties": {
"ok": {
"type": "false",
"required": true,
"enum": [
false
]
},
"data": {
"type": "string",
"required": true
},
"error": {
"type": "string",
"required": true
}
}
}示例响应
{
"ok": false,
"data": "当前暂无时刻表",
"error": "not_found"
}406
Accept 请求头不支持 JSON 响应。
响应头
x-api-remainx-api-costRetry-After
application/jsonobject
响应结构
{
"type": "object",
"required": [
"ok",
"data",
"error"
],
"properties": {
"ok": {
"type": "false",
"required": true,
"enum": [
false
]
},
"data": {
"type": "string",
"required": true
},
"error": {
"type": "string",
"required": true
}
}
}示例响应
{
"ok": false,
"data": "Accept 不支持 application/json 或 application/x-protobuf",
"error": "not_acceptable"
}429
额度不足或请求过于频繁,建议等 Retry-After 提示的时间后再试。
响应头
x-api-remainx-api-costRetry-After
application/jsonobject
响应结构
{
"type": "object",
"required": [
"ok",
"data",
"error"
],
"properties": {
"ok": {
"type": "false",
"required": true,
"enum": [
false
]
},
"data": {
"type": "string",
"required": true
},
"error": {
"type": "string",
"required": true
}
}
}示例响应
{
"ok": false,
"data": "额度不足,请稍后再试",
"error": "quota_exceeded"
}500
服务内部错误或响应编码失败。
响应头
x-api-remainx-api-costRetry-After
application/jsonobject
响应结构
{
"type": "object",
"required": [
"ok",
"data",
"error"
],
"properties": {
"ok": {
"type": "false",
"required": true,
"enum": [
false
]
},
"data": {
"type": "string",
"required": true
},
"error": {
"type": "string",
"required": true
}
}
}示例响应
{
"ok": false,
"data": "服务内部错误,请稍后再试",
"error": "internal_error"
}