接口文档

版本 v1,协议 HTTPS + JSON。所有数据接口均需签名鉴权,按返回条数计费。

快速开始

  1. 注册账号并登录客户控制台(需填写你自己的网站域名与服务器地址)。
  2. 在 API 密钥 页面创建密钥,填写调用服务器的出口 IP。
  3. 管理员人工审核密钥,并把对应 IP 写入白名单(未审核通过的密钥无法调用)。
  4. 按下方规则对请求签名,调用 https://api.jxphotos.cn/api/v1/...。
  5. 在控制台查看调用流水与余额;余额不足请联系管理员充值。
接口根地址:https://api.jxphotos.cn; 余额与用量查询:GET /api/v1/balance、GET /api/v1/usage(均需签名)。

鉴权与签名

每个请求都必须携带以下 4 个请求头,缺一不可:

请求头说明
X-Api-Key密钥 ID(形如 jxak_xxxxxxxxxxxxxxxx),控制台可见。
X-Api-TimestampUnix 时间戳(秒)。与服务器时间偏差不得超过 300 秒。
X-Api-Nonce一次性随机数,8-64 位字母/数字/下划线/短横线,每次请求必须不同。
X-Api-Signature小写十六进制 HMAC-SHA256 签名。

待签名内容(字符串)

按下列顺序逐行拼接,共 6 行,行之间用换行符 \n 分隔,末尾不加换行:

HTTP 方法(大写,如 GET)
请求路径(不含查询串,如 /api/v1/train-units)
规范化查询串(参数名按字典序升序,RFC3986 编码)
时间戳(十进制秒)
随机数 nonce
请求体的 SHA-256 十六进制小写(GET 无请求体时固定为 e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855)

规范化查询串规则:解析原始查询串后按参数名升序排序,同名参数按值升序, 使用 RFC3986 编码(空格为 %20,百分号编码用大写十六进制)。 无查询参数时该行为空字符串。

签名:signature = hex(HMAC-SHA256(待签名内容, API_SECRET))。

示例待签名内容

GET
/api/v1/train-units
page=1&per_page=20&train_type=%E5%86%85%E7%87%83%E6%9C%BA%E8%BD%A6
1750000000
a1b2c3d4e5f60718
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

代码示例

PHP:

<?php
$keyId = 'jxak_xxxxxxxxxxxxxxxx';
$secret = 'jxsk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
$path = '/api/v1/train-units';
$query = ['train_type' => '内燃机车', 'page' => 1, 'per_page' => 20];

ksort($query, SORT_STRING);
$queryString = http_build_query($query, '', '&', PHP_QUERY_RFC3986);

$timestamp = (string) time();
$nonce = bin2hex(random_bytes(8));

$canonical = implode("\n", [
    'GET',
    $path,
    $queryString,
    $timestamp,
    $nonce,
    hash('sha256', ''),           // GET 无请求体
]);
$signature = hash_hmac('sha256', $canonical, $secret);

$ch = curl_init('https://api.jxphotos.cn' . $path . '?' . $queryString);
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'X-Api-Key: ' . $keyId,
        'X-Api-Timestamp: ' . $timestamp,
        'X-Api-Nonce: ' . $nonce,
        'X-Api-Signature: ' . $signature,
    ],
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);

Python:

import hashlib, hmac, secrets, time, urllib.parse, requests

key_id = "jxak_xxxxxxxxxxxxxxxx"
secret = "jxsk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
path = "/api/v1/train-units"
params = {"train_type": "内燃机车", "page": 1, "per_page": 20}

query = urllib.parse.urlencode(sorted(params.items()), quote_via=urllib.parse.quote)
timestamp, nonce = str(int(time.time())), secrets.token_hex(8)

canonical = "\n".join(["GET", path, query, timestamp, nonce, hashlib.sha256(b"").hexdigest()])
signature = hmac.new(secret.encode(), canonical.encode(), hashlib.sha256).hexdigest()

resp = requests.get("https://api.jxphotos.cn" + path, params=params, headers={
    "X-Api-Key": key_id,
    "X-Api-Timestamp": timestamp,
    "X-Api-Nonce": nonce,
    "X-Api-Signature": signature,
}, timeout=10)
print(resp.status_code, resp.json())

Node.js:

const crypto = require('crypto');

const keyId = 'jxak_xxxxxxxxxxxxxxxx';
const secret = 'jxsk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
const path = '/api/v1/train-units';

const params = new URLSearchParams({ train_type: '内燃机车', page: '1', per_page: '20' });
params.sort();
const query = params.toString();                 // URLSearchParams 已按 RFC3986 编码
const timestamp = Math.floor(Date.now() / 1000).toString();
const nonce = crypto.randomBytes(8).toString('hex');

const canonical = ['GET', path, query, timestamp, nonce,
    crypto.createHash('sha256').update('').digest('hex')].join('\n');
const signature = crypto.createHmac('sha256', secret).update(canonical).digest('hex');

const res = await fetch(`https://api.jxphotos.cn${path}?${query}`, {
    headers: {
        'X-Api-Key': keyId,
        'X-Api-Timestamp': timestamp,
        'X-Api-Nonce': nonce,
        'X-Api-Signature': signature,
    },
});
console.log(res.status, await res.json());

通用查询参数

参数类型说明
pageint页码,从 1 开始,默认 1,最大 1000。
per_pageint每页条数,1-100,默认 20。计费按实际返回条数计算。
keywordstring关键词模糊匹配(也支持 q),长度 ≤ 100。

各数据集还支持等值筛选参数(见下方对应章节)。所有参数必须一并参与签名计算,否则会返回 40105。

响应格式

统一信封:code 为 0 表示成功;非 0 时 msg 为原因,data 可能带补充字段。

{
  "code": 0,
  "msg": "ok",
  "data": {
    "dataset": "train_units",
    "page": 1,
    "per_page": 20,
    "total": 128,
    "count": 20,
    "has_more": true,
    "filters": { "train_type": "内燃机车" },
    "billed": {
      "unit_price": "0.01",
      "amount": "0.2",
      "balance": "99.8"
    },
    "items": [ { "unit_number": "HXD1-0001", "model_name": "HXD1" } ]
  },
  "request_id": "1f2c3d4e5a6b7c8d"
}
  • total 为符合筛选条件的总条数,count 为本次实际返回条数。
  • billed.amount 为本次扣费金额(元),billed.balance 为扣费后余额。
  • request_id 可用于对账与故障排查。
  • 空字符串统一输出为 null;数值型字段输出为 JSON 数字。

铁路车号台账

在售 · 0.01 元/条

机车 / 动车组车号明细,含所属车型、配属、制造厂家。

GET /api/v1/train-units
记录数 按需咨询
单价 0.01 元/条
等值筛选 unit_number</code> <code class="inline">model_name</code> <code class="inline">train_type</code> <code class="inline">manufacturer</code> <code class="inline">bureau
关键词范围 unit_number / model_name / name_cn / manufacturer / bureau
排序 unit_number ASC

返回字段

  • unit_number 车号
  • model_name 车型
  • name_cn 车型中文名
  • series_name 系列
  • train_type 类型
  • manufacturer 厂家
  • bureau 配属

示例请求

https://api.jxphotos.cn/api/v1/train-units?unit_number=<示例值>&page=1&per_page=20

示例响应

{
    "code": 0,
    "msg": "ok",
    "data": {
        "dataset": "train_units",
        "page": 1,
        "per_page": 20,
        "total": 128,
        "count": 20,
        "has_more": true,
        "filters": [],
        "billed": {
            "unit_price": "0.01",
            "amount": "0.2",
            "balance": "<扣费后余额>"
        },
        "items": [
            {
                "unit_number": "<值>",
                "model_name": "<值>",
                "name_cn": "<值>",
                "series_name": "<值>",
                "train_type": "<值>",
                "manufacturer": "<值>",
                "bureau": "<值>"
            }
        ]
    },
    "request_id": "<请求唯一标识>"
}

铁路车型资料

在售 · 0.01 元/条

车型型号库,含最高速度、功率、编组、简介等参数。

GET /api/v1/train-models
记录数 按需咨询
单价 0.01 元/条
等值筛选 model_name</code> <code class="inline">train_type</code> <code class="inline">series_name</code> <code class="inline">manufacturer_name</code> <code class="inline">unit_count</code> <code class="inline">max_speed_kmh
关键词范围 model_name / name_cn / series_name / manufacturer_name / formation
排序 model_name ASC

返回字段

  • model_name 车型
  • name_cn 中文名
  • series_name 系列
  • manufacturer_name 厂家
  • train_type 类型
  • unit_count 在册车号数
  • max_speed_kmh 最高速度
  • power_kw 功率
  • formation 编组
  • summary 简介

示例请求

https://api.jxphotos.cn/api/v1/train-models?model_name=<示例值>&page=1&per_page=20

示例响应

{
    "code": 0,
    "msg": "ok",
    "data": {
        "dataset": "train_models",
        "page": 1,
        "per_page": 20,
        "total": 128,
        "count": 20,
        "has_more": true,
        "filters": [],
        "billed": {
            "unit_price": "0.01",
            "amount": "0.2",
            "balance": "<扣费后余额>"
        },
        "items": [
            {
                "model_name": "<值>",
                "name_cn": "<值>",
                "series_name": "<值>",
                "manufacturer_name": "<值>",
                "train_type": "<值>",
                "unit_count": "<值>",
                "max_speed_kmh": "<值>",
                "power_kw": "<值>",
                "formation": "<值>",
                "summary": "<值>"
            }
        ]
    },
    "request_id": "<请求唯一标识>"
}

车站资料

在售 · 0.01 元/条

铁路车站名录,含电报码、所属城市、经纬度、经过线路。

GET /api/v1/stations
记录数 按需咨询
单价 0.01 元/条
等值筛选 name</code> <code class="inline">city</code> <code class="inline">region</code> <code class="inline">country</code> <code class="inline">telegraph_code</code> <code class="inline">station_type
关键词范围 name / name_en / pinyin / telegraph_code / city / region / lines
排序 name ASC

返回字段

  • name 车站名
  • name_en 英文名
  • pinyin 拼音
  • telegraph_code 电报码
  • city 城市
  • region 省/州
  • country 国家
  • station_type 类型
  • business 业务
  • lines 线路
  • lat 纬度
  • lng 经度

示例请求

https://api.jxphotos.cn/api/v1/stations?name=<示例值>&page=1&per_page=20

示例响应

{
    "code": 0,
    "msg": "ok",
    "data": {
        "dataset": "stations",
        "page": 1,
        "per_page": 20,
        "total": 128,
        "count": 20,
        "has_more": true,
        "filters": [],
        "billed": {
            "unit_price": "0.01",
            "amount": "0.2",
            "balance": "<扣费后余额>"
        },
        "items": [
            {
                "name": "<值>",
                "name_en": "<值>",
                "pinyin": "<值>",
                "telegraph_code": "<值>",
                "city": "<值>",
                "region": "<值>",
                "country": "<值>",
                "station_type": "<值>",
                "business": "<值>",
                "lines": "<值>",
                "lat": "<值>",
                "lng": "<值>"
            }
        ]
    },
    "request_id": "<请求唯一标识>"
}

飞机注册号资料

在售 · 0.01 元/条

注册号台账,含国家、机型、序列号、状态等。出于隐私保护不含机主姓名。

GET /api/v1/aircraft-registrations
记录数 按需咨询
单价 0.01 元/条
等值筛选 registration</code> <code class="inline">country_code</code> <code class="inline">registration_type</code> <code class="inline">model_name</code> <code class="inline">icao_type_code</code> <code class="inline">manufacturer_name</code> <code class="inline">serial_number</code> <code class="inline">status</code> <code class="inline">year_manufactured
关键词范围 registration / serial_number / model_name / manufacturer_name / operator_name / airline_name / icao_type_code
排序 registration ASC

返回字段

  • registration 注册号
  • country_code 国家代码
  • registration_type 注册类型
  • serial_number 序列号
  • manufacturer_name 制造商
  • model_name 机型
  • icao_type_code ICAO 机型代码
  • aircraft_category 类别
  • engine_type 发动机类型
  • engine_count 发动机数量
  • seats 座位数
  • year_manufactured 出厂年份
  • owner_type 持有方类型
  • operator_name 运营人
  • status 状态

示例请求

https://api.jxphotos.cn/api/v1/aircraft-registrations?registration=<示例值>&page=1&per_page=20

示例响应

{
    "code": 0,
    "msg": "ok",
    "data": {
        "dataset": "aircraft_registrations",
        "page": 1,
        "per_page": 20,
        "total": 128,
        "count": 20,
        "has_more": true,
        "filters": [],
        "billed": {
            "unit_price": "0.01",
            "amount": "0.2",
            "balance": "<扣费后余额>"
        },
        "items": [
            {
                "registration": "<值>",
                "country_code": "<值>",
                "registration_type": "<值>",
                "serial_number": "<值>",
                "manufacturer_name": "<值>",
                "model_name": "<值>",
                "icao_type_code": "<值>",
                "aircraft_category": "<值>",
                "engine_type": "<值>",
                "engine_count": "<值>",
                "seats": "<值>",
                "year_manufactured": "<值>",
                "owner_type": "<值>",
                "operator_name": "<值>",
                "status": "<值>"
            }
        ]
    },
    "request_id": "<请求唯一标识>"
}

铁路车型分类字典

在售 · 0.01 元/条

机车 / 动车组 / 高速列车分类字典(大类、子类、名称)。

GET /api/v1/railway-types
记录数 按需咨询
单价 0.01 元/条
等值筛选 name</code> <code class="inline">category</code> <code class="inline">subcategory
关键词范围 name / category / subcategory
排序 id ASC

返回字段

  • name 名称
  • category 大类
  • subcategory 子类

示例请求

https://api.jxphotos.cn/api/v1/railway-types?name=<示例值>&page=1&per_page=20

示例响应

{
    "code": 0,
    "msg": "ok",
    "data": {
        "dataset": "railway_types",
        "page": 1,
        "per_page": 20,
        "total": 128,
        "count": 20,
        "has_more": true,
        "filters": [],
        "billed": {
            "unit_price": "0.01",
            "amount": "0.2",
            "balance": "<扣费后余额>"
        },
        "items": [
            {
                "name": "<值>",
                "category": "<值>",
                "subcategory": "<值>"
            }
        ]
    },
    "request_id": "<请求唯一标识>"
}

计费与余额

  • 计费公式:本次费用 = 数据集单价 × 本次返回条数;返回 0 条不扣费。
  • 单价由管理员在后台为每个数据集单独设置,调整后立即生效(以请求时的单价为准)。
  • 余额不足时接口返回 40201,不会返回数据、不会欠费。
  • 余额由管理员充值/调整,客户可在 余额明细 中查看每一笔变动。
  • 数据集被管理员停售后返回 40304,恢复上架后即可继续调用。

限流与风控

  • 每秒最多 10 次请求(返回 42901)。
  • 每分钟最多 120 次请求(返回 42902)。
  • 触发限流、IP 不在白名单、签名错误等异常时,服务器会立即断开连接(响应头 Connection: close)。
  • 短时间内反复触发限流会导致密钥或 IP 被临时封禁(默认 10 分钟,返回 40303)。
  • 每个请求的随机数在 300 秒内只能使用一次,重复使用返回 40104。

错误码

codeHTTP说明处理建议
40101 401 缺少鉴权请求头 检查 X-Api-Key / X-Api-Timestamp / X-Api-Nonce / X-Api-Signature 是否齐全
40102 401 密钥不存在或未通过审核 确认密钥已由管理员审核通过,且未被停用
40103 401 时间戳超出允许范围 服务器时间需与标准时间同步(允许偏差 300 秒)
40104 401 随机数重复(疑似重放) 每次请求使用新的唯一随机数
40105 401 签名校验失败 核对待签名字符串拼装顺序与 Secret
40301 403 调用方 IP 不在白名单内 联系管理员把该服务器出口 IP 加入白名单
40302 403 账号或密钥已被停用 联系管理员恢复账号状态
40303 403 触发风控被临时封禁 等待封禁到期(默认 600 秒)后重试
40304 403 数据集已停售 该数据集暂未开放,请联系管理员
40201 402 余额不足 联系管理员充值后重试
42901 429 超过每秒调用限制(10 次/秒) 降低并发,连接会被立即断开
42902 429 超过每分钟调用限制(120 次/分钟) 降低频率,连接会被立即断开
40001 400 请求参数不合法 按文档检查查询参数与取值格式
50001 500 服务端异常 稍后重试;持续出现请联系管理员