# RaptDrama 接口清单 基址使用 `https://apis.raptdrama.com`。`https://app.raptdrama.com` 上部分路径也能通,脚本以 `apis` 为准。 本文只记录已经实际调用过的返回结构。安装包里还有一批路径,返回格式没有核对,放在最后一节,不要把它们当成已确认的协议。 ## 通用约定 业务响应外面都有同一层包装。HTTP 状态经常仍是 200,成功与否看 `code`。 ```json { "code": 200, "msg": "ok", "data": {} } ``` 已见到的业务码: | code | 含义 | | --- | --- | | 200 | 成功。`msg` 可能是 `ok`、`成功` 或 `Login success` | | 299 | 未登录,`msg` 为 `Please login first`。用 `Authorization: Bearer` 调播放接口时会出现 | | 500 | 参数错误,例如 `Invalid email format`、`Password cannot be empty`、`Error Type` | 请求头: | 头 | 值 | | --- | --- | | Content-Type | `application/json`。播放和登录都用 JSON,不要用表单 | | Accept | `application/json` | | User-Agent | `RaptDrama/1.1.81 (Android 12; 23113RKC6C; Redmi)` | | apasstk | 登录后拿到的 `token`。游客 `autologin` 本身不带这个头 | | x-app-build | `139` | | x-app-version | `1.1.81` | | x-device-type | `phone` | | x-device-brand | `Redmi` | | x-device-model | `23113RKC6C` | | x-device-id | 设备号,例如 `rd_` 开头的字符串 | | x-device-fingerprint | 设备指纹 | | x-device-physical | `true` | | x-os-name | `Android` | | x-os-version | `12` | | accept-language | `en-US` | | accept-language-custom | `en-US` | 登录凭证只放在 `apasstk`。不要再使用 `Authorization: Bearer`。 ## 登录 ### POST /app/open/autologin 每次调用都新建一个游客,不会沿用上一次的账号。不需要 `apasstk`。 请求体:`{}` `data`: | 字段 | 类型 | 说明 | | --- | --- | --- | | id | string | 新游客 id | | nickname | string | 随机昵称 | | token | string | 后续请求的 `apasstk` | | score | int | | | vipday | int | | | badge | string | 例如 `BRONZE` | | watched | int | | | rewards | int | | | avatarNum | int | | | avatarNumUrl | string | 头像地址 | ### POST /app/open/emailLogin 同一邮箱重复登录返回同一个用户。不需要先带 `apasstk`。 请求体: ```json {"email": "邮箱", "password": "密码"} ``` `email` 或 `password` 用错字段名时,`code` 为 500。 `data`: | 字段 | 类型 | | --- | --- | | id | int | | nickname | string | | email | string | | email_bind | int | | score | int | | tgid | int | | isguanzhu | int | | sxid | int | | os | string | | channel | string | | token | string | | google_bind | int | `/auth/login` 在这个基址上没有返回上述 JSON 包装,邮箱登录以 `/app/open/emailLogin` 为准。 ### POST /app/user/getUserInfo 需要 `apasstk`。游客 token 也可以调用。 请求体:`{}` `data`: | 字段 | 类型 | | --- | --- | | id | int | | nickname | string | | email_bind | int | | mobile_bind | int | | score | int | | tgid | int | | isguanzhu | int | | sxid | int | | os | string | | channel | string | | google_bind | int | | apple_bind | int | | login_day | int | | vipday | int | | badge | string | | watched | int | | rewards | int | | avatarNum | int | | avatarNumUrl | string | 这里的 `id` 是数字。`autologin` 返回的 `id` 是字符串。 ## 分类和剧列表 剧对象在多个接口里重复出现,下面称它为剧目: | 字段 | 类型 | 说明 | | --- | --- | --- | | id | int | 剧 id,播放接口的 `vid` 用这个值 | | title | string | | | update_time | int | Unix 时间 | | view | int | | | image | string | 封面 | | tstype | string | 分类 id,Passion 为 `"20"` | | desc | string | | | forstaus | string | | | forstausen | string | 连载状态文案,例如完结 | | author | string | | | classify | string[] | 题材标签 | | score | string | 评分,是字符串 | ### POST /app/open/classifyv2 请求体:`{}` `data` 是分类数组: | 字段 | 类型 | 说明 | | --- | --- | --- | | id | int | 传给分类视频接口的 `type` | | label | string | 英文名 | | label_origin | string | | | image | string 或 null | | 已见到的分类:`18` Comedy,`20` Passion,`21` Newest,`22` Western,`23` Comic drama。首页顶栏就是这五个标签,脚本用 `sections` 记成 `comedy`、`passion`、`newest`、`western`、`comic`。 ### 首页区块对应 发现页上能对上接口的区块: | 界面 | 接口 | 脚本里的 `sections` | | --- | --- | --- | | 顶栏 Comedy / Passion / Newest / Western / Comic drama | `POST /app/open/classify_video`,`type` 分别为 18 / 20 / 21 / 22 / 23 | `comedy` / `passion` / `newest` / `western` / `comic` | | New Releases | `GET /app/open/orgin` | `new_releases` | | Recommend | `POST /app/open/recommend`,按 `page` 翻页 | `recommend` | 同一部剧可以同时出现在多个区块。脚本按剧 id 合并,播放地址只请求一次,`sections` 列出它出现过的区块,例如 `["passion","new_releases","recommend"]`。 Trending Now 对不上单独的短列表。安装包里发现页有 `trendingDramas` 和 `_buildTrendingSection`,但没有单独的拉取方法或 `/app/open/` 路径。核对过的结果: - `POST /app/open/extra_broadcast` 是历史页里的 extra broadcast,不是发现页的 Trending Now。当前 9 部里没有截图上的 Bai Jie: A Young Wife、Desire Manor、The Love Curse。改 `type` 或 `ishot` 仍是这 9 部。 - `GET /app/open/orgin` 只有 Bai Jie: A Young Wife,没有另外两部。 - Recommend 全量里三部都在,但分散在第 4、7、11 页,不是这一行的短列表。 - 三部的 `videoinfo.ishot` 都是 `0`。猜的 `/app/open/banner`、`/hot`、`/ranking` 返回 404。 - `/app/open/foryou` 不作为首页来源,脚本不调用。 ### POST /app/open/classify_video 按分类分页。`type` 才是分类 id。传 `tstype`、`classify` 或 `id` 会返回 `code` 500、`Error Type`。 请求体: ```json {"page": 1, "limit": 10, "type": 20} ``` `page` 从 1 开始。每页 10 条,空页表示结束。`limit` 增大也不会一次返回超过 10 条。 `data` 是剧目数组。 ### POST /app/open/recommend 首页 Recommend。`page` 从 1 开始,`limit` 用 10。`start` 会被忽略,不能用来翻页。空对象 `{}` 和带 `page`/`limit` 的第一页一样,大约 10 条,不是全站列表。 请求体: ```json {"page": 1, "limit": 10} ``` 每页 10 条,相邻页的剧 id 不同。某一页条数不足 10 时还要继续请求下一页。只有空页,或这一页的 id 全部在前面出现过,才停止。脚本最多翻 80 页,避免死循环。 2026-09-26 用游客 token 翻页:第 1–33 页各 10 条,第 34 页 2 条,第 35 页为空。去重后 332 部。 `data` 是剧目数组。 ### POST /app/open/foryou 请求体:`{}` `data` 是剧目数组,并多一个 `firstchapter`: | 字段 | 类型 | 说明 | | --- | --- | --- | | firstchapter.id | int | 集 id | | firstchapter.title | string | | | firstchapter.idx | int | 集序号 | | firstchapter.playurl | string | 这一集的播放地址 | ### POST /app/open/extra_broadcast 请求体:`{}` `data` 是剧目数组。这是历史页的列表,不是首页 Trending Now。不传分页参数时返回固定的一小批剧;带 `page` 也不会换成 Trending Now 那一排。 ### GET /app/open/orgin 无请求体。`POST` 空对象同样返回这一批。`data` 是剧目数组。 这是首页 New Releases。当前一次返回 10 部,按较新的剧排在前面。截图里能看到的 Reaping What She Sowed、The Fall of a Mountain Flower、The Delivery Guy's Rise 是这 10 部的最后三部。加上 `type=trending`,或 `page`/`limit`,仍然只有 10 条,不是另一份 Trending Now 列表。 ### POST /app/open/search 请求体: ```json {"keyword": "love", "page": 1, "limit": 10} ``` `data` 是剧目数组,并多一个 `totalvideo`(int,集数)。 ### POST /app/open/bank 请求体:`{}` `data` 不是剧目数组,而是观看或片库记录: | 字段 | 类型 | | --- | --- | | id | int | | vid | int | | cid | int | | create_time | int | | video.id | int | | video.title | string | | video.image | string | | video.desc | string | | video.forstaus | string | | video.author | string | | video.forstausen | string | ## 剧集和播放地址 ### GET /app/video/getchapters 查询参数: | 参数 | 说明 | | --- | --- | | vid | 剧 id | | start | 起始偏移,从 0 开始 | | limit | 每页条数,可用 200 | 示例:`/app/video/getchapters?vid=1942&start=0&limit=200` `data`: | 字段 | 类型 | 说明 | | --- | --- | --- | | count | int | 总集数 | | list[].id | int | 集 id,对应播放列表里的 `cid` | | list[].title | string | | | list[].idx | int | 集序号 | | list[].isvip | string | `"0"` 免费,`"1"` 锁定。这是字符串,不是布尔值 | ### POST /app/video/playlist 安装包里没有这个路径,但服务端仍接受,GET 和 POST 都可以。请求体与 `playlistv2` 相同。 `data` 的字段和 `playlistv2` 一样。区别是它一次返回该剧全部集,不再按每页 10 条分页。剧 1942 一次返回 `count` 30、`list` 30 条,其中免费的 3 集有 `src`,其余为空。第一集的 `src` 与 `playlistv2` 第一页相同。脚本优先调用这个接口,结果为空、条数少于 `count` 或请求失败时,再按页调用 `playlistv2`。 `playlistv1` 和 `playlistv3` 返回 nginx 404。 ### POST /app/video/playlistv2 这是播放地址接口。`vid` 是剧 id,不是集 id。 请求体: ```json {"vid": 1942, "page": 1, "before": 1} ``` 第一页 `before` 为 `1`,后面的页为 `0`。每页 10 集。`data.count` 到齐后停止。 `data`: | 字段 | 类型 | 说明 | | --- | --- | --- | | count | int | 总集数 | | list[].cid | int | 集 id | | list[].idx | int | 集序号 | | list[].msg | string | 例如 `EP.1` | | list[].src | string | 主 m3u8。未解锁时是空字符串 | | list[].state | string | 例如 `pause` | | list[].like | int | | | list[].like_n | int | | | list[].playNumber | int | | | list[].fufei | int | | | list[].playIng | bool | | | list[].isShowimage | bool | | | list[].needScore | string | | | list[].isplay | bool | | 游客和未购买账号只能拿到免费集的 `src`。锁定集的 `src` 为空,接口不会因为换了登录方式就返回地址。 `src` 是 BunnyCDN 签名地址,形如: ```text https://vz-<编号>.b-cdn.net/bcdn_token=<签名>&token_path=%2F<视频uuid>%2F&expires=/<视频uuid>/playlist.m3u8 ``` 签名写在路径里,不是查询字符串。主列表里有一行相对路径 `1080p/video.m3u8`。子列表是点播,分片名为 `video0.ts`、`video1.ts`。同一段签名前缀可以访问该视频目录下的子列表和 ts。签名会过期,需要时重新请求 `playlistv2`。 ### POST /app/video/videoinfo 请求体: ```json {"vid": 1942} ``` `data`: | 字段 | 类型 | | --- | --- | | moshi | int | | video.id | int | | video.title | string | | video.view | int | | video.desc | string | | video.ishot | string | | video.like | int | | video.is_on | int | | video.poster | string | | video.forstaus | string | | video.author | string | | video.forstausen | string | 带已登录账号时,`data` 里还出现过 `history`。 ### POST /app/video/addreadlog App 播放时发出的请求体如下,返回格式没有单独保存: ```json {"vid": 2286, "del": 0, "cid": 26125} ``` `vid` 是剧 id,`cid` 是集 id。 ## 其他已核对接口 ### POST /app/open/contact 请求体:`{}` `data`: | 字段 | 类型 | | --- | --- | | techniacl_email | string | | business_email | string | 字段名在服务端就是 `techniacl_email`。 ### POST /app/appopen/getAuthConfig 请求体:`{}` `data`: | 字段 | 类型 | 说明 | | --- | --- | --- | | platform | string | | | google.enabled | bool | | | google.android_client_id | string | | | google.ios_client_id | string | | | google.web_client_id | string | | | google.client_id | string | | | google.server_client_id | string | | | apple.enabled | bool | | | apple.service_id | string | | | apple.team_id | string | | | apple.key_id | string | | | supported_platforms | string[] | | ## 安装包中的路径 这些路径从 `libapp.so` 提取。除上面已写明的接口外,访问方式和返回格式都还没有核对。 认证: - POST /app/user/appleLogin - POST /app/user/googleLogin - POST /app/user/bindEmail - POST /auth/register - POST /auth/refresh - POST /auth/bind-email 用户: - /app/user/accountBindingStatus - /app/user/editProfile - /app/user/changePassword - /app/user/deleteAccount - /app/user/activate - /app/user/activationSubOverview - /app/user/getPlatformBinds - /app/user/getSensorsProfile - /app/user/recordAttribution - /app/user/readhistory - /app/user/delhistory 视频: - /app/video/overview - /app/video/addToWishlist - /app/video/markvideo - /app/video/exitRecommendm - /app/video/screening - /app/User/checkViewTime 支付和订阅: - /app/pay/google_iap_create_order - /app/pay/google_iap_verify - /app/pay/google_iap_status - /app/pay/google_iap_recovery - /app/pay/apple_iap_create_order - /app/pay/apple_iap_verify - /app/pay/apple_iap_recovery - /app/pay/paylmpay_create_order - /app/pay/paypal_return - /app/pay/paypal_cancel - /app/pay/paystatus - /app/pay/paysuccess - /app/pay/initiateCheckout - /app/pay/report_payment_panel_context - /app/pay_center/create_order - /app/pay_center/paylist - /app/pay_center/third_party_qualification - /app/user/paylist - /app/user/paylistv2 - /app/user/paylistv3 - /app/subscription/list - /app/subscription/cancel 签到、反馈、通知: - /app/checkin/config - /app/checkin/status - /app/checkin/perform - /app/checkin/history - /app/checkin/statistics - /app/checkin/tasks - /app/feedback/submit - /app/feedback/list - /app/feedback/detail - /app/feedback/read - /app/feedback/categories - /app/feedback/unreadCount - /app/feedback/upload - /app/notification/getList - /app/notification/getDetail - /app/notification/device - /app/notification/settings - /app/notification/action - /app/notification/clear