Booking 酒店房态 API:入住日期、房价与 NO DATA 排查

发布于 2026年10月17日

酒店详情请求拿到了 HTTP 200,响应却是 status=false、message=NO DATA!、data=null。这时不能显示“有房”,也不能直接标成“满房”。已保存的反例使用不存在的酒店 ID 999999999,但它只能证明这次请求没有得到酒店数据,不能替所有 NO DATA 解释原因。

HTTP 200 仍可能失败:先检查 status、status_code 和 data

先分清三层结果:HTTP 状态、网关外层的 code/message/data、其中业务载荷的 status/status_code/data。外层通过,不代表酒店查询成功;业务 status_code=400 也不是 HTTP 400。下面是反例的业务层原文,不是完整网关响应:

{
  "message": "NO DATA!",
  "status": false,
  "status_code": 400,
  "data": null
}

程序应先判断业务状态,再访问酒店字段;失败时保留消息并进入未解决分支,不要对空 data 继续取价格。成功样本则有 status=true、message=Success 和填充后的酒店对象,并非只返回一个成功标记。也不要要求每个成功响应都带有反例中的 status_code。

如果业务状态显示成功,酒店对象却缺失,也应保留异常,而不是补一个零元房价。记录失败时应区分传输错误、外层错误和业务无数据,避免把本来含义不同的情况压成同一个“查询成功”。

一次未传日期的探测为何返回 2026-10-18 至 2026-10-22

已保存的酒店详情请求只传 hotel_id=180769、currency_code=USD、language_code=en-us,没有传住宿日期。响应确认酒店为 Hyatt Grand Central New York,arrival_date=2026-10-18、departure_date=2026-10-22,并包含 rooms、房价块 block 和 composite_price_breakdown。

这与文档所述“当天入住、四天后离店”的动态默认值相符。它是一次历史观察,不是永久使用这两个日期,更不是未来仍有房的承诺。不能把今天省略日期的结果,与明天省略日期的结果直接当成同一住宿条件下的涨跌;先记录响应实际使用的日期。

比房价之前固定入住离店日期、人数、房间数和币种

每次比较都明确传入 checkin_date、checkout_date、adults、rooms、currency_code 和 language_code。有儿童时保留一致的 children_age,例如两名儿童的年龄可写为 5,7,不要只记录“亲子入住”而丢掉年龄。字段是否必填仍以各接口为准,不能跨接口套用。

搜索中的 priceBreakdown.grossPrice 要连同其 currency 一起读;详情中的 gross_amount_per_night 与整段住宿金额不能混作一个价格。还需核对税费、excluded_amount、房价块适用人数,以及 block_text.policies 的取消和预付条款。相同酒店和日期,不代表不同房价块可以直接比价,更不要自行把某个金额解释成最终应付总额。

酒店 ID 180769 与纽约城市 UFI 20088325 不能混用

180769 是本例酒店的 hotel_id;20088325 是纽约城市 UFI,在住宿搜索中使用的是 query=city:20088325。城市标识不能填进 hotel_id,详情里出现 ufi 也不表示它是酒店主键。

从搜索结果进入详情,应传递结果行的 id,再核对详情返回的 hotel_id、酒店名和位置。不要把首行、城市名或另一个工作流的 detail_id 当作同一家酒店。两条失败的住宿地点自动补全接口已被省略,因此当前需要从独立可靠来源取得已知目的地标识或酒店 ID,不能假设输入中文城市名就能完成地点发现。

先核对首批 20 家酒店,再处理 549 条匹配结果的分页

保存的纽约搜索使用 2026-11-15 入住、2026-11-17 离店、两名成人、一间房。请求带了 page_size=10,实际却返回 20 行,业务层同时报告 currentPage=1、resultsPerPage=20、totalResultCount=549。

因此分页必须核对响应元数据和实际行数,不能按请求值认定“一页十家”。后续页继续保持住宿条件一致,检查返回页码、重复酒店 ID 与空页等异常;不要仅凭 549 就宣布已采全,也不要把匹配总数当成城市全部酒店库存。后续请求的排序、价格和数量都可能变化,第一页证据不能证明完整分页已经验证。

NO DATA 先记为未解决:每次只改变一个请求条件

排查时先保存脱敏参数、HTTP 状态和两层响应;核实 ID 的来源及类型,再检查日期顺序、人数和字段拼写。用已知酒店建立对照后,每次只改一个条件,并把结果记为成功、失败或仍未解决。换日期不是已证实的通用修复,尤其不能声称它能修复不存在的酒店 ID。

以下是条件一致的只读搜索与详情示例。日期沿用保存样本,执行前确认仍然有效。详情是已知酒店的独立对照,不表示搜索任意一页一定包含它。将 YOUR_API_KEY 换成自己的可用平台密钥,主动执行才会发送请求;打开页面、导航、展开字段或复制代码均不会触发查询。示例不保证当前仍有数据。

curl --get 'https://api.opendata-api.com/api/project/booking/stays-search?key=YOUR_API_KEY' \
  --data-urlencode 'query=city:20088325' \
  --data-urlencode 'checkin_date=2026-11-15' \
  --data-urlencode 'checkout_date=2026-11-17' \
  --data-urlencode 'adults=2' --data-urlencode 'rooms=1' \
  --data-urlencode 'currency_code=USD' --data-urlencode 'language_code=en-us' \
  --data-urlencode 'page=1' --data-urlencode 'page_size=10'

curl --get 'https://api.opendata-api.com/api/project/booking/get-hotel-details?key=YOUR_API_KEY' \
  --data-urlencode 'hotel_id=180769' \
  --data-urlencode 'checkin_date=2026-11-15' \
  --data-urlencode 'checkout_date=2026-11-17' \
  --data-urlencode 'adults=2' --data-urlencode 'rooms=1' \
  --data-urlencode 'currency_code=USD' --data-urlencode 'language_code=en-us'

不要把带真实密钥的 URL 贴进日志或工单。即使对照成功,原失败请求的原因仍需独立确认;保持未解决状态,比把所有空数据归因于满房更准确。

报价不等于锁房,快照不等于历史房价接口

这些响应是随时间变化的只读快照,不会创建预订、收款或锁定价格。房型列表和房态日历有独立文档,但这里没有它们的实测结论,也不应套用外部同名 API 的参数或权限规则。

留存的成功证据仅覆盖住宿搜索、酒店详情和机票自动补全三个不同接口;当前保留的其余 67 个接口未实测,不能由此推断都可用。历史房价监控需要在符合内容使用规则的前提下,自行留存采集时间、住宿条件和响应快照,不能把当前报价接口当成历史数据库。进入任何独立预订流程前,仍需重新确认房态、价格和条款。