{
  "openapi": "3.1.0",
  "info": {
    "title": "妙音 Sarasvati OpenAPI",
    "version": "1.2.0",
    "description": "妙音 Sarasvati（sarasvati.cn）是中国内容 Agent 基础设施：信息采集 → AI 改写 → 多平台分发 → 数据回流全链路自动化。本 API 供第三方系统与 AI Agent 查询选题、稿件、发布状态与效果数据，提交内容需求指令，并通过「发布即服务」一次调用完成内容生成/适配与多渠道入队发布。所有接口严格按 API Key 所属账号隔离数据。\n\n人类可读文档：https://sarasvati.cn/developers\nAgent 索引：https://sarasvati.cn/llms.txt\n\nWebhook 回调：支持订阅稿件待审批 / 渠道发布成功 / 渠道发布失败事件，主动 POST 推送到租户自配地址（HMAC-SHA256 验签，失败按 1/5/15 分钟退避重试 3 次）；配置入口在控制台「OpenAPI」页，详见开发者文档 Webhook 章节。",
    "contact": {
      "name": "妙音开发者支持（控制台「工单」）",
      "url": "https://sarasvati.cn/developers"
    }
  },
  "servers": [
    {
      "url": "https://sarasvati.cn/api/v1",
      "description": "生产环境"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "tags": [
    {
      "name": "发布",
      "description": "发布即服务：一次调用完成内容生成/适配、审核质检与多渠道入队发布（每日前 20 个渠道发布免费）"
    },
    {
      "name": "账号",
      "description": "账号概要与计费"
    },
    {
      "name": "选题",
      "description": "选题清单查询"
    },
    {
      "name": "稿件",
      "description": "稿件与各渠道发布状态"
    },
    {
      "name": "效果",
      "description": "已发布内容的阅读/点赞/回复/收藏回流数据"
    },
    {
      "name": "指令",
      "description": "提交内容需求指令（创建后为待确认，不产生扣费）"
    }
  ],
  "paths": {
    "/publish": {
      "post": {
        "tags": [
          "发布"
        ],
        "summary": "发布即服务：一次调用完成生成/适配与多渠道发布",
        "description": "两种模式 × 两种内容形态（contentType 缺省 article）：\n① 自带内容（title + content，正文保持原文核心内容不变，仅做平台适配）；\n② 代为生成（generate=true + topic，由平台 AI 生产全文）；\n③ 视频·自带内容（contentType=video + videoUrl 成片直链 + title，content 选填作为视频简介/文案，按各视频平台简介格式适配）；\n④ 视频·代为生成（contentType=video + generate=true + topic，走图文成片管线：接口立即返回 manuscriptId，后台合成完成后自动发布，用 GET /manuscripts/{id} 轮询 video.status 与各渠道进度；合成失败发布费自动全额退还）。\n所有内容走与控制台相同的审核 + AI 质检管线；防线降级时转人工审批（status=pending_review）且不计费。\n\n计费：每账号每日前 20 个「渠道发布」免费（1 篇发 N 个渠道 = N 个渠道发布，图文/视频共享额度），超出部分图文 0.5、视频 1.5 单元/渠道；只对成功入队的渠道计费，失败自动退还。限流 30 次/分钟/Key。现阶段仅开放国内渠道（video 可发好看视频/AcFun 等纯视频渠道）。\n\n幂等：请求头 Idempotency-Key（可选，≤128 字符）——同一账号同一 Key 重试直接返回首次的响应（带 idempotentReplay: true），不重复产稿/扣费/入队；同 Key 请求处理中返回 409。",
        "operationId": "publish",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "幂等键（≤128 字符）：同一账号同一 Key 的重复请求返回首次结果，不重复扣费",
            "schema": {
              "type": "string",
              "maxLength": 128
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "brandId",
                  "channels"
                ],
                "properties": {
                  "brandId": {
                    "type": "integer",
                    "description": "品牌 ID（必须属于当前账号且品牌启用中）"
                  },
                  "channels": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "maxItems": 20,
                    "description": "渠道 key 数组（自动去重）；按内容形态收口：video 可发视频渠道（含好看视频/AcFun 等纯视频渠道），不合法渠道在 400 中逐个报出并附可用清单"
                  },
                  "contentType": {
                    "type": "string",
                    "enum": [
                      "article",
                      "video"
                    ],
                    "default": "article",
                    "description": "内容形态：article 图文（默认）/ video 视频"
                  },
                  "videoUrl": {
                    "type": "string",
                    "format": "uri",
                    "description": "成片 URL（http/https，mp4，≤200MB）；视频·自带内容模式必填，与 generate 互斥"
                  },
                  "title": {
                    "type": "string",
                    "maxLength": 200,
                    "description": "稿件标题（自带内容模式必填；generate 模式可省略，由 AI 拟定）"
                  },
                  "content": {
                    "type": "string",
                    "maxLength": 50000,
                    "description": "Markdown 正文（图文·自带内容模式必填；视频模式下选填，作为视频简介/文案）"
                  },
                  "images": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uri"
                    },
                    "maxItems": 9,
                    "description": "配图 URL 数组（http/https，仅图文模式）"
                  },
                  "generate": {
                    "type": "boolean",
                    "description": "传 true 进入代为生成模式"
                  },
                  "topic": {
                    "type": "string",
                    "maxLength": 2000,
                    "description": "主题/素材描述（generate=true 时必填）"
                  },
                  "requirement": {
                    "type": "string",
                    "maxLength": 1000,
                    "description": "附加要求（调性、字数、必须提到的点等）"
                  }
                }
              },
              "examples": {
                "byo": {
                  "summary": "图文·自带内容",
                  "value": {
                    "brandId": 3,
                    "channels": [
                      "zhihu",
                      "toutiao",
                      "wechat"
                    ],
                    "title": "智慧公路的三个常见误区",
                    "content": "## 误区一……",
                    "images": [
                      "https://example.com/cover.png"
                    ]
                  }
                },
                "generate": {
                  "summary": "图文·代为生成",
                  "value": {
                    "brandId": 3,
                    "channels": [
                      "zhihu",
                      "toutiao"
                    ],
                    "generate": true,
                    "topic": "智慧公路的三个常见误区",
                    "requirement": "1500 字左右，举 2 个真实项目例子"
                  }
                },
                "videoByo": {
                  "summary": "视频·自带成片",
                  "value": {
                    "brandId": 3,
                    "channels": [
                      "haokan",
                      "acfun",
                      "douyin"
                    ],
                    "contentType": "video",
                    "videoUrl": "https://example.com/intro.mp4",
                    "title": "3 分钟看懂智慧公路",
                    "content": "视频简介/文案（选填）"
                  }
                },
                "videoGenerate": {
                  "summary": "视频·代为生成（异步合成）",
                  "value": {
                    "brandId": 3,
                    "channels": [
                      "douyin",
                      "bilibili"
                    ],
                    "contentType": "video",
                    "generate": true,
                    "topic": "智慧公路的三个常见误区"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "已入队（或防线降级转人工审批）",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublishResponse"
                },
                "example": {
                  "ok": true,
                  "data": {
                    "manuscriptId": 128,
                    "taskIds": [
                      901,
                      902
                    ],
                    "perPlatform": {
                      "zhihu": {
                        "taskId": 901,
                        "status": "queued"
                      },
                      "toutiao": {
                        "taskId": 902,
                        "status": "queued"
                      }
                    },
                    "chargedUnits": 0,
                    "freeQuotaUsed": 2,
                    "freeQuotaRemaining": 18,
                    "unitsRemaining": 2000,
                    "status": "queued"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/me": {
      "get": {
        "tags": [
          "账号"
        ],
        "summary": "验证 Key 并返回账号概要",
        "description": "返回租户 ID、名称、认证档、认证到期、单元余额、状态与常用单元单价。",
        "operationId": "getAccount",
        "responses": {
          "200": {
            "description": "账号概要",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MeResponse"
                },
                "example": {
                  "ok": true,
                  "data": {
                    "tenantId": 5,
                    "name": "路信通",
                    "plan": "pro",
                    "certifiedUntil": "2027-09-01T00:00:00.000Z",
                    "balanceUnits": 2000,
                    "status": "active",
                    "unitCosts": {
                      "rewritePerArticle": 0.5,
                      "imagePerPiece": 2,
                      "eoReport": 30
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/topics": {
      "get": {
        "tags": [
          "选题"
        ],
        "summary": "查询选题清单",
        "description": "按状态/品牌过滤选题，时间倒序分页。",
        "operationId": "listTopics",
        "parameters": [
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/BrandId"
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "选题状态过滤；不传 = 全部",
            "schema": {
              "type": "string",
              "enum": [
                "proposed",
                "approved",
                "auto_approved",
                "rejected",
                "producing",
                "produced",
                "expired"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "选题列表",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TopicListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/manuscripts": {
      "get": {
        "tags": [
          "稿件"
        ],
        "summary": "查询稿件列表",
        "description": "返回稿件及各渠道发布状态（不含正文，详情见 /manuscripts/{id}）。",
        "operationId": "listManuscripts",
        "parameters": [
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/BrandId"
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "稿件状态过滤；不传 = 全部",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "稿件列表",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ManuscriptListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/manuscripts/{id}": {
      "get": {
        "tags": [
          "稿件"
        ],
        "summary": "查询稿件详情",
        "description": "返回稿件详情，含各渠道完整正文与发布状态。跨账号返回 404。",
        "operationId": "getManuscript",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "稿件 ID"
          }
        ],
        "responses": {
          "200": {
            "description": "稿件详情",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ManuscriptDetailResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/effects": {
      "get": {
        "tags": [
          "效果"
        ],
        "summary": "查询内容效果回流数据",
        "description": "已发布内容的查看/点赞/回复/分享回采记录，按抓取时间倒序。同一作品会多次回采（多条记录体现增长曲线），取每个 manuscriptId+platform 的最新一条即当前值。",
        "operationId": "listEffects",
        "parameters": [
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/BrandId"
          },
          {
            "name": "days",
            "in": "query",
            "required": false,
            "description": "回采时间范围（天），默认 7，最大 90",
            "schema": {
              "type": "integer",
              "default": 7,
              "minimum": 1,
              "maximum": 90
            }
          }
        ],
        "responses": {
          "200": {
            "description": "效果数据列表",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EffectListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/directives": {
      "post": {
        "tags": [
          "指令"
        ],
        "summary": "提交内容需求指令",
        "description": "提交大白话需求（10-500 字）。创建后为「待确认」状态，**不产生扣费、不执行**；LLM 解析与扣费发生在用户在控制台「指令」页确认时。返回 confirmUrl 供引导用户前往确认。",
        "operationId": "submitDirective",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "rawText"
                ],
                "properties": {
                  "rawText": {
                    "type": "string",
                    "minLength": 10,
                    "maxLength": 500,
                    "description": "大白话需求，如「每天给路信通产出 1 篇智慧公路主题的图文，发知乎和头条」"
                  },
                  "brandId": {
                    "type": "integer",
                    "description": "品牌 ID（可选，必须属于当前账号且品牌启用中）"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "指令已创建（待确认）",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DirectiveResponse"
                },
                "example": {
                  "ok": true,
                  "data": {
                    "directiveId": 123,
                    "status": "pending_confirm",
                    "confirmUrl": "https://sarasvati.cn/console/directives"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/leads": {
      "post": {
        "tags": [
          "线索"
        ],
        "summary": "线索推入",
        "description": "已有自己的表单/CRM（金数据、问卷星、麦客、自有官网表单 webhook）时，把线索推进妙音线索库。与官网嵌入表单同口径校验、同联系方式 24h 去重、实时通知。不扣单元。",
        "operationId": "createLead",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name",
                  "contact"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 60,
                    "description": "称呼"
                  },
                  "contact": {
                    "type": "string",
                    "maxLength": 120,
                    "description": "联系方式：手机号/邮箱/微信号/座机（格式白名单校验）"
                  },
                  "email": {
                    "type": "string",
                    "maxLength": 120,
                    "description": "邮箱（可选，填了就必须是合法邮箱）"
                  },
                  "note": {
                    "type": "string",
                    "maxLength": 500,
                    "description": "需求描述（可选）"
                  },
                  "brandId": {
                    "type": "integer",
                    "description": "品牌 ID（可选，必须属于当前账号）"
                  },
                  "utmCampaign": {
                    "type": "string",
                    "maxLength": 64,
                    "description": "归因标记（可选）"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "线索已录入（或 24h 内重复，未重复创建）",
            "content": {
              "application/json": {
                "example": {
                  "ok": true,
                  "data": {
                    "duplicate": false
                  },
                  "message": "线索已录入，控制台「销售线索」页可跟进"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "API Key 格式为 svt_ + 48 位十六进制，在控制台「我的」页生成。示例：Authorization: Bearer svt_xxx"
      }
    },
    "parameters": {
      "Page": {
        "name": "page",
        "in": "query",
        "required": false,
        "schema": {
          "type": "integer",
          "default": 1,
          "minimum": 1
        },
        "description": "页码（从 1 开始）"
      },
      "Limit": {
        "name": "limit",
        "in": "query",
        "required": false,
        "schema": {
          "type": "integer",
          "default": 20,
          "minimum": 1,
          "maximum": 100
        },
        "description": "每页条数（最大 100）"
      },
      "BrandId": {
        "name": "brandId",
        "in": "query",
        "required": false,
        "schema": {
          "type": "integer"
        },
        "description": "品牌 ID 过滤（可选）"
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "API Key 无效或账号已停用",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "ok": false,
              "error": "API Key 无效或账号已停用"
            }
          }
        }
      },
      "BadRequest": {
        "description": "参数错误",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "NotFound": {
        "description": "资源不存在或不属于当前账号",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "ok": false,
              "error": "稿件不存在"
            }
          }
        }
      },
      "PaymentRequired": {
        "description": "单元余额不足，响应带 rechargeUrl 引导充值",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "ok": false,
              "error": "单元余额不足：本次发布 3 个渠道，今日免费额度剩余 0 个，需支付 1.5 单元，当前余额 1 单元",
              "rechargeUrl": "https://sarasvati.cn/console/billing"
            }
          }
        }
      },
      "Forbidden": {
        "description": "账号不可用（试用期已结束且未完成认证/续费），响应带 upgradeUrl",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "ok": false,
              "error": "发布 API 需要账号处于可用状态（试用期内或认证未过期），请先完成认证或续费",
              "upgradeUrl": "https://sarasvati.cn/console/mine"
            }
          }
        }
      },
      "RateLimited": {
        "description": "触发限流（发布接口同一 Key 30 次/分钟）",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "ok": false,
              "error": "请求过于频繁，请 12 秒后重试"
            }
          }
        }
      },
      "Conflict": {
        "description": "相同 Idempotency-Key 的请求正在处理中",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "ok": false,
              "error": "相同 Idempotency-Key 的请求正在处理中，请稍后重试"
            }
          }
        }
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean",
            "example": false
          },
          "error": {
            "type": "string"
          }
        }
      },
      "Pagination": {
        "type": "object",
        "properties": {
          "page": {
            "type": "integer"
          },
          "limit": {
            "type": "integer"
          },
          "total": {
            "type": "integer"
          },
          "hasNext": {
            "type": "boolean"
          }
        }
      },
      "BrandRef": {
        "type": "object",
        "nullable": true,
        "properties": {
          "id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          }
        }
      },
      "MeResponse": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "type": "object",
            "properties": {
              "tenantId": {
                "type": "integer"
              },
              "name": {
                "type": "string"
              },
              "plan": {
                "type": "string",
                "enum": [
                  "trial",
                  "basic",
                  "pro",
                  "premium"
                ]
              },
              "certifiedUntil": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              },
              "balanceUnits": {
                "type": "number"
              },
              "status": {
                "type": "string"
              },
              "unitCosts": {
                "type": "object",
                "properties": {
                  "rewritePerArticle": {
                    "type": "number"
                  },
                  "imagePerPiece": {
                    "type": "number"
                  },
                  "eoReport": {
                    "type": "number"
                  }
                }
              }
            }
          }
        }
      },
      "Topic": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "score": {
            "type": "number",
            "nullable": true
          },
          "source": {
            "type": "string",
            "nullable": true
          },
          "brand": {
            "$ref": "#/components/schemas/BrandRef"
          },
          "manuscriptId": {
            "type": "integer",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "TopicListResponse": {
        "allOf": [
          {
            "type": "object",
            "properties": {
              "ok": {
                "type": "boolean",
                "example": true
              },
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Topic"
                }
              }
            }
          },
          {
            "$ref": "#/components/schemas/Pagination"
          }
        ]
      },
      "PlatformVersion": {
        "type": "object",
        "properties": {
          "platform": {
            "type": "string",
            "description": "渠道标识，如 wechat / toutiao / zhihu / xiaohongshu"
          },
          "title": {
            "type": "string"
          },
          "publishStatus": {
            "type": "string",
            "description": "published 已发布 / drafted 草稿箱待手动发布 / failed 失败 / 其他中间态"
          },
          "publishedUrl": {
            "type": "string",
            "nullable": true
          },
          "publishedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "lastError": {
            "type": "string",
            "nullable": true
          },
          "content": {
            "type": "string",
            "description": "渠道正文（仅详情接口返回）"
          },
          "summary": {
            "type": "string",
            "description": "渠道摘要（仅详情接口返回）"
          }
        }
      },
      "Manuscript": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "contentType": {
            "type": "string",
            "description": "article 图文 / video 视频"
          },
          "summary": {
            "type": "string",
            "description": "稿件摘要（仅详情接口返回）"
          },
          "brand": {
            "$ref": "#/components/schemas/BrandRef"
          },
          "video": {
            "type": "object",
            "nullable": true,
            "properties": {
              "status": {
                "type": "string"
              },
              "durationSec": {
                "type": "number",
                "nullable": true
              }
            }
          },
          "platforms": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PlatformVersion"
            }
          },
          "publishedCount": {
            "type": "integer"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "ManuscriptListResponse": {
        "allOf": [
          {
            "type": "object",
            "properties": {
              "ok": {
                "type": "boolean",
                "example": true
              },
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Manuscript"
                }
              }
            }
          },
          {
            "$ref": "#/components/schemas/Pagination"
          }
        ]
      },
      "ManuscriptDetailResponse": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "$ref": "#/components/schemas/Manuscript"
          }
        }
      },
      "Effect": {
        "type": "object",
        "properties": {
          "manuscriptId": {
            "type": "integer",
            "nullable": true
          },
          "manuscriptTitle": {
            "type": "string",
            "nullable": true
          },
          "brand": {
            "$ref": "#/components/schemas/BrandRef"
          },
          "platform": {
            "type": "string"
          },
          "publishedUrl": {
            "type": "string",
            "nullable": true
          },
          "views": {
            "type": "integer"
          },
          "likes": {
            "type": "integer"
          },
          "comments": {
            "type": "integer"
          },
          "shares": {
            "type": "integer"
          },
          "fetchedAt": {
            "type": "string",
            "format": "date-time"
          },
          "error": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "EffectListResponse": {
        "allOf": [
          {
            "type": "object",
            "properties": {
              "ok": {
                "type": "boolean",
                "example": true
              },
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Effect"
                }
              }
            }
          },
          {
            "$ref": "#/components/schemas/Pagination"
          },
          {
            "type": "object",
            "properties": {
              "days": {
                "type": "integer"
              }
            }
          }
        ]
      },
      "PublishResponse": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "type": "object",
            "properties": {
              "manuscriptId": {
                "type": "integer",
                "description": "生成的稿件 ID，用 GET /manuscripts/{id} 跟踪进度"
              },
              "taskIds": {
                "type": "array",
                "items": {
                  "type": "integer"
                },
                "description": "本次创建的发布任务 ID 列表"
              },
              "perPlatform": {
                "type": "object",
                "description": "逐渠道结果：成功 { taskId, status: \"queued\" }；失败 { status: \"failed\", error }"
              },
              "chargedUnits": {
                "type": "number",
                "description": "本次实扣单元（失败渠道已自动退还）"
              },
              "freeQuotaUsed": {
                "type": "integer",
                "description": "本次用掉的免费渠道发布数"
              },
              "freeQuotaRemaining": {
                "type": "integer",
                "description": "今日剩余免费额度"
              },
              "unitsRemaining": {
                "type": "number",
                "description": "当前单元余额"
              },
              "status": {
                "type": "string",
                "enum": [
                  "queued",
                  "pending_review"
                ],
                "description": "queued 已入队；pending_review 内容安全防线降级转人工审批（本次不计费）"
              },
              "note": {
                "type": "string",
                "description": "视频·代为生成时返回：提示合成为异步，轮询 GET /manuscripts/{id} 跟踪"
              },
              "idempotentReplay": {
                "type": "boolean",
                "description": "仅幂等重放时出现：true = Idempotency-Key 命中，本次为首次响应的副本，未重复执行"
              }
            }
          }
        }
      },
      "DirectiveResponse": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "type": "object",
            "properties": {
              "directiveId": {
                "type": "integer"
              },
              "status": {
                "type": "string",
                "example": "pending_confirm"
              },
              "confirmUrl": {
                "type": "string"
              }
            }
          }
        }
      }
    }
  }
}