Greenhouse will schedule your interviews for you. It will not tell you that a candidate has been sitting in Take Home Test for eleven days, or that Tuesday's onsite finished and nobody has filed a scorecard. Those are the two failures that quietly stall a pipeline, and both are visible through the Harvest API. A scheduled agent that walks your active applications, flags the stalls, and posts a short digest closes the gap that the ATS itself does not cover. It sits alongside the other jobs on our roundup of AI agents for recruiters, but it is the one most teams never think to build.

A Greenhouse hiring pipeline with stalled candidates and missing scorecards flagged for a recruiter
What Greenhouse already automates, and where it stops

What Greenhouse already automates, and where it stops

Start here, because it decides whether you should build anything at all. Greenhouse's scheduling features are mature, and a post telling you to replace them would be wasting your time. What follows is the honest boundary.

Greenhouse handles the booking side natively:

What none of that does is notice absence. Every one of those features fires when a human starts a scheduling action. Nothing fires when a human does nothing, and "nobody did anything" is precisely the state that hurts a pipeline. A candidate who was never moved out of a stage generates no event, no notification, and no calendar entry. They simply age. It is the same blind spot we hit in Jira backlog grooming, where the tickets that cause trouble are the ones nobody opened.

Where the native features end and a scheduled agent starts
JobGreenhouse nativeNeeds an agent
Find a time that works for four interviewersYes, pooled availabilityNo
Let the candidate pick a slotYes, self-schedulingNo
Protect prep time around interviewsYes, buffersNo
Notice a candidate untouched for 10 daysReports exist, but you must open themYes, on a schedule
Chase a scorecard nobody submittedStatus is visible per interviewYes, aggregated and ranked
Deliver one weekly digest into SlackNoYes

The two signals worth watching

Pipeline hygiene sounds vague until you reduce it to queries. Two signals cover most of the damage, and both map to a specific Harvest field rather than a heuristic you have to invent.

Stalled applications

GET /v1/applications takes a last_activity_after parameter that returns only applications whose last_activity_at falls at or after a timestamp. Invert it: ask for active applications, then keep the ones whose last activity is older than your threshold. The status parameter accepts active, converted, hired, and rejected, so filtering to active removes the closed records that would otherwise dominate the list. Pagination runs up to 500 records per page.

Interviews awaiting feedback

This is the one most teams try to infer and get wrong. You do not need to diff completed interviews against submitted scorecards. Greenhouse already models the state: a scheduled interview carries a status, and awaiting feedback is one of the values it can hold. GET /v1/scheduled_interviews supports ends_before, so "interviews that finished before yesterday and are still awaiting feedback" is a single filtered query.

If you want the confirming half, GET /v1/applications/{id}/scorecards lists all submitted scorecards for an application. Absence from that list is the missing scorecard. Use it as a cross-check on the interviews you have already flagged, not as your primary scan, because it costs one call per application.

The Harvest primitives it needs

The whole agent is built from five endpoints and one auth header. Nothing here requires a Greenhouse Marketplace partnership.

Authentication is HTTP Basic over HTTPS. The username is your Harvest API token and the password is blank, which in curl means a trailing colon after the token. Unauthenticated requests return 401.

Rate limiting is header-driven rather than a fixed published number: responses carry X-RateLimit-Limit and X-RateLimit-Remaining, and the window is per 10 seconds. Exceeding it returns 429 with Retry-After and X-RateLimit-Reset telling you when to resume. Read those headers rather than hardcoding a sleep, because unlisted vendors can be subject to additional limits.

The permission trap worth knowing before you start

This is the detail that changes how you scope the project, and it is stated plainly in Greenhouse's own documentation: access to data in Harvest is binary. A key that can read an endpoint can read all the data in that endpoint. There is no per-job or per-department narrowing inside a key.

What you can control is which endpoints a key touches at all. Keys created after 18 January 2017 start with no endpoint permissions and must be granted each one explicitly, from Configure, then Dev Center, then API Credential Management. Creating a Harvest key at all requires the "Can manage ALL organization's API Credentials" developer permission.

Three consequences for a hygiene agent:

What we ran, and what surprised us

We built this scan against a test Greenhouse org seeded with a few dozen applications across several stages, then ran it daily for a fortnight to see what a real digest would look like. Three things were not what we expected.

First, the stall list was front-loaded with noise on day one. Every application older than the threshold appeared at once, including ones that were legitimately parked. A first run against a real pipeline is a backlog report, not a daily digest. Suppress the first run, or mark everything it finds as acknowledged, or the recruiter's reaction to a 60-item list will be to ignore the whole thing.

Second, the awaiting feedback signal was far cleaner than the stall signal. Missing scorecards are unambiguous: the interview ended, the feedback is not in, and someone specific owes it. Stalls are ambiguous, because "no activity for ten days" describes both a forgotten candidate and one who is waiting on a scheduled onsite next week. We ended up ranking missing scorecards above stalls in the digest for that reason alone.

Third, threshold choice mattered more than anything in the summarising step. At seven days the digest was too long to read. At fourteen it was short but arrived after the damage. The useful version was stage-aware: a short threshold for stages that should move fast, a longer one for stages that legitimately wait on a candidate. The same ranking discipline decides whether a digest survives contact with a real inbox, which we ran into building Microsoft Teams message summaries.

How to set one up

Working order, assuming you have the developer permission to create a key:

  1. Create a read-scoped Harvest key. Dev Center, API Credential Management, then grant only applications, scheduled interviews, and scorecards read access.
  2. Pick thresholds per stage. Write them down as a small table before you write any logic; this is a hiring-process decision, not an engineering one.
  3. Scan interviews first. Query scheduled interviews with ends_before set to yesterday, keep those still awaiting feedback, and resolve each to its application and interviewer.
  4. Scan applications second. Query active applications, keep those whose last_activity_at is older than the stage threshold, and drop any that already appeared in the interview scan.
  5. Rank and cut. Missing scorecards first, then stalls by age. Cap the digest length; a list nobody finishes is a list nobody acts on.
  6. Deliver where the work happens. Slack or email beats a note inside Greenhouse, because the point is to reach someone who is not currently looking at Greenhouse.
  7. Suppress the first run and re-run on a weekly cadence before considering daily.

With Gravity you describe that outcome in plain words and the agent runs on the schedule you set, so the part you own is the threshold table and the delivery target, not the polling loop or the pagination.

When you should not build this

Skip it if any of these describe you:

If outreach rather than hygiene is your bottleneck, LinkedIn Recruiter outreach is the job to automate first, and it is a different shape of agent entirely.

What it costs

The API calls themselves are free; Harvest access is included with Greenhouse, and the constraint is the rate limit rather than a per-call charge. Cost lives in whatever runs the agent on a schedule.

A weekly scan of a few hundred active applications is a handful of paginated calls plus a small number of per-application confirmations, which is trivial against a limit measured per 10 seconds. Costs only become real if you run it hourly across thousands of applications and fan out a scorecard check per record, which is the pattern to avoid: filter first, confirm second.

On Gravity, the free tier runs one agent at $0 per month, which is enough for a single weekly hygiene scan. Paid plans start at $20 per month and include $20 of usage, with extra usage available beyond your plan if you add more agents or move to a daily cadence. If you are still choosing a platform, our comparison of the cheapest AI agent platforms prices the same scheduled-scan workload across the alternatives, and what an AI agent actually is covers the distinction between this and a workflow rule. Recruiting is one of many roles in our index of AI agents for every profession.

Frequently asked questions

Does Greenhouse have an API for interview scheduling?

Yes. Scheduled interviews can be created with POST /v2/scheduled_interviews and updated with PATCH /v2/scheduled_interviews/{id}. The V1 versions of both were deprecated on 5 April 2020 and should not be used. Reading is still on V1: GET /v1/scheduled_interviews/{id} and GET /v1/applications/{id}/scheduled_interviews.

How do I find candidates who have gone quiet in Greenhouse?

Query GET /v1/applications with status=active, then filter on the last_activity_at field. The endpoint also accepts last_activity_after directly, which is useful for incremental scans where you only want records that moved since your last run.

Can an agent tell me which scorecards are missing?

Yes, and you should use the native status rather than inferring it. Scheduled interviews can hold an awaiting feedback status, which marks exactly this state. GET /v1/applications/{id}/scorecards returns only submitted scorecards, so it works as a per-application confirmation.

Does the agent need write access to Greenhouse?

No, and it is better if it does not have it. Every signal described here is a read. Only posting a note back into the candidate's activity feed requires a write permission, and delivering the digest to Slack or email avoids even that. Because Harvest access is binary within an endpoint, each permission you skip is a meaningful reduction in what a leaked key could do.

Is this different from a Greenhouse report?

Yes, in when it runs. Greenhouse reports answer a question when you open them, which means they cover the pipelines somebody remembered to check. A scheduled agent runs whether or not anyone logs in, and delivers into the channel where the recruiter already works. The data is largely the same; the difference is that one requires attention and the other supplies it.

Will this work on every Greenhouse plan?

It depends on your Harvest API access and your developer permissions rather than on the scheduling features, since the agent reads data rather than using the scheduling flows. Confirm you can reach API Credential Management in the Dev Center before you plan the build.

Sources