# Greenhouse API: Which of the 5 APIs to Use (2026)

By Ingrid Kovarová · 2026-11-01 · Source: https://www.activepieces.com/blog/greenhouse-api-which-of-the-5-apis-to-use-2026

---
<aside class="tldr"><p class="tldr-label">Summary</p><p>Greenhouse API requires choosing among five different APIs with varying purposes, credentials, rate limits and permissions; the wrong choice fails at runtime.</p><ul><li>Greenhouse offers five separate APIs: Harvest, Job Board, Ingestion, Assessment, and Onboarding.</li><li>Harvest v3 rate limit is 2.5 requests per second, half the speed of v1/v2.</li><li>A leaked Harvest credential exposes all candidate records that key can access.</li></ul></aside>

The Greenhouse API is a set of HTTP interfaces that let your own systems, or a workflow tool like [Activepieces](https://www.activepieces.com), read and write recruiting data in Greenhouse, the applicant tracking system.

![Workflow tool connected to recruiting data cabinet](https://ap-marketing-media.fra1.cdn.digitaloceanspaces.com/uploads/b5da718f-ec07-42b5-87db-99da91c7f09d/greenhouse-api-which-of-the-5-apis-to-use-2026-i-e399a17e.webp)

Greenhouse grants access per credential, so whoever creates the key also owns what it can touch.

The [Harvest API docs](https://developers.greenhouse.io/harvest.html) are the reference.

## Greenhouse API access and credentials

### What you can build with it

You set Harvest permissions per endpoint and per method when you create the key, so each item below needs its own grant:

- Read candidates, jobs and applications, which needs the matching GET permission for each of those endpoints.
- Write candidates, which needs the POST or PATCH permission on the candidates endpoint.
- Add notes to a candidate, which needs the permission on the notes endpoint, separate from the candidate one.
- Create or change jobs, which needs the write permission on the jobs endpoint.
- Ingest candidates from a partner, which goes through the separate [Candidate Ingestion API](https://developers.greenhouse.io/candidate-ingestion.html) and its own partner credentials, not a Harvest key.

If a key can read applications but can't write notes, it fails only when the workflow reaches the note step. That failure shows up late, and someone has to be able to tell, at 2am, which grant was missing and who can add it.

![Activepieces workflow showing a form response trigger connected to an email validation step with configuration panel open.](https://ap-marketing-media.fra1.cdn.digitaloceanspaces.com/uploads/2e8f0431-a6bb-42ba-b7f1-a198fffc6825/hootsuite-api-setup-authentication-and-docs-2026-087aed1b.webp)

Granting by endpoint is safer, but it makes each workflow's requirements something you have to write down.

### Who can create a key, and on which plan

To create a key, someone with developer-level permission to manage API credentials, usually a site admin, works inside Greenhouse in the [Dev Center](https://developers.greenhouse.io/harvest.html). The docs pages I cited don't name a plan tier for this.

![Activepieces connection setup dialog for Drip integration with API credential fields and vault-based secret management](https://ap-marketing-media.fra1.cdn.digitaloceanspaces.com/uploads/b62b3eb1-2b0c-4fb4-aa9f-41ce51e5d58e/datadog-api-keys-endpoints-and-getting-started-s-3e17d356.webp)

Confirm that your contract includes API access before you build, because a missing entitlement looks the same as a bad key. Decide up front who owns the key, since it ties to that person's role.

[Activepieces](https://www.activepieces.com), which has 746 integrations in its MIT-licensed core, still takes that same Greenhouse key, so the ownership question doesn't go away.

## Greenhouse's separate APIs compared on purpose and auth

Whoever holds the key owns the blast radius, and with Greenhouse that depends on which API the key belongs to, because the five APIs differ in audience, data and credentials.

Picking the wrong one is the first mistake, and it usually surfaces later as a 401 or a missing field at an inconvenient hour.

<blockquote class="pull"><p>Whoever holds the key owns the blast radius, and with Greenhouse that depends on which API the key belongs to, because the five APIs differ in audience, data and credentials.</p></blockquote>

Side by side on the four questions that decide the choice, the five APIs sit in the table below. Read it as a filter: find the row whose audience and data match your job, and the authentication and write access follow from it.

Check the rate limits against Greenhouse's developer documentation on the day you build, since they can change.

| API | Data touched | Intended user | Authentication method | Read-only or writable |
|---|---|---|---|---|
| Harvest | Candidates, applications, jobs, offers, users | Employer | Credentials issued by the employer's Greenhouse account | Both reads and writes |
| Job Board | Published jobs and application submission | Public | Public reads on job data; a credential for submitting applications | Reads, plus submitting applications |
| Ingestion | Candidates sourced from outside Greenhouse | Partner | Partner credentials | Writable |
| Assessment | Test orders and results for candidates | Partner | Partner credentials | Writable |
| Onboarding | New hire and onboarding data | Employer | Credentials issued by the employer's Greenhouse account | Both reads and writes |

Treat the authentication column as a starting point and confirm the exact scheme in the docs before you commit, because that's where hand-built integrations fail first. What follows explains each group in turn.

### Harvest API for internal data

If a Harvest credential leaks, **candidate data leaks with it**, because Harvest is the employer's own door into its hiring records. Name the owner of that key before you write any code.

![Flow History panel showing two versions of a flow with timestamps and status indicators](https://ap-marketing-media.fra1.cdn.digitaloceanspaces.com/uploads/17dfdf51-685f-4316-aaee-1dd5f16dc705/what-is-a-webhook-payload-structure-and-examples-f2789ff4.webp)

Because it reads and writes the records recruiters actually work with, most automation needs this API, and write access means a faulty run can **change live candidate records rather than merely fail** to read them.

### Job Board API for public careers pages

Publishing openings to the public is the whole job of the Job Board API, so it's built for careers pages rather than internal workflows. Job listings are readable without a secret, which is convenient for a website and useless for anything involving candidate pipelines.

If your task needs application stages or internal notes, this is the wrong API, and no amount of retrying will change that.

### Ingestion and partner APIs

For Ingestion and Assessment, the audience is vendors who plug into Greenhouse, such as sourcing tools that push in candidates or test providers that return results. Onboarding is the exception in this group: it serves the employer's own post-hire process.

Greenhouse issues partner credentials through its partner arrangements, so an employer building an internal script generally can't simply generate them. Your job decides the API; the API decides who must hand you the key, which is the next question to settle.

## Authentication steps for Harvest and Job Board APIs

Before anything runs, a Greenhouse admin with Dev Center access creates the credential and scopes it per endpoint. You send it as Basic auth for Harvest v1/v2 or as a bearer token for v3. Someone must own it afterward.

To see which steps need an admin and which are yours, follow the sequence below, which runs from the Dev Center to storage.

1. Open credential management in the Dev Center.
2. Create the credential for the API type you chose.
3. Scope permissions per endpoint.
4. Send it: Basic with the key for v1/v2, an OAuth bearer token for v3.
5. Store the secret.

Each step below says who acts and what breaks if it's skipped.

In Dev Center credential management, an admin creates the credential, and its type must match the API. Record who created it and which team answers when it fails, because the key belongs to that setup and not to you.

Grant only the endpoints your process calls. A credential scoped to candidates can't read jobs, so a missing permission shows up as a rejected call, not a silent gap.

That's the cheaper failure; a broad grant means one leaked key exposes every candidate record it can reach.

### Send the credential correctly

For v1/v2, the key goes in the Basic auth header as the username. For v3, you exchange for an OAuth bearer token that lasts 1 hour, so any scheduled job running longer than that needs refresh handling or it fails mid-run.

![Hour sand timer beside expiring bearer token card](https://ap-marketing-media.fra1.cdn.digitaloceanspaces.com/uploads/665f789d-f503-44c0-8765-4213fb9f9b01/greenhouse-api-which-of-the-5-apis-to-use-2026-i-2ec2d268.webp)

This is the main change between versions. Confirm details against the current Greenhouse developer docs before building.

Store the secret in a secrets manager, never in the workflow definition or a repository, and name its owner.

## A minimal working Greenhouse API request, with pagination

Start with one authenticated GET against the Harvest API's candidates endpoint, and you have a working first request. A correct pagination loop follows the Link header the server returns instead of counting pages yourself.

The key you just put in a secrets manager is what makes the first call possible, so read it from there at run time.

### Making your first Greenhouse Harvest API request

Harvest uses HTTP Basic authentication: the API key is the username and the password is left blank. Export the key from your secrets manager into an environment variable, then call the candidates endpoint with a small page size.

![Command line with API key as username and blank password](https://ap-marketing-media.fra1.cdn.digitaloceanspaces.com/uploads/a476c673-cc87-4f29-b126-135561536320/greenhouse-api-which-of-the-5-apis-to-use-2026-i-a0113f72.webp)

```bash
curl -u "$GREENHOUSE_HARVEST_KEY:" \
 "https://harvest.greenhouse.io/v1/candidates?per_page=10"
```

The trailing colon after the key matters. Without it, curl prompts for a password and a scheduled job hangs with nobody watching. Whoever owns the key owns this failure, so name them in the job's runbook.

### Reading the Greenhouse API response

When the call succeeds, you get a JSON array of candidate objects, each with its own id, name fields, and nested records such as applications. An empty array means you've run past the end or your filters match nothing.

You will see an authentication failure as a 401 status, which almost always means a wrong key or a missing colon.

A 403 means the key is valid but lacks permission for that endpoint, and whoever administers the key's permissions has to fix that; retrying will not.

Check the response headers too, because that's where the pagination instructions live.

### Paging through all Greenhouse API results

To page through everything, use the Link header, which carries rel values such as next and last; the documented loop follows it.

Request the first page with per_page, read the next URL from the header, request that URL exactly as given, and stop when the header has no next link.

Don't rebuild the URL yourself or increment a page number: the server's link is the contract, and hand-built URLs drift when parameters change.

If a run dies partway, you want it to resume rather than re-pull everything or silently skip records. Persist the last URL you completed.

Activepieces lets you skip writing that loop by hand: describe the Greenhouse sync in its built-in chat and it publishes a live flow in your account, the same artifact a builder would have assembled step by step.

The run trace for each execution records what every step received, so the last page requested and the status it returned are on the record rather than inferred.

The flow sits under the same RBAC and audit logs as any other, and MoneyGram, Moneypenny, Alan and FundingSocieties run Activepieces in production.

## Greenhouse API rate limits and quotas as documented

### Documented limits and headers

At 2am the pager goes to whoever assumed one number covered all three, because Greenhouse limits requests per time window and the window differs by API. A resumed run that replays pages too fast hits the ceiling first.

In the chart below, you can read the sustained allowed requests per second for each API. Harvest v1/v2 allows the most, **Harvest v3 half that**, and Audit Log pagination a small fraction.

So a job that pages through audit history needs a much longer schedule than a candidate sync.

| API | Documented window | Sustained rate |
|---|---|---|
| Harvest v1/v2 | 50 requests per 10 seconds | 5 per second |
| Harvest v3 | 75 requests per 30 seconds | 2.5 per second |
| Audit Log pagination | 3 requests per 30 seconds | 0.1 per second |

At Audit Log's rate, roughly one page every ten seconds, a backfill of many pages is a long-running job, not a quick call. A moving Harvest v3 migration shouldn't reuse v1/v2 pacing, because it would exceed its budget.

Go past a limit and you get HTTP 429, and Harvest responses carry limit and remaining headers you can read before the server throttles you.

I haven't confirmed the exact header behavior for every API here, so check the run trace for what actually comes back.

Because Greenhouse revises these by version, verify the figures on the docs page the day you build.

As I have it, Greenhouse's documentation publishes no per-call price and no per-tier request quotas. Treat API access as part of your plan and the limits above as the only documented ceiling.

Ask your Greenhouse account contact whether your contract changes either one before you size a nightly job around it.

## Greenhouse API errors and fixes

Most of the failures you'll be paged for come down to six status codes, and most trace to how the integration was set up rather than to Greenhouse being down.

The table shows what the docs say each code means, what usually causes it in production, and the fix.

| Code | Documented meaning | Usual production cause | Fix | Docs |
|---|---|---|---|---|
| 401 | Authentication failed | Wrong key type, or a key that was revoked | Issue a Harvest key and send it as the Basic auth username | [Harvest API](https://developers.greenhouse.io/harvest.html) |
| 403 | Authenticated, not permitted | Key lacks permission for that endpoint | Grant the endpoint permission on the key | [Harvest API](https://developers.greenhouse.io/harvest.html) |
| 404 | Resource not found | Wrong ID or deleted record | Verify the ID, then stop retrying | [Harvest API](https://developers.greenhouse.io/harvest.html) |
| 422 | Request could not be processed | Bad payload, or missing On-Behalf-Of on a write | Correct the body and send the header | [Harvest API](https://developers.greenhouse.io/harvest.html) |
| 429 | Rate limit exceeded | Burst of calls from a nightly job | Back off, then resume | [Harvest API](https://developers.greenhouse.io/harvest.html) |
| 5xx | Server-side error | Greenhouse-side fault | Retry later, then escalate | [Harvest API](https://developers.greenhouse.io/harvest.html) |

Read the table by who owns the fix: the first four are yours, and only the last two may clear without a change on your side.

When you get a 401, the key is usually the wrong kind for the API you called, so confirm the key type before regenerating anything. A 403 means the key is valid but was never granted that endpoint.

Name the person who owns the key's permissions, because they're the one who must change it.

When the body is malformed, or when the On-Behalf-Of header (which names the Greenhouse user the action is attributed to) is missing, writes fail. Log the response body, since it says which field was rejected.

Retry a 429 with increasing delays rather than a fixed loop. Be careful with writes: a retried create can duplicate a record if the first attempt actually succeeded. Check for the record before you resend.

## Call the Greenhouse API without code with Activepieces

Activepieces can call the same Greenhouse endpoints with the same credential, through its Greenhouse integration or its HTTP step, with no code to maintain.

**Flows are unlimited on every plan, including free**, and a run costs 1 credit however many steps it has, so a candidate sync is priced by its runs rather than its step count.

![Activepieces workflow builder showing a multi-step automation with an HTTP request step configuration panel open on the…](https://ap-marketing-media.fra1.cdn.digitaloceanspaces.com/uploads/a5180460-e385-4bee-8927-f2b3b0530b63/google-ads-api-access-levels-costs-and-setup-202-39596d54.webp)

### Using the same credential in a workflow

Who owns the sync when it fails at 2am? With a script, that's whoever wrote it. In a workflow, it's whoever owns the flow, and the run history shows which step failed and what it received.

Authentication, retries and paging then live in a visible step rather than in code someone has to remember.

### Finding the Greenhouse step in the builder

In the builder, that looks like this.

Below, a three-step flow (an Every Hour trigger, an Ask ChatGPT action, an End node) sits on the canvas, and the open "Select Step" panel, searched for "sheet", lists spreadsheet integrations such as Google Sheets and Microsoft Excel 365.

![Activepieces flow builder showing a piece selector panel with spreadsheet app options filtered by search term "sheet"](https://ap-marketing-media.fra1.cdn.digitaloceanspaces.com/uploads/04948e09-900a-4544-98d6-20b39b03d6fb/self-host-deepseek-r1-for-private-automation-202-1b88673a.webp)

Finding a Greenhouse integration is a search, not a build, since each app is a selectable integration.

Once you pick a step, check the Greenhouse integration page for which actions it supports, such as reading candidates or applications.

### Falling back to the HTTP step, and budget

If the action you need is missing, the HTTP step can call the endpoint directly with the credential you already created. Either way, confirm the integration or HTTP request uses the same key or token type your Greenhouse plan grants.

![Activepieces workflow builder with HTTP request step selected and its settings panel open showing method, URL, headers, and…](https://ap-marketing-media.fra1.cdn.digitaloceanspaces.com/uploads/9e36e973-de4a-435f-8912-12e666216b2d/self-host-mistral-ai-enterprise-deployment-guide-3f7fe28d.webp)

Budget matters too. [Activepieces](https://www.activepieces.com/blog/activepieces-cloud-pricing-plans-2026-price-guide) cloud pricing is credit-based, with Free, Plus, Team, Ultimate and Embed tiers, and flows are unlimited on every one of them.

The self-hosted Community edition is free under the MIT licence, and enterprise governance is quoted by sales, so check the live pricing page at https://www.activepieces.com/pricing before you commit a workload.

### When to stay in code

Stay in code for bulk backfills and high-volume syncs.

Loading years of candidate history means thousands of paged requests, and a per-step workflow adds overhead to each one while giving you less control over backoff when Greenhouse limits you, so you'll get throttled before loading all the candidates.

![Activepieces workflow builder with the Send HTTP request step selected, showing its configuration panel with HTTP method…](https://ap-marketing-media.fra1.cdn.digitaloceanspaces.com/uploads/58352882-31ce-42ab-9b0f-c4a0fe866a5c/deepseek-r1-vs-v3-for-business-ai-2026-guide-scr-ae99964b.webp)

A script you run once, with explicit pacing and checkpoints, is easier to reason about and cheaper to rerun. Use the workflow for the steady, small, ongoing syncs after the backfill is done.

## Frequently asked questions

### Is the Greenhouse API free?

You can't check the API out online as a separate product, because Greenhouse doesn't sell it that way. Access depends on your account's plan and on an admin creating credentials for you.

Before you build, ask whoever owns the Greenhouse contract whether API access is included, because the answer decides who approves the key and who is accountable when it stops working. Confirm the terms in Greenhouse's developer documentation or with your account representative.

### Does Greenhouse support webhooks instead of polling?

Yes. Greenhouse can send webhooks for events such as a candidate being hired or an application changing stage. You configure them in the Dev Center with an endpoint you control.

Use webhooks to learn that something changed, and keep a scheduled API read as the safety net.

When a webhook endpoint is down at 2am on a Tuesday, it doesn't replay what it missed on its own, so decide up front who is paged and how a gap gets reconciled.

### Is there a sandbox for testing the Greenhouse API?

Greenhouse provides sandbox environments, but availability depends on your account arrangement, so ask your account contact rather than assuming one exists. If you get one, treat it as separate from production: its credentials, candidates, and webhook targets are all distinct.

**Never point a test workflow at production credentials because the sandbox request is still pending.** A test that writes to real candidate records is an incident, and the person who owns the production account will be the one to explain it.

### Which Greenhouse API version should a new integration use?

Use v3. The older v1 and v2 interfaces are being retired, so **anything built on them becomes a migration project** you have scheduled for yourself.

v3 also changes how you authenticate, so build against its token flow from the first commit rather than retrofitting it. Check Greenhouse's developer documentation for the current retirement status of the older versions before you commit to anything.

## Related reading

- [Greenhouse Pricing 2026: Plans and What Each Costs](https://www.activepieces.com/blog/greenhouse-pricing-2026-plans-and-what-each-costs)
- [Best Tools for Citizen Developers in 2026](https://www.activepieces.com/blog/tools-for-citizen-developers-in-2024)
- [Best AI Agent Builders for Sales Teams, Ranked](https://www.activepieces.com/blog/best-ai-agent-builders-for-sales-teams-ranked)

## References

- [AgentGid](https://agentgid.com/pricing/history/activepieces/)
