DEVELOPER PLATFORM

开发者平台

用 API 令牌把写作工具、脚本或 Agent 直接接到拆书铺:创建作品、发布章节、设置完结,全程无需打开浏览器。

基础地址 https://doaiapp.com数据格式 JSON字符编码 UTF-8

快速开始

三步就能让脚本发出第一章。

第一步:创建 API 令牌

登录 拆书铺,点右上角头像打开个人中心,在「API 令牌」面板里填写名称、选择有效期,点「创建新令牌」。

令牌只显示一次

生成后请立刻复制保存。关闭面板后无法再次查看,只能删除重建。令牌等同于你的账号权限,不要提交进代码仓库或公开分享。

第二步:创建一部小说

拿到令牌后,创建作品。注意这个接口用的是 multipart/form-data,因为要支持上传封面。

bash
curl -X POST https://doaiapp.com/api/novels \
  -H "authorization: Bearer csk_你的令牌" \
  -F "title=山海食肆" \
  -F "author=听风" \
  -F "description=一间开在昆仑山脚的食肆,只招待非人之客。厨子沉默寡言,菜单上写着的价格,从来不是钱。" \
  -F "audience=general" \
  -F "primaryCategory=玄幻" \
  -F "secondaryCategory=东方玄幻" \
  -F "tags=美食,志怪,治愈" \
  -F "serialStatus=serializing"

返回作品 ID,后面发章要用:

json
{ "id": "9f2c...e41a", "title": "山海食肆", "author": "听风", "status": "listed" }

第三步:发布章节

bash
curl -X POST https://doaiapp.com/api/novels/9f2c...e41a/chapters \
  -H "authorization: Bearer csk_你的令牌" \
  -H "content-type: application/json" \
  -d '{"title":"第一章 夜客","content":"灯笼亮起的时候,第一位客人推门进来……"}'

章号由服务端自动递增,你不需要自己维护计数。

json
{ "chapterNumber": 1, "title": "第一章 夜客", "wordCount": 1284 }

认证

所有内容接口都接受两种身份:浏览器登录态(Cookie)和 API 令牌(Bearer)。脚本用后者。

http
authorization: Bearer csk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

令牌以 csk_ 开头。服务端只保存它的哈希值,即使数据库泄露也无法反推原文。每次调用会刷新「最近使用」时间(60 秒内不重复写入)。

两层权限

内容接口(建书、发章、完结、打赏)—— 令牌或登录态皆可。

令牌管理接口(创建、查看、删除令牌)—— 只接受登录态。令牌不能用来创建新令牌,这样一个泄露的令牌无法自我续命,你删掉它就是真的删掉了。

失效情形

接口参考

POST/api/novels令牌或登录态

创建一部新作品。请求体为 multipart/form-data

参数类型 / 约束说明
titlestring,2—18 字作品名称
authorstring,≤40 字作者署名
descriptionstring,20—500 字作品简介,少于 20 字会被拒绝
primaryCategorystring,必填一级分类,如「玄幻」
secondaryCategorystring,必填二级分类,如「东方玄幻」
audiencemale / female / general面向读者,默认 general
serialStatusserializing / completed连载状态,默认 serializing
tagsstring,逗号分隔,最多 8 个标签,超出部分截断
protagonistsstring,逗号分隔,最多 6 个主角名
coverFile,≤5MB封面图,仅支持 JPG / PNG / WebP

成功返回 201,响应体含 idtitleauthorstatus

POST/api/novels/{id}/chapters令牌或登录态

发布新章节。章号自动递增,正文按有效字符计数(不含空格和标点)。

参数类型 / 约束说明
titlestring,≤80 字章节标题
contentstring,≥100 有效字,≤120000 字符章节正文,\r\n 会被归一化为 \n

成功返回 201chapterNumberwordCount。作品已完结时返回 409

GET/api/novels/{id}/chapters/{number}令牌或登录态

读回某一章的标题与正文,方便先取再改。只有作者本人能读自己的章节原文。

PATCH/api/novels/{id}/chapters/{number}令牌或登录态

修改已发布的章节。两个字段都可选,省略哪个就保留哪个原值;字数和全书总字数会自动重算。

参数类型 / 约束说明
titlestring,≤80 字,选填新的章节标题
contentstring,≥100 有效字,≤120000 字符,选填新的章节正文

两个都不传返回 400。章节号不变,读者看到的顺序不受影响。

PATCH/api/novels/{id}/status令牌或登录态

将作品设为完结。目前只支持这一个方向,完结后无法继续发章,也无法改回连载中。

json
{ "status": "completed" }
DELETE/api/novels/{id}令牌或登录态

删除作品,有两种语义。

参数类型 / 约束说明
purgetrue,查询参数,选填不传 = 下架;传 true = 彻底删除

下架(默认):把状态改为 removed,读者立刻不可见,市场、阅读、下载、预览全部失效,但订单、积分流水、创作者收益和打赏记录原样保留。

彻底删除?purge=true):连同章节、作品资料、审核记录和封面文件一并抹掉,不可恢复。若该作品存在任何交易或打赏记录,会返回 409 并拒绝执行 —— 付费凭证和待结算收益不能被删掉。这条限制是故意的,想清空这类作品请改用下架。

POST/api/novels/{id}/tip令牌或登录态

给某一章打赏积分。不能打赏自己的作品。

参数类型 / 约束说明
chapterNumberinteger,≥1章节序号
points1 / 5 / 10 / 20 / 50 / 100打赏积分,只接受这六档
requestIdstring,≤100 字符,选填幂等键,重复提交同一个值不会重复扣分

积分不足返回 402

GET/api/tokens仅登录态

列出当前有效的令牌。只返回前缀,不返回明文。

POST/api/tokens仅登录态

创建令牌,每个账号最多同时保留 10 个。

参数类型 / 约束说明
namestring,2—40 字令牌名称,便于区分用途
expiresInDaysinteger,1—365,选填有效期天数,留空或 null 表示长期有效
DELETE/api/tokens/{id}仅登录态

吊销令牌,立即生效且不可恢复。

内容分级

每次发布或修改章节后,正文会交给 DeepSeek 自动判级,结果记在作品上,无需你传任何参数。

general常规题材。市场卡片不显示任何分级角标
mature含露骨性描写、详细暴力血腥、自残或毒品细节。卡片与阅读页显示红色「18+」角标
pending尚未判级 —— 判级服务不可用或调用失败。不显示角标,后续可重新判级

分级只升不降:一部作品里只要有一章被判为 mature,整部作品就是 mature,后续发布常规章节不会把它降回去。

判级失败不会阻断发布

判级服务超时或报错时,章节照常发布成功,作品分级记为 pending。发章和改章的响应里会带上 rating 字段,告诉你当前作品的分级结果。

作品列表(GET /api/books)和阅读接口都会返回 rating,你可以据此自行决定要不要展示或过滤。

错误码

所有错误响应体格式统一为 { "error": "中文描述" }

400参数不合法 —— 字数超限、分类缺失、打赏档位无效等,错误信息会指出具体哪一项
401未认证 —— 令牌缺失、格式错误、已删除或已过期
402积分不足(仅打赏接口)
403账号已停用
404作品或章节不存在,或不属于你
409状态冲突 —— 作品已完结仍尝试发章、令牌数已达上限,或对有交易记录的作品执行彻底删除
413内容过大 —— 封面超过 5MB,或单章超过 12 万字符
500服务端异常,可稍后重试

完整示例

Bash:建书并批量发章

把本地 chapters/ 目录下按文件名排序的 txt 依次发布,文件第一行作标题,其余作正文。

bash
#!/usr/bin/env bash
set -euo pipefail

TOKEN="csk_你的令牌"
BASE="https://doaiapp.com"

# 1. 建书,取回作品 ID
BOOK_ID=$(curl -s -X POST "$BASE/api/novels" \
  -H "authorization: Bearer $TOKEN" \
  -F "title=山海食肆" \
  -F "author=听风" \
  -F "description=一间开在昆仑山脚的食肆,只招待非人之客。" \
  -F "primaryCategory=玄幻" \
  -F "secondaryCategory=东方玄幻" \
  | python3 -c 'import sys,json; print(json.load(sys.stdin)["id"])')

echo "作品已创建:$BOOK_ID"

# 2. 按文件名顺序发章
for file in chapters/*.txt; do
  title=$(head -n 1 "$file")
  content=$(tail -n +2 "$file")
  payload=$(python3 -c 'import json,sys; print(json.dumps({"title":sys.argv[1],"content":sys.argv[2]}))' "$title" "$content")

  response=$(curl -s -X POST "$BASE/api/novels/$BOOK_ID/chapters" \
    -H "authorization: Bearer $TOKEN" \
    -H "content-type: application/json" \
    -d "$payload")

  echo "$file -> $response"
  sleep 1   # 温柔一点,别把自己的站点打疼
done

Python:带重试的发章函数

python
import os, time, requests

BASE = "https://doaiapp.com"
TOKEN = os.environ["CHAISHU_TOKEN"]   # 令牌放环境变量,别写进代码
HEADERS = {"authorization": f"Bearer {TOKEN}"}


def publish_chapter(book_id: str, title: str, content: str, retries: int = 3) -> dict:
    """发布一章,遇到 5xx 自动退避重试;4xx 直接抛出,因为重试也不会成功。"""
    url = f"{BASE}/api/novels/{book_id}/chapters"
    for attempt in range(retries):
        response = requests.post(url, headers=HEADERS, json={"title": title, "content": content}, timeout=30)
        if response.status_code == 201:
            return response.json()
        if response.status_code < 500:
            raise RuntimeError(f"{response.status_code}: {response.json().get('error')}")
        time.sleep(2 ** attempt)
    raise RuntimeError("服务端持续异常,已放弃")


if __name__ == "__main__":
    result = publish_chapter("9f2c...e41a", "第一章 夜客", open("ch01.txt", encoding="utf-8").read())
    print(f"已发布第 {result['chapterNumber']} 章,{result['wordCount']} 字")

使用须知