{
  "openapi": "3.1.0",
  "info": {
    "title": "企服科学新闻 API",
    "version": "1.0.0",
    "summary": "企业服务 / To B / SaaS / 产业互联网 / AI 产业新闻的公开只读接口",
    "description": "企服科学（qifukexue.com）面向 Agent 与开发者的公开只读接口。无需密钥、无需注册。\n\n提供 9 个端点：稿件列表与检索、单篇详情、热门选题、日报、栏目与标签清单，以及用于增量同步的精选快照/变更接口。\n\n使用约定：\n- 只读：仅支持 GET / HEAD，其余方法返回 405\n- 缓存：响应带 ETag 与 Cache-Control，建议携带 If-None-Match，命中返回 304\n- 限流：10 请求/秒，突发 60\n- 时区：publishedAt 为 ISO 8601 带 +08:00，publishedAtUtc 为 UTC\n- 署名：对外展示必须署名「企服科学」并附原文链接，正文不得整篇搬运",
    "contact": { "name": "企服科学", "url": "https://qifukexue.com/qifu-agent/" },
    "license": { "name": "企服科学内容开放条款 v1", "url": "https://qifukexue.com/qifu-agent/#license" }
  },
  "servers": [{ "url": "https://qifukexue.com/qifu-agent/api/v1", "description": "生产环境" }],
  "tags": [
    { "name": "内容", "description": "稿件列表、检索与单篇详情" },
    { "name": "选题", "description": "热点、热词与栏目标签清单" },
    { "name": "日报", "description": "每日策展日报" },
    { "name": "同步", "description": "增量同步用快照与变更" },
    { "name": "服务", "description": "服务自述与统计" }
  ],
  "paths": {
    "/meta": {
      "get": {
        "tags": ["服务"],
        "operationId": "getMeta",
        "summary": "服务与统计概览",
        "description": "返回版本、时区、站点统计（稿件数、快讯数、24 小时与 7 天发布量、栏目与标签总数、最新发布时间）、端点清单与授权条款。适合作为接入前的自检与能力发现入口。",
        "responses": {
          "200": {
            "description": "服务概览",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/MetaResponse" }
              }
            }
          }
        }
      }
    },
    "/items": {
      "get": {
        "tags": ["内容"],
        "operationId": "listItems",
        "summary": "稿件列表与检索",
        "description": "按模式、时间窗、栏目、标签、关键词取稿件。默认窗口 7 天；全站 4000 余篇可回溯，需显式传 window=all。\n\nmode 说明：\n- latest：全部已发布稿件（默认）\n- selected：「深度」栏目的编辑精选\n- daily：标题以「企服科学：」开头的每日策展稿\n- flash：快讯流",
        "parameters": [
          {
            "name": "mode",
            "in": "query",
            "schema": { "type": "string", "enum": ["latest", "selected", "daily", "flash"], "default": "latest" },
            "description": "取数模式"
          },
          {
            "name": "window",
            "in": "query",
            "schema": { "type": "string", "default": "7d", "examples": ["24h", "3d", "7d", "30d", "all"] },
            "description": "时间窗。支持 24h / 3d / 7d / 30d / all，也可传 ISO 日期或日期时间（如 2026-09-01）"
          },
          { "name": "category", "in": "query", "schema": { "type": "string" }, "description": "栏目 slug，取值见 /categories" },
          { "name": "tag", "in": "query", "schema": { "type": "string" }, "description": "标签名，如 OpenAI、算力" },
          { "name": "q", "in": "query", "schema": { "type": "string" }, "description": "关键词，匹配标题与正文" },
          {
            "name": "limit",
            "in": "query",
            "schema": { "type": "integer", "minimum": 1, "maximum": 50, "default": 20 },
            "description": "返回条数上限"
          },
          {
            "name": "offset",
            "in": "query",
            "schema": { "type": "integer", "minimum": 0, "maximum": 5000, "default": 0 },
            "description": "翻页偏移"
          },
          {
            "name": "fields",
            "in": "query",
            "schema": { "type": "string", "enum": ["full", "brief"], "default": "full" },
            "description": "brief 时只返回精简字段集，适合列表展示"
          },
          { "name": "type", "in": "query", "schema": { "type": "string", "enum": ["post", "kuaixun"] }, "description": "稿件类型，通常无需指定" }
        ],
        "responses": {
          "200": {
            "description": "稿件列表。响应头 X-Qifu-Count 为「返回条数/命中总数」",
            "headers": { "X-Qifu-Count": { "schema": { "type": "string" }, "description": "如 10/103" } },
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ItemsResponse" } } }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "404": { "description": "未知栏目 slug", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } },
          "405": { "$ref": "#/components/responses/MethodNotAllowed" }
        }
      }
    },
    "/search": {
      "get": {
        "tags": ["内容"],
        "operationId": "searchItems",
        "summary": "检索（/items 的别名，必须带 q）",
        "description": "等价于 /items?mode=latest，但强制要求提供 q 参数，缺失时返回 400。",
        "parameters": [
          { "name": "q", "in": "query", "required": true, "schema": { "type": "string" }, "description": "检索关键词" },
          { "name": "window", "in": "query", "schema": { "type": "string", "default": "7d" } },
          { "name": "limit", "in": "query", "schema": { "type": "integer", "minimum": 1, "maximum": 50, "default": 20 } },
          { "name": "offset", "in": "query", "schema": { "type": "integer", "minimum": 0, "maximum": 5000, "default": 0 } },
          { "name": "fields", "in": "query", "schema": { "type": "string", "enum": ["full", "brief"], "default": "full" } }
        ],
        "responses": {
          "200": { "description": "检索结果", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ItemsResponse" } } } },
          "400": { "$ref": "#/components/responses/BadRequest" }
        }
      }
    },
    "/stories/{id}": {
      "get": {
        "tags": ["内容"],
        "operationId": "getStory",
        "summary": "单篇详情（含正文纯文本）",
        "description": "返回单篇稿件的完整字段，附加 body（正文纯文本）与 contentHtml（原始 HTML）。id 可用数字或 qfk-<数字> 形式。",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": { "type": "string", "pattern": "^(qfk-)?[0-9]+$" },
            "description": "稿件 ID，如 37166 或 qfk-37166"
          }
        ],
        "responses": {
          "200": {
            "description": "稿件详情",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/StoryResponse" } } }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "404": { "description": "未找到该稿件，或稿件尚未发布", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }
        }
      }
    },
    "/hot-topics": {
      "get": {
        "tags": ["选题"],
        "operationId": "getHotTopics",
        "summary": "时间窗内的热门栏目与标签",
        "description": "返回 topCategories、topTags（按该窗口内稿件数排序）与 rising24h（最近 24 小时热词前 30）。适合回答「最近在聊什么」。",
        "parameters": [
          {
            "name": "window",
            "in": "query",
            "schema": { "type": "string", "enum": ["24h", "3d", "7d", "30d"], "default": "24h" }
          },
          { "name": "limit", "in": "query", "schema": { "type": "integer", "minimum": 1, "maximum": 50, "default": 12 }, "description": "栏目与标签各返回若干条" }
        ],
        "responses": {
          "200": { "description": "热门选题", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HotTopicsResponse" } } } }
        }
      }
    },
    "/dailies": {
      "get": {
        "tags": ["日报"],
        "operationId": "listDailies",
        "summary": "每日策展日报（按日聚合）",
        "description": "日报即标题以「企服科学：」开头的每日策展稿件。返回按日期分组的数组，每组含当天日报条目（精简字段）。",
        "parameters": [
          { "name": "limit", "in": "query", "schema": { "type": "integer", "minimum": 1, "maximum": 30, "default": 7 }, "description": "返回多少个日期分组" },
          { "name": "date", "in": "query", "schema": { "type": "string", "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$" }, "description": "只取指定日期，如 2026-09-15" }
        ],
        "responses": {
          "200": { "description": "日报列表", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DailiesResponse" } } } },
          "400": { "$ref": "#/components/responses/BadRequest" }
        }
      }
    },
    "/selected/snapshot": {
      "get": {
        "tags": ["同步"],
        "operationId": "getSelectedSnapshot",
        "summary": "精选全量快照 + 水印",
        "description": "返回「深度」栏目精选的全量列表，并给出 watermark（形如 qfk1.1789000000）。把该水印交给 /selected/changes?since= 即可做增量同步。",
        "parameters": [
          { "name": "limit", "in": "query", "schema": { "type": "integer", "minimum": 1, "maximum": 200, "default": 200 } }
        ],
        "responses": {
          "200": { "description": "精选快照", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SnapshotResponse" } } } }
        }
      }
    },
    "/selected/changes": {
      "get": {
        "tags": ["同步"],
        "operationId": "getSelectedChanges",
        "summary": "自水印以来的变更",
        "description": "返回自 since 之后内容有更新或新发布的稿件（精简字段）与新的 watermark。since 可传 snapshot 返回的 watermark、Unix 秒或 ISO 时间；省略则返回最近一批变更。\n\n注意：本站不做删除回溯，删除请以 snapshot 全量为准。",
        "parameters": [
          { "name": "since", "in": "query", "schema": { "type": "string" }, "description": "qfk1.<unix> 或 Unix 秒或 ISO 时间" },
          { "name": "limit", "in": "query", "schema": { "type": "integer", "minimum": 1, "maximum": 200, "default": 100 } }
        ],
        "responses": {
          "200": { "description": "变更列表", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ChangesResponse" } } } },
          "400": { "$ref": "#/components/responses/BadRequest" }
        }
      }
    },
    "/categories": {
      "get": {
        "tags": ["选题"],
        "operationId": "listCategories",
        "summary": "栏目清单",
        "description": "返回全部栏目及其 slug、稿件数与站点链接，并标出精选栏目 slug（selected）。所有用到 category 参数的端点都应以本清单为准。",
        "responses": {
          "200": { "description": "栏目清单", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CategoriesResponse" } } } }
        }
      }
    },
    "/tags": {
      "get": {
        "tags": ["选题"],
        "operationId": "listTags",
        "summary": "热门标签",
        "description": "返回时间窗内稿件数最多的标签，及其 slug 与站点链接。",
        "parameters": [
          { "name": "window", "in": "query", "schema": { "type": "string", "enum": ["24h", "3d", "7d", "30d"], "default": "7d" } },
          { "name": "limit", "in": "query", "schema": { "type": "integer", "minimum": 1, "maximum": 200, "default": 50 } }
        ],
        "responses": {
          "200": { "description": "标签清单", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TagsResponse" } } } }
        }
      }
    }
  },
  "components": {
    "responses": {
      "BadRequest": {
        "description": "参数不合法",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } }
      },
      "MethodNotAllowed": {
        "description": "本接口只提供只读 GET / HEAD",
        "headers": { "Allow": { "schema": { "type": "string" }, "description": "GET, HEAD, OPTIONS" } },
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } }
      }
    },
    "schemas": {
      "ErrorResponse": {
        "type": "object",
        "required": ["ok", "error"],
        "properties": {
          "ok": { "type": "boolean", "const": false },
          "error": {
            "type": "object",
            "required": ["code", "message"],
            "properties": {
              "code": { "type": "string", "examples": ["invalid_window", "unknown_category", "missing_query", "not_found", "method_not_allowed"] },
              "message": { "type": "string" },
              "at": { "type": "string", "format": "date-time" }
            },
            "additionalProperties": true
          }
        }
      },
      "Term": {
        "type": "object",
        "properties": {
          "id": { "type": "integer" },
          "name": { "type": "string" },
          "slug": { "type": "string" }
        }
      },
      "Item": {
        "type": "object",
        "description": "稿件对象",
        "properties": {
          "id": { "type": "integer", "description": "WordPress 稿件 ID" },
          "publicId": { "type": "string", "description": "对外稳定标识，形如 qfk-37166" },
          "type": { "type": "string", "enum": ["post", "kuaixun"], "description": "post 为正式稿件，kuaixun 为快讯" },
          "title": { "type": "string", "description": "标题（已解码 HTML 实体）" },
          "url": { "type": "string", "format": "uri", "description": "原文链接，务必对外展示" },
          "publishedAt": { "type": "string", "description": "发布时间，ISO 8601 带 +08:00" },
          "publishedAtUtc": { "type": ["string", "null"], "description": "发布时间（UTC）" },
          "updatedAt": { "type": ["string", "null"], "description": "最后修改时间（UTC）" },
          "author": { "type": ["string", "null"], "description": "署名作者" },
          "summary": { "type": "string", "description": "摘要，正文纯文本截断至 140 字" },
          "wordCount": { "type": "integer", "description": "正文字数（纯文本）" },
          "cover": { "type": ["string", "null"], "format": "uri", "description": "封面图地址，可能为空" },
          "categories": { "type": "array", "items": { "$ref": "#/components/schemas/Term" }, "description": "所属栏目" },
          "tags": { "type": "array", "items": { "type": "string" }, "description": "标签名列表" },
          "tagObjects": { "type": "array", "items": { "$ref": "#/components/schemas/Term" }, "description": "标签对象列表（含 slug）" },
          "sourceUrl": { "type": ["string", "null"], "format": "uri", "description": "上游原始来源地址，便于溯源" },
          "sourceName": { "type": ["string", "null"], "description": "上游来源名称" },
          "body": { "type": "string", "description": "正文纯文本，仅 /stories/{id} 返回" },
          "contentHtml": { "type": "string", "description": "原始 HTML 正文，仅 /stories/{id} 返回" }
        }
      },
      "BriefItem": {
        "type": "object",
        "description": "fields=brief 时的精简字段集",
        "properties": {
          "id": { "type": "integer" },
          "publicId": { "type": "string" },
          "type": { "type": "string" },
          "title": { "type": "string" },
          "url": { "type": "string", "format": "uri" },
          "publishedAt": { "type": "string" },
          "summary": { "type": "string" },
          "cover": { "type": ["string", "null"] },
          "categories": { "type": "array", "items": { "type": "string" } },
          "tags": { "type": "array", "items": { "type": "string" } },
          "sourceUrl": { "type": ["string", "null"] }
        }
      },
      "Stats": {
        "type": "object",
        "properties": {
          "articles": { "type": "integer", "description": "已发布正式稿件总数" },
          "flash": { "type": "integer", "description": "已发布快讯总数" },
          "published24h": { "type": "integer" },
          "published7d": { "type": "integer" },
          "categories": { "type": "integer" },
          "tags": { "type": "integer" },
          "latestAt": { "type": ["string", "null"], "description": "最新发布时间（UTC）" }
        }
      },
      "License": {
        "type": "object",
        "properties": {
          "name": { "type": "string" },
          "summary": { "type": "string" },
          "require": { "type": "array", "items": { "type": "string" } },
          "contact": { "type": "string" },
          "retire": { "type": ["string", "null"] }
        }
      },
      "MetaResponse": {
        "type": "object",
        "properties": {
          "ok": { "type": "boolean" },
          "service": { "type": "string", "const": "qifu-news" },
          "title": { "type": "string" },
          "version": { "type": "string" },
          "site": { "type": "string", "format": "uri" },
          "generatedAt": { "type": "string" },
          "timezone": { "type": "string" },
          "stats": { "$ref": "#/components/schemas/Stats" },
          "scopes": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": { "key": { "type": "string" }, "name": { "type": "string" }, "desc": { "type": "string" } }
            }
          },
          "endpoints": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": { "method": { "type": "string" }, "path": { "type": "string" }, "desc": { "type": "string" } }
            }
          },
          "channels": { "type": "object", "additionalProperties": { "type": "string" } },
          "openapi": { "type": "string", "format": "uri" },
          "license": { "$ref": "#/components/schemas/License" }
        }
      },
      "ItemsResponse": {
        "type": "object",
        "properties": {
          "ok": { "type": "boolean" },
          "generatedAt": { "type": "string" },
          "query": {
            "type": "object",
            "properties": {
              "mode": { "type": "string" },
              "window": { "type": "string" },
              "category": { "type": ["string", "null"] },
              "tag": { "type": ["string", "null"] },
              "q": { "type": ["string", "null"] },
              "limit": { "type": "integer" },
              "offset": { "type": "integer" }
            }
          },
          "count": { "type": "integer" },
          "total": { "type": "integer" },
          "items": { "type": "array", "items": { "$ref": "#/components/schemas/Item" } }
        }
      },
      "StoryResponse": {
        "type": "object",
        "properties": {
          "ok": { "type": "boolean" },
          "generatedAt": { "type": "string" },
          "item": { "$ref": "#/components/schemas/Item" }
        }
      },
      "HotTopicsResponse": {
        "type": "object",
        "properties": {
          "ok": { "type": "boolean" },
          "generatedAt": { "type": "string" },
          "window": { "type": "string" },
          "since": { "type": ["string", "null"] },
          "topCategories": {
            "type": "array",
            "items": {
              "allOf": [
                { "$ref": "#/components/schemas/Term" },
                {
                  "type": "object",
                  "properties": {
                    "count": { "type": "integer" },
                    "latestAt": { "type": ["string", "null"] },
                    "url": { "type": "string", "format": "uri" },
                    "feed": { "type": ["string", "null"], "format": "uri" }
                  }
                }
              ]
            }
          },
          "topTags": {
            "type": "array",
            "items": {
              "allOf": [
                { "$ref": "#/components/schemas/Term" },
                {
                  "type": "object",
                  "properties": {
                    "count": { "type": "integer" },
                    "latestAt": { "type": ["string", "null"] },
                    "url": { "type": "string", "format": "uri" },
                    "feed": { "type": ["string", "null"] }
                  }
                }
              ]
            }
          },
          "rising24h": {
            "type": "array",
            "items": { "type": "object", "properties": { "name": { "type": "string" }, "count": { "type": "integer" } } }
          }
        }
      },
      "DailiesResponse": {
        "type": "object",
        "properties": {
          "ok": { "type": "boolean" },
          "generatedAt": { "type": "string" },
          "count": { "type": "integer" },
          "dailies": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "date": { "type": "string", "description": "YYYY-MM-DD" },
                "count": { "type": "integer" },
                "items": { "type": "array", "items": { "$ref": "#/components/schemas/BriefItem" } }
              }
            }
          },
          "note": { "type": "string" }
        }
      },
      "SnapshotResponse": {
        "type": "object",
        "properties": {
          "ok": { "type": "boolean" },
          "generatedAt": { "type": "string" },
          "scope": { "type": "string", "const": "selected" },
          "category": { "type": "string" },
          "count": { "type": "integer" },
          "total": { "type": "integer" },
          "watermark": { "type": "string", "description": "形如 qfk1.1789000000，交给 /selected/changes 使用" },
          "items": { "type": "array", "items": { "$ref": "#/components/schemas/Item" } }
        }
      },
      "ChangesResponse": {
        "type": "object",
        "properties": {
          "ok": { "type": "boolean" },
          "generatedAt": { "type": "string" },
          "since": { "type": ["string", "null"] },
          "count": { "type": "integer" },
          "watermark": { "type": "string" },
          "items": { "type": "array", "items": { "$ref": "#/components/schemas/BriefItem" } },
          "note": { "type": "string" }
        }
      },
      "CategoriesResponse": {
        "type": "object",
        "properties": {
          "ok": { "type": "boolean" },
          "generatedAt": { "type": "string" },
          "count": { "type": "integer" },
          "selected": { "type": "string", "description": "精选栏目 slug" },
          "categories": { "type": "array", "items": { "$ref": "#/components/schemas/Term" } }
        }
      },
      "TagsResponse": {
        "type": "object",
        "properties": {
          "ok": { "type": "boolean" },
          "generatedAt": { "type": "string" },
          "window": { "type": "string" },
          "count": { "type": "integer" },
          "tags": {
            "type": "array",
            "items": {
              "allOf": [
                { "$ref": "#/components/schemas/Term" },
                {
                  "type": "object",
                  "properties": { "count": { "type": "integer" }, "url": { "type": "string", "format": "uri" } }
                }
              ]
            }
          }
        }
      }
    }
  }
}
