开放 API 与 Webhook 对接文档

把轻聘 ATS 的职位与候选人接进你自己的系统(HR 系统 / 招聘中台 / 自动化脚本)。

← 返回工作台

三步跑通

  1. 工作台 → 开放 API → 创建密钥(明文只显示一次,立刻保存)。
  2. 把下面的 curl 示例复制走,先调 GET /api/v1/jobs 确认鉴权通了。
  3. 要实时通知就到 Webhook 填你的接收地址,用验签密钥校验推送(下方有现成验签代码)。

开放 API 与 Webhook 是专业版功能;密钥只存哈希,丢了只能吊销重建,客服也无法帮你找回明文。

通用约定

Base URL:
https://qingats.itianshu.cn
鉴权:
请求头 Authorization: Bearer ats_xxx。走密钥不走 Cookie,与网页登录态无关;吊销后立即失效。
编码:
请求与响应均为 UTF-8 JSON。
状态码含义处理建议
401invalid_api_key:没带 / 填错 / 已吊销的密钥检查 Bearer 头;到工作台确认密钥未吊销
400参数错误(message 是中文原因)按提示修正参数
503数据库尚未初始化服务端迁移未完成,稍后重试

GET/api/v1/jobs

列出密钥属主名下的全部职位(含每个职位的候选人数),按创建时间倒序。

查询参数

参数必填说明
limit否返回条数,1–200,默认 50,超出范围自动钳制

调用示例

curl 'https://qingats.itianshu.cn/api/v1/jobs?limit=20' \
  -H 'Authorization: Bearer ats_你的密钥'

响应示例

{
  "jobs": [
    {
      "id": 3,
      "title": "前厅经理",
      "dept": "门店运营",
      "status": "open",
      "created_at": "2026-10-15T08:30:00.000Z",
      "candidate_count": 12
    }
  ]
}

字段说明:status 为 open(在招)/ closed(已关闭);created_at 是 ISO 8601 字符串;candidate_count 是该职位下的候选人总数。

GET/api/v1/candidates

列出候选人,可按职位 / 阶段过滤,按 id 倒序。

查询参数

参数必填说明
job_id否按职位过滤(数字,必须是名下职位)
stage否按阶段过滤,枚举:待筛选 / 面试中 / offer / 淘汰
limit否返回条数,1–200,默认 50

调用示例(含中文参数,用 --data-urlencode 免转码)

curl -G 'https://qingats.itianshu.cn/api/v1/candidates' \
  --data-urlencode 'job_id=3' \
  --data-urlencode 'stage=面试中' \
  --data-urlencode 'limit=20' \
  -H 'Authorization: Bearer ats_你的密钥'

响应示例

{
  "candidates": [
    {
      "id": 88,
      "name": "张三",
      "email": "zhangsan@example.com",
      "job_id": 3,
      "stage": "面试中",
      "note": "内推,5 年连锁餐饮经验",
      "created_at": 1760582400000,
      "job_title": "前厅经理"
    }
  ]
}

字段说明:created_at 是毫秒时间戳(2026-10-16 之前登记的老数据为 0);job_title 是关联职位的名称。

POST/api/v1/candidates

创建一个候选人(Body 为 JSON)。创建成功会触发 candidate.created Webhook 推送。

Body 参数

参数必填说明
name是候选人姓名,最长 60 字
job_id是职位 id(数字,必须是名下职位,否则 400)
email否邮箱,最长 120 字
stage否初始阶段,默认「待筛选」;非法值也会归一化为「待筛选」
note否备注,最长 500 字

调用示例

curl -X POST 'https://qingats.itianshu.cn/api/v1/candidates' \
  -H 'Authorization: Bearer ats_你的密钥' \
  -H 'Content-Type: application/json' \
  -d '{"name":"李四","email":"lisi@example.com","job_id":3,"stage":"待筛选","note":"来自招聘网站"}'

响应示例

{
  "ok": true,
  "candidate": {
    "id": 89,
    "name": "李四",
    "email": "lisi@example.com",
    "job_id": 3,
    "stage": "待筛选",
    "note": "来自招聘网站",
    "created_at": 1760582400000
  }
}

Webhook 对接(接收事件推送)

在工作台 → Webhook 填你的接收地址并勾选订阅事件。有动作时,轻聘 ATS 会向该地址发 POST 请求。

事件列表

事件触发时机data 内容
candidate.created新增候选人(网页添加或开放 API 创建都会触发)candidate:完整候选人记录
candidate.stage_changed候选人阶段变更id / stage(新阶段)/ from(原阶段)/ candidate:完整记录

推送格式

POST /ats/webhook HTTP/1.1
content-type: application/json
user-agent: QingATS-Webhook/1.0
x-ats-event: candidate.stage_changed
x-ats-signature: sha256=9f2c8e...(HMAC-SHA256,hex 小写)
{
  "event": "candidate.stage_changed",
  "created_at": 1760582400000,
  "data": {
    "id": 89,
    "stage": "面试中",
    "from": "待筛选",
    "candidate": { ... }   // 完整候选人记录,字段同 candidate.created
  }
}

顶层 created_at 与候选人记录里的 created_at 均为毫秒时间戳。

验签(Node.js / Express 示例)

签名 = HMAC-SHA256(验签密钥, 原始请求体),hex 小写,放在 X-ATS-Signature 头(带 sha256= 前缀)。⚠️ 必须拿原始请求体计算——先解析 JSON 再重新序列化会得到不同字节,验签必然失败。

// Express 示例:先拿原始请求体再验签(不能先 JSON.parse 再重新序列化)
app.post('/ats/webhook', express.raw({ type: '*/*' }), (req, res) => {
  const crypto = require('crypto')
  const secret = 'whsec_xxxx'                        // 创建 Webhook 时保存的验签密钥
  const sig = String(req.headers['x-ats-signature'] || '')
  const expect = 'sha256=' +
    crypto.createHmac('sha256', secret).update(req.body).digest('hex')
  if (sig !== expect) return res.status(401).send('bad signature')

  const payload = JSON.parse(req.body.toString('utf8'))
  if (payload.event === 'candidate.created') {
    console.log('新候选人:', payload.data.candidate.name)
  } else if (payload.event === 'candidate.stage_changed') {
    console.log(`候选人 ${payload.data.id}:${payload.data.from} → ${payload.data.stage}`)
  }
  res.sendStatus(200) // 返回 2xx 即视为投递成功
})

投递行为(对接前必读)

  • 超时 5 秒;你的接口返回 2xx 才算投递成功。
  • 失败不会自动重试;每次投递(含失败原因)都在 工作台 → Webhook → 最近投递记录 里可查。
  • 只推送你勾选订阅的事件;投递失败绝不影响业务动作本身(候选人该建成功还是成功)。
  • 建议接收端做幂等:同一事件理论上可能因网络重发收到不止一次。

对接调试技巧

  • 401 先查三件事:Bearer 头拼写、key 是否以 ats_ 开头、工作台里是否已吊销。
  • 收不到推送:先看工作台的投递记录——有记录且 status=0 是你服务端的问题(超时 / 非 2xx / 签名错);没记录说明事件没触发或没勾选订阅。
  • 验签失败:99% 是用了重新序列化后的 body。务必用原始字节计算(见上方 express.raw 示例)。
  • 本地联调可用 webhook.site 之类的临时接收地址,先看真实推送长什么样。
  • 测试完记得吊销测试密钥;secret 只在创建时显示一次。

轻聘 ATS · 招聘管理 · qingats.itianshu.cn

© 2026 轻聘 ATS · 由 Nuxt 4 + Cloudflare 驱动
换友链联系QQ:513146055