{
  "openapi": "3.1.0",
  "info": {
    "title": "geo信源 Agent API",
    "version": "1.0.0",
    "description": "供 AI Agent 与脚本调用：写稿、质检、选媒体、报价、下单。鉴权使用企业资料 → API 接入创建的令牌（Authorization: Bearer xy_pat_...）。扣积分必须先 POST /orders/quote 取得确认码，再凭确认码 POST /orders；同一确认码重复提交不会重复扣费。同等能力亦通过 MCP（POST /api/mcp，Streamable HTTP）提供。"
  },
  "servers": [{ "url": "/api/agent/v1" }],
  "security": [{ "bearer": [] }],
  "paths": {
    "/me": {
      "get": {
        "operationId": "getAccount",
        "summary": "账户、积分余额与令牌额度",
        "description": "需要 account:read。",
        "responses": { "200": { "$ref": "#/components/responses/Ok" }, "default": { "$ref": "#/components/responses/Error" } }
      }
    },
    "/articles": {
      "get": {
        "operationId": "listArticles",
        "summary": "列出稿件",
        "description": "需要 articles:read。",
        "parameters": [
          { "name": "status", "in": "query", "schema": { "type": "string", "enum": ["draft", "reviewing", "published", "rejected"] } },
          { "name": "limit", "in": "query", "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 20 } }
        ],
        "responses": { "200": { "$ref": "#/components/responses/Ok" }, "default": { "$ref": "#/components/responses/Error" } }
      },
      "post": {
        "operationId": "createArticle",
        "summary": "新建草稿",
        "description": "需要 articles:write。正文按白名单清洗并做违禁词筛查。",
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ArticleInput" } } } },
        "responses": { "201": { "$ref": "#/components/responses/Ok" }, "default": { "$ref": "#/components/responses/Error" } }
      }
    },
    "/articles/draft": {
      "post": {
        "operationId": "draftArticle",
        "summary": "AI 联网成文",
        "description": "需要 articles:write。每小时 5 次，与网页端共用额度；耗时可达 60 秒。",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["topic"],
                "properties": {
                  "topic": { "type": "string", "minLength": 2, "maxLength": 100, "description": "选题，会原样作为标题" },
                  "save": { "type": "boolean", "default": true, "description": "false 只返回成稿不入库" }
                }
              }
            }
          }
        },
        "responses": { "200": { "$ref": "#/components/responses/Ok" }, "default": { "$ref": "#/components/responses/Error" } }
      }
    },
    "/articles/{id}": {
      "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }],
      "get": {
        "operationId": "getArticle",
        "summary": "读取稿件",
        "description": "需要 articles:read。",
        "responses": { "200": { "$ref": "#/components/responses/Ok" }, "default": { "$ref": "#/components/responses/Error" } }
      },
      "patch": {
        "operationId": "updateArticle",
        "summary": "修改草稿（整篇替换标题与正文）",
        "description": "需要 articles:write。仅草稿或被驳回稿可改，否则返回 ARTICLE_LOCKED。",
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ArticleInput" } } } },
        "responses": { "200": { "$ref": "#/components/responses/Ok" }, "default": { "$ref": "#/components/responses/Error" } }
      }
    },
    "/quality": {
      "post": {
        "operationId": "checkArticleQuality",
        "summary": "稿件质检",
        "description": "需要 articles:read。传 articleId 检测已保存稿件，或直接传 title + content。",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "articleId": { "type": "string" },
                  "title": { "type": "string", "maxLength": 100 },
                  "content": { "type": "string" }
                }
              }
            }
          }
        },
        "responses": { "200": { "$ref": "#/components/responses/Ok" }, "default": { "$ref": "#/components/responses/Error" } }
      }
    },
    "/media/recommend": {
      "post": {
        "operationId": "recommendMedia",
        "summary": "按稿件推荐媒体",
        "description": "需要 media:read。价格单位为积分。",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "articleIds": { "type": "array", "items": { "type": "string" }, "maxItems": 10 },
                  "texts": { "type": "array", "items": { "type": "string", "maxLength": 4000 }, "maxItems": 10 },
                  "goal": { "type": "string", "enum": ["awareness", "crossverify"], "default": "awareness" },
                  "budgetCredits": { "type": "number", "exclusiveMinimum": 0 },
                  "count": { "type": "integer", "minimum": 1, "maximum": 5, "default": 3 },
                  "needNewsSource": { "type": "boolean", "default": false },
                  "needLink": { "type": "boolean", "default": false },
                  "excludeMediaIds": { "type": "array", "items": { "type": "string" }, "maxItems": 200 }
                }
              }
            }
          }
        },
        "responses": { "200": { "$ref": "#/components/responses/Ok" }, "default": { "$ref": "#/components/responses/Error" } }
      }
    },
    "/media/search": {
      "get": {
        "operationId": "searchMedia",
        "summary": "搜索媒体库",
        "description": "需要 media:read。",
        "parameters": [
          { "name": "q", "in": "query", "schema": { "type": "string", "maxLength": 100 } },
          { "name": "category", "in": "query", "schema": { "type": "string" } },
          { "name": "region", "in": "query", "schema": { "type": "string" } },
          { "name": "module", "in": "query", "schema": { "type": "string", "enum": ["media", "self_media"] } },
          { "name": "newsSource", "in": "query", "schema": { "type": "boolean" } },
          { "name": "page", "in": "query", "schema": { "type": "integer", "minimum": 1, "default": 1 } },
          { "name": "limit", "in": "query", "schema": { "type": "integer", "minimum": 1, "maximum": 50, "default": 20 } }
        ],
        "responses": { "200": { "$ref": "#/components/responses/Ok" }, "default": { "$ref": "#/components/responses/Error" } }
      }
    },
    "/orders/quote": {
      "post": {
        "operationId": "quoteOrder",
        "summary": "报价（不扣费）",
        "description": "需要 orders:write。返回逐项价格、合计、剩余额度、summary 与 10 分钟有效的 confirmToken；超出单笔/每日上限或余额不足时 confirmToken 为 null 并给出 blockedReason。",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["articleIds", "mediaIds"],
                "properties": {
                  "articleIds": { "type": "array", "items": { "type": "string" }, "minItems": 1, "maxItems": 10 },
                  "mediaIds": { "type": "array", "items": { "type": "string" }, "minItems": 1, "maxItems": 5 },
                  "expectedDate": { "type": "string", "format": "date", "description": "最早北京时间次日，默认次日" },
                  "note": { "type": "string", "maxLength": 500 }
                }
              }
            }
          }
        },
        "responses": { "200": { "$ref": "#/components/responses/Ok" }, "default": { "$ref": "#/components/responses/Error" } }
      }
    },
    "/orders": {
      "get": {
        "operationId": "listOrders",
        "summary": "订单列表",
        "description": "需要 account:read。viaApi 标记经 API 令牌下的单。",
        "parameters": [
          { "name": "status", "in": "query", "schema": { "type": "string", "enum": ["pending", "published", "failed", "rejected"] } },
          { "name": "articleId", "in": "query", "schema": { "type": "string" } },
          { "name": "limit", "in": "query", "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 20 } }
        ],
        "responses": { "200": { "$ref": "#/components/responses/Ok" }, "default": { "$ref": "#/components/responses/Error" } }
      },
      "post": {
        "operationId": "placeOrder",
        "summary": "凭确认码下单（扣积分）",
        "description": "需要 orders:write。金额与报价不一致返回 QUOTE_CHANGED；重复提交返回 created: 0，不重复扣费。",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["confirmToken"],
                "properties": { "confirmToken": { "type": "string" } }
              }
            }
          }
        },
        "responses": { "201": { "$ref": "#/components/responses/Ok" }, "default": { "$ref": "#/components/responses/Error" } }
      }
    },
    "/orders/{id}": {
      "get": {
        "operationId": "getOrder",
        "summary": "订单详情与发布链接",
        "description": "需要 account:read。",
        "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }],
        "responses": { "200": { "$ref": "#/components/responses/Ok" }, "default": { "$ref": "#/components/responses/Error" } }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearer": { "type": "http", "scheme": "bearer", "bearerFormat": "xy_pat_..." }
    },
    "schemas": {
      "ArticleInput": {
        "type": "object",
        "required": ["title", "content"],
        "properties": {
          "title": { "type": "string", "minLength": 1, "maxLength": 100 },
          "content": { "type": "string", "description": "HTML 正文" },
          "summary": { "type": "string", "maxLength": 300 },
          "tags": { "type": "array", "items": { "type": "string", "maxLength": 20 }, "maxItems": 10 }
        }
      },
      "Error": {
        "type": "object",
        "required": ["error"],
        "properties": {
          "error": {
            "type": "object",
            "required": ["code", "message", "retryable"],
            "properties": {
              "code": {
                "type": "string",
                "description": "UNAUTHORIZED、FORBIDDEN、RATE_LIMITED、INVALID_REQUEST、INVALID_JSON、ARTICLE_NOT_FOUND、ARTICLE_LOCKED、ARTICLE_QUALITY_BLOCK、ARTICLE_NOT_PUBLISHABLE、QUOTE_EXPIRED、QUOTE_INVALID、QUOTE_CHANGED、TOKEN_ORDER_LIMIT、TOKEN_SPEND_LIMIT、INSUFFICIENT_CREDITS 等"
              },
              "message": { "type": "string" },
              "retryable": { "type": "boolean" }
            }
          }
        }
      }
    },
    "responses": {
      "Ok": { "description": "成功", "content": { "application/json": { "schema": { "type": "object" } } } },
      "Error": { "description": "错误（统一格式）", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
    }
  }
}
