{
  "openapi": "3.1.0",
  "info": {
    "title": "Offer岛 (OfferDao) API",
    "version": "1.0.0",
    "summary": "AI 行业岗位、公司、面经与每日资讯的公开 API",
    "description": "Offer岛（OfferDao，https://offerdao.ai）是面向 AI 方向的求职 / 招聘信息平台。\n这份规格覆盖对外承诺的公开接口：岗位搜索与发布、AI 公司目录、面经攻略、每日行业资讯。\n\n- 开发者文档：https://offerdao.ai/docs\n- agent skill（自然语言用法）：https://offerdao.ai/skill.md\n- 站点索引（llms.txt）：https://offerdao.ai/llms.txt\n\n鉴权：搜索、精选、发布需要 API key（`Authorization: Bearer <key>` 或 `X-API-Key: <key>`）；\n公司目录、面经攻略、行业资讯、健康检查无需 key。\n个人 key 在「我的设置 → API keys」自助创建；免注册的只读测试 key 见 GET /api/v1/agent/test-key。\n\n## 版本与弃用（Versioning & deprecation）\n\n版本写在 URL 路径里：`https://offerdao.ai/api/v1/...` 是当前 major。\n不带版本段的 `https://offerdao.ai/api/...` 是**永久别名**，始终指向当前 major，两种写法完全等价——\n既有集成不需要改动，新集成建议直接写 /v1。\n\n- 破坏性变更只会以新 major（`/api/v2`）发布；v1 的响应字段不会被删除或改变含义。\n- 新增字段 / 新增可选参数 / 新增端点属于兼容变更，随时可能发生——请忽略未知字段。\n- 弃用信号：`Deprecation`（RFC 9745）+ `Sunset`（RFC 8594）+ `Link; rel=\"deprecation\"`；\n  从打上 Deprecation 到真正下线，至少保留 180 天。\n- 机器可读的版本与弃用策略：https://offerdao.ai/api/versions\n- 每个 /api 响应都带 `X-API-Version: v1`。\n\n## 限流（Rate limits）\n\n每个 /api 响应都带标准限流头（draft-ietf-httpapi-ratelimit-headers）：\n\n- `RateLimit-Policy: \"api\";q=1200;w=60, \"search\";q=60;w=60` —— 生效的配额策略（q=配额，w=窗口秒）。\n- `RateLimit: \"api\";r=1199;t=57, \"search\";r=59;t=57` —— 实时余量（r=剩余，t=窗口剩余秒）。\n- 同时发老的 `RateLimit-Limit` / `-Remaining` / `-Reset` 与 `X-RateLimit-*`，取最紧那条策略，三套同源。\n- 429 带 `Retry-After`（秒，不早于 t）。看到 `r` 接近 0 就该主动降速，别等撞墙。\n- 策略明细见 info[\"x-rate-limits\"] 与 https://offerdao.ai/docs#rate-limits。\n\n域名不要写死：用 OFFERDAO_BASE 环境变量解析 base URL。",
    "x-rate-limits": {
      "standard": "draft-ietf-httpapi-ratelimit-headers-11",
      "headers": {
        "policy": "RateLimit-Policy",
        "state": "RateLimit",
        "legacy": [
          "RateLimit-Limit",
          "RateLimit-Remaining",
          "RateLimit-Reset"
        ],
        "vendorLegacy": [
          "X-RateLimit-Limit",
          "X-RateLimit-Remaining",
          "X-RateLimit-Reset"
        ],
        "retryAfter": "Retry-After"
      },
      "partitioning": "按策略分区：IP 策略按客户端 IP（Serverless 上每个函数实例各记一份，实际放行量只会更宽松，不会更严）；开放测试 key 的每日额度按 key 记，北京时间零点重置。",
      "policies": [
        {
          "name": "api",
          "quota": 1200,
          "window_seconds": 60,
          "quota_unit": "requests",
          "partition": "ip",
          "applies_to": "全部 /api/* 请求",
          "note": "兜底闸，防跑飞的循环；正常调用不会碰到"
        },
        {
          "name": "search",
          "quota": 60,
          "window_seconds": 60,
          "quota_unit": "requests",
          "partition": "ip",
          "applies_to": "岗位搜索 / 精选 / 快照 / mention-index、公司目录、面经攻略、资讯 feed",
          "note": "读接口的主闸"
        },
        {
          "name": "manual",
          "quota": 10,
          "window_seconds": 3600,
          "quota_unit": "requests",
          "partition": "ip",
          "applies_to": "网页表单发布岗位",
          "note": "写接口从严"
        },
        {
          "name": "agent",
          "quota": 10,
          "window_seconds": 3600,
          "quota_unit": "requests",
          "partition": "ip",
          "applies_to": "POST /api/v1/postings/agent（agent 发布岗位）",
          "note": "与网页表单同额度但独立计数"
        },
        {
          "name": "daemon",
          "quota": 120,
          "window_seconds": 60,
          "quota_unit": "requests",
          "partition": "ip",
          "applies_to": "本机 daemon 注册 / 心跳",
          "note": "单台 daemon 约 1 次/分；额度按同一 NAT 后面多台留"
        },
        {
          "name": "compile",
          "quota": 120,
          "window_seconds": 60,
          "quota_unit": "requests",
          "partition": "ip",
          "applies_to": "简历 LaTeX 编译",
          "note": "前端有 600ms 防抖，只在停手时触发"
        },
        {
          "name": "test-key",
          "quota": 20,
          "window_seconds": 60,
          "quota_unit": "requests",
          "partition": "ip",
          "applies_to": "GET /api/v1/agent/test-key（免注册领开放 key）",
          "note": "领一次存起来复用，不要每次请求前都领"
        },
        {
          "name": "activity",
          "quota": 60,
          "window_seconds": 60,
          "quota_unit": "requests",
          "partition": "ip",
          "applies_to": "访问日历心跳",
          "note": "正常一个账号一天一次"
        },
        {
          "name": "contacts",
          "quota": 60,
          "window_seconds": 60,
          "quota_unit": "requests",
          "partition": "ip",
          "applies_to": "岗位联系方式明文（需登录）",
          "note": "挡的是拿一个账号遍历 posting_id"
        }
      ],
      "dailyQuotas": [
        {
          "name": "open-key-daily-search",
          "window_seconds": 86400,
          "partition": "api-key",
          "applies_to": "开放测试 key 的每日查询次数",
          "note": "配额值随 key 而定（开放测试 key 才有），个人 API key 不受此限。"
        },
        {
          "name": "open-key-daily-publish",
          "window_seconds": 86400,
          "partition": "api-key",
          "applies_to": "开放测试 key 的每日发布次数",
          "note": "配额值随 key 而定（开放测试 key 才有），个人 API key 不受此限。"
        }
      ],
      "onThrottle": "收到 429 就按 Retry-After 退避；余量将尽（RateLimit 的 r 接近 0）时应主动降速，不要等撞墙。"
    },
    "x-api-versioning": {
      "scheme": "url-path",
      "current": "v1",
      "versionedBasePath": "/api/v1",
      "unversionedAlias": "/api",
      "versionHeader": "X-API-Version",
      "deprecationNoticeDays": 180,
      "deprecationSignals": [
        "Deprecation (RFC 9745)",
        "Sunset (RFC 8594)",
        "Link; rel=\"deprecation\""
      ],
      "policyUrl": "https://offerdao.ai/docs#versioning",
      "versionsUrl": "https://offerdao.ai/api/versions"
    },
    "contact": {
      "name": "Offer岛 团队",
      "email": "offerdao.ai@gmail.com",
      "url": "https://offerdao.ai/contact"
    },
    "termsOfService": "https://offerdao.ai/terms",
    "license": {
      "name": "Offer岛 服务条款（非开源许可）",
      "url": "https://offerdao.ai/terms"
    }
  },
  "servers": [
    {
      "url": "https://offerdao.ai",
      "description": "生产环境"
    }
  ],
  "externalDocs": {
    "description": "Offer岛 开发者文档",
    "url": "https://offerdao.ai/docs"
  },
  "tags": [
    {
      "name": "postings",
      "description": "岗位搜索与发布"
    },
    {
      "name": "companies",
      "description": "AI 公司目录"
    },
    {
      "name": "guides",
      "description": "面经与求职攻略"
    },
    {
      "name": "news",
      "description": "每日 AI 行业资讯（markdown 即数据）"
    },
    {
      "name": "agent",
      "description": "agent 接入：skill、prompt、API key、健康检查"
    },
    {
      "name": "docs",
      "description": "机器可读的文档与站点索引"
    }
  ],
  "paths": {
    "/api/v1/postings/search": {
      "get": {
        "tags": [
          "postings"
        ],
        "operationId": "searchPostings",
        "summary": "搜索已审核岗位",
        "description": "多条件 AND 组合 + 分页。不带参数返回最近发布的 30 条。中文参数需 URL 编码。",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "apiKeyHeader": []
          }
        ],
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "description": "多词 AND 搜索（按空格切分），命中公司 / 团队 / 岗位 / 地点 / 简介 / 描述 / 要求 / 标签 / 工作类型",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "organization",
            "in": "query",
            "description": "公司字段子串匹配",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "role",
            "in": "query",
            "description": "岗位字段子串匹配",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "location",
            "in": "query",
            "description": "地点字段子串匹配",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "company_tag",
            "in": "query",
            "description": "公司类型精确匹配（非子串）",
            "schema": {
              "type": "string",
              "enum": [
                "国内大厂",
                "知名外企",
                "独角兽",
                "知名初创",
                "明星团队"
              ]
            }
          },
          {
            "name": "employment_type",
            "in": "query",
            "description": "工作类型，逗号分隔或重复传参；每个值需等于岗位 employment_type 数组中的一项",
            "schema": {
              "type": "string",
              "examples": [
                "正式,实习"
              ]
            }
          },
          {
            "name": "role_tag",
            "in": "query",
            "description": "岗位方向标签，语义同 employment_type",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "published_within_days",
            "in": "query",
            "description": "只保留最近 N 天发布的岗位（无可解析发布时间的会被剔除）",
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          },
          {
            "name": "has_contact",
            "in": "query",
            "description": "只保留至少有一个联系方式的岗位",
            "schema": {
              "type": "string",
              "enum": [
                "1",
                "true"
              ]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 30,
              "default": 30
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "published",
                "fetched",
                "organization",
                "role"
              ],
              "default": "published"
            }
          },
          {
            "name": "order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "命中的岗位与分页信息",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Posting"
                      }
                    },
                    "total": {
                      "type": "integer",
                      "description": "符合筛选条件的总条数，不受 limit/offset 影响"
                    },
                    "limit": {
                      "type": "integer"
                    },
                    "offset": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "items",
                    "total"
                  ]
                }
              }
            },
            "headers": {
              "X-API-Version": {
                "$ref": "#/components/headers/ApiVersion"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          },
          "400": {
            "description": "offset 过大（offset_too_large，响应带 max_offset）",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-API-Version": {
                "$ref": "#/components/headers/ApiVersion"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          },
          "401": {
            "description": "缺少或无效 API key（missing_api_key / invalid_api_key）",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-API-Version": {
                "$ref": "#/components/headers/ApiVersion"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          },
          "403": {
            "description": "key 有效但无该操作权限（scope_forbidden）",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-API-Version": {
                "$ref": "#/components/headers/ApiVersion"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          },
          "429": {
            "description": "限流。响应带 Retry-After（秒）与 RateLimit 头，退避时长以它们为准。rate_limit_exceeded 是按 IP 的频率闸，正文的 retry_after 与 Retry-After 同值；rate_limited 是开放测试 key 当日额度用尽，Retry-After 指向次日重置时刻——与其等，不如改用个人 API key（不限量）。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-API-Version": {
                "$ref": "#/components/headers/ApiVersion"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            }
          },
          "500": {
            "description": "服务端错误 / 偶发超时。与 key、参数无关——隔几秒重试一两次即可；仍失败就如实报告，不要据此认定域名已更换。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-API-Version": {
                "$ref": "#/components/headers/ApiVersion"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          }
        }
      }
    },
    "/api/v1/postings/featured": {
      "get": {
        "tags": [
          "postings"
        ],
        "operationId": "featuredPostings",
        "summary": "岛上精选（随机抽样）",
        "description": "从管理员精选的岗位里随机抽 limit 条。每次结果不同，不适合分页。",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "apiKeyHeader": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 30,
              "default": 3
            }
          }
        ],
        "responses": {
          "200": {
            "description": "随机精选岗位",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Posting"
                      }
                    },
                    "total": {
                      "type": "integer",
                      "description": "本次返回条数"
                    },
                    "limit": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "items"
                  ]
                }
              }
            },
            "headers": {
              "X-API-Version": {
                "$ref": "#/components/headers/ApiVersion"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          },
          "401": {
            "description": "缺少或无效 API key（missing_api_key / invalid_api_key）",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-API-Version": {
                "$ref": "#/components/headers/ApiVersion"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          },
          "403": {
            "description": "key 有效但无该操作权限（scope_forbidden）",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-API-Version": {
                "$ref": "#/components/headers/ApiVersion"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          },
          "429": {
            "description": "限流。响应带 Retry-After（秒）与 RateLimit 头，退避时长以它们为准。rate_limit_exceeded 是按 IP 的频率闸，正文的 retry_after 与 Retry-After 同值；rate_limited 是开放测试 key 当日额度用尽，Retry-After 指向次日重置时刻——与其等，不如改用个人 API key（不限量）。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-API-Version": {
                "$ref": "#/components/headers/ApiVersion"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            }
          },
          "500": {
            "description": "服务端错误 / 偶发超时。与 key、参数无关——隔几秒重试一两次即可；仍失败就如实报告，不要据此认定域名已更换。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-API-Version": {
                "$ref": "#/components/headers/ApiVersion"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          }
        }
      }
    },
    "/api/v1/postings/agent": {
      "post": {
        "tags": [
          "postings"
        ],
        "operationId": "publishPosting",
        "summary": "发布岗位（进审核队列）",
        "description": "把 JD 解析成结构化字段后提交。总是进入审核，posting_id 以 agent_ 开头，审核通过前不对外可见（/j/<id> 为 404）。需要个人 key 的 publish 权限——开放测试 key 会 403。用个人 key 发布的岗位归属到 key 拥有者。",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "apiKeyHeader": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PublishRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "已入队待审核。短时间内重复提交同一岗位会带 duplicate: true 且不重复入库。",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "posting_id": {
                      "type": "string",
                      "examples": [
                        "agent_ab12cd34"
                      ]
                    },
                    "duplicate": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "ok",
                    "posting_id"
                  ]
                }
              }
            },
            "headers": {
              "X-API-Version": {
                "$ref": "#/components/headers/ApiVersion"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          },
          "400": {
            "description": "校验失败（缺必填、邮箱格式、链接不可达等）。error 已是可直接转述的中文文案。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-API-Version": {
                "$ref": "#/components/headers/ApiVersion"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          },
          "401": {
            "description": "缺少或无效 API key（missing_api_key / invalid_api_key）",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-API-Version": {
                "$ref": "#/components/headers/ApiVersion"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          },
          "403": {
            "description": "key 有效但无该操作权限（scope_forbidden）",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-API-Version": {
                "$ref": "#/components/headers/ApiVersion"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          },
          "429": {
            "description": "限流。响应带 Retry-After（秒）与 RateLimit 头，退避时长以它们为准。rate_limit_exceeded 是按 IP 的频率闸，正文的 retry_after 与 Retry-After 同值；rate_limited 是开放测试 key 当日额度用尽，Retry-After 指向次日重置时刻——与其等，不如改用个人 API key（不限量）。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-API-Version": {
                "$ref": "#/components/headers/ApiVersion"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            }
          },
          "500": {
            "description": "服务端错误 / 偶发超时。与 key、参数无关——隔几秒重试一两次即可；仍失败就如实报告，不要据此认定域名已更换。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-API-Version": {
                "$ref": "#/components/headers/ApiVersion"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          }
        }
      }
    },
    "/api/v1/companies": {
      "get": {
        "tags": [
          "companies"
        ],
        "operationId": "listCompanies",
        "summary": "AI 公司目录（无需 API key）",
        "description": "含公司简介、团队、融资、产品与在招岗位。不传分页参数时一次返回全部，按更新时间倒序。",
        "security": [],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "description": "省略即全量",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 50
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "公司列表",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Company"
                      }
                    },
                    "total": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "items",
                    "total"
                  ]
                }
              }
            },
            "headers": {
              "X-API-Version": {
                "$ref": "#/components/headers/ApiVersion"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          },
          "429": {
            "description": "限流。响应带 Retry-After（秒）与 RateLimit 头，退避时长以它们为准。rate_limit_exceeded 是按 IP 的频率闸，正文的 retry_after 与 Retry-After 同值；rate_limited 是开放测试 key 当日额度用尽，Retry-After 指向次日重置时刻——与其等，不如改用个人 API key（不限量）。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-API-Version": {
                "$ref": "#/components/headers/ApiVersion"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            }
          },
          "500": {
            "description": "服务端错误 / 偶发超时。与 key、参数无关——隔几秒重试一两次即可；仍失败就如实报告，不要据此认定域名已更换。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-API-Version": {
                "$ref": "#/components/headers/ApiVersion"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          }
        }
      }
    },
    "/api/v1/guides": {
      "get": {
        "tags": [
          "guides"
        ],
        "operationId": "listGuides",
        "summary": "面经攻略外链（无需 API key）",
        "description": "管理员精选的面经 / 求职攻略外链（小红书、X 等）。内容本体在外站，本接口只给元数据与 url。",
        "security": [],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "description": "省略即全量",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 50
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "面经列表",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Guide"
                      }
                    },
                    "total": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "items",
                    "total"
                  ]
                }
              }
            },
            "headers": {
              "X-API-Version": {
                "$ref": "#/components/headers/ApiVersion"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          },
          "429": {
            "description": "限流。响应带 Retry-After（秒）与 RateLimit 头，退避时长以它们为准。rate_limit_exceeded 是按 IP 的频率闸，正文的 retry_after 与 Retry-After 同值；rate_limited 是开放测试 key 当日额度用尽，Retry-After 指向次日重置时刻——与其等，不如改用个人 API key（不限量）。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-API-Version": {
                "$ref": "#/components/headers/ApiVersion"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            }
          },
          "500": {
            "description": "服务端错误 / 偶发超时。与 key、参数无关——隔几秒重试一两次即可；仍失败就如实报告，不要据此认定域名已更换。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-API-Version": {
                "$ref": "#/components/headers/ApiVersion"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          }
        }
      }
    },
    "/api/v1/news/feed": {
      "get": {
        "tags": [
          "news"
        ],
        "operationId": "newsFeed",
        "summary": "每日行业资讯 JSON（无需 API key）",
        "description": "全部日期解析好的条目，按日期倒序。没有筛选参数——日期 / 类型过滤在调用方做。",
        "security": [],
        "responses": {
          "200": {
            "description": "资讯条目与分类",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "categories": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "count": {
                      "type": "integer"
                    },
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NewsItem"
                      }
                    },
                    "insights": {
                      "type": "object",
                      "additionalProperties": true,
                      "description": "前台洞察栏配置，抓资讯可忽略"
                    }
                  },
                  "required": [
                    "items"
                  ]
                }
              }
            },
            "headers": {
              "X-API-Version": {
                "$ref": "#/components/headers/ApiVersion"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          },
          "429": {
            "description": "限流。响应带 Retry-After（秒）与 RateLimit 头，退避时长以它们为准。rate_limit_exceeded 是按 IP 的频率闸，正文的 retry_after 与 Retry-After 同值；rate_limited 是开放测试 key 当日额度用尽，Retry-After 指向次日重置时刻——与其等，不如改用个人 API key（不限量）。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-API-Version": {
                "$ref": "#/components/headers/ApiVersion"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            }
          },
          "500": {
            "description": "服务端错误 / 偶发超时。与 key、参数无关——隔几秒重试一两次即可；仍失败就如实报告，不要据此认定域名已更换。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-API-Version": {
                "$ref": "#/components/headers/ApiVersion"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          }
        }
      }
    },
    "/news/md": {
      "get": {
        "tags": [
          "news"
        ],
        "operationId": "newsMarkdownIndex",
        "summary": "资讯 markdown 索引（无需 API key）",
        "description": "一行一个文件的链接列表：每天一个 YYYYMMDD.md，外加 sources.md / insights.md。先抓这里再决定抓哪天。",
        "security": [],
        "responses": {
          "200": {
            "description": "markdown 索引",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/news/md/{name}": {
      "get": {
        "tags": [
          "news"
        ],
        "operationId": "newsMarkdownFile",
        "summary": "某一天的资讯原文（无需 API key）",
        "description": "markdown 原文即数据。没有数据的日期不存在文件（404）——索引里列出的就是全部。",
        "security": [],
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "required": true,
            "description": "YYYYMMDD.md / sources.md / insights.md",
            "schema": {
              "type": "string",
              "pattern": "^(\\d{8}|sources|insights)\\.md$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "资讯原文",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "该日期没有资讯文件"
          }
        }
      }
    },
    "/api/v1/agent/test-key": {
      "get": {
        "tags": [
          "agent"
        ],
        "operationId": "getTestApiKey",
        "summary": "免注册领取开放测试 key（仅查询）",
        "description": "共享的只读 key，仅有 search 权限、按日限量；发布会 403。额度用尽后重新领同一把 key 无用，需创建个人 key。",
        "security": [],
        "responses": {
          "200": {
            "description": "测试 key 明文",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "key": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "key"
                  ]
                }
              }
            },
            "headers": {
              "X-API-Version": {
                "$ref": "#/components/headers/ApiVersion"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          },
          "404": {
            "description": "暂无可用测试 key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-API-Version": {
                "$ref": "#/components/headers/ApiVersion"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          },
          "429": {
            "description": "限流。响应带 Retry-After（秒）与 RateLimit 头，退避时长以它们为准。rate_limit_exceeded 是按 IP 的频率闸，正文的 retry_after 与 Retry-After 同值；rate_limited 是开放测试 key 当日额度用尽，Retry-After 指向次日重置时刻——与其等，不如改用个人 API key（不限量）。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-API-Version": {
                "$ref": "#/components/headers/ApiVersion"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            }
          },
          "500": {
            "description": "服务端错误 / 偶发超时。与 key、参数无关——隔几秒重试一两次即可；仍失败就如实报告，不要据此认定域名已更换。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-API-Version": {
                "$ref": "#/components/headers/ApiVersion"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          }
        }
      }
    },
    "/api/v1/agent-config": {
      "get": {
        "tags": [
          "agent"
        ],
        "operationId": "agentConfig",
        "summary": "agent 接入配置（无需 API key）",
        "description": "解析好的 origin、skill / prompt 地址与安装命令，供接入向导与工具直接消费。",
        "security": [],
        "responses": {
          "200": {
            "description": "接入配置",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "origin": {
                      "type": "string"
                    },
                    "skill_url": {
                      "type": "string"
                    },
                    "agent_md_url": {
                      "type": "string"
                    },
                    "skill_references": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "install": {
                      "type": "object",
                      "additionalProperties": true
                    }
                  },
                  "required": [
                    "origin",
                    "skill_url"
                  ]
                }
              }
            },
            "headers": {
              "X-API-Version": {
                "$ref": "#/components/headers/ApiVersion"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          }
        }
      }
    },
    "/api/v1/health": {
      "get": {
        "tags": [
          "agent"
        ],
        "operationId": "health",
        "summary": "健康检查（无需 API key）",
        "description": "含一次数据库往返；ok 为 false 时返回 500。",
        "security": [],
        "responses": {
          "200": {
            "description": "服务正常",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "db": {
                      "type": "string",
                      "enum": [
                        "up",
                        "down"
                      ]
                    }
                  },
                  "required": [
                    "ok"
                  ]
                }
              }
            },
            "headers": {
              "X-API-Version": {
                "$ref": "#/components/headers/ApiVersion"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          },
          "500": {
            "description": "数据库不可用",
            "headers": {
              "X-API-Version": {
                "$ref": "#/components/headers/ApiVersion"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          }
        }
      }
    },
    "/skill.md": {
      "get": {
        "tags": [
          "agent"
        ],
        "operationId": "skillMd",
        "summary": "agent skill 全文（自然语言用法说明）",
        "description": "可直接安装为 Claude Code / Codex 等的 skill；示例里的域名会按请求 origin 重写。",
        "security": [],
        "responses": {
          "200": {
            "description": "SKILL.md 全文",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/agent.md": {
      "get": {
        "tags": [
          "agent"
        ],
        "operationId": "agentMd",
        "summary": "站内 AI 助手的产品级 prompt",
        "security": [],
        "responses": {
          "200": {
            "description": "AGENT.md 全文",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/llms.txt": {
      "get": {
        "tags": [
          "docs"
        ],
        "operationId": "llmsTxt",
        "summary": "llms.txt 站点索引（llmstxt.org 格式）",
        "security": [],
        "responses": {
          "200": {
            "description": "站点与开发者资源索引",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              },
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "406": {
            "description": "Accept 里既没有 text/plain 也没有 text/markdown"
          }
        }
      }
    },
    "/openapi.json": {
      "get": {
        "tags": [
          "docs"
        ],
        "operationId": "openApiSpec",
        "summary": "这份 OpenAPI 规格本身",
        "security": [],
        "responses": {
          "200": {
            "description": "OpenAPI 3.1 文档",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          }
        }
      }
    },
    "/docs": {
      "get": {
        "tags": [
          "docs"
        ],
        "operationId": "developerDocs",
        "summary": "开发者文档（HTML / markdown 按 Accept 协商）",
        "description": "浏览器拿 HTML，Accept: text/markdown 拿 markdown；也可直接取 /docs.md。",
        "security": [],
        "responses": {
          "200": {
            "description": "开发者文档",
            "content": {
              "text/html": {
                "schema": {
                  "type": "string"
                }
              },
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "406": {
            "description": "Accept 里没有本资源可提供的表示"
          }
        }
      }
    },
    "/api/versions": {
      "get": {
        "tags": [
          "docs"
        ],
        "operationId": "apiVersions",
        "summary": "版本与弃用策略（机器可读）",
        "description": "当前 major、不带版本别名的口径、已弃用端点清单与弃用信号约定。/api 与 /api/v1 返回同一份。",
        "security": [],
        "responses": {
          "200": {
            "description": "版本与弃用策略",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            },
            "headers": {
              "X-API-Version": {
                "$ref": "#/components/headers/ApiVersion"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          }
        }
      }
    },
    "/.well-known/api-catalog": {
      "get": {
        "tags": [
          "docs"
        ],
        "operationId": "apiCatalog",
        "summary": "API Catalog（RFC 9727 linkset）",
        "description": "固定位置的开发者资源目录：service-desc → OpenAPI，service-doc → /docs，service-meta → 版本策略与 llms.txt。",
        "security": [],
        "responses": {
          "200": {
            "description": "application/linkset+json",
            "content": {
              "application/linkset+json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          }
        }
      }
    },
    "/agent-instructions.md": {
      "get": {
        "tags": [
          "agent"
        ],
        "operationId": "agentInstructions",
        "summary": "给外部 agent 的「何时使用 / 怎么调用」说明",
        "description": "适用与不适用场景、每类任务的调用配方、鉴权与礼节。注意与 /agent.md 区分：那是站内助手的人设 prompt。",
        "security": [],
        "responses": {
          "200": {
            "description": "agent 使用说明全文",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "406": {
            "description": "Accept 里既没有 text/markdown 也没有 text/plain"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Authorization: Bearer <API key>。个人 key 在「我的设置 → API keys」创建。"
      },
      "apiKeyHeader": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "与 bearerAuth 等价的另一种写法。"
      }
    },
    "schemas": {
      "Posting": {
        "type": "object",
        "description": "已审核岗位。完整逐字段说明见 /skill/references/posting-fields.md",
        "properties": {
          "posting_id": {
            "type": "string",
            "examples": [
              "manual_ab12cd34"
            ]
          },
          "organization": {
            "type": "string",
            "description": "公司 / 学校 / 机构"
          },
          "team": {
            "type": [
              "string",
              "null"
            ],
            "description": "团队 / 部门"
          },
          "role": {
            "type": "string",
            "description": "岗位名称"
          },
          "employment_type": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "工作类型；常见值 正式 / 实习 / 访问 / 研究助理 / PhD / Postdoc"
          },
          "role_tags": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "岗位方向标签，≤5"
          },
          "company_tag": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "国内大厂",
              "知名外企",
              "独角兽",
              "知名初创",
              "明星团队",
              null
            ],
            "description": "公司类型，管理员维护"
          },
          "location": {
            "type": "string",
            "description": "工作地点；多地用 ' / ' 分隔"
          },
          "intro": {
            "type": [
              "string",
              "null"
            ]
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "description": "JD 正文"
          },
          "requirements": {
            "type": [
              "string",
              "null"
            ]
          },
          "contact_email": {
            "type": [
              "string",
              "null"
            ]
          },
          "contact_wechat": {
            "type": [
              "string",
              "null"
            ]
          },
          "contact_xiaohongshu": {
            "type": [
              "string",
              "null"
            ]
          },
          "contact_link": {
            "type": [
              "string",
              "null"
            ]
          },
          "referral_code": {
            "type": [
              "string",
              "null"
            ]
          },
          "source_url": {
            "type": [
              "string",
              "null"
            ]
          },
          "logo_url": {
            "type": [
              "string",
              "null"
            ],
            "description": "相对图片端点（/api/postings/<id>/logo）或 http(s) 绝对地址"
          },
          "positions": {
            "type": [
              "string",
              "null"
            ],
            "description": "多岗位卡片：JSON 字符串，需 JSON.parse；单岗位为 null"
          },
          "published_at": {
            "type": [
              "string",
              "null"
            ],
            "examples": [
              "2026-05-12"
            ]
          },
          "published_ts": {
            "type": [
              "integer",
              "null"
            ],
            "description": "unix 秒"
          },
          "valid_period": {
            "type": [
              "string",
              "null"
            ]
          },
          "poster_type": {
            "type": [
              "string",
              "null"
            ]
          },
          "featured": {
            "type": "boolean"
          },
          "saved_count": {
            "type": "integer"
          },
          "view_count": {
            "type": "integer"
          },
          "review_status": {
            "type": "string",
            "description": "公开接口恒为 approved"
          }
        },
        "required": [
          "posting_id",
          "organization",
          "role",
          "employment_type",
          "location"
        ]
      },
      "Company": {
        "type": "object",
        "description": "AI 公司目录条目。完整结构见 /skill/references/company-object.md",
        "properties": {
          "company_id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "company_tag": {
            "type": [
              "string",
              "null"
            ]
          },
          "stage": {
            "type": [
              "string",
              "null"
            ],
            "description": "阶段 / 融资轮次"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "location": {
            "type": [
              "string",
              "null"
            ]
          },
          "company_intro": {
            "type": [
              "string",
              "null"
            ]
          },
          "team_members": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "funding_rounds": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "products": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "news_links": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "interview_links": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "open_positions": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            },
            "description": "该公司在招岗位精简版（≤8 条，不含 JD 正文与联系方式）"
          }
        },
        "required": [
          "company_id",
          "name"
        ]
      },
      "Guide": {
        "type": "object",
        "description": "面经 / 求职攻略外链",
        "properties": {
          "guide_id": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "summary": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "description": "原帖外链"
          },
          "source": {
            "type": "string",
            "enum": [
              "xiaohongshu",
              "x",
              "other"
            ]
          },
          "direction": {
            "type": "string",
            "description": "岗位方向短标签"
          },
          "job_type": {
            "type": "string",
            "description": "岗位类型短标签"
          },
          "company": {
            "type": "string"
          },
          "logo_url": {
            "type": "string"
          },
          "published_at": {
            "type": "string"
          },
          "created_at": {
            "type": "integer",
            "description": "unix 秒"
          },
          "updated_at": {
            "type": "integer"
          }
        },
        "required": [
          "guide_id",
          "title",
          "url"
        ]
      },
      "NewsItem": {
        "type": "object",
        "description": "每日 AI 资讯条目。格式见 /skill/references/news-format.md",
        "properties": {
          "id": {
            "type": "string"
          },
          "date": {
            "type": "string",
            "examples": [
              "2026-06-10"
            ]
          },
          "title": {
            "type": "string"
          },
          "category": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "资讯",
                "产品",
                "模型",
                "播客",
                "论文",
                "博文"
              ]
            },
            "description": "受控枚举，一条可属多类"
          },
          "time": {
            "type": [
              "string",
              "null"
            ]
          },
          "source": {
            "type": [
              "string",
              "null"
            ]
          },
          "handle": {
            "type": [
              "string",
              "null"
            ]
          },
          "url": {
            "type": [
              "string",
              "null"
            ]
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "summary": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "id",
          "date",
          "title",
          "category"
        ]
      },
      "PublishRequest": {
        "type": "object",
        "description": "发布岗位。必填五组：organization / role（或 positions）/ employment_type / location / 至少一个 contact_*。绝不要编造字段，尤其联系方式。",
        "properties": {
          "organization": {
            "type": "string"
          },
          "role": {
            "type": "string",
            "description": "单岗位必填；多岗位改用 positions"
          },
          "employment_type": {
            "type": "array",
            "items": {
              "type": "string",
              "maxLength": 16
            },
            "minItems": 1
          },
          "location": {
            "type": "string",
            "description": "多地用 ' / ' 分隔；纯远程写 远程"
          },
          "contact_email": {
            "type": "string",
            "format": "email"
          },
          "contact_wechat": {
            "type": "string",
            "minLength": 2
          },
          "contact_xiaohongshu": {
            "type": "string",
            "maxLength": 80
          },
          "contact_link": {
            "type": "string",
            "format": "uri",
            "description": "服务端会做可达性探测"
          },
          "team": {
            "type": "string"
          },
          "intro": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "requirements": {
            "type": "string"
          },
          "source_url": {
            "type": "string",
            "format": "uri"
          },
          "role_tags": {
            "type": "array",
            "items": {
              "type": "string",
              "maxLength": 7
            },
            "maxItems": 5
          },
          "referral_code": {
            "type": "string",
            "maxLength": 64
          },
          "poster_type": {
            "type": "string",
            "maxLength": 24
          },
          "positions": {
            "type": "array",
            "description": "同公司多岗位合并成一张卡片；顶层 role / employment_type 可省略",
            "items": {
              "type": "object",
              "properties": {
                "role": {
                  "type": "string"
                },
                "employment_type": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  },
                  "minItems": 1
                },
                "description": {
                  "type": "string"
                },
                "requirements": {
                  "type": "string"
                }
              },
              "required": [
                "role",
                "employment_type"
              ]
            }
          },
          "logo_url": {
            "type": "string",
            "description": "data:image/... URL，≤256KB"
          }
        },
        "required": [
          "organization",
          "employment_type",
          "location"
        ]
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "description": "错误码或面向用户的中文文案"
          },
          "hint": {
            "type": "string"
          },
          "retry_after": {
            "type": "integer",
            "description": "rate_limit_exceeded 时的退避秒数"
          }
        },
        "required": [
          "error"
        ]
      }
    },
    "headers": {
      "RateLimitPolicy": {
        "description": "配额策略，跨响应稳定（draft-ietf-httpapi-ratelimit-headers)。一次请求可能同时受多条策略约束：q=配额，w=窗口秒数。策略按客户端 IP 分区；开放测试 key 的每日额度按 key 分区。",
        "schema": {
          "type": "string"
        },
        "example": "\"api\";q=1200;w=60, \"search\";q=60;w=60"
      },
      "RateLimit": {
        "description": "本次请求之后各策略的实时余量：r=剩余可用量，t=该余量所在窗口的剩余秒数。来自缓存的响应（Age > 0）里这个值可能已过期，按规范应忽略。",
        "schema": {
          "type": "string"
        },
        "example": "\"api\";r=1199;t=60, \"search\";r=59;t=57"
      },
      "RateLimitLimit": {
        "description": "最紧那条策略的配额（老的三字段形态，与 RateLimit 同源）。",
        "schema": {
          "type": "integer"
        },
        "example": 60
      },
      "RateLimitRemaining": {
        "description": "最紧那条策略的剩余可用量。",
        "schema": {
          "type": "integer"
        },
        "example": 59
      },
      "RateLimitReset": {
        "description": "最紧那条策略的窗口剩余秒数。",
        "schema": {
          "type": "integer"
        },
        "example": 57
      },
      "RetryAfter": {
        "description": "退避秒数（RFC 9110 §10.2.3）。不会早于 RateLimit 的 t，可直接 sleep 这个值。",
        "schema": {
          "type": "integer"
        },
        "example": 57
      },
      "ApiVersion": {
        "description": "本次响应所属的 API major 版本，恒为当前 major。",
        "schema": {
          "type": "string"
        },
        "example": "v1"
      }
    }
  }
}
