Offer岛 (OfferDao) 开发者文档
Offer岛(OfferDao,https://offerdao.ai)是面向 AI 方向的求职 / 招聘平台。岗位、公司、面经与每日行业资讯尽量公开——对人开放,也对工具开放:整个已审核岗位库都可以让你自己的 agent 直接查询,也可以把一份 JD 结构化后发布进审核队列。
这一页是 Offer岛 API 的人类可读入口。机器可读的那份在 /openapi.json(OpenAPI 3.1),站点索引在 /llms.txt,自然语言用法说明在 /skill.md。
机器可读入口
- /openapi.json — Offer岛 API 的 OpenAPI 3.1 规格(同一份也在 /api/openapi.json 与 /.well-known/openapi.json)
- /llms.txt — 站点与开发者资源索引(llmstxt.org 格式)
- /skill.md — agent skill 全文,可直接装进 Claude Code / Codex / Cursor Agent
- /skill/references/posting-fields.md — 岗位对象与发布字段逐字段说明
- /skill/references/company-object.md — 公司对象字段说明
- /skill/references/news-format.md — 资讯 markdown 与 feed JSON 格式
- /agent-instructions.md — 给外部 agent 的「何时该用本站 / 每类任务怎么调」说明
- /.well-known/api-catalog — API Catalog(RFC 9727 linkset),只知道域名时从这里入手
- /api/versions — 机器可读的版本与弃用策略
- /agent.md — 站内 AI 助手的产品级 prompt
- /sitemap.xml — 全部可抓取页面
这一页本身也有 markdown 版:请求时带 Accept: text/markdown,或直接取 /docs.md。首页、关于、条款、隐私、联系同理(/index.md、/about.md …)。
Base URL
生产环境是 https://offerdao.ai。不要把域名写死——用环境变量解析一次再复用,将来换域名时只改这一处:
OFFERDAO_BASE="${OFFERDAO_BASE:-https://offerdao.ai}"
带版本的规范写法是 $OFFERDAO_BASE/api/v1/…;不带版本段的 $OFFERDAO_BASE/api/… 是永久别名,两者完全等价(见下面的版本与弃用策略)。本页示例为了与既有集成一致,仍写不带版本的形式。
版本与弃用策略
agent 不该去接一个「随时可能变、且不打招呼」的接口。这里把承诺写死:
- 版本在 URL 路径里。
/api/v1/…是当前 major。每个/api响应都带X-API-Version: v1。 /api/…是永久别名。它始终指向当前 major,既有集成一行都不用改。新集成建议直接写/v1。- 破坏性变更只走新 major。v1 的响应字段不会被删除,也不会改变含义;
/api/v2出现之前,v1 就是稳定的。 - 新增是兼容变更。新字段、新可选参数、新端点随时可能出现——请忽略未知字段,不要用严格模式解析。
- 弃用有信号也有时间表。被弃用的端点会在响应上带
Deprecation(RFC 9745,值为@<unix 秒>)与Sunset(RFC 8594,IMF-fixdate),并附Link; rel="deprecation";有替代端点时再附Link; rel="successor-version"。从打上 Deprecation 到真正下线,至少保留 180 天。 - 目前没有任何公开端点处于弃用状态。
机器可读的同一份声明在 /api/versions(/api 与 /api/v1 返回同一份),OpenAPI 规格里对应 info.x-api-versioning。
curl -s "$OFFERDAO_BASE/api/versions"
# 两种写法等价
curl -sI "$OFFERDAO_BASE/api/health"
curl -sI "$OFFERDAO_BASE/api/v1/health" # → X-API-Version: v1
鉴权
岗位搜索、精选与发布需要 API key;公司目录、面经攻略、行业资讯、健康检查不需要。两种写法等价:
curl -sG "$OFFERDAO_BASE/api/postings/search" \
-H "Authorization: Bearer $OFFERDAO_API_KEY" \
--data-urlencode "q=infra" --data-urlencode "limit=5"
# 或者
curl -sG "$OFFERDAO_BASE/api/postings/search" -H "X-API-Key: $OFFERDAO_API_KEY"
拿 key 的两条路
- 个人 key(推荐,查询与发布都可用,不限量):登录后在「我的设置 → API keys」自助创建。用某个个人 key 发布的岗位会归属到该 key 的拥有者,出现在 TA 的「我的发布」里。
- 开放测试 key(免注册,仅查询):
GET /api/agent/test-key领取。共享、按日限量,调发布接口会403 scope_forbidden。
端点总览
下表由 /openapi.json 直接生成,字段与参数细节以规格为准。
| 方法 | 路径 | 用途 | 鉴权 |
|---|---|---|---|
GET | /api/v1/postings/search | 搜索已审核岗位 | 需要 API key |
GET | /api/v1/postings/featured | 岛上精选(随机抽样) | 需要 API key |
POST | /api/v1/postings/agent | 发布岗位(进审核队列) | 需要 API key |
GET | /api/v1/companies | AI 公司目录(无需 API key) | 公开 |
GET | /api/v1/guides | 面经攻略外链(无需 API key) | 公开 |
GET | /api/v1/news/feed | 每日行业资讯 JSON(无需 API key) | 公开 |
GET | /news/md | 资讯 markdown 索引(无需 API key) | 公开 |
GET | /news/md/{name} | 某一天的资讯原文(无需 API key) | 公开 |
GET | /api/v1/agent/test-key | 免注册领取开放测试 key(仅查询) | 公开 |
GET | /api/v1/agent-config | agent 接入配置(无需 API key) | 公开 |
GET | /api/v1/health | 健康检查(无需 API key) | 公开 |
GET | /skill.md | agent skill 全文(自然语言用法说明) | 公开 |
GET | /agent.md | 站内 AI 助手的产品级 prompt | 公开 |
GET | /llms.txt | llms.txt 站点索引(llmstxt.org 格式) | 公开 |
GET | /openapi.json | 这份 OpenAPI 规格本身 | 公开 |
GET | /docs | 开发者文档(HTML / markdown 按 Accept 协商) | 公开 |
GET | /api/versions | 版本与弃用策略(机器可读) | 公开 |
GET | /.well-known/api-catalog | API Catalog(RFC 9727 linkset) | 公开 |
GET | /agent-instructions.md | 给外部 agent 的「何时使用 / 怎么调用」说明 | 公开 |
快速上手
搜索岗位
# 北京的 infra 岗位,只要正式,最近 30 天
curl -sG "$OFFERDAO_BASE/api/postings/search" \
-H "Authorization: Bearer $OFFERDAO_API_KEY" \
--data-urlencode "q=infra" \
--data-urlencode "location=北京" \
--data-urlencode "employment_type=正式" \
--data-urlencode "published_within_days=30"
返回 { items, total, limit, offset }。total 是该筛选条件的总条数,不受分页影响。岗位详情页短链是 $OFFERDAO_BASE/j/<posting_id>,可以直接给用户点开。
发布岗位
必填五组:公司、岗位名称(多岗位改用 positions)、工作类型、工作地点、至少一个联系方式。缺什么就问用户,绝不要编造——联系方式尤其不能凭空捏造。发布总是进审核队列,审核通过前 /j/<posting_id> 是 404。
curl -s -X POST "$OFFERDAO_BASE/api/postings/agent" \
-H "Authorization: Bearer $OFFERDAO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"organization": "某 AI 公司",
"role": "多模态算法工程师",
"employment_type": ["正式"],
"location": "北京 / 上海",
"contact_email": "[email protected]",
"role_tags": ["多模态"]
}'
免 key 的公开数据
curl -s "$OFFERDAO_BASE/api/companies" # AI 公司目录
curl -s "$OFFERDAO_BASE/api/guides" # 面经攻略外链
curl -s "$OFFERDAO_BASE/news/md" # 每日资讯的 markdown 索引
curl -s "$OFFERDAO_BASE/news/md/20260610.md" # 某一天的资讯原文
限流
每个 /api 响应都带标准限流头(draft-ietf-httpapi-ratelimit-headers),所以不用先撞一次墙才知道额度:
RateLimit-Policy: "api";q=1200;w=60, "search";q=60;w=60
RateLimit: "api";r=1199;t=57, "search";r=59;t=57
Retry-After: 57 # 只在 429 上出现
RateLimit-Policy— 生效的配额策略,跨响应稳定。q是配额,w是窗口秒数。RateLimit— 实时余量。r是剩余可用量,t是这批余量的剩余秒数。r接近 0 就该主动降速,别等 429。- 同时还发老写法
RateLimit-Limit/RateLimit-Remaining/RateLimit-Reset与X-RateLimit-*,取最紧那条策略;三套值同源,随便读哪套都行。 Retry-After(秒)只在429上出现,且不会早于t——可以直接 sleep 这个值。- 来自缓存的响应(
Age > 0)里的RateLimit可能已经过期,按规范应当忽略。
一次请求可能同时受多条策略约束(兜底闸 + 端点闸 + 开放 key 的每日额度),头里就会同时出现多个成员。当前策略:
| 策略名 | 配额 | 作用范围 | 说明 |
|---|---|---|---|
api | 1200 次 / 60 秒 | 全部 /api/* 请求 | 兜底闸,防跑飞的循环;正常调用不会碰到 |
search | 60 次 / 60 秒 | 岗位搜索 / 精选 / 快照 / mention-index、公司目录、面经攻略、资讯 feed | 读接口的主闸 |
manual | 10 次 / 1 小时 | 网页表单发布岗位 | 写接口从严 |
agent | 10 次 / 1 小时 | POST /api/v1/postings/agent(agent 发布岗位) | 与网页表单同额度但独立计数 |
daemon | 120 次 / 60 秒 | 本机 daemon 注册 / 心跳 | 单台 daemon 约 1 次/分;额度按同一 NAT 后面多台留 |
compile | 120 次 / 60 秒 | 简历 LaTeX 编译 | 前端有 600ms 防抖,只在停手时触发 |
test-key | 20 次 / 60 秒 | GET /api/v1/agent/test-key(免注册领开放 key) | 领一次存起来复用,不要每次请求前都领 |
activity | 60 次 / 60 秒 | 访问日历心跳 | 正常一个账号一天一次 |
contacts | 60 次 / 60 秒 | 岗位联系方式明文(需登录) | 挡的是拿一个账号遍历 posting_id |
open-key-daily-search | 随 key 而定 / 24 小时 | 开放测试 key 的每日查询次数 | 只有开放测试 key 有;个人 key 不限量 |
open-key-daily-publish | 随 key 而定 / 24 小时 | 开放测试 key 的每日发布次数 | 只有开放测试 key 有;个人 key 不限量 |
频率闸按客户端 IP 分区;开放测试 key 的每日额度按 key 分区、北京时间零点重置。诚实的边界:线上每个 Serverless 实例各记一份计数,所以实际放行量可能比广告值宽松(只会更宽,不会更严)。机器可读的同一份声明在 /openapi.json 的 info.x-rate-limits。
错误码
429 rate_limit_exceeded— 按 IP 的频率闸。按Retry-After头(正文retry_after同值)退避后重试。429 rate_limited— 开放测试 key 当日额度用尽,Retry-After指向次日重置。等它没意义,重新领 key 也没用(发的是同一把),改用个人 key。401 missing_api_key/401 invalid_api_key— 别拿同一把 key 重试;个人 key 失效请在「我的设置 → API keys」重建。403 scope_forbidden— key 有效但没这个权限(典型是用测试 key 调发布)。400— 校验失败。error已是面向用户的中文文案,可直接转述。
内容协商与 404
页面类 URL 支持 Accept 协商(acceptmarkdown.com 口径):浏览器拿 HTML,带 Accept: text/markdown 拿 markdown,响应带 Vary: Accept, Accept-Encoding;一个表示都满足不了时回 406 并在正文列出可用类型。
curl -sI -H "Accept: text/markdown" "$OFFERDAO_BASE/docs"
首页也一样:$OFFERDAO_BASE/ 带 Accept: text/markdown 就地返回站点总览 markdown(同一个 URL,不再重定向)。HTML 响应带 Link: </index.md>; rel="alternate"; type="text/markdown",不做协商的客户端也能发现同一份内容在 /index.md。
不存在的路径回真正的 404(不是 200 + 首页外壳),markdown 正文里带着 llms.txt / 开发者文档 / OpenAPI / sitemap 的入口——探测失败时照着它重新定位,不要顺着猜路径。
agent 接入
把 Offer岛 装进你自己的 agent:npx skills add offerdaoai/skills,或直接把 /skill.md 交给它。站内 AI 助手(/agent)跑在用户自己的电脑上——本机 daemon + 用户自己的 CLI(Claude Code / Codex / Cursor Agent / Kimi CLI),简历原件留在本地。安装脚本见 /install.sh,接入配置见 /api/agent-config。
使用边界
数据可以查、可以推荐给用户,但请遵守服务条款:不要批量抓取转售,不要把联系方式拿去做无关营销。有商务合作或接入问题,联系我们。