Create or update a job with Harvest API

Permissions: Basic and above who can manage ALL organization's API credentials

Product tier: Available for all subscription tiers

This article outlines the API requests needed in order to create a new job in Greenhouse Recruiting and import all job information from a third-party system through the Greenhouse Harvest API.

Note: This article assumes that you have established API connectivity.

Integration development in Greenhouse Recruiting sandboxes

A Greenhouse Recruiting sandbox isn't a copy of production. A sandbox is a distinct environment, and the settings and data cannot be copied over or moved between a Greenhouse Recruiting sandbox and a production instance. The Greenhouse Recruiting sandbox is a secondary empty production instance that can be used for testing integrations or alternative workflows or settings. It's important to note that Greenhouse Recruiting object IDs (such as job ID, user ID, or custom fIeld IDs) will be different between sandbox and production, and the Harvest API key will be different between sandbox and production instances as well.

Create a new Greenhouse Recruiting job (via POST: Create job)

The POST request can be used only to initially create the job and add the following default field values:

  • Number of openings
  • Job name
  • department
  • office
  • Requisition / opening IDs

You will also need to make a subsequent PATCH: Update Job request to add custom job field values (see: Add custom Job Field Values and Update Existing Jobs).

Only the Greenhouse Recruiting template job ID, number of openings, and job name are required. The template job will be used to populate workflows and objects that cannot be imported via the API (like scorecards or hiring teams), as Greenhouse Recruiting typically is the source of truth for these items.

Note: We strongly recommend including an office and / or department value in the initial POST: Create job request because the offices and departments a job is assigned to can have many dependent workflows in Greenhouse. Check out the Office and department dependent workflows help guide for more information. We recommend reviewing these dependencies with your recruiting team to see if any will be impacted by your integration.

Below are the additional resources typically required to create the POST: Create Job request:

  • GET: List Jobs: to retrieve the job ID values needed to fill the template_job_id
  • GET: List offices: to retrieve the Greenhouse office ID values or external values stored in Greenhouse Recruiting
  • GET: List departments: to retrieve the Greenhouse department ID values or external values stored in Greenhouse Recruiting

Example

curl -X POST \
https://harvest.greenhouse.io/v1/jobs \
-H 'Authorization: Basic *******' \
-H 'Content-Type: application/json' \
-H 'on-behalf-of: 123456 \
-d '{
"template_job_id": 1023578,
"number_of_openings": 2,
"job_post_name": "API Test Job - External Name",
"job_name": "API Test Job",
"external_department_id": “GEN”,
"office_ids": [
61348
],
"requisition_id": "ABC",
"opening_ids": [
"ABC-1",
"ABC-2"
]
}'

Add custom job field values and update existing jobs (via PATCH: Update job)

This can be used to update both default and custom job field values on existing jobs, or to add custom field job values to a new job. To make this PATCH request to update custom job field values, you must:

1. GET: List jobs to pull the Greenhouse Recruiting job ID for the job you need to update. The below example retrieves the job using the requisition_id "ABC-123."

Example

curl -X GET \
'https://harvest.greenhouse.io/v1/jobs?requisition_id=ABC-123' \
-H 'Authorization: Basic *******’ \

2. GET: List custom fields to retrieve all custom job field name keys and available option values for single and multi-select fields

Note: Any single-select or multi-select field values must match an available field option name or ID in Greenhouse Recruiting exactly for the PATCH to be successful.

Example

curl -X GET \
https://harvest.greenhouse.io/v1/custom_fields/job \
-H 'Authorization: Basic *******' \

[
{
"id": 152956,
"name": "Short Textbox Test",
"active": true,
"field_type": "job",
"priority": 11,
"value_type": "short_text",
"private": true,
"required": false,
"require_approval": true,
"trigger_new_version": false,
"name_key": "short_textbox",
"custom_field_options": []
},
{
"id": 284617,
"name": "Cost Center",
"active": true,
"field_type": "job",
"priority": 14,
"value_type": "single_select",
"private": false,
"required": true,
"require_approval": true,
"trigger_new_version": false,
"name_key": "cost_center",
"custom_field_options": [
{
"id": 12302153,
"name": "option 1",
"priority": 0
},
{
"id": 12302154,
"name": "option 2",
"priority": 1
},
{
"id": 12302155,
"name": "option 3",
"priority": 2
},
{
"id": 12302156,
"name": "option 4",
"priority": 3
},
{
"id": 12302157,
"name": "option 5",
"priority": 4
}
]
},...
}
]

Once you have retrieved all the custom field name_keys and custom_field_options, you can use this request to PATCH an existing job’s custom field values. Below is an example including each available custom field type, for reference. The multi-select and single-select fields use text matching to write / update values:

Example

curl -X PATCH \
https://harvest.greenhouse.io/v1/jobs/1019899 \
-H 'Authorization: Basic *******' \
-H 'Content-Type: application/json' \
-H 'on-behalf-of: 123456 \
-d '{
"name": "Updated Job Name",
"department_id":53771,
"external_office_ids": "APAC-1",
"custom_fields":[
{
"name_key":"short_textbox",
"value":"This is a short text field for comments."
},
{
"name_key":"long_textbox",
"value":"This is a long text field for comments exceeding 255 characters."
},
{
"name_key": "cost_center",
"value": "option 4"
},
{
"name_key": "custom_multi_select_field",
"value":
[
"Multi select 1",
"Multi select 2"
]
},
{
"name_key":"recruiter",
"value": 793196
},
{
"name_key": "salary_range",
"min_value": 75000,
"max_value": 95000,
"unit": "USD"
},
{
"name_key": "currency_field",
"value": 87500,
"unit": "USD"
},
{
"name_key": "number_range",
"min_value": 0,
"max_value": 10
},
{
"name_key":"level",
"value":"Mid"
},
{
"name_key": "travel_required_",
"value": "no"
},
{
"name_key": "expiration_date",
"value": "01/01/2020"
},
{
"name_key":"url_example",
"value": "https://testingexample.com"
}
]
}'

Add a job post description (via PATCH: Update job post)

Each Greenhouse Recruiting job can have one or more job posts that can be made live on your careers page. The job must already have a placeholder job post created in order to use this endpoint.

  1. Retrieve the job post ID via GET: List job posts for job.
  2. Make the PATCH: Update job post request:

Example

curl -X PATCH \
https://harvest.greenhouse.io/v1/job_posts/1611527 \
-H 'Authorization: Basic *******' \
-H 'Content-Type: application/json' \
-H 'on-behalf-of: 123456 \
-d '{
"status": "live",
"title": "Ice Cream Vendor",
"location": "New York, NY",
"content": "This is where the job post description should go."
}'

Add a hiring team to a job

Click here for information on how to add a hiring team to a job via Harvest API.

Add a job opening (via POST: Create new openings)

The POST: Create new openings endpoint can be used to add a new opening to an existing job.

Example

curl -X POST \
https://harvest.greenhouse.io/v1/jobs/1019899/openings \
-H 'Authorization: Basic *******' \
-H 'Content-Type: application/json' \
-H 'on-behalf-of: 123456’ \
-d '{
"opening_id": "ABC-3"
}
}'

Edit a job opening (via PATCH: Edit openings)

This endpoint can be used to edit an existing opening on a job. You can close an opening via the API, but you cannot re-open a closed opening via the API.

Note: You need to first GET: List job openings for the job and use the Greenhouse Recruiting opening ID that is returned in the response. You can only PATCH open openings, and you are limited to either updating the opening ID or closing the opening (you can not do both at once). The example below demonstrates how you would close opening ID 2460180. Close_reason_id is an optional field; you can pull the available close reasons via GET: List close reasons.

Example

curl -X PATCH \
https://harvest.greenhouse.io/v1/jobs/1019899/openings/2460180 \
-H 'Authorization: Basic *******' \
-H 'Content-Type: application/json' \
-H 'on-behalf-of: 123456’ \
-d '{
"status": "closed",
"close_reason_id": 18137
}'

Custom job field options

Custom field options can be added and maintained through the API on single-select or multi-select custom job fields. You can find more information about this in the following article: Custom options sync overview.

  • GET: List Custom Fields – retrieve field and option value IDs for PATCH Update Job request.
  • POST / PATCH / DELETE Custom field options – modify option values on an existing custom field.