Skip to content

Proposal: new source greenhouse (Greenhouse Harvest v3 — ATS / recruiting) #690

Description

@chrishronek

Source name

greenhouse

Describe the source data.

Greenhouse Harvest v3 is a REST API exposing recruiting / ATS data — candidates, applications, jobs, offers, interviews, scorecards, EEOC self-id responses, and the organizational metadata around them. Used by ~5,000+ companies as their applicant tracking system. JSON responses, RFC 5988 Link-header pagination, OAuth2 client_credentials auth.

Current status.

I've written it and run it in production

What is your plan for this source.

I want to run it in production

Use case

  1. Recruiting funnel analytics — applications → interviews → offers → hires by job/department/source, time-in-stage, recruiter productivity, source ROI. Standard ops dashboards that recruiting leadership reviews weekly.
  2. Compensation analysis — offer data (base / bonus / equity / total comp, all captured in Greenhouse custom fields) joined to candidate and job dimensions for pay-equity analysis, comp benchmarking, and budget planning.
  3. EEOC / DEI reporting — demographic self-id responses (gender, race, disability status, veteran status) per application for legally required EEO-1 reporting and internal diversity dashboards.

Describe the desired tables.

~33 resources from Harvest v3, all loaded incrementally on updated_at using v3's operator-prefixed filter syntax (updated_at=gte|):

Top-level entities (merge on id):
candidates, applications, jobs, job_posts, offers, scorecards, interviews, openings, departments, offices, users, sources, eeoc, demographic_answers

** Side resources (also incremental on updated_at)**:
job_hiring_managers, job_owners, interviewers (= scheduled-interview attendees), scorecard_candidate_attributes (per-attribute ratings), job_candidate_attributes (attribute definitions)

Reference / lookup data (replace per run, small):
close_reasons, rejection_reasons, user_roles, prospect_pools, email_templates, candidate_tags, demographic_question_sets, demographic_questions, demographic_answer_options, approvers, approver_groups, user_emails, attachments, notes

dlt's auto-flattening of nested arrays (e.g. candidates.addresses, candidates.email_addresses, candidates.phone_numbers) handles the child tables that other vendor packages typically expose as separate endpoints — no special handling needed.

Source is parameterized with a resources list so users who need additional endpoints can add them without modifying the source code.

Who else will benefit?

  • Companies using Greenhouse as their ATS — ~5,000+ organizations, heavy mid-market and enterprise representation, plus most YC/venture-backed companies. A large chunk are currently paying Fivetran for this same data.
  • Recruiting ops / People analytics teams that need warehouse access for funnel analysis beyond Greenhouse's native UI.
  • DEI and compliance teams producing EEO-1 reports and diversity dashboards.
  • Comp / total rewards teams doing pay-equity and benchmarking work.
  • Data teams migrating off Fivetran specifically for Greenhouse to reduce ELT spend.
  • HR analytics consultancies (Visier, Lightcast, etc.) who help customers build People warehouses.

Additional information

  • Already running in production for a client that I consult that is leaving Fivetran — full Fivetran-shape parity across 8 downstream dbt marts (application_enhanced, application_history, offer, job_opening, job_enhanced, close_reason, interview_enhanced, interview_scorecard_detail). On three of those marts our coverage exceeds Fivetran's (more LinkedIn/GitHub URL hits via content-matching, has_interviewed_w_hiring_manager correctly populated, comp fields preserved from custom_fields).
  • Auth shape note — Harvest's token endpoint expects credentials via HTTP Basic header, not POST body. dlt's stock OAuth2ClientCredentials uses the latter. The source ships a tiny @configspec subclass overriding build_access_token_request to fix this. Worth confirming whether the dlt-core team would rather absorb that into OAuth2ClientCredentials itself as a client_auth_method='basic'|'post' option, since it's a common deviation across vendors.
  • Legacy auth out of scope — Greenhouse is deprecating Harvest's legacy basic-auth method. OAuth2 client_credentials is the forward path and what the source supports.
  • Tests — I can provide a complete mock-fixture suite for offline CI. Would need an OAuth sandbox cred (or instructions to provision one against an empty Greenhouse trial) for live integration tests against Postgres + DuckDB per the contributing guide.
  • Follow-up contribution — happy to also contribute the matching dbt models (Fivetran-shape-compatible) as a separate dbt-package repo or as dbt_helpers/ if the project accepts that pattern. They're already written and tested in production.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    Status
    Planned

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions