openapi: 3.0.3 info: title: 车辆数据开放平台 API version: 1.5.0 license: name: Proprietary description: | 向授权合作方开放车辆单日用氢量、单日里程、区间日里程和指定时刻总里程。 appKey 和逐车授权必须完整覆盖查询自然日。 servers: - url: / description: 当前服务 tags: - name: 合作方数据接口 description: 使用 appKey 查询已授权车辆的日统计数据 - name: 开放平台管理 description: 仅车辆数据平台管理员可调用的应用和车辆授权管理接口 paths: /api/v1/vehicles/hydrogen-consumption/query: post: tags: [合作方数据接口] summary: 查询车辆单日用氢量 description: plateNumbers 省略或传空数组时,返回该应用在查询自然日有效授权的全部车辆。 operationId: queryDailyHydrogenConsumption security: - AppKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/VehicleDailyQuery' example: date: '2026-07-01' responses: '200': description: 查询成功;无数据车辆仍保留在结果中 content: application/json: schema: $ref: '#/components/schemas/HydrogenQueryResponse' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '500': $ref: '#/components/responses/InternalError' /api/v1/vehicles/mileage/query: post: tags: [合作方数据接口] summary: 查询车辆单日里程 description: | plateNumbers 省略或传空数组时,返回该应用在查询自然日有效授权的全部车辆。 protocolPriority 传入时,逐车按数组顺序选择第一个有效协议,未列出的协议完全禁用且不会兜底;省略时保持平台默认选源行为。 NORMAL 结果同时包含日里程、累计总里程、实际来源协议、源数据时间和投影更新时间。 当日无有效里程时,日里程补 0,累计总里程、来源协议、dataTime 和 updatedAt 沿用此前最近的有效统计;updatedAt 仍为上一统计周期的计算时间。 operationId: queryDailyMileage security: - AppKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/MileageDailyQuery' example: date: '2026-07-01' protocolPriority: [GB32960, MQTT, JT808] responses: '200': description: 查询成功;无数据车辆仍保留在结果中 content: application/json: schema: $ref: '#/components/schemas/MileageQueryResponse' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '500': $ref: '#/components/responses/InternalError' /api/v1/vehicles/mileage/range/query: post: tags: [合作方数据接口] summary: 分页查询车辆区间日里程 description: | 最长支持 366 天。plateNumbers 省略或传空数组时固化应用在整个查询区间有效授权的全部车辆。 首次请求返回 snapshotId 和 nextCursor;后续请求保持原参数并传回 nextCursor。 快照仅固化授权车辆清单,逐页读取已建立索引的日统计投影,不扫描原始时序明细。 protocolPriority 对区间内每辆车、每个自然日独立生效;未列出的协议完全禁用。 某日无有效里程时,dailyMileageKm 补 0,其余里程证据沿用此前最近的有效统计。 operationId: queryDailyMileageRange security: - AppKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/MileageRangeQuery' example: startDate: '2026-07-01' endDate: '2026-07-23' plateNumbers: [沪A00001, 沪A00002] protocolPriority: [JT808, GB32960, MQTT] cursor: null pageSize: 5000 responses: '200': description: 查询成功;每辆授权车辆每天均有一条 NORMAL 或 NO_DATA 记录 content: application/json: schema: $ref: '#/components/schemas/MileageRangeQueryResponse' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '500': $ref: '#/components/responses/InternalError' /api/v1/vehicles/total-mileage/query: post: tags: [合作方数据接口] summary: 查询指定时刻的车辆总里程 description: | 返回不晚于请求时间的最近一条有效总里程记录、实际记录时间和时间差秒数。 protocol 不传时严格按 GB32960 > YUTONG_MQTT > JT808 选择首个有数据的协议。 GB32960 和 YUTONG_MQTT 为车辆仪表盘或车端累计里程;JT808 为定位终端/GPS侧累计里程。 operationId: queryTotalMileageAtTime security: - AppKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/TotalMileageQuery' example: vin: LA9GG68L2PBAF4790 time: '2026-07-21 09:30:00' protocol: GB32960 responses: '200': description: 查询成功;没有可用记录时返回 NO_DATA content: application/json: schema: $ref: '#/components/schemas/TotalMileageQueryResponse' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '500': $ref: '#/components/responses/InternalError' /api/v2/open-platform/apps: get: tags: [开放平台管理] summary: 查询开放平台应用 operationId: listOpenPlatformApps security: - AdminBearer: [] responses: '200': description: 应用列表 content: application/json: schema: $ref: '#/components/schemas/AdminAppListResponse' '401': description: 未登录 '403': description: 非管理员 post: tags: [开放平台管理] summary: 创建应用和 appKey description: appKey 明文仅在本次响应中返回。 operationId: createOpenPlatformApp security: - AdminBearer: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AppInput' responses: '200': description: 创建成功 content: application/json: schema: $ref: '#/components/schemas/AdminAppCreatedResponse' '400': description: 参数错误 '401': description: 未登录 '403': description: 非管理员 /api/v2/open-platform/apps/{id}: put: tags: [开放平台管理] summary: 更新应用状态和有效期 operationId: updateOpenPlatformApp security: - AdminBearer: [] parameters: - $ref: '#/components/parameters/AppId' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AppInput' responses: '200': description: 更新成功 '400': description: 参数错误 '404': description: 应用不存在 /api/v2/open-platform/apps/{id}/rotate-key: post: tags: [开放平台管理] summary: 轮换 appKey description: 旧 Key 立即失效,新 Key 明文仅在本次响应中返回。 operationId: rotateOpenPlatformAppKey security: - AdminBearer: [] parameters: - $ref: '#/components/parameters/AppId' responses: '200': description: 轮换成功 content: application/json: schema: $ref: '#/components/schemas/AdminAppCreatedResponse' '404': description: 应用不存在 /api/v2/open-platform/apps/{id}/vehicles: get: tags: [开放平台管理] summary: 查询应用的车辆授权 operationId: listOpenPlatformVehicleGrants security: - AdminBearer: [] parameters: - $ref: '#/components/parameters/AppId' responses: '200': description: 授权列表 '404': description: 应用不存在 put: tags: [开放平台管理] summary: 完整替换车辆授权 operationId: replaceOpenPlatformVehicleGrants security: - AdminBearer: [] parameters: - $ref: '#/components/parameters/AppId' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/VehicleGrantRequest' responses: '200': description: 替换成功 '400': description: VIN 或有效期不正确 '404': description: 应用不存在 components: securitySchemes: AppKeyAuth: type: http scheme: bearer bearerFormat: 32-character appKey description: 32 位无连字符 UUID appKey AdminBearer: type: http scheme: bearer bearerFormat: Platform session token description: 车辆数据平台管理员令牌 parameters: AppId: name: id in: path required: true schema: type: integer format: int64 minimum: 1 responses: BadRequest: description: 请求参数不正确 content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' examples: invalidDate: value: code: INVALID_DATE_FORMAT message: date格式必须为yyyy-MM-dd traceId: 4ccf63c4e51d4d4ab9107d931783a53e Unauthorized: description: appKey 不存在、停用或过期 content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' Forbidden: description: Key 或车辆授权未完整覆盖查询自然日 content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' InternalError: description: 服务内部异常 content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' schemas: VehicleDailyQuery: type: object additionalProperties: false required: [date] properties: plateNumbers: type: array maxItems: 200 uniqueItems: true items: type: string minLength: 1 maxLength: 32 description: 可选;指定时查询这些已授权车牌,省略或传空数组时查询该自然日有效授权的全部车辆 date: type: string format: date description: 查询自然日,yyyy-MM-dd MileageDailyQuery: type: object additionalProperties: false required: [date] properties: plateNumbers: type: array maxItems: 200 uniqueItems: true items: type: string minLength: 1 maxLength: 32 description: 可选;指定时查询这些已授权车牌,省略或传空数组时查询该自然日有效授权的全部车辆 date: type: string format: date description: 查询自然日,yyyy-MM-dd protocolPriority: $ref: '#/components/schemas/ProtocolPriority' MileageRangeQuery: type: object additionalProperties: false required: [startDate, endDate] properties: startDate: type: string format: date description: 区间开始自然日,Asia/Shanghai endDate: type: string format: date description: 区间结束自然日,含当日;与 startDate 最多相隔 365 天 plateNumbers: type: array maxItems: 5000 uniqueItems: true items: type: string minLength: 1 maxLength: 32 description: 可选;省略或传空数组时查询整个区间均有效授权的全部车辆 protocolPriority: $ref: '#/components/schemas/ProtocolPriority' cursor: type: string nullable: true description: 首次查询传 null 或省略;翻页时原样传入上一页 nextCursor pageSize: type: integer minimum: 1 maximum: 5000 default: 5000 ProtocolPriority: type: array minItems: 1 maxItems: 3 uniqueItems: true items: type: string enum: [GB32960, MQTT, JT808] description: 可选;按数组顺序逐车逐日选择第一个有效协议。未列出的协议被禁用且不会作为兜底;省略字段时保持平台默认选源行为 TotalMileageQuery: type: object additionalProperties: false required: [vin, time] properties: vin: type: string pattern: '^[A-HJ-NPR-Z0-9]{17}$' description: 已授权车辆 VIN time: type: string pattern: '^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$' description: 请求时刻,北京时间,固定格式 yyyy-MM-dd HH:mm:ss protocol: type: string enum: [GB32960, YUTONG_MQTT, JT808] description: 可选;只接受平台统一协议标识;不传时按 GB32960 > YUTONG_MQTT > JT808 HydrogenResult: type: object required: [plateNumber, date, hydrogenConsumptionKg, status] properties: plateNumber: type: string date: type: string format: date hydrogenConsumptionKg: type: number format: double nullable: true description: 单日用氢量,kg;无数据时为 null status: $ref: '#/components/schemas/DataStatus' MileageResult: type: object required: [vin, plateNumber, date, dailyMileageKm, totalMileageKm, dataTime, updatedAt, sourceProtocol, status] properties: vin: type: string plateNumber: type: string date: type: string format: date dailyMileageKm: type: number format: double nullable: true description: 单日里程,km;当日无记录但存在历史累计里程时为 0 totalMileageKm: type: number format: double nullable: true description: 当日所选协议最后有效累计总里程,km;status=NORMAL 时必定有值,NO_DATA 时为 null dataTime: type: string format: date-time nullable: true description: 本次统计实际采用的最后一条车辆源数据时间;status=NO_DATA 时为 null updatedAt: type: string format: date-time nullable: true description: 本行所依据统计周期的计算时间;前向填充时为上一统计周期计算时间,status=NO_DATA 时为 null sourceProtocol: type: string enum: [GB32960, MQTT, JT808] nullable: true description: 本行实际选中的来源协议;status=NO_DATA 时为 null status: $ref: '#/components/schemas/DataStatus' MileageRangeResult: type: object required: [vin, plateNumber, date, dailyMileageKm, totalMileageKm, dataTime, updatedAt, sourceProtocol, status] properties: vin: type: string plateNumber: type: string date: type: string format: date dailyMileageKm: type: number format: double nullable: true minimum: 0 description: 当日无记录但存在历史累计里程时为 0 totalMileageKm: type: number format: double nullable: true minimum: 0 description: 当日所选协议累计总里程;缺日时沿用此前最近有效值 dataTime: type: string format: date-time nullable: true updatedAt: type: string format: date-time nullable: true description: 本行所依据统计周期的计算时间;缺日补齐时为上一统计周期计算时间 sourceProtocol: type: string enum: [GB32960, MQTT, JT808] nullable: true description: 本行实际选中的来源协议;status=NO_DATA 时为 null status: $ref: '#/components/schemas/DataStatus' DataStatus: type: string enum: [NORMAL, NO_DATA] HydrogenQueryResponse: allOf: - $ref: '#/components/schemas/SuccessEnvelope' - type: object required: [data] properties: data: type: array items: $ref: '#/components/schemas/HydrogenResult' MileageQueryResponse: allOf: - $ref: '#/components/schemas/SuccessEnvelope' - type: object required: [data] properties: data: type: array items: $ref: '#/components/schemas/MileageResult' MileageRangeQueryResponse: type: object required: [code, message, data, snapshotId, nextCursor, traceId] properties: code: type: string enum: [SUCCESS] message: type: string example: success data: type: array items: $ref: '#/components/schemas/MileageRangeResult' snapshotId: type: string description: 同一次分页查询保持不变的授权车辆快照标识 nextCursor: type: string nullable: true description: 下一页游标;最后一页为 null traceId: type: string TotalMileageResult: type: object required: [vin, queryTime, totalMileageKm, selectionPolicy, status] properties: vin: type: string queryTime: type: string description: 请求时刻,北京时间 totalMileageKm: type: number format: double nullable: true description: 总里程,km;无数据时为 null protocol: type: string enum: [GB32960, YUTONG_MQTT, JT808] description: 实际采用的采集协议 protocolInput: type: string description: 请求中指定的协议原值;未指定时省略 mileageMeaning: type: string description: 当前协议总里程的业务含义 recordTime: type: string description: 命中的实际采集记录时间,北京时间 timeDifferenceSeconds: type: integer format: int64 minimum: 0 description: 请求时间减实际记录时间,单位秒 selectionPolicy: type: string example: GB32960 > YUTONG_MQTT > JT808 status: $ref: '#/components/schemas/DataStatus' TotalMileageQueryResponse: allOf: - $ref: '#/components/schemas/SuccessEnvelope' - type: object required: [data] properties: data: $ref: '#/components/schemas/TotalMileageResult' SuccessEnvelope: type: object required: [code, message, traceId] properties: code: type: string enum: [SUCCESS] message: type: string example: success traceId: type: string example: 4ccf63c4e51d4d4ab9107d931783a53e ErrorResponse: type: object required: [code, message, traceId] properties: code: type: string enum: - INVALID_REQUEST - INVALID_DATE_FORMAT - UNAUTHORIZED - FORBIDDEN - INTERNAL_ERROR message: type: string traceId: type: string AppInput: type: object additionalProperties: false required: [name, status, validFrom] properties: name: type: string maxLength: 96 example: 示例合作方 status: type: string enum: [enabled, disabled] validFrom: type: string format: date-time example: '2026-07-01T00:00:00+08:00' validTo: type: string format: date-time nullable: true example: '2027-07-01T00:00:00+08:00' App: type: object required: [id, name, appKeyPrefix, status, validFrom] properties: id: type: integer format: int64 name: type: string appKeyPrefix: type: string minLength: 8 maxLength: 8 status: type: string enum: [enabled, disabled] validFrom: type: string format: date-time validTo: type: string format: date-time nullable: true AppCreated: allOf: - $ref: '#/components/schemas/App' - type: object required: [appKey] properties: appKey: type: string minLength: 32 maxLength: 32 pattern: '^[0-9a-f]{32}$' description: 仅本次响应返回 VehicleGrantRequest: type: object additionalProperties: false required: [vehicles] properties: vehicles: type: array maxItems: 500 items: $ref: '#/components/schemas/VehicleGrantInput' VehicleGrantInput: type: object additionalProperties: false required: [vin, validFrom] properties: vin: type: string minLength: 17 maxLength: 17 validFrom: type: string format: date-time validTo: type: string format: date-time nullable: true AdminAppListResponse: type: object properties: data: type: array items: $ref: '#/components/schemas/App' traceId: type: string AdminAppCreatedResponse: type: object properties: data: $ref: '#/components/schemas/AppCreated' traceId: type: string