なぜATSエンジニアはAPIを理解する必要があるか

ATS(採用管理システム)の価値は単体のプロダクトとしてではなく、 HRエコシステムのハブとして機能することで最大化されます。 ATSとHRIS(人事情報システム)・ジョブボード・評価ツール・バックグラウンドチェックサービスの連携は、 すべてAPIを通じて行われます。

エンジニアがATSのAPIを扱う場面は主に3つです。

  • ① HR Techプロダクト開発(ATSとの連携機能): 自社プロダクトをATSと統合する際、ATSのAPIエンドポイント・認証方式・データスキーマの理解が不可欠です。 例えば、評価プラットフォームが「候補者のステージ変更」をトリガーにスコアをATSに書き戻す場合などが典型です。
  • ② 社内採用システムのカスタム連携: 大企業では既製のATS連携では要件を満たせず、独自の統合レイヤーを構築するケースがあります。 求人情報のマルチポストや、複数ATSからのデータ統合ダッシュボードなどがその例です。
  • ③ 採用データの分析パイプライン構築: 時間帯別応募数・チャネル別ソース・ファネル通過率などの採用データを データウェアハウスに取り込むETLパイプラインの構築では、ATSのAPIとWebhookを扱います。

本章では市場シェアが高い3つのAPI——Greenhouse Harvest API v3、Lever API、LinkedIn Job Posting API——の 実装詳細と、Google for Jobs対応のためのJSON-LD実装を解説します。

Greenhouse Harvest API v3

v1/v2 vs v3 の主要変更点

項目v1 / v2v3備考
認証方式Basic Auth(APIキー)OAuth 2.0 Bearer JWTトークン取得先: https://auth.greenhouse.io/token
ページネーションオフセットベース(page, per_page)カーソルベース(after, limit)件数多い場合のパフォーマンス大幅改善
レスポンス形式JSON(配列直接返却)JSON(data + meta ラッパー)ページネーション情報が meta に含まれる
Webhook署名なし or SHA256(オプション)HMAC-SHA256(必須)X-Greenhouse-Signatureヘッダー
廃止予定2026年8月31日継続サポートv3移行推奨

主要エンドポイント解説

Greenhouse Harvest API v3 の中心となるエンドポイントを3つ紹介します。 ベースURLは https://harvest.greenhouse.io です。

GET /v1/applications は採用パイプライン全体の状況把握に使います。 フィルタパラメータ job_idstatuscreated_afterlast_activity_afterを組み合わせて差分取得が可能です。

// GET /v1/applications のレスポンス例
{
  "id": 123,
  "status": "active",
  "applied_at": "2026-06-16T09:00:00Z",
  "current_stage": {
    "id": 456,
    "name": "一次面接",
    "interviews": []
  },
  "source": { "id": 1, "name": "LinkedIn" },
  "credited_to": {
    "id": 789,
    "email": "recruiter@example.com",
    "name": "採用 太郎"
  },
  "custom_fields": {},
  "attachments": []
}

その他の主要エンドポイントは以下の通りです。

エンドポイント用途主要フィルタ
GET /v1/applications応募一覧・ステータス取得job_id, status, created_after
GET /v1/candidates候補者プロフィール取得email, created_after, updated_after
GET /v1/jobs求人票一覧・ステータスstatus, department_id
PATCH /v1/applications/{id}/advanceステージ進行from_stage_id(必須)

Webhookイベント一覧

Greenhouse のWebhookは全30種類以上が定義されており、すべてHMAC-SHA256署名付きで配信されます。 カテゴリ別の主要イベントを以下に整理します。

カテゴリイベント名発火タイミング
アプリケーション系new_candidate_application新規応募作成時
offer_createdオファー作成時
offer_approvedオファー承認時
候補者系candidate_stage_changeステージ進行時(最頻出)
hire_candidateオファー承諾時
reject_candidate不採用時
candidate_anonymized匿名化処理時(GDPR対応)

candidate_stage_change のWebhookペイロード例です。action フィールドでイベント種別を判別し、payload.application.current_stageで遷移後のステージを取得します。

// candidate_stage_change Webhookペイロード
{
  "action": "candidate_stage_change",
  "payload": {
    "application": {
      "id": 123,
      "status": "active",
      "current_stage": { "id": 456, "name": "二次面接" },
      "source": { "name": "LinkedIn" }
    }
  }
}

Lever API

Lever の最大の特徴はOpportunity中心のデータモデルです。 他のATSが「候補者(Candidate)」を中心に設計されているのに対し、 Lever は「応募機会(Opportunity)」を第一級エンティティとして扱います。

graph LR
  A[Contact\n(人・永続ID)] -->|1対多| B[Opportunity A\nバックエンドエンジニア]
  A -->|1対多| C[Opportunity B\nSREポジション]
  A -->|1対多| D[Opportunity C\n2年後の再応募]
  B --> E[ステージ・タグ・メモ]
  C --> F[ステージ・タグ・メモ]
  D --> G[ステージ・タグ・メモ]

  style A fill:#10b981,stroke:#059669,color:#fff
  style B fill:#1e40af,stroke:#1d4ed8,color:#fff
  style C fill:#1e40af,stroke:#1d4ed8,color:#fff
  style D fill:#1e40af,stroke:#1d4ed8,color:#fff
LeverのOpportunity中心モデル。1人のContactが複数のOpportunityを持てるため、転職後の再応募や複数ポジション同時選考を自然に表現できる

ベースURLは https://api.lever.co/v1。 認証はBasic Auth(APIキー)またはOAuth 2.0が利用可能です。

主要エンドポイント

エンドポイント用途
GET /opportunities候補者パイプライン一覧(中心エンドポイント)
GET /opportunities/deleted削除済みOpportunity(差分同期に必要)
GET /postings求人票一覧・ステータス
GET /contacts/{id}個人コンタクト情報(全Opportunity横断)
POST /opportunities/{id}/stageステージ更新

Lever APIのレスポンスはすべて以下の共通構造を持ちます。 ページネーションは next トークンによるカーソル方式です。

// Lever APIレスポンス共通構造
{
  "data": [...],
  "next": "0.1414895548650.a6070140-33db-407c-91f5-2760e15c8e94",
  "hasNext": true
}

LinkedIn Job Posting API

LinkedIn Job Posting API(Foundation Schema)は、採用担当者や HR Tech企業が 求人票をLinkedInプラットフォームに直接掲載するための標準APIです。 バージョニングヘッダー LinkedIn-Version: li-lts-2025-01 以降を使用します。

Foundation Schema 必須フィールド

フィールド名説明・制約
jobPostingOperationTypeenumCREATE / UPDATE / CLOSE
companyURNurn:li:organization:{id} 形式
companyApplyUrlURL応募フォームURL(Easy Apply無効時必須)
externalJobPostingIdstring外部ユニークID(最大75文字)
titlestring求人タイトル(200文字以内)
descriptionstring職務内容(100〜25,000文字)
listedAtnumber掲載日時(epochミリ秒)
locationstring地名(例: "Tokyo, Japan")
workplaceTypesarrayOn-site / Hybrid / Remote
posterEmailstring掲載者メール(不正掲載防止)

給与情報(compensation)はオプションですが、記載することでLinkedInの求人検索での表示優先度が上がります。 給与フィールドの構造例です。

// LinkedIn Job Posting API: compensation フィールド例
"compensation": {
  "compensations": [{
    "period": "YEARLY",
    "type": "BASE_SALARY",
    "value": {
      "range": {
        "start": {"amount": "6000000", "currencyCode": "JPY"},
        "end": {"amount": "9000000", "currencyCode": "JPY"}
      }
    }
  }]
}

Google for Jobs JSON-LD実装

Google for Jobs は求人票ページに構造化データ(JSON-LD)を埋め込むことで、 Googleの求人検索結果に表示される仕組みです。 求人SEOにおいてオーガニックトラフィックを大幅に増やせる重要な施策であり、 ジョブボードを持つ企業は必ず対応すべき実装です。

最低限必要な5つのフィールド

Google for Jobsに求人を表示させるための最小限のJSON-LD実装例です。script タグを求人詳細ページの head または body 内に配置します。

<script type="application/ld+json">
{
  "@context": "https://schema.org/",
  "@type": "JobPosting",
  "title": "Backendエンジニア",
  "description": "<p>職務内容...</p>",
  "datePosted": "2026-06-16",
  "validThrough": "2026-08-31T00:00",
  "employmentType": "FULL_TIME",
  "hiringOrganization": {
    "@type": "Organization",
    "name": "株式会社Example",
    "sameAs": "https://example.co.jp"
  },
  "jobLocation": {
    "@type": "Place",
    "address": {
      "@type": "PostalAddress",
      "addressLocality": "渋谷区",
      "addressCountry": "JP"
    }
  }
}
</script>
フィールド必須/推奨備考
title必須求人タイトル
description必須HTMLタグ使用可
datePosted必須ISO 8601形式(YYYY-MM-DD)
hiringOrganization必須name と sameAs(企業URL)
jobLocation必須PostalAddress で詳細指定可
validThrough推奨締切日。未指定だと期限なし掲載
baseSalary推奨給与情報(表示優先度向上)
jobLocationTypeリモート必須"TELECOMMUTE"(リモート求人のみ)

Webhookの実装パターン — ポーリング vs イベント駆動

観点ポーリングWebhook(イベント駆動)
遅延最大ポーリング間隔(1〜5分)ほぼリアルタイム(秒〜数十秒)
サーバー負荷一定の定期リクエスト負荷イベント発生時のみ
実装難易度シンプル(クーロンジョブ等)エンドポイント公開・署名検証が必要
レート制限リスク高(頻繁なポーリングで抵触)低(受信側なのでレート制限なし)
適用場面外部Webhookが利用できない場合本番環境の推奨パターン

HMAC-SHA256署名の検証(Node.js実装例)

Greenhouse・Leverともに、Webhookの送信元が正規のATSサーバーであることを確認するため、 HMAC-SHA256署名をリクエストヘッダーに付与します。 受信側では以下のように検証します。

const crypto = require('crypto');

// Greenhouse: X-Greenhouse-Signature ヘッダーの検証
function verifyWebhookSignature(payload, signature, secret) {
  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(payload, 'utf8')
    .digest('hex');
  // timingSafeEqual でタイミング攻撃を防ぐ
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expectedSignature)
  );
}

// Express ミドルウェアでの使用例
app.post('/webhooks/greenhouse', express.raw({ type: 'application/json' }), (req, res) => {
  const signature = req.headers['x-greenhouse-signature'];
  const secret = process.env.GREENHOUSE_WEBHOOK_SECRET;

  if (!verifyWebhookSignature(req.body, signature, secret)) {
    return res.status(401).json({ error: 'Invalid signature' });
  }

  const event = JSON.parse(req.body);
  // べき等処理: event_id で重複排除
  processEvent(event);
  res.status(200).json({ received: true });
});

べき等性の設計 — Deduplication

ネットワーク障害やATSサーバーのリトライにより、同一Webhookが複数回配信されることがあります。 これを適切に処理するためにべき等性(Idempotency)の設計が必要です。

event_id による重複排除パターン

  1. ① Webhookペイロードの id または event_id を抽出
  2. ② Redisや処理済みテーブルで「既に処理したか」を確認
  3. ③ 未処理の場合のみビジネスロジックを実行
  4. ④ 処理済みとしてIDをマーク(TTL: 24〜72時間が目安)
  5. ⑤ 重複の場合は 200 OK を返す(再送停止のため)

エンジニア視点のコラム: ATS APIは「採用のGit」だ

ATS APIのWebhookイベントをよく見ると、Gitのコマンドと驚くほど対応していることに気づきます。

ATSイベントGitの概念意味
new_candidate_applicationgit init / git clone採用パイプラインの開始
candidate_stage_changegit commitステージ進行(状態変化の記録)
pipeline(採用フロー)git branch候補者ごとの並行進行
hire_candidategit merge採用決定(チームへの合流)
reject_candidategit branch -d不採用(ブランチのクローズ)

この対応から見えてくるのは、採用データが本質的にイベントソーシング(Event Sourcing)的な性質を持つということです。 候補者のステージ変更はすべてAppend-onlyで記録され、現在のステータスはイベントの積み上げによって導出されます。 Gitのコミット履歴がコードの変遷を追えるように、ATSのWebhookイベントは候補者の採用プロセスを完全に再現できます。

この視点をアーキテクチャに活かした実装パターンが、Webhookイベントをイベントバスに流してデータレイクに格納する構成です。

graph LR
  A[Greenhouse / Lever\nWebhook配信] --> B[APIゲートウェイ\n署名検証・べき等チェック]
  B --> C[イベントバス\nAmazon SQS / Pub/Sub]
  C --> D[ストリーム処理\nCloud Functions]
  D --> E[データレイク\nBigQuery / Redshift]
  E --> F[採用ダッシュボード\n通過率・時間・チャネル分析]
  D --> G[HRIS連携\n入社処理自動化]

  style A fill:#f97316,stroke:#ea580c,color:#fff
  style C fill:#3b82f6,stroke:#1d4ed8,color:#fff
  style E fill:#10b981,stroke:#059669,color:#fff
  style F fill:#10b981,stroke:#059669,color:#fff
Webhookイベントをイベントバス経由でデータレイクに格納するアーキテクチャ。採用データのリアルタイム分析とHRIS連携の自動化を実現する

このアーキテクチャにより、採用ファネルの各ステージの通過率・所要時間・チャネル別効果を リアルタイムに可視化できます。さらに hire_candidate イベントをトリガーに HRIS(Workday等)への入社手続き自動起票まで連携すれば、 採用決定から入社手続き完了までの工数を大幅に削減できます。

理解度チェック

問題 0 / 40%
Q1

Greenhouse Harvest API v3 で v1/v2 から変更された認証方式はどれですか?

キーボード: 1〜4 で選択、Enter で回答