{
  "openapi": "3.0.3",
  "info": {
    "title": "OnePesr 语音 API",
    "version": "1.2.0",
    "description": "OnePesr 语音开放接口，覆盖四个核心功能：查询声音模型列表、声音克隆（指定音色合成）、声音设计（描述词生成声音）、创建声音模型（上传录音克隆音色）。鉴权方式：请求中携带 api_key 与 api_secret。统一返回 {\"code\":0或非0,\"msg\":\"...\",\"data\":{...}}，code=0 表示成功。合成类接口为同步阻塞，HTTP 超时请设置 60 秒以上。"
  },
  "servers": [
    { "url": "https://tts.yirenbang.cc" }
  ],
  "paths": {
    "/api/v1/models": {
      "get": {
        "operationId": "list_models",
        "summary": "查询当前 API 密钥用户可用的声音模型列表",
        "description": "返回系统音色（AI 音色库，33 个）和用户自己创建的音色。合成前建议先调用此接口获取音色编码。",
        "parameters": [
          { "name": "api_key", "in": "query", "required": true, "schema": { "type": "string" }, "description": "API Key，op- 开头" },
          { "name": "api_secret", "in": "query", "required": true, "schema": { "type": "string" }, "description": "API Secret" }
        ],
        "responses": {
          "200": {
            "description": "查询成功",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": { "type": "integer", "example": 0 },
                    "msg": { "type": "string", "example": "ok" },
                    "data": {
                      "type": "object",
                      "properties": {
                        "system_voices": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "model_code": { "type": "string", "example": "sys_f_xiaolin" },
                              "name": { "type": "string", "example": "晓琳" },
                              "category": { "type": "string", "example": "女声" },
                              "gender": { "type": "string", "example": "女" },
                              "language": { "type": "string", "example": "中文" },
                              "description": { "type": "string", "example": "温柔知性的年轻女声" },
                              "type": { "type": "string", "example": "system" }
                            }
                          }
                        },
                        "my_voices": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "model_code": { "type": "string", "example": "usr_3_1792007397" },
                              "name": { "type": "string", "example": "我的声音" },
                              "category": { "type": "string", "example": "男声" },
                              "gender": { "type": "string", "example": "未知" },
                              "language": { "type": "string", "example": "中文" },
                              "description": { "type": "string", "example": "日常说话" },
                              "type": { "type": "string", "example": "custom" }
                            }
                          }
                        },
                        "total": { "type": "integer", "example": 34 }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": { "description": "鉴权失败或无 VIP 权限" }
        }
      }
    },
    "/api/v1/tts": {
      "post": {
        "operationId": "voice_clone_tts",
        "summary": "声音克隆：指定音色，文本转语音，同步返回音频 URL",
        "description": "按字符扣费（1 汉字/字母/标点 = 1 额度），合成失败自动全额返还。audio_url 已带鉴权参数，直接 GET 下载，音频保留 1 天。",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["api_key", "api_secret", "text", "model_code"],
                "properties": {
                  "api_key": { "type": "string", "description": "API Key，op- 开头" },
                  "api_secret": { "type": "string", "description": "API Secret，50 位十六进制" },
                  "text": { "type": "string", "minLength": 1, "maxLength": 5000, "description": "待合成文本，按字符扣费" },
                  "model_code": { "type": "string", "description": "音色编码。系统音色 sys_ 开头（女声 sys_f_*、男声 sys_m_*、童声 sys_c_*、方言 sys_d_*），用户自建音色 usr_ 开头（由 model_create 获得）", "example": "sys_f_xiaotian" },
                  "speed": { "type": "number", "minimum": 0.5, "maximum": 2.0, "default": 1.0, "description": "语速" },
                  "emotion_ext": {
                    "type": "object",
                    "description": "语气向量（可选）。8 维各取 0-1，最多 3 项非 0，超出自动保留数值最高的 3 项；全 0 或不传 = 跟随参考音频。仅普通话/多语言音色生效",
                    "properties": {
                      "happy": { "type": "number", "minimum": 0, "maximum": 1, "description": "开心" },
                      "sad": { "type": "number", "minimum": 0, "maximum": 1, "description": "悲伤" },
                      "angry": { "type": "number", "minimum": 0, "maximum": 1, "description": "愤怒" },
                      "surprised": { "type": "number", "minimum": 0, "maximum": 1, "description": "惊讶" },
                      "calm": { "type": "number", "minimum": 0, "maximum": 1, "description": "平静" },
                      "melancholic": { "type": "number", "minimum": 0, "maximum": 1, "description": "忧郁" },
                      "afraid": { "type": "number", "minimum": 0, "maximum": 1, "description": "恐惧" },
                      "disgusted": { "type": "number", "minimum": 0, "maximum": 1, "description": "厌恶" }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "合成成功",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/TaskResult" }
              }
            }
          },
          "400": { "description": "参数错误或音色不可用（code=1，见 msg）" },
          "401": { "description": "密钥无效 / 已停用 / 账号不可用" },
          "402": { "description": "额度不足，请充值或兑换 CDKEY" },
          "500": { "description": "合成失败，额度已自动返还，可稍后重试" }
        }
      }
    },
    "/api/v1/dubbing": {
      "post": {
        "operationId": "voice_design_dubbing",
        "summary": "声音设计：用描述词生成声音并合成文本",
        "description": "无需录音与音色编码，用描述词（性别/年龄/质感/语速/情绪/场景）生成声音朗读文本。按字符扣费，失败自动全额返还。",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["api_key", "api_secret", "text", "design_prompt"],
                "properties": {
                  "api_key": { "type": "string" },
                  "api_secret": { "type": "string" },
                  "text": { "type": "string", "minLength": 1, "description": "朗读文本，按字符扣费；引擎限制 1000 字节（约 330 汉字），超长请切分" },
                  "design_prompt": { "type": "string", "maxLength": 200, "description": "声音描述词，越具体效果越好", "example": "温柔知性的年轻女声，语速平缓，像深夜电台主播" }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "合成成功",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/TaskResult" }
              }
            }
          },
          "400": { "description": "参数错误（如缺少 design_prompt、文本超长）" },
          "401": { "description": "密钥无效 / 已停用 / 账号不可用" },
          "402": { "description": "额度不足" },
          "500": { "description": "合成失败，额度已自动返还" }
        }
      }
    },
    "/api/v1/model/create": {
      "post": {
        "operationId": "voice_model_create",
        "summary": "创建声音模型：上传录音样本注册专属音色",
        "description": "上传 3-60 秒清晰人声样本（推荐 3-10 秒干声），返回 model_code（usr_ 开头），立即可用于 voice_clone_tts。创建不扣费。样本须为本人或已获授权的声音。",
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": ["api_key", "api_secret", "name", "category", "sample"],
                "properties": {
                  "api_key": { "type": "string" },
                  "api_secret": { "type": "string" },
                  "name": { "type": "string", "maxLength": 32, "description": "音色名称" },
                  "category": { "type": "string", "enum": ["男声", "女声", "童声", "其他"], "description": "音色分类" },
                  "language": { "type": "string", "default": "中文", "description": "语言" },
                  "description": { "type": "string", "maxLength": 100, "description": "音色描述" },
                  "sample": { "type": "string", "format": "binary", "description": "录音文件，MP3/WAV/M4A，3-60 秒，≤20MB" }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "创建成功",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": { "type": "integer", "enum": [0] },
                    "msg": { "type": "string", "example": "音色创建成功，已可立即用于合成" },
                    "data": {
                      "type": "object",
                      "properties": {
                        "model_code": { "type": "string", "description": "音色编码（usr_ 开头），用于 voice_clone_tts", "example": "usr_3_1792007397" },
                        "name": { "type": "string" },
                        "id": { "type": "integer" }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": { "description": "参数错误（名称/分类/样本格式或大小不合规、样本质量不达标）" },
          "401": { "description": "密钥无效 / 已停用 / 账号不可用" }
        }
      }
    },
    "/api/v1/audio": {
      "get": {
        "operationId": "audio_get",
        "summary": "获取合成音频二进制流",
        "description": "返回 WAV/MP3 二进制（按 Content-Type 区分）。仅可获取本密钥所属账号的任务音频。通常无需直接调用——合成接口返回的 audio_url 即本接口完整地址。",
        "parameters": [
          { "name": "task_no", "in": "query", "required": true, "schema": { "type": "string" }, "description": "任务编号" },
          { "name": "api_key", "in": "query", "required": true, "schema": { "type": "string" } },
          { "name": "api_secret", "in": "query", "required": true, "schema": { "type": "string" } }
        ],
        "responses": {
          "200": {
            "description": "音频二进制流",
            "content": {
              "audio/wav": { "schema": { "type": "string", "format": "binary" } },
              "audio/mpeg": { "schema": { "type": "string", "format": "binary" } }
            }
          },
          "401": { "description": "密钥无效" },
          "404": { "description": "任务不存在或音频已过期" }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "TaskResult": {
        "type": "object",
        "properties": {
          "code": { "type": "integer", "enum": [0] },
          "msg": { "type": "string", "example": "合成成功" },
          "data": {
            "type": "object",
            "properties": {
              "task_no": { "type": "string", "description": "任务编号" },
              "audio_url": { "type": "string", "description": "带鉴权的音频下载地址，保留 1 天" },
              "chars_used": { "type": "integer", "description": "本次扣除的字符额度" }
            }
          }
        }
      }
    }
  }
}
