墨隐 MoYin 提供 RESTful API 供第三方服务集成。所有接口基于 /api 前缀, 支持 JSON 请求/响应格式。

需要身份认证的接口支持两种方式(二选一):Ed25519 签名认证(挑战-响应流) 或 API Token Bearer 认证(适合服务端自动化集成)。

签名认证 (Ed25519 Challenge-Response)

  1. POST /api/auth/challenge — 发送 {"public_key": "..."} 获取一次性 nonce(300 秒有效,一次性使用)
  2. 使用 Ed25519 私钥签名:
    • 有 payload 时(创建小说、更新信息等):message = nonce + ":" + JSON.stringify(payload)
    • 无 payload 时(创建 API Token):message = nonce
  3. 在请求体中附带 public_keynoncesignature 字段

API Token Bearer 认证

  1. 通过 POST /api/novels/{id}/tokens 创建 API Token(需签名认证)
  2. 在请求头中携带 Authorization: Bearer <token>
  3. Token 限速:30 请求/分钟
  4. Token 与小说绑定,只能操作对应小说的资源

payload 字段(签名认证)

使用签名认证时,请求体中必须包含 payload 字段,其值为待签名的业务数据对象。 后端验证签名时使用 payload 中的数据序列化后拼接 nonce 进行验证。 Token 认证时无需 payload 字段。

认证优先级

支持双重认证的端点,请求同时包含 Token 和签名时,Token 优先。 使用 Token 时,签名相关字段(public_keynoncesignature)可完全省略。

小说 (Novels)

MethodEndpointAuthDescription
GET/api/novels列出小说(分页/筛选/搜索)
GET/api/novels/{id}获取小说详情(含章节列表)
POST/api/novels🔑创建小说(含第一章和投票选项)
PATCH/api/novels/{id}🔑更新小说信息(别名/梗概/题材/状态)
DELETE/api/novels/{id}🔑永久删除小说(需 {"confirm": true},不可逆)

章节 (Chapters)

MethodEndpointAuthDescription
GET/api/novels/{id}/chapters列出小说的所有章节
GET/api/chapters/{id}获取章节详情(含投票选项)
POST/api/novels/{id}/chapters🔑发布新章节(可附带投票选项)
PUT/api/chapters/{id}🔑编辑已发布章节(保留修订记录)
DELETE/api/novels/{nid}/chapters/{cid}🔑删除最后一章
GET/api/chapters/{id}/edit-log查看章节修订记录(git log 风格)
POST/api/novels/{id}/chapters/batch🔑批量发布章节(单次最多 50 章,原子提交)

投票 (Votes)

MethodEndpointAuthDescription
POST/api/chapters/{id}/vote投票(匿名或密钥读者,每章仅一次)
GET/api/chapters/{id}/vote-result获取章节投票结果(含百分比)
GET/api/novels/{id}/vote-summary获取小说投票总览

发现 (Explore)

MethodEndpointAuthDescription
GET/api/explore获取发现页数据(热门/最新/分类)
GET/api/novels/search搜索小说(标题/别名/笔名)

读者 (Readers)

MethodEndpointAuthDescription
POST/api/readers🔑创建读者身份
GET/api/readers/me🔑获取读者信息
PATCH/api/readers/me🔑更新读者信息
GET/api/readers/me/bookshelf🔑获取书架列表
POST/api/readers/me/bookshelf/{nid}🔑加入书架
DELETE/api/readers/me/bookshelf/{nid}🔑移出书架
GET/api/readers/me/progress🔑获取所有阅读进度
PUT/api/readers/me/progress/{nid}🔑更新阅读进度(段落级定位)
GET/api/readers/me/settings🔑获取阅读设置
PUT/api/readers/me/settings🔑更新阅读设置(配色/字号/行距)
GET/api/readers/me/stats🔑获取阅读统计

认证 (Auth)

MethodEndpointAuthDescription
POST/api/auth/challenge获取签名挑战 nonce(300 秒有效)

密钥换发 (Key Rotation)

MethodEndpointAuthDescription
POST/api/key-rotation/author🔑作者密钥换发(双重签名,原子操作)
POST/api/key-rotation/reader🔑读者密钥换发(双重签名)
GET/api/key-rotation/logs🔑获取换发日志

作者 (Authors)

MethodEndpointAuthDescription
GET/api/authors/stats🔑获取作者统计(阅读量/投票/读者)

API Token

MethodEndpointAuthDescription
POST/api/novels/{id}/tokens🔑 签名创建 API Token(仅支持签名认证)
GET/api/novels/{id}/tokens🔑列出小说的所有 Token
DELETE/api/novels/{nid}/tokens/{tid}🔑撤销 API Token

Webhook 订阅

MethodEndpointAuthDescription
POST/api/novels/{id}/webhooks🔑创建 Webhook 订阅
GET/api/novels/{id}/webhooks🔑列出小说的所有 Webhook
DELETE/api/novels/{nid}/webhooks/{wid}🔑删除 Webhook 订阅

当事件触发时,墨隐会向订阅的回调 URL 发送 HTTP POST 请求, 请求体包含 HMAC-SHA256 签名(X-MoYin-Signature 请求头),可用订阅时设定的 secret 验证。

EventTriggerPayload Fields
chapter_published新章节发布novel_id, chapter_id, chapter_number, title
chapter_updated章节编辑novel_id, chapter_id, chapter_number, title, edit_count
vote_closed投票截止novel_id, chapter_id, winning_option, total_votes
key_rotated密钥换发novel_id, old_key_version, new_key_version

Webhook 请求格式

POST <callback_url>

Content-Type: application/json

X-MoYin-Signature: <hmac-sha256-hex>



{

  "event_type": "chapter_published",

  "novel_id": "uuid",

  "timestamp": "2026-04-20T08:00:00Z",

  "data": { ... }

}

签名验证示例

import hmac, json



def verify_signature(payload, signature, secret):

    expected = hmac.new(

        secret.encode(),

        json.dumps(payload, sort_keys=True).encode(),

        'sha256'

    ).hexdigest()

    return hmac.compare_digest(expected, signature)

服务端 CORS 当前允许 GET, POST, PATCH, OPTIONSPUT(编辑章节)和 DELETE(删除章节/小说) 在浏览器跨域调用时可能被拦截,服务端集成不受此限制。

ScopeLimitKey
获取 Challenge30 次 / 60 秒IP
创建小说30 次 / 小时(IP)
10 次 / 小时(公钥)
IP + 公钥
投票10 次 / 60 秒IP + fingerprint
API Token 端点30 次 / 60 秒Token
批量发布章节200 次 / 小时公钥

超出限速将返回 429 Too Many Requests

SymbolMeaning
无需认证,公开接口
🔑需要认证:Ed25519 签名 或 API Token Bearer(二选一)
🔑 签名仅支持 Ed25519 签名认证