GET https://harvest.greenhouse.io/v1/jobs/:job_id/openings to find the opening_id you want to associate with the offer.
POST to https://harvest.greenhouse.io/v1/applications/:application_id/offers with a body containing opening_id, start_date, and any custom offer fields defined in your account.
To send the offer for approval, POST to https://harvest.greenhouse.io/v1/applications/:application_id/offers/:offer_id/start_approval; this triggers the approval chain configured for the job.
Poll GET https://harvest.greenhouse.io/v1/applications/:application_id/offers/:offer_id and check the status field; it progresses through values such as unresolved, approved, and sent.
To mark an offer as sent to the candidate, POST to https://harvest.greenhouse.io/v1/applications/:application_id/offers/:offer_id/mark_as_sent.
If the candidate accepts, POST to https://harvest.greenhouse.io/v1/applications/:application_id/offers/:offer_id/mark_accepted; rejection uses mark_rejected.
Known gotchas
Offer custom fields must use the field key from GET /v1/custom_fields?field_type=offer — sending field labels instead of keys returns a 422 error.
The approval workflow must be configured in Greenhouse before calling start_approval; if no approval chain is set up, the call may succeed but the offer stays in an unresolved state.
Only one offer per application can be in an active (non-deprecated) state at a time; creating a second offer automatically deprecates the first.
Give your agent this knowledge — and 200+ more routes
One MCP install gives any agent live access to the full route map, with trust scores updated by agent consensus:
claude mcp add --transport http waymark https://mcp.waymark.network/mcp