Offers

Create offer

Create a new offer on an existing application. application_id is always required; starts_on and custom_fields (compensation components plus any offer custom fields configured on the hiring plan) are optional in the schema, but organization configuration may require more: offer custom fields marked as required must be provided in custom_fields (a 422 response names the missing fields), starts_on must be provided when the Start Date field is marked required, and opening_id must be provided when your organization requires an opening on offers. opening_id must be an open opening on the application's job that no other unresolved offer holds. Discover the organization's offer fields — including required and name_key — via GET /v3/custom_fields?field_type=offer&active=true. The new offer is created with status=Created at version=1. If the application already has an offer, the submission is applied to the same offer chain rather than creating a competing record: a new version is created — and the prior version marked Deprecated — only when a version-triggering field changes, namely starts_on (when your organization enables offer versioning on start-date changes) or a compensation/offer custom field configured to trigger a new version; otherwise the current offer is updated in place. Approval flows configured for the hiring plan are attached automatically — partners must drive the approval through /v3/approval_flows before the offer can be sent to the candidate. Offers carry private compensation data, so writing them is gated separately from the harvest:offers:create scope: when the access token includes a sub claim, the Site Admin it names must also hold the "See private notes, private fields, salary info, manage offers, request approval, and approve jobs/offers" advanced permission, or the request is rejected with 403 Forbidden. Tokens issued without a sub claim act as your integration user and are not subject to it.

post/v3/offers

Request

  • Base URL
    https://harvest.greenhouse.io
  • URL
    https://harvest.greenhouse.io/v3/offers
  • Auth
    • OAuth 2
      Authorization code: https://auth.greenhouse.io/authorize
      Client credentials
      Token URL: https://auth.greenhouse.io/token scopes: harvest:offers:create
    • or HTTP bearer

Request body

application_idinteger required

Id of the application this offer is being extended on. Required.

starts_onstring date

Candidate's proposed start date, in ISO 8601 (YYYY-MM-DD). Required when the organization marks the Start Date offer field as required.

opening_idinteger

Id of the opening this offer is for. Must be an open opening on the application's job that no other unresolved offer holds; otherwise the request fails with a 422. Required when the organization requires an opening on offers. List the job's openings via GET /v3/openings?job_ids={id}&open=true.

Response

Successful

idinteger
created_atstring date-time
updated_atstring date-time
versioninteger

Revision number of this offer within its application. Greenhouse creates a new offer row (incrementing version) whenever a tracked field on an existing offer changes — typically starts_on, opening_id, or a custom field configured to trigger a new version. Pair with current_only=true to filter the list endpoint down to the latest version per application.

application_idinteger

Id of the application this offer is extended on. Every offer belongs to exactly one application; the offer is voided if the application is rejected or deleted.

job_idinteger

Id of the job this offer's application is on.

candidate_idinteger

Id of the candidate (person) receiving this offer. Resolved through the offer's application.

opening_idinteger nullable

Id of the specific opening this offer is being extended for. null when the offer has not yet been linked to an opening.

status'Created' | 'Accepted' | 'Rejected' | 'Deprecated'

Lifecycle status of the offer. Created for offers still being drafted or pending approval, Accepted once the candidate accepts, Rejected if declined or withdrawn, and Deprecated for superseded prior versions (a new offer version replaces an earlier one with this status).

starts_onstring date nullable

Candidate's proposed start date, in ISO 8601 (YYYY-MM-DD). null when no start date has been set on the offer.

sent_onstring date nullable

Date the offer was sent to the candidate, in ISO 8601 (YYYY-MM-DD). null until the offer has been sent.

resolved_atstring date-time nullable

Timestamp the offer was resolved (Accepted or Rejected), in ISO 8601. Date updates submitted through PATCH /v3/offers/{id} are normalized to noon UTC on the supplied date. null while the offer is still Created or has been superseded as Deprecated without a resolution.

custom_fieldsobject nullable

Changes

No recorded changes to this operation across all 1 revision of this API.