{"openapi":"3.1.0","info":{"title":"短剧与小说开放 API","version":"1.6.2","description":"无需访问密钥的短剧搜索播放、小说搜索阅读和 PSeries 公开接口。"},"servers":[{"url":"https://api.heib.show/api","description":"当前服务器"}],"paths":{"/duanju":{"get":{"tags":["接入"],"summary":"客户端统一入口","description":"客户端只需保存这个地址；搜索时自动混合展示短剧和漫剧，并兼容 CMS 的 ac、wd、ids 参数。","operationId":"client_source","parameters":[{"name":"ac","in":"query","required":false,"description":"调用动作；detail=搜索或详情，留空返回接口能力；也兼容 action","schema":{"type":"string","example":"detail"}},{"name":"wd","in":"query","required":false,"description":"搜索关键词；也兼容 keyword、key、q","schema":{"type":"string","example":"系统"}},{"name":"ids","in":"query","required":false,"description":"详情页 vod_id","schema":{"type":"string"}},{"name":"page","in":"query","required":false,"description":"搜索页码，从 1 开始；也兼容 pg","schema":{"type":"integer","example":1}},{"name":"item_id","in":"query","required":false,"description":"action=play 时必填的剧集 ID","schema":{"type":"string"}},{"name":"definition","in":"query","required":false,"description":"action=play 时使用的清晰度；也兼容 quality","schema":{"type":"string","example":"720p"}}],"x-response-fields":[{"name":"code","type":"integer","description":"CMS 状态码；1 表示成功。"},{"name":"msg","type":"string","description":"本次搜索、详情或能力查询的说明。"},{"name":"page","type":"integer","description":"当前页码。"},{"name":"pagecount","type":"integer","description":"可继续请求到的页码上限。"},{"name":"limit","type":"integer","description":"接口声明的每页数量。"},{"name":"total","type":"integer","description":"当前可估算的记录总数。"},{"name":"list[]","type":"object[]","description":"搜索或详情记录；包含 vod_id、vod_name、vod_pic、简介和播放信息。"},{"name":"list[].episodes[]","type":"object[]","description":"详情模式下的选集；包含剧集 ID、序号、标题和 play_url。"},{"name":"class[]","type":"object[]","description":"CMS 分类列表。"},{"name":"api","type":"object","description":"无业务参数时返回的接口能力、鉴权方式和示例地址。"},{"name":"action=play 响应","type":"binary","description":"播放动作直接返回 video/mp4，不再返回 CMS JSON。"}],"responses":{"200":{"description":"调用成功","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CmsResponse"}}}},"422":{"description":"参数错误"},"502":{"description":"上游服务异常"}}}},"/duanju/search":{"get":{"tags":["片库"],"summary":"混合搜索短剧和漫剧","description":"一次请求同时检索短剧和漫剧，交错合并后返回标准化片单。旧 content_type、type、t 参数会被忽略。","operationId":"search","parameters":[{"name":"key","in":"query","required":true,"description":"片名或关键词","schema":{"type":"string","example":"系统"}},{"name":"offset","in":"query","required":false,"description":"分页偏移","schema":{"type":"integer","example":0}},{"name":"raw","in":"query","required":false,"description":"1=额外返回体积较大的上游原始数据","schema":{"type":"integer","example":0}}],"x-response-fields":[{"name":"code","type":"integer","description":"业务状态码；0 表示成功，负数表示错误。"},{"name":"msg","type":"string","description":"响应消息；成功时通常为 ok。"},{"name":"data.items[]","type":"object[]","description":"短剧和漫剧混合搜索结果。"},{"name":"data.items[].book_id","type":"string","description":"片目 ID，供详情和选集接口使用。"},{"name":"data.items[].title","type":"string","description":"片名。"},{"name":"data.items[].cover","type":"string","description":"封面图片地址。"},{"name":"data.items[].first_vid","type":"string","description":"首集视频 ID。"},{"name":"data.items[].episode_count","type":"integer","description":"总集数。"},{"name":"data.items[].content_type","type":"integer","description":"上游内容类型码。"},{"name":"data.items[].abstract","type":"string","description":"简介。"},{"name":"data.items[].media_type","type":"string","description":"内容类型：短剧或漫剧。"},{"name":"data.items[].score","type":"string","description":"评分。"},{"name":"data.items[].rec_text","type":"string","description":"推荐说明。"},{"name":"data.items[].category","type":"string","description":"分类。"},{"name":"data.items[].author","type":"string","description":"作者或主创。"},{"name":"data.has_more","type":"boolean","description":"是否还有下一页。"},{"name":"data.next_offset","type":"integer","description":"下一页应使用的 offset。"},{"name":"data.sources[]","type":"string[]","description":"本次成功参与搜索的片源类型。"},{"name":"data.raw","type":"object","description":"仅在请求 raw=1 时返回的完整上游响应。"}],"responses":{"200":{"description":"调用成功","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"参数错误"},"502":{"description":"上游服务异常"}}}},"/duanju/catalog":{"get":{"tags":["片库"],"summary":"获取选集","description":"传入搜索结果中的 book_id，返回全集 item_id。","operationId":"catalog","parameters":[{"name":"book_id","in":"query","required":true,"description":"片目 series_id","schema":{"type":"string","example":"7600384110636321816"}},{"name":"raw","in":"query","required":false,"description":"1=额外返回体积较大的上游原始数据","schema":{"type":"integer","example":0}}],"x-response-fields":[{"name":"code","type":"integer","description":"业务状态码；0 表示成功，负数表示错误。"},{"name":"msg","type":"string","description":"响应消息；成功时通常为 ok。"},{"name":"data.items[]","type":"object[]","description":"按播放顺序排列的全集目录。"},{"name":"data.items[].index","type":"integer","description":"剧集序号，从 1 开始。"},{"name":"data.items[].item_id","type":"string","description":"剧集 ID，供播放相关接口使用。"},{"name":"data.items[].title","type":"string","description":"剧集标题。"},{"name":"data.raw","type":"object","description":"仅在请求 raw=1 时返回的完整上游响应。"}],"responses":{"200":{"description":"调用成功","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"参数错误"},"502":{"description":"上游服务异常"}}}},"/duanju/detail":{"get":{"tags":["片库"],"summary":"获取详情","description":"读取片目完整上游详情。","operationId":"detail","parameters":[{"name":"book_id","in":"query","required":true,"description":"片目 series_id","schema":{"type":"string","example":"7600384110636321816"}}],"x-response-fields":[{"name":"code","type":"integer","description":"业务状态码；0 表示成功，负数表示错误。"},{"name":"msg","type":"string","description":"响应消息；成功时通常为 ok。"},{"name":"data","type":"object","description":"完整上游详情响应。"},{"name":"data.data","type":"object","description":"片目节点，包含名称、封面、简介、作者、标签等字段。"}],"responses":{"200":{"description":"调用成功","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"参数错误"},"502":{"description":"上游服务异常"}}}},"/duanju/content":{"get":{"tags":["播放"],"summary":"查询播放源","description":"返回各清晰度的加密 CDN 地址和视频元数据。","operationId":"content","parameters":[{"name":"item_id","in":"query","required":true,"description":"剧集 item_id","schema":{"type":"string","example":"7600387588385410073"}},{"name":"raw","in":"query","required":false,"description":"1=额外返回体积较大的上游原始数据","schema":{"type":"integer","example":0}}],"x-response-fields":[{"name":"code","type":"integer","description":"业务状态码；0 表示成功，负数表示错误。"},{"name":"msg","type":"string","description":"响应消息；成功时通常为 ok。"},{"name":"data.item_id","type":"string","description":"当前剧集 ID。"},{"name":"data.sources[]","type":"object[]","description":"按清晰度返回的加密 CDN 视频源。"},{"name":"data.sources[].definition","type":"string","description":"清晰度，如 720p。"},{"name":"data.sources[].codec_type","type":"string","description":"视频编码类型。"},{"name":"data.sources[].width","type":"integer","description":"视频宽度，单位像素。"},{"name":"data.sources[].height","type":"integer","description":"视频高度，单位像素。"},{"name":"data.sources[].duration","type":"integer","description":"视频时长，单位由上游元数据定义。"},{"name":"data.sources[].size","type":"integer","description":"视频文件大小，单位字节。"},{"name":"data.sources[].urls[]","type":"string[]","description":"主 CDN 与备用 CDN 地址。"},{"name":"data.sources[].spade_a","type":"string","description":"用于派生播放解密密钥的上游参数。"},{"name":"data.raw","type":"object","description":"仅在请求 raw=1 时返回的完整上游响应。"}],"responses":{"200":{"description":"调用成功","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"参数错误"},"502":{"description":"上游服务异常"}}}},"/duanju/key":{"get":{"tags":["播放"],"summary":"获取播放参数","description":"返回选定清晰度的服务端播放解密参数与 CDN 地址。","operationId":"key","parameters":[{"name":"item_id","in":"query","required":true,"description":"剧集 item_id","schema":{"type":"string","example":"7600387588385410073"}},{"name":"definition","in":"query","required":false,"description":"目标清晰度","schema":{"type":"string","example":"720p"}}],"x-response-fields":[{"name":"code","type":"integer","description":"业务状态码；0 表示成功，负数表示错误。"},{"name":"msg","type":"string","description":"响应消息；成功时通常为 ok。"},{"name":"data.item_id","type":"string","description":"当前剧集 ID。"},{"name":"data.definition","type":"string","description":"服务器最终选择的清晰度。"},{"name":"data.key_hex","type":"string","description":"CENC AES-CTR 解密密钥的十六进制文本。"},{"name":"data.encryption_method","type":"string","description":"加密方式，当前为 cenc-aes-ctr。"},{"name":"data.urls[]","type":"string[]","description":"可下载的加密 MP4 CDN 地址。"},{"name":"data.size","type":"integer","description":"视频文件大小，单位字节。"}],"responses":{"200":{"description":"调用成功","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"参数错误"},"502":{"description":"上游服务异常"}}}},"/duanju/download":{"get":{"tags":["播放"],"summary":"获取可播放 MP4","description":"服务端下载并解密剧集，直接返回 video/mp4。","operationId":"download","parameters":[{"name":"item_id","in":"query","required":true,"description":"剧集 item_id","schema":{"type":"string","example":"7600387588385410073"}},{"name":"definition","in":"query","required":false,"description":"目标清晰度","schema":{"type":"string","example":"720p"}}],"x-response-fields":[{"name":"HTTP 状态","type":"integer","description":"成功时为 200。"},{"name":"响应体","type":"binary","description":"已解密、可保存或播放的 MP4 二进制数据。"},{"name":"Content-Type","type":"header","description":"固定为 video/mp4。"},{"name":"Content-Disposition","type":"header","description":"inline 文件名，便于浏览器直接处理。"},{"name":"Content-Length","type":"header","description":"MP4 文件的字节数。"},{"name":"X-Duanju-Definition","type":"header","description":"服务器最终选择的清晰度。"},{"name":"Accept-Ranges","type":"header","description":"当前为 none，不声明分段下载能力。"},{"name":"Cache-Control","type":"header","description":"视频缓存策略。"}],"responses":{"200":{"description":"调用成功","content":{"video/mp4":{"schema":{"type":"string","format":"binary"}}}},"422":{"description":"参数错误"},"502":{"description":"上游服务异常"}}}},"/duanju/discovery/categories":{"get":{"tags":["发现"],"summary":"获取分类","description":"获取发现页可用的短剧分类。","operationId":"categories","parameters":[{"name":"raw","in":"query","required":false,"description":"1=额外返回体积较大的上游原始数据","schema":{"type":"integer","example":0}}],"x-response-fields":[{"name":"code","type":"integer","description":"业务状态码；0 表示成功，负数表示错误。"},{"name":"msg","type":"string","description":"响应消息；成功时通常为 ok。"},{"name":"data.items[]","type":"object[]","description":"可用于分类浏览的分类记录。"},{"name":"data.items[].category_id","type":"string","description":"分类 ID；字段名以实际上游记录为准。"},{"name":"data.items[].name","type":"string","description":"分类名称；字段名以实际上游记录为准。"},{"name":"data.raw","type":"object","description":"仅在请求 raw=1 时返回的完整上游响应。"}],"responses":{"200":{"description":"调用成功","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"参数错误"},"502":{"description":"上游服务异常"}}}},"/duanju/discovery":{"get":{"tags":["发现"],"summary":"分类浏览","description":"按分类、性别和分页参数浏览片单。","operationId":"discovery","parameters":[{"name":"category_id","in":"query","required":true,"description":"分类 ID","schema":{"type":"string","example":"19"}},{"name":"offset","in":"query","required":false,"description":"分页偏移","schema":{"type":"integer","example":0}},{"name":"limit","in":"query","required":false,"description":"返回数量，最多 50","schema":{"type":"integer","example":12}},{"name":"gender","in":"query","required":false,"description":"0=全部，1/2=上游性别选项","schema":{"type":"integer","example":0}}],"x-response-fields":[{"name":"code","type":"integer","description":"业务状态码；0 表示成功，负数表示错误。"},{"name":"msg","type":"string","description":"响应消息；成功时通常为 ok。"},{"name":"data","type":"object","description":"分类浏览的完整上游数据。"},{"name":"data.data","type":"object","description":"分类片单、分页游标及上游附加信息。"}],"responses":{"200":{"description":"调用成功","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"参数错误"},"502":{"description":"上游服务异常"}}}},"/duanju2":{"get":{"tags":["短剧二"],"summary":"短剧二客户端统一入口","description":"第二条独立 CMS V10 兼容接口；一个地址完成短剧搜索、详情、选集和播放。","operationId":"duanju2_client_source","parameters":[{"name":"ac","in":"query","required":false,"description":"调用动作；detail=搜索或详情，留空返回接口能力；也兼容 action","schema":{"type":"string","example":"detail"}},{"name":"wd","in":"query","required":false,"description":"搜索关键词；也兼容 keyword、key、q","schema":{"type":"string","example":"通古今"}},{"name":"ids","in":"query","required":false,"description":"详情页 vod_id","schema":{"type":"string"}},{"name":"page","in":"query","required":false,"description":"搜索页码，从 1 开始；也兼容 pg","schema":{"type":"integer","example":1}},{"name":"playlet_id","in":"query","required":false,"description":"action=play 时必填的短剧 ID","schema":{"type":"string"}},{"name":"episode","in":"query","required":false,"description":"action=play 时播放的集数；也兼容 ep","schema":{"type":"integer","example":1}},{"name":"codec","in":"query","required":false,"description":"action=play 时使用 h264 或 h265","schema":{"type":"string","example":"h264"}}],"x-response-fields":[{"name":"code","type":"integer","description":"CMS 状态码；1 表示成功。"},{"name":"msg","type":"string","description":"本次搜索、详情或能力查询的说明。"},{"name":"page","type":"integer","description":"当前页码。"},{"name":"pagecount","type":"integer","description":"可继续请求到的页码上限。"},{"name":"limit","type":"integer","description":"接口声明的每页数量。"},{"name":"total","type":"integer","description":"当前可估算的记录总数。"},{"name":"list[]","type":"object[]","description":"搜索或详情记录；包含 vod_id、vod_name、vod_pic、简介和播放信息。"},{"name":"list[].episodes[]","type":"object[]","description":"详情模式下的选集；包含剧集 ID、序号、标题和 play_url。"},{"name":"class[]","type":"object[]","description":"CMS 分类列表。"},{"name":"api","type":"object","description":"无业务参数时返回的接口能力、鉴权方式和示例地址。"},{"name":"action=play 响应","type":"HTTP 302","description":"播放动作跳转到 HLS 地址，不再返回 CMS JSON。"}],"responses":{"200":{"description":"调用成功","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CmsResponse"}}}},"422":{"description":"参数错误"},"502":{"description":"上游服务异常"}}}},"/duanju2/search":{"get":{"tags":["短剧二"],"summary":"搜索短剧二","description":"按关键词搜索第二片源，返回封面、类型、集数和播放量。","operationId":"duanju2_search","parameters":[{"name":"key","in":"query","required":true,"description":"片名或关键词","schema":{"type":"string","example":"通古今"}},{"name":"page","in":"query","required":false,"description":"页码，从 1 开始","schema":{"type":"integer","example":1}},{"name":"limit","in":"query","required":false,"description":"每页数量，最多 10","schema":{"type":"integer","example":10}},{"name":"raw","in":"query","required":false,"description":"1=额外返回体积较大的上游原始数据","schema":{"type":"integer","example":0}}],"x-response-fields":[{"name":"code","type":"integer","description":"业务状态码；0 表示成功，负数表示错误。"},{"name":"msg","type":"string","description":"响应消息；成功时通常为 ok。"},{"name":"data.keyword","type":"string","description":"本次搜索关键词。"},{"name":"data.page","type":"integer","description":"当前页码。"},{"name":"data.items[]","type":"object[]","description":"第二片源搜索结果。"},{"name":"data.items[].playlet_id","type":"string","description":"短剧 ID。"},{"name":"data.items[].title","type":"string","description":"短剧标题。"},{"name":"data.items[].cover","type":"string","description":"封面地址。"},{"name":"data.items[].episode_count","type":"integer","description":"总集数。"},{"name":"data.items[].category / sub_title","type":"string","description":"分类与副标题。"},{"name":"data.items[].total_num / play_num","type":"string","description":"上游集数文本与播放量文本。"},{"name":"data.items[].content_type","type":"string","description":"来源内容类型标识。"},{"name":"data.has_more","type":"boolean","description":"是否还有下一页。"},{"name":"data.next_page","type":"integer","description":"下一页页码；0 表示没有下一页。"},{"name":"data.raw","type":"object","description":"仅在请求 raw=1 时返回的完整上游响应。"}],"responses":{"200":{"description":"调用成功","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"参数错误"},"502":{"description":"上游服务异常"}}}},"/duanju2/detail":{"get":{"tags":["短剧二"],"summary":"获取短剧二详情","description":"返回封面、完整简介、标签、创作者和剧集总数。","operationId":"duanju2_detail","parameters":[{"name":"playlet_id","in":"query","required":true,"description":"短剧 ID","schema":{"type":"string","example":"26783"}},{"name":"raw","in":"query","required":false,"description":"1=额外返回体积较大的上游原始数据","schema":{"type":"integer","example":0}}],"x-response-fields":[{"name":"code","type":"integer","description":"业务状态码；0 表示成功，负数表示错误。"},{"name":"msg","type":"string","description":"响应消息；成功时通常为 ok。"},{"name":"data.playlet","type":"object","description":"短剧详情，包含标题、封面、简介、创作者和标签。"},{"name":"data.playlet.playlet_id","type":"string","description":"短剧 ID。"},{"name":"data.playlet.title","type":"string","description":"短剧标题。"},{"name":"data.playlet.cover","type":"string","description":"封面地址。"},{"name":"data.playlet.intro","type":"string","description":"完整简介。"},{"name":"data.playlet.total_num / latest_num","type":"string","description":"总集数文本与最新集数文本。"},{"name":"data.playlet.is_over","type":"string","description":"是否完结的上游状态。"},{"name":"data.playlet.creator","type":"string","description":"创作者。"},{"name":"data.playlet.tags[]","type":"string[]","description":"标签。"},{"name":"data.catalog_total","type":"integer","description":"目录中的实际剧集数。"},{"name":"data.raw","type":"object","description":"仅在请求 raw=1 时返回的完整上游响应。"}],"responses":{"200":{"description":"调用成功","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"参数错误"},"502":{"description":"上游服务异常"}}}},"/duanju2/catalog":{"get":{"tags":["短剧二"],"summary":"获取短剧二选集","description":"返回全集 video_id、集数、时长、封面和视频尺寸。","operationId":"duanju2_catalog","parameters":[{"name":"playlet_id","in":"query","required":true,"description":"短剧 ID","schema":{"type":"string","example":"26783"}},{"name":"raw","in":"query","required":false,"description":"1=额外返回体积较大的上游原始数据","schema":{"type":"integer","example":0}}],"x-response-fields":[{"name":"code","type":"integer","description":"业务状态码；0 表示成功，负数表示错误。"},{"name":"msg","type":"string","description":"响应消息；成功时通常为 ok。"},{"name":"data.playlet","type":"object","description":"短剧基本信息。"},{"name":"data.total","type":"integer","description":"目录总集数。"},{"name":"data.items[]","type":"object[]","description":"按顺序排列的选集。"},{"name":"data.items[].video_id","type":"string","description":"剧集视频 ID。"},{"name":"data.items[].item_id","type":"string","description":"标准化剧集 ID。"},{"name":"data.items[].index","type":"integer","description":"剧集序号。"},{"name":"data.items[].title","type":"string","description":"剧集标题。"},{"name":"data.items[].duration","type":"integer","description":"视频时长。"},{"name":"data.items[].frame_cover","type":"string","description":"剧集画面封面。"},{"name":"data.items[].status","type":"string","description":"剧集状态。"},{"name":"data.items[].width / height","type":"integer","description":"视频宽高，单位像素。"},{"name":"data.raw","type":"object","description":"仅在请求 raw=1 时返回的完整上游响应。"}],"responses":{"200":{"description":"调用成功","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"参数错误"},"502":{"description":"上游服务异常"}}}},"/duanju2/content":{"get":{"tags":["短剧二"],"summary":"查询短剧二播放地址","description":"按剧集序号返回 H.264/H.265 HLS 播放地址。","operationId":"duanju2_content","parameters":[{"name":"playlet_id","in":"query","required":true,"description":"短剧 ID","schema":{"type":"string","example":"26783"}},{"name":"episode","in":"query","required":false,"description":"集数，从 1 开始","schema":{"type":"integer","example":1}},{"name":"video_id","in":"query","required":false,"description":"也可按 video_id 精确选择","schema":{"type":"string"}},{"name":"raw","in":"query","required":false,"description":"1=额外返回体积较大的上游原始数据","schema":{"type":"integer","example":0}}],"x-response-fields":[{"name":"code","type":"integer","description":"业务状态码；0 表示成功，负数表示错误。"},{"name":"msg","type":"string","description":"响应消息；成功时通常为 ok。"},{"name":"data.playlet","type":"object","description":"短剧基本信息。"},{"name":"data.episode","type":"object","description":"选中的剧集。"},{"name":"data.episode 目录字段","type":"object","description":"同时包含目录接口中的 item_id、title、duration、frame_cover、width、height、status。"},{"name":"data.episode.index","type":"integer","description":"剧集序号。"},{"name":"data.episode.video_id","type":"string","description":"剧集视频 ID。"},{"name":"data.episode.video_url","type":"string","description":"H.264 HLS 播放地址。"},{"name":"data.episode.video_url_h265","type":"string","description":"H.265 HLS 播放地址；可能为空。"},{"name":"data.episode.play_url","type":"string","description":"优先选出的可播放地址。"},{"name":"data.raw","type":"object","description":"仅在请求 raw=1 时返回的完整上游响应。"}],"responses":{"200":{"description":"调用成功","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"参数错误"},"502":{"description":"上游服务异常"}}}},"/duanju2/play":{"get":{"tags":["短剧二"],"summary":"播放短剧二","description":"刷新该集地址后 302 跳转到 HLS 播放清单。","operationId":"duanju2_play","parameters":[{"name":"playlet_id","in":"query","required":true,"description":"短剧 ID","schema":{"type":"string","example":"26783"}},{"name":"episode","in":"query","required":false,"description":"集数，从 1 开始","schema":{"type":"integer","example":1}},{"name":"codec","in":"query","required":false,"description":"h264 或 h265","schema":{"type":"string","example":"h264"}}],"x-response-fields":[{"name":"HTTP 状态","type":"integer","description":"成功时为 302。"},{"name":"Location","type":"header","description":"刷新后可直接播放的 HLS 清单地址。"},{"name":"Cache-Control","type":"header","description":"固定为 no-store，避免缓存过期播放地址。"}],"responses":{"302":{"description":"跳转到播放地址","content":[]},"422":{"description":"参数错误"},"502":{"description":"上游服务异常"}}}},"/xiaoshuo":{"get":{"tags":["小说"],"summary":"小说统一入口","description":"一个公开地址完成小说搜索、详情、目录和章节正文读取，不需要访问密钥。","operationId":"xiaoshuo_client_source","parameters":[{"name":"ac","in":"query","required":false,"description":"search、detail、catalog 或 content；也兼容 action","schema":{"type":"string","example":"search"}},{"name":"wd","in":"query","required":false,"description":"搜索关键词；也兼容 keyword、key、q","schema":{"type":"string","example":"大唐辟珠记"}},{"name":"bid","in":"query","required":false,"description":"书籍 ID","schema":{"type":"string"}},{"name":"chapter_id","in":"query","required":false,"description":"章节 ID","schema":{"type":"string"}},{"name":"index","in":"query","required":false,"description":"章节序号，从 1 开始","schema":{"type":"integer","example":1}},{"name":"limit","in":"query","required":false,"description":"搜索返回数量，最多 10","schema":{"type":"integer","example":10}}],"x-response-fields":[{"name":"code","type":"integer","description":"业务状态码；0 表示成功，负数表示错误。"},{"name":"msg","type":"string","description":"响应消息；成功时通常为 ok。"},{"name":"data","type":"object","description":"根据 ac 返回接口能力、搜索结果、书籍详情、目录或正文。"},{"name":"data.base_url","type":"string","description":"无业务参数时返回的小说统一入口。"},{"name":"data.authentication","type":"string","description":"鉴权方式，当前为 none。"},{"name":"data.items[]","type":"object[]","description":"搜索或目录动作返回的记录列表。"},{"name":"data.book","type":"object","description":"详情、目录或正文动作返回的书籍信息。"},{"name":"data.chapter","type":"object","description":"正文动作返回的当前章节信息。"},{"name":"data.text","type":"string","description":"正文动作返回的纯文本。"}],"responses":{"200":{"description":"调用成功","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"参数错误"},"502":{"description":"上游服务异常"}}}},"/xiaoshuo/search":{"get":{"tags":["小说"],"summary":"搜索小说","description":"按关键词搜索小说，并补全作者、分类、简介和封面。","operationId":"xiaoshuo_search","parameters":[{"name":"keyword","in":"query","required":true,"description":"小说名或关键词","schema":{"type":"string","example":"大唐辟珠记"}},{"name":"limit","in":"query","required":false,"description":"返回数量，最多 10","schema":{"type":"integer","example":10}}],"x-response-fields":[{"name":"code","type":"integer","description":"业务状态码；0 表示成功，负数表示错误。"},{"name":"msg","type":"string","description":"响应消息；成功时通常为 ok。"},{"name":"data.keyword","type":"string","description":"本次搜索关键词。"},{"name":"data.items[]","type":"object[]","description":"小说搜索结果。"},{"name":"data.items[].book_id","type":"string","description":"书籍 ID。"},{"name":"data.items[].title","type":"string","description":"书名。"},{"name":"data.items[].author","type":"string","description":"作者。"},{"name":"data.items[].category / subcategory","type":"string","description":"主分类与子分类。"},{"name":"data.items[].intro","type":"string","description":"简介。"},{"name":"data.items[].cover","type":"string","description":"封面地址。"},{"name":"data.items[].cover_large","type":"string","description":"大尺寸封面地址。"},{"name":"data.items[].chapter_count","type":"integer","description":"章节数。"},{"name":"data.items[].last_chapter_id","type":"string","description":"最新章节 ID。"},{"name":"data.items[].last_chapter_title","type":"string","description":"最新章节标题。"},{"name":"data.items[].updated_at","type":"string","description":"更新时间。"},{"name":"data.items[].source_name","type":"string","description":"来源名称。"},{"name":"data.items[].content_type","type":"string","description":"内容类型，固定为 novel。"},{"name":"data.total","type":"integer","description":"本次返回数量。"},{"name":"data.has_more","type":"boolean","description":"是否还有更多结果；当前为 false。"},{"name":"data.source","type":"string","description":"来源标识。"}],"responses":{"200":{"description":"调用成功","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"参数错误"},"502":{"description":"上游服务异常"}}}},"/xiaoshuo/detail":{"get":{"tags":["小说"],"summary":"获取小说详情","description":"返回书名、作者、分类、简介、封面、章节数和最新章节。","operationId":"xiaoshuo_detail","parameters":[{"name":"bid","in":"query","required":true,"description":"书籍 ID","schema":{"type":"string","example":"2033291"}}],"x-response-fields":[{"name":"code","type":"integer","description":"业务状态码；0 表示成功，负数表示错误。"},{"name":"msg","type":"string","description":"响应消息；成功时通常为 ok。"},{"name":"data.book","type":"object","description":"标准化书籍详情。"},{"name":"data.book.book_id","type":"string","description":"书籍 ID。"},{"name":"data.book.title","type":"string","description":"书名。"},{"name":"data.book.author","type":"string","description":"作者。"},{"name":"data.book.category","type":"string","description":"分类。"},{"name":"data.book.intro","type":"string","description":"简介。"},{"name":"data.book.cover","type":"string","description":"封面地址。"},{"name":"data.book.chapter_count","type":"integer","description":"章节数。"},{"name":"data.book.last_chapter_id","type":"string","description":"最新章节 ID。"},{"name":"data.book.last_chapter_title","type":"string","description":"最新章节标题。"}],"responses":{"200":{"description":"调用成功","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"参数错误"},"502":{"description":"上游服务异常"}}}},"/xiaoshuo/catalog":{"get":{"tags":["小说"],"summary":"获取小说目录","description":"返回完整章节目录、章节 ID、序号和字数。","operationId":"xiaoshuo_catalog","parameters":[{"name":"bid","in":"query","required":true,"description":"书籍 ID","schema":{"type":"string","example":"2033291"}}],"x-response-fields":[{"name":"code","type":"integer","description":"业务状态码；0 表示成功，负数表示错误。"},{"name":"msg","type":"string","description":"响应消息；成功时通常为 ok。"},{"name":"data.book","type":"object","description":"书籍基本信息。"},{"name":"data.total","type":"integer","description":"目录章节总数。"},{"name":"data.items[]","type":"object[]","description":"按阅读顺序排列的章节。"},{"name":"data.items[].chapter_id","type":"string","description":"章节 ID。"},{"name":"data.items[].index","type":"integer","description":"章节序号，从 1 开始。"},{"name":"data.items[].title","type":"string","description":"章节标题。"},{"name":"data.items[].words","type":"integer","description":"章节字数。"},{"name":"data.items[].source_index","type":"integer","description":"上游原始章节序号。"},{"name":"data.items[].parent_id","type":"string","description":"所属卷 ID。"},{"name":"data.items[].content_md5","type":"string","description":"正文校验摘要。"},{"name":"data.items[].content_type","type":"string","description":"上游章节内容类型。"},{"name":"data.items[].chapter_sort","type":"integer","description":"上游排序值。"},{"name":"data.items[].is_volume","type":"boolean","description":"是否为卷标题；可读章节固定为 false。"}],"responses":{"200":{"description":"调用成功","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"参数错误"},"502":{"description":"上游服务异常"}}}},"/xiaoshuo/content":{"get":{"tags":["小说"],"summary":"读取小说正文","description":"按章节 ID 或序号读取并解密 EPUB/XHTML 正文，返回纯文本。","operationId":"xiaoshuo_content","parameters":[{"name":"bid","in":"query","required":true,"description":"书籍 ID","schema":{"type":"string","example":"2033291"}},{"name":"chapter_id","in":"query","required":false,"description":"章节 ID；与 index 二选一","schema":{"type":"string"}},{"name":"index","in":"query","required":false,"description":"章节序号，从 1 开始","schema":{"type":"integer","example":1}}],"x-response-fields":[{"name":"code","type":"integer","description":"业务状态码；0 表示成功，负数表示错误。"},{"name":"msg","type":"string","description":"响应消息；成功时通常为 ok。"},{"name":"data.book","type":"object","description":"书籍基本信息。"},{"name":"data.chapter","type":"object","description":"当前章节的 ID、标题、序号和字数。"},{"name":"data.text","type":"string","description":"解密并清理后的章节纯文本。"},{"name":"data.source","type":"string","description":"内容来源标识，固定为 xiaoshuo。"}],"responses":{"200":{"description":"调用成功","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"参数错误"},"502":{"description":"上游服务异常"}}}},"/pseries/detail":{"get":{"tags":["PSeries"],"summary":"PSeries 详情","description":"读取 PSeries 详情与标准化选集。","operationId":"pseries_detail","parameters":[{"name":"pseries_id","in":"query","required":true,"description":"PSeries ID","schema":{"type":"string","example":"7657524778131000344"}},{"name":"min_behot_time","in":"query","required":false,"description":"上一页返回的最小时间游标","schema":{"type":"string"}},{"name":"max_behot_time","in":"query","required":false,"description":"上一页返回的最大时间游标","schema":{"type":"string"}},{"name":"count","in":"query","required":false,"description":"单次读取集数，1 到 200","schema":{"type":"integer","example":200}}],"x-response-fields":[{"name":"code","type":"integer","description":"业务状态码；0 表示成功，负数表示错误。"},{"name":"msg","type":"string","description":"响应消息；成功时通常为 ok。"},{"name":"data.pseries_id","type":"string","description":"PSeries ID。"},{"name":"data.title","type":"string","description":"系列标题。"},{"name":"data.total","type":"integer","description":"系列总集数。"},{"name":"data.cover","type":"string","description":"封面地址。"},{"name":"data.category","type":"string","description":"分类。"},{"name":"data.hot_value","type":"string","description":"热度文本。"},{"name":"data.update_status","type":"string","description":"更新状态。"},{"name":"data.first_episode_id","type":"string","description":"首集 ID。"},{"name":"data.episodes[]","type":"object[]","description":"本页标准化选集。"},{"name":"data.has_more","type":"boolean","description":"是否还有下一页。"},{"name":"data.next_cursor","type":"string","description":"下一页游标。"}],"responses":{"200":{"description":"调用成功","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"参数错误"},"502":{"description":"上游服务异常"}}}},"/pseries/content":{"get":{"tags":["PSeries"],"summary":"PSeries 播放地址","description":"按序号返回公开 MP4 播放地址。","operationId":"pseries_content","parameters":[{"name":"pseries_id","in":"query","required":true,"description":"PSeries ID","schema":{"type":"string","example":"7657524778131000344"}},{"name":"episode_index","in":"query","required":true,"description":"剧集序号，从 1 开始","schema":{"type":"integer","example":1}},{"name":"min_behot_time","in":"query","required":false,"description":"上一页返回的最小时间游标","schema":{"type":"string"}},{"name":"max_behot_time","in":"query","required":false,"description":"上一页返回的最大时间游标","schema":{"type":"string"}},{"name":"count","in":"query","required":false,"description":"单次读取集数，1 到 200","schema":{"type":"integer","example":200}}],"x-response-fields":[{"name":"code","type":"integer","description":"业务状态码；0 表示成功，负数表示错误。"},{"name":"msg","type":"string","description":"响应消息；成功时通常为 ok。"},{"name":"data.index","type":"integer","description":"剧集序号。"},{"name":"data.episode_id","type":"string","description":"剧集 ID。"},{"name":"data.video_id","type":"string","description":"视频 ID。"},{"name":"data.title","type":"string","description":"剧集标题。"},{"name":"data.description","type":"string","description":"剧集简介。"},{"name":"data.duration","type":"integer","description":"视频时长。"},{"name":"data.width / height","type":"integer","description":"视频宽高，单位像素。"},{"name":"data.definition","type":"string","description":"视频清晰度。"},{"name":"data.codec_type","type":"string","description":"视频编码类型。"},{"name":"data.size","type":"integer","description":"视频大小，单位字节。"},{"name":"data.urls[]","type":"string[]","description":"可直接播放的 MP4 地址。"},{"name":"data.cover","type":"string","description":"剧集封面地址。"}],"responses":{"200":{"description":"调用成功","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"参数错误"},"502":{"description":"上游服务异常"}}}},"/pseries/catalog":{"get":{"tags":["PSeries"],"summary":"PSeries 选集","description":"读取 PSeries 标准化选集目录。","operationId":"pseries_catalog","parameters":[{"name":"pseries_id","in":"query","required":true,"description":"PSeries ID","schema":{"type":"string","example":"7657524778131000344"}},{"name":"min_behot_time","in":"query","required":false,"description":"上一页返回的最小时间游标","schema":{"type":"string"}},{"name":"max_behot_time","in":"query","required":false,"description":"上一页返回的最大时间游标","schema":{"type":"string"}},{"name":"count","in":"query","required":false,"description":"单次读取集数，1 到 200","schema":{"type":"integer","example":200}}],"x-response-fields":[{"name":"code","type":"integer","description":"业务状态码；0 表示成功，负数表示错误。"},{"name":"msg","type":"string","description":"响应消息；成功时通常为 ok。"},{"name":"data.pseries_id","type":"string","description":"PSeries ID。"},{"name":"data.title","type":"string","description":"系列标题。"},{"name":"data.total","type":"integer","description":"系列总集数。"},{"name":"data.episodes[]","type":"object[]","description":"本页标准化选集。"},{"name":"data.episodes[].index","type":"integer","description":"剧集序号。"},{"name":"data.episodes[].episode_id","type":"string","description":"剧集 ID。"},{"name":"data.episodes[].title","type":"string","description":"剧集标题。"},{"name":"data.has_more","type":"boolean","description":"是否还有下一页。"},{"name":"data.next_cursor","type":"string","description":"下一页游标。"}],"responses":{"200":{"description":"调用成功","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"参数错误"},"502":{"description":"上游服务异常"}}}},"/health":{"get":{"tags":["服务"],"summary":"健康检查","description":"检查 API 服务、PHP 运行时和设备池是否正常。","operationId":"health","parameters":[],"x-response-fields":[{"name":"code","type":"integer","description":"业务状态码；0 表示成功，负数表示错误。"},{"name":"msg","type":"string","description":"响应消息；成功时通常为 ok。"},{"name":"data.status","type":"string","description":"服务状态，正常时为 ok。"},{"name":"data.version","type":"string","description":"当前 API 版本。"},{"name":"data.runtime","type":"string","description":"服务器 PHP 版本。"},{"name":"data.pool_size","type":"integer","description":"设备池设备总数。"},{"name":"data.active_count","type":"integer","description":"当前可用设备数。"}],"responses":{"200":{"description":"调用成功","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"参数错误"},"502":{"description":"上游服务异常"}}}},"/meta":{"get":{"tags":["服务"],"summary":"读取服务元数据","description":"返回服务版本、三个客户端入口、文档地址、鉴权模式和完整接口目录。","operationId":"meta","parameters":[],"x-response-fields":[{"name":"code","type":"integer","description":"业务状态码；0 表示成功，负数表示错误。"},{"name":"msg","type":"string","description":"响应消息；成功时通常为 ok。"},{"name":"data.name","type":"string","description":"服务名称。"},{"name":"data.version","type":"string","description":"当前 API 版本。"},{"name":"data.base_url","type":"string","description":"API 基础地址。"},{"name":"data.client_api_urls","type":"object","description":"三个客户端统一入口地址。"},{"name":"data.client_api_url","type":"string","description":"第一条短剧统一入口。"},{"name":"data.duanju2_api_url","type":"string","description":"第二条短剧统一入口。"},{"name":"data.xiaoshuo_api_url","type":"string","description":"小说统一入口。"},{"name":"data.portal_url","type":"string","description":"开发者文档地址。"},{"name":"data.openapi_url","type":"string","description":"OpenAPI JSON 地址。"},{"name":"data.authentication","type":"object","description":"公开调用的鉴权说明。"},{"name":"data.endpoints[]","type":"object[]","description":"完整接口目录及参数、返回字段说明。"}],"responses":{"200":{"description":"调用成功","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"参数错误"},"502":{"description":"上游服务异常"}}}},"/openapi.json":{"get":{"tags":["服务"],"summary":"下载 OpenAPI 文档","description":"返回可导入 Postman、Apifox 或代码生成器的 OpenAPI 3.1 JSON。","operationId":"openapi","parameters":[],"x-response-fields":[{"name":"openapi","type":"string","description":"OpenAPI 规范版本，当前为 3.1.0。"},{"name":"info","type":"object","description":"API 名称、版本和总体说明。"},{"name":"servers[]","type":"object[]","description":"当前部署的 API 基础地址。"},{"name":"paths","type":"object","description":"全部公开路由、方法、参数和响应定义。"},{"name":"components.schemas","type":"object","description":"可复用的响应数据结构。"}],"responses":{"200":{"description":"调用成功","content":{"application/json":{"schema":{"type":"object"}}}},"422":{"description":"参数错误"},"502":{"description":"上游服务异常"}}}},"/device/list":{"get":{"tags":["设备"],"summary":"查看设备池","description":"返回当前自动签名设备的脱敏列表和设备池状态。","operationId":"device_list","parameters":[],"x-response-fields":[{"name":"code","type":"integer","description":"业务状态码；0 表示成功，负数表示错误。"},{"name":"msg","type":"string","description":"响应消息；成功时通常为 ok。"},{"name":"data.devices[]","type":"object[]","description":"已脱敏的设备列表，不包含 secret_key。"},{"name":"data.devices[].device_id","type":"string","description":"设备 ID。"},{"name":"data.devices[].install_id","type":"string","description":"安装 ID。"},{"name":"data.devices[].status","type":"string","description":"设备状态。"},{"name":"data.devices[].fail_count","type":"integer","description":"连续失败次数。"},{"name":"data.devices[].last_used / last_fail","type":"number","description":"最近使用和最近失败时间戳。"},{"name":"data.devices[].created_at","type":"number","description":"设备创建时间戳。"},{"name":"data.devices[].update_time","type":"string","description":"最近更新时间。"},{"name":"data.devices[].remaining_seconds","type":"integer","description":"距离过期的剩余秒数。"},{"name":"data.devices[].expired","type":"boolean","description":"设备是否过期。"},{"name":"data.devices[].has_secret_key","type":"boolean","description":"服务器是否保存签名密钥；不返回密钥本身。"},{"name":"data.pool_size","type":"integer","description":"设备总数。"},{"name":"data.active_count","type":"integer","description":"可用设备数。"}],"responses":{"200":{"description":"调用成功","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"参数错误"},"502":{"description":"上游服务异常"}}}},"/device/register":{"get":{"tags":["设备"],"summary":"注册设备","description":"立即向上游注册一个或多个签名设备并加入本地设备池。","operationId":"device_register","parameters":[{"name":"count","in":"query","required":false,"description":"注册数量，1 到 100","schema":{"type":"integer","example":1}}],"x-response-fields":[{"name":"code","type":"integer","description":"业务状态码；0 表示成功，负数表示错误。"},{"name":"msg","type":"string","description":"响应消息；成功时通常为 ok。"},{"name":"data.registered","type":"integer","description":"本次成功注册的设备数。"},{"name":"data.devices[]","type":"object[]","description":"新注册设备的脱敏信息。"},{"name":"data.devices[].device_id","type":"string","description":"设备 ID。"},{"name":"data.devices[].install_id","type":"string","description":"安装 ID。"},{"name":"data.devices[].has_secret_key","type":"boolean","description":"服务器是否已保存签名密钥。"},{"name":"data.pool","type":"object","description":"注册后的设备池统计。"}],"responses":{"200":{"description":"调用成功","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"参数错误"},"502":{"description":"上游服务异常"}}}},"/device/remove":{"delete":{"tags":["设备"],"summary":"移除设备","description":"按设备 ID 从本地设备池移除一台设备。请先调用设备列表取得真实 ID。","operationId":"device_remove","parameters":[{"name":"device_id","in":"query","required":true,"description":"要移除的设备 ID；请从设备列表复制真实值","schema":{"type":"string","example":"123456"}}],"x-response-fields":[{"name":"code","type":"integer","description":"业务状态码；0 表示成功，负数表示错误。"},{"name":"msg","type":"string","description":"响应消息；成功时通常为 ok。"},{"name":"data.device_id","type":"string","description":"已移除的设备 ID。"},{"name":"data.removed","type":"boolean","description":"是否移除成功。"}],"responses":{"200":{"description":"调用成功","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"参数错误"},"502":{"description":"上游服务异常"}}}},"/device/cleanup":{"post":{"tags":["设备"],"summary":"清理过期设备","description":"按照配置的 device_ttl 清理本地设备池中过期的设备。","operationId":"device_cleanup","parameters":[],"x-response-fields":[{"name":"code","type":"integer","description":"业务状态码；0 表示成功，负数表示错误。"},{"name":"msg","type":"string","description":"响应消息；成功时通常为 ok。"},{"name":"data.before","type":"integer","description":"清理前设备数。"},{"name":"data.after","type":"integer","description":"清理后设备数。"},{"name":"data.removed","type":"integer","description":"本次移除的过期设备数。"}],"responses":{"200":{"description":"调用成功","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"参数错误"},"502":{"description":"上游服务异常"}}}}},"components":{"schemas":{"ApiResponse":{"type":"object","required":["code","msg","data"],"properties":{"code":{"type":"integer","example":0},"msg":{"type":"string","example":"ok"},"data":{"type":["object","array","null"]}}},"CmsResponse":{"type":"object","required":["code","msg","list","class"],"properties":{"code":{"type":"integer","example":1},"msg":{"type":"string","example":"接口正常"},"list":{"type":"array","items":{"type":"object"}},"class":{"type":"array","items":{"type":"object"}},"api":{"type":"object"}}}}}}