{
  "openapi": "3.1.0",
  "info": {
    "title": "Aipedia 内容接口",
    "version": "1.0.0",
    "summary": "AI 取证撰写的中文百科：给程序的是「带出处、带状态、可直接引用的断言」",
    "description": "所有 /api/* 接口都需要 API key（Authorization: Bearer <key> 或 X-API-Key），到 https://aipedia.apexera-ai.com/account 创建应用即可。网页浏览与图片不需要 key。"
  },
  "servers": [
    {
      "url": "https://aipedia.apexera-ai.com"
    }
  ],
  "security": [
    {
      "ApiKeyAuth": []
    }
  ],
  "paths": {
    "/api/entry/{slug}": {
      "get": {
        "summary": "取一个词条（结构化断言 + 出处）",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "format",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "json",
                "md",
                "text",
                "html"
              ],
              "default": "json"
            },
            "description": "同一份内容的不同呈现：json 给程序 / md 喂模型 / text 最省 token / html 直接嵌"
          },
          {
            "name": "lang",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "词条语言，默认 zh"
          }
        ],
        "responses": {
          "200": {
            "description": "词条内容；带 ETag，命中 If-None-Match 时返回 304",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "稳定 id：aipedia:{slug}"
                    },
                    "url": {
                      "type": "string"
                    },
                    "title": {
                      "type": "string"
                    },
                    "aliases": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "lang": {
                      "type": "string"
                    },
                    "oneLiner": {
                      "type": "string"
                    },
                    "domain": {
                      "type": "string",
                      "description": "内容领域标记（撰写时用），**不是**主题——别和 groups 混"
                    },
                    "groups": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "description": "主题：Aipedia 公域的主题集合（文章本身叫「词条」，你私有的那个叫「领域」）。**一个词条可以属于多个主题**；而「主题关系不同的同名词条是两个独立的词条」——「排位赛」在 {F1} 与 {GT} 下是两篇。词条上没有 groups 字段 = 全局，不属于任何主题。",
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "稳定 id。主题名会改、id 不会——要存就存 id"
                          },
                          "name": {
                            "type": "string"
                          }
                        }
                      },
                      "description": "所属的主题；缺席 = 全局"
                    },
                    "version": {
                      "type": "integer"
                    },
                    "generatedAt": {
                      "type": "string"
                    },
                    "updatedAt": {
                      "type": "string",
                      "description": "文件最后一次改动时间；校正环改写正文也会刷新它"
                    },
                    "source": {
                      "type": "string"
                    },
                    "citation": {
                      "type": "string",
                      "description": "现成的引用串（带版本与日期），引用时直接用这个"
                    },
                    "cover": {
                      "type": "object",
                      "description": "配图。来自外部 CC 授权来源并自托管，署名是合规硬要求，请保留 credit 与 sourceUrl。",
                      "properties": {
                        "section": {
                          "type": "string"
                        },
                        "src": {
                          "type": "string"
                        },
                        "caption": {
                          "type": "string"
                        },
                        "credit": {
                          "type": "string"
                        },
                        "sourceUrl": {
                          "type": "string"
                        }
                      }
                    },
                    "figures": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "description": "配图。来自外部 CC 授权来源并自托管，署名是合规硬要求，请保留 credit 与 sourceUrl。",
                        "properties": {
                          "section": {
                            "type": "string"
                          },
                          "src": {
                            "type": "string"
                          },
                          "caption": {
                            "type": "string"
                          },
                          "credit": {
                            "type": "string"
                          },
                          "sourceUrl": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "infobox": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "label": {
                            "type": "string"
                          },
                          "value": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "claims": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "description": "一条断言（知识的最小单位）",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "text": {
                            "type": "string",
                            "description": "断言正文；[[slug]] 是站内链接标记"
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "verified",
                              "contested",
                              "stale",
                              "unverified"
                            ],
                            "description": "已核验 / 存有争议 / 已过时 / 待考证"
                          },
                          "confidence": {
                            "type": "number",
                            "description": "0–1，由交叉验证给出"
                          },
                          "checkedAt": {
                            "type": "string",
                            "description": "该断言最近一次被重新核验的日期"
                          },
                          "counterpoints": {
                            "type": "array",
                            "description": "存在争议时的对立说法（并列，不裁决）",
                            "items": {
                              "type": "object",
                              "properties": {
                                "text": {
                                  "type": "string"
                                },
                                "sources": {
                                  "type": "array",
                                  "items": {
                                    "type": "string"
                                  }
                                }
                              }
                            }
                          },
                          "sources": {
                            "type": "array",
                            "items": {
                              "$ref": "#/components/schemas/Source"
                            }
                          }
                        }
                      }
                    },
                    "relations": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "title": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                }
              },
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              },
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              },
              "text/html": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "description": "缺少 / 无效的 API key"
          },
          "404": {
            "description": "没有这个词条"
          },
          "429": {
            "description": "超速率或超配额"
          }
        }
      }
    },
    "/api/entry/{slug}/history": {
      "get": {
        "summary": "版本清单；给 from/to 则返回两版之间的差异",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "版本清单或 diff"
          },
          "401": {
            "description": "缺少 / 无效的 API key"
          },
          "404": {
            "description": "没有这个词条"
          },
          "429": {
            "description": "超速率或超配额"
          }
        }
      }
    },
    "/api/resolve": {
      "get": {
        "summary": "消解：这串字指向哪个物",
        "description": "kind=entry 唯一命中；ambiguous 指向多个物（列出候选，不替调用方裁决）；pending 物已认出但词条没写；none 标签表里没有。\n\n每个响应都带 `proposal`（用这串字提过的提案及其状态，没提过则 null）。**这是判断「我提的那个词现在怎么样了」的唯一办法**：kind=none 既可能是「还没轮到」也可能是「判定撑不起独立词条」，看 proposal.status 是 pending 还是 skipped，后者带 skipReason。",
        "parameters": [
          {
            "name": "text",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "lang",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "消解结果：{ kind, entity, entry, choices, similar, proposal }"
          },
          "401": {
            "description": "缺少 / 无效的 API key"
          },
          "404": {
            "description": "没有这个词条"
          },
          "429": {
            "description": "超速率或超配额"
          }
        }
      }
    },
    "/api/search": {
      "get": {
        "summary": "检索词条与命中的断言",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "命中列表"
          },
          "401": {
            "description": "缺少 / 无效的 API key"
          },
          "404": {
            "description": "没有这个词条"
          },
          "429": {
            "description": "超速率或超配额"
          }
        }
      }
    },
    "/api/topics": {
      "get": {
        "summary": "全库词条清单（语料边界）",
        "parameters": [
          {
            "name": "domain",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "词条清单与内容领域分布"
          },
          "401": {
            "description": "缺少 / 无效的 API key"
          },
          "404": {
            "description": "没有这个词条"
          },
          "429": {
            "description": "超速率或超配额"
          }
        }
      },
      "post": {
        "summary": "提交一个词（agent 用）",
        "description": "把一串字当主题提进来：已收录的直接回 slug，没有的排队去写。与网页版 POST /api/propose **语义相同、返回同形**，区别只在鉴权与额度（这里走 key，额度 1000/小时，与 /api/contribute 的写额度分开计）。注意：判定「撑不起一篇独立词条」的主题不会建词条，也不会出现在 /api/topics 里——用 GET /api/resolve 看它的提案状态。",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "topic"
                ],
                "properties": {
                  "topic": {
                    "type": "string",
                    "description": "主题原文（2–4000 字）"
                  },
                  "note": {
                    "type": "string",
                    "description": "线索 / 范围，≤2000 字。它会同时作为**消解**和**撰写**的判断依据——写上领域、释义、为什么值得成篇，判定质量会明显不同。"
                  },
                  "groups": {
                    "description": "**所属的主题**（主题名或主题 id，一个字符串或一个数组）：**主题关系不同的同名词条是两个独立的词条**——先说「排位赛」属于 F1、后说属于 GT，会得到两篇。不传则从 note 的「领域：X」那行取；都没有就是全局。提案的去重键 = 主题 + 主题关系。",
                    "oneOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      }
                    ]
                  },
                  "by": {
                    "type": "string",
                    "description": "署名：调用方自己的稳定标识（如 `sorp:<userId>`）。这是署名、不是来源；来源固定记 `via:api`。不传则记成 `app:<应用名>`。"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "已收录：`{ resolved:true, slug, url }`；歧义（一个词指向多个物）：`{ resolved:true, ambiguous:true, url }` 且**没有 slug**；重复提交：`{ id, slug, status, deduped:true }`"
          },
          "202": {
            "description": "新主题已入队：`{ id, status }`"
          },
          "401": {
            "description": "缺少 / 无效的 API key"
          },
          "404": {
            "description": "没有这个词条"
          },
          "429": {
            "description": "超速率或超配额"
          }
        }
      }
    },
    "/api/groups": {
      "get": {
        "summary": "主题列表（公开的主题集合）",
        "description": "主题由 Aipedia 的 AI 创建与维护，**对外只读**（没有写接口）。消费方（如私域的用户领域）引用主题的 id，靠它读这个主题集合下的词条。**一个词条可以属于多个主题**。注意：公域不读私域，Aipedia 不知道谁引用了自己（没有反向索引），所以主题改名/并主题只能靠 id 稳定 + 重定向。",
        "responses": {
          "200": {
            "description": "主题的清单与各自的词条数"
          },
          "401": {
            "description": "缺少 / 无效的 API key"
          },
          "404": {
            "description": "没有这个词条"
          },
          "429": {
            "description": "超速率或超配额"
          }
        }
      }
    },
    "/api/groups/{id}": {
      "get": {
        "summary": "单个主题 + 它下面的词条",
        "description": "路径段 id 优先、主题名也认（传名字只作兼容；拿得到 id 就存 id）。`entries` 是已经有词条的成员，`pending` 是认下了但还没写出词条的成员。",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "主题信息 + entries[] + pending[]"
          },
          "401": {
            "description": "缺少 / 无效的 API key"
          },
          "404": {
            "description": "没有这个主题"
          },
          "429": {
            "description": "超速率或超配额"
          }
        }
      }
    },
    "/api/groups/resolve": {
      "get": {
        "summary": "把一个字符串映到主题（建「领域 ↔ 主题」关联用）",
        "description": "kind=one 唯一命中；many 命中多个主题（**不要替调用方挑一个**，会挂到错的主题集合上）；none 没有对应的主题。这个端点不会顺手建主题。",
        "parameters": [
          {
            "name": "text",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "{ text, kind, groups[] }"
          },
          "401": {
            "description": "缺少 / 无效的 API key"
          },
          "404": {
            "description": "没有这个词条"
          },
          "429": {
            "description": "超速率或超配额"
          }
        }
      }
    },
    "/api/snapshot": {
      "get": {
        "summary": "全库快照（离线建索引 / RAG）",
        "parameters": [
          {
            "name": "domain",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "since",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "只返回 updatedAt 晚于该时刻的词条"
          }
        ],
        "responses": {
          "200": {
            "description": "全库结构化内容"
          },
          "401": {
            "description": "缺少 / 无效的 API key"
          },
          "404": {
            "description": "没有这个词条"
          },
          "429": {
            "description": "超速率或超配额"
          }
        }
      }
    },
    "/api/contribute": {
      "post": {
        "summary": "提交一条纠正（agent 用）",
        "description": "只入队、不直接改正文：进审核队列，判定为采纳后才落到正文并留下变更记录。写操作限流与读取分开计。",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "slug",
                  "after"
                ],
                "properties": {
                  "slug": {
                    "type": "string"
                  },
                  "claimId": {
                    "type": "string",
                    "description": "要改的是哪条断言"
                  },
                  "before": {
                    "type": "string",
                    "description": "原文；不填则服务端按当前正文快照"
                  },
                  "after": {
                    "type": "string"
                  },
                  "reason": {
                    "type": "string"
                  },
                  "sources": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "maxItems": 5
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "已入队（重复投递返回 duplicate: true 与既有 id）"
          },
          "400": {
            "description": "参数不合法"
          },
          "401": {
            "description": "缺少 / 无效的 API key"
          },
          "404": {
            "description": "没有这个词条"
          },
          "429": {
            "description": "超速率或超配额"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "Authorization",
        "description": "写 Bearer <key>；也可用 X-API-Key: <key>"
      }
    },
    "schemas": {
      "Claim": {
        "type": "object",
        "description": "一条断言（知识的最小单位）",
        "properties": {
          "id": {
            "type": "string"
          },
          "text": {
            "type": "string",
            "description": "断言正文；[[slug]] 是站内链接标记"
          },
          "status": {
            "type": "string",
            "enum": [
              "verified",
              "contested",
              "stale",
              "unverified"
            ],
            "description": "已核验 / 存有争议 / 已过时 / 待考证"
          },
          "confidence": {
            "type": "number",
            "description": "0–1，由交叉验证给出"
          },
          "checkedAt": {
            "type": "string",
            "description": "该断言最近一次被重新核验的日期"
          },
          "counterpoints": {
            "type": "array",
            "description": "存在争议时的对立说法（并列，不裁决）",
            "items": {
              "type": "object",
              "properties": {
                "text": {
                  "type": "string"
                },
                "sources": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              }
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Source"
            }
          }
        }
      },
      "Source": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "publisher": {
            "type": "string"
          },
          "url": {
            "type": "string"
          },
          "date": {
            "type": "string"
          },
          "accessedAt": {
            "type": "string"
          },
          "kind": {
            "type": "string",
            "enum": [
              "paper",
              "doc",
              "standard",
              "news",
              "repo"
            ]
          }
        }
      },
      "Figure": {
        "type": "object",
        "description": "配图。来自外部 CC 授权来源并自托管，署名是合规硬要求，请保留 credit 与 sourceUrl。",
        "properties": {
          "section": {
            "type": "string"
          },
          "src": {
            "type": "string"
          },
          "caption": {
            "type": "string"
          },
          "credit": {
            "type": "string"
          },
          "sourceUrl": {
            "type": "string"
          }
        }
      },
      "Entry": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "稳定 id：aipedia:{slug}"
          },
          "url": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "aliases": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "lang": {
            "type": "string"
          },
          "oneLiner": {
            "type": "string"
          },
          "domain": {
            "type": "string",
            "description": "内容领域标记（撰写时用），**不是**主题——别和 groups 混"
          },
          "groups": {
            "type": "array",
            "items": {
              "type": "object",
              "description": "主题：Aipedia 公域的主题集合（文章本身叫「词条」，你私有的那个叫「领域」）。**一个词条可以属于多个主题**；而「主题关系不同的同名词条是两个独立的词条」——「排位赛」在 {F1} 与 {GT} 下是两篇。词条上没有 groups 字段 = 全局，不属于任何主题。",
              "properties": {
                "id": {
                  "type": "string",
                  "description": "稳定 id。主题名会改、id 不会——要存就存 id"
                },
                "name": {
                  "type": "string"
                }
              }
            },
            "description": "所属的主题；缺席 = 全局"
          },
          "version": {
            "type": "integer"
          },
          "generatedAt": {
            "type": "string"
          },
          "updatedAt": {
            "type": "string",
            "description": "文件最后一次改动时间；校正环改写正文也会刷新它"
          },
          "source": {
            "type": "string"
          },
          "citation": {
            "type": "string",
            "description": "现成的引用串（带版本与日期），引用时直接用这个"
          },
          "cover": {
            "type": "object",
            "description": "配图。来自外部 CC 授权来源并自托管，署名是合规硬要求，请保留 credit 与 sourceUrl。",
            "properties": {
              "section": {
                "type": "string"
              },
              "src": {
                "type": "string"
              },
              "caption": {
                "type": "string"
              },
              "credit": {
                "type": "string"
              },
              "sourceUrl": {
                "type": "string"
              }
            }
          },
          "figures": {
            "type": "array",
            "items": {
              "type": "object",
              "description": "配图。来自外部 CC 授权来源并自托管，署名是合规硬要求，请保留 credit 与 sourceUrl。",
              "properties": {
                "section": {
                  "type": "string"
                },
                "src": {
                  "type": "string"
                },
                "caption": {
                  "type": "string"
                },
                "credit": {
                  "type": "string"
                },
                "sourceUrl": {
                  "type": "string"
                }
              }
            }
          },
          "infobox": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "label": {
                  "type": "string"
                },
                "value": {
                  "type": "string"
                }
              }
            }
          },
          "claims": {
            "type": "array",
            "items": {
              "type": "object",
              "description": "一条断言（知识的最小单位）",
              "properties": {
                "id": {
                  "type": "string"
                },
                "text": {
                  "type": "string",
                  "description": "断言正文；[[slug]] 是站内链接标记"
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "verified",
                    "contested",
                    "stale",
                    "unverified"
                  ],
                  "description": "已核验 / 存有争议 / 已过时 / 待考证"
                },
                "confidence": {
                  "type": "number",
                  "description": "0–1，由交叉验证给出"
                },
                "checkedAt": {
                  "type": "string",
                  "description": "该断言最近一次被重新核验的日期"
                },
                "counterpoints": {
                  "type": "array",
                  "description": "存在争议时的对立说法（并列，不裁决）",
                  "items": {
                    "type": "object",
                    "properties": {
                      "text": {
                        "type": "string"
                      },
                      "sources": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      }
                    }
                  }
                },
                "sources": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Source"
                  }
                }
              }
            }
          },
          "relations": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "title": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "Group": {
        "type": "object",
        "description": "主题：Aipedia 公域的主题集合（文章本身叫「词条」，你私有的那个叫「领域」）。**一个词条可以属于多个主题**；而「主题关系不同的同名词条是两个独立的词条」——「排位赛」在 {F1} 与 {GT} 下是两篇。词条上没有 groups 字段 = 全局，不属于任何主题。",
        "properties": {
          "id": {
            "type": "string",
            "description": "稳定 id。主题名会改、id 不会——要存就存 id"
          },
          "name": {
            "type": "string"
          }
        }
      }
    }
  }
}