Introduction
The Candidate Ingestion API enables sourcing partners with whom Greenhouse shares mutual customers to submit prospects and candidates.
The API allows partners to:
- Send candidates from the partner application to Greenhouse.
- Retrieve the current stage and status of candidates.
- Retrieve jobs on which the Greenhouse user is allowed to operate.
Note: The organization must be able to create prospects in order to create prospects using the Candidate Ingestion API.
Authentication
This API offers two methods of authentication: OAuth 2.0 and Basic Auth.
Authentication via OAuth 2.0
If the mutual customer’s users have accounts in both Greenhouse and the partner’s system, the preferred authentication method is OAuth 2.0. In this case, the partner would place an integration option on their website which would allow the user to authenticate in to Greenhouse via the partner’s application. This is similar to allowing people to register for a website using Facebook credentials. For a partner to configure this, they must supply Greenhouse with the following information:
- Application Name: The name of the application as it would appear in Greenhouse.
- Application URL: The URL to the primary application.
- Callback URL: This is the URL to which Greenhouse will send authenticated users.
- Logo Image: This is a 128x128 image that will be included in the permissions modal.
When Greenhouse receives this information, we will supply the partner with a consumer key, a consumer secret, a token URL, and an authorize URL. For example:
Attribute | Example Value |
---|---|
Consumer Key | bMipe4KWf987654321GrLG1Nfk1234567UshvloD |
Consumer Secret | LQdulabcdefghijklEZok2fE5xGzeBcDa123gNXtN |
Token URL | https://api.greenhouse.io/oauth/token |
Authorize URL | https://api.greenhouse.io/oauth/authorize |
The partner should use this information to initiate an OAuth 2.0 flow in their application. Note the customer user can rescind this at any time.
When the user attempts to connect with Greenhouse, they will see a prompt asking them to confirm the connection. This prompt will then associate the user’s account in the partner system with their Greenhouse account.
Once the OAuth process is complete and the user grants the partner permission to access their data on Greenhouse, the partner will receive an access token. This access token must be included in the Authorization header:
Authorization: Bearer <access_token>
Authentication via Basic Auth
If your users only have an account in Greenhouse and you will be submitting candidates as a partner (and not sourced by a user), you will likely want to authenticate via HTTP Basic Authentication. Users do not have to take any action to authorize your application to modify Greenhouse data. When using basic auth, you are required to set the On-Behalf-Of header for every request. The value should be the e-mail address of the user on behalf of whom you are taking action. For example:
On-Behalf-Of: john.smith@example.com
Normally, this will be a service user created specifically for this purpose. If this header is missing, or Greenhouse doesn't recognize the address, the API will issue a 401 Unauthorized response. The application must also supply the API key. Via basic auth, you will include the API key as the basic auth username and nothing as the password. Since only a username needs to be provided in our case, you’ll need to append a : (colon) to the API token and then Base64 encode the resulting string. This may be included via URL:
https://<base64_encoded_api_key>:@api.greenhouse.io/v1/partners/candidates
or as an authorized header:
Authorization: Basic base64_encoded_api_key:
In all cases, the customer will have supplied the partner with a Partner API Key and a service user. Both items are required to submit candidates.
Note: Capabilities with the Ingestion API will be limited to the permissions of the On-Behalf-Of user
There are four user types, Site Admin, Job Admin, Interviewer, and Basic.
Site Admins have access to all jobs by default, whereas Job Admins/Interviewers are assigned to specific jobs. Job Admins/Interviewers will only be able to retrieve jobs via the API that they are assigned access to, or that are live on the company's job board. However they can add Candidates to jobs they have access to, as well as jobless Prospects to Greenhouse.
Because all user permissions are job-based, in order to retrieve jobless Prospects from the API, Site Admins, Job Admins, and Interviewers need the additional Greenhouse permission to manage jobless Prospects. Otherwise, they can only add Prospects, and not retrieve them. This is true of the UI as well.
Basic users have the most restrictions, since their abilities in the UI are also very limited:
Basic users can:
- Retrieve jobs
- Retrieve information about the current user
- Create prospects on no jobs
- Create candidates on jobs
They can't:
- Retrieve prospects
- Retrieve candidates
- Create a tracking link
OAuth Scopes
If you use OAuth for authentication, there are 3 permission scopes to be aware of. Some endpoints will require a specific permission scope while others require none.
candidates.create
: Create new candidates or prospectscandidates.view
: View candidates imported via this partnerjobs.view
: View my jobs.
General considerations
Unless otherwise specified, API methods generally conform to the following:
- Properties without a value will use
null
instead of being undefined - "Snake Case" is used for attribute names (e.g.
first_name
) - We reserve the right to add more properties to objects, but will never change or remove them
Ingestion API Change Log
The timestamps below are Eastern Time.
Date | Description |
---|---|
Oct 7, 2024 | Updated favicon, github mark, and color palette. Fixed typos and formatting errors. |
Apr 15, 2021 03:00:00PM | Added full_name and id to the [GET current_user] response |
Aug 22, 2019 11:00:00AM | Added Change Log and General Consideration sections to the Ingestion API documentation |
Candidates
Retrieve Candidates
curl 'https://api.greenhouse.io/v1/partner/candidates'
-H "Authorization: Basic MGQwMzFkODIyN2VhZmE2MWRjMzc1YTZjMmUwNjdlMjQ6"
{
"candidate_ids": 17681532
}
API Response
{
"id": 17681532,
"name": "Harry Potter",
"external_id": "24680",
"applications": [
{
"id": 59724,
"job": "Auror",
"status": "Active",
"stage": "Application Review",
"profile_url": "https://app.greenhouse.io/people/17681532?application_id=26234709"
}
]
}
Retrieve a candidate's data. Note that this call will only return candidates that the current user has permission to view.
GET https://api.greenhouse.io/v1/partner/candidates
scope: candidates.view
Request Parameters
The request should contain a single query parameter that specifies a comma-delimited list of candidate IDs or a single candidate ID. If you provide any candidate ids that don't exist or to which you do not have access, this endpoint will ignore them and only return the candidates that exist to this API key or Bearer token, or will return an empty response if you have only supplied one candidate ID.
An empty array will be returned for "Retrieve Candidates" requests with a single candidate ID for the following use-cases:
- Permissions changes made on a Greenhouse user account associated to the email address used to authenticate the request (e.g. User has been disabled or deprovisioned).
- The candidate is on a job that the user account/email address doesn't have access to. Note that the user account must be at least a job admin on the job associated to the candidate ID. If added as a prospect, the user must have the permission to manage unattached prospects.
- The candidate profile was manually deleted by the organization.
- The source on the candidate profile was manually changed to a new source different from the original partner source.
- The candidate has been merged with another profile generating a new candidate ID.
If you would like more information about why you are not able to access a specific candidate ID, please contact the customer for more details, as Greenhouse Support will not share candidate details without the permission of the organization that owns the candidate record.
Query Parameter Name | Required | Description |
---|---|---|
candidate_ids | Yes | Comma-delimited list of Candidate IDs (e.g. 123, 456) |
Response Parameters
The response will always be an array of objects, even if only one candidate_id
is provided.
Property Name | Type | Description |
---|---|---|
id | Integer | The ID of the candidate |
external_id | String | The external ID that was provided in your initial candidate creation request. Can be null if you request the status of a candidate not associated with an external entity. |
applications[] | Array | An array containing 0 or more applications representing the jobs to which this candidate has applied. Each of the sub-elements are required for each of the applications. |
applications.id | Integer | The ID of the application. |
applications.job | String | Name of the job this application is for (e.g. "Software developer). |
applications.status | String | The candidate’s current status. Must be one of "rejected," "active," or "hired." |
applications.stage | String | The applicant’s current stage in the interview pipeline (e.g. "Recruiter Phone Screen"). |
applications.profile_url | String | A URL to the candidate’s profile in Greenhouse. You must be signed in to Greenhouse to view the profile. |
Post Candidates
curl -X POST 'https://api.greenhouse.io/v1/partner/candidates'
-H "Authorization: Basic MGQwMzFkODIyN2VhZmE2MWRjMzc1YTZjMmUwNjdlMjQ6"
-H "Content-Type: application/json"
{
"prospect": "true",
"first_name": "Harry",
"last_name": "Potter",
"company": "Hogwarts",
"title": "Student",
"resume": "https://hogwarts.com/resume",
"phone_numbers": [
{
"phone_number": "123-456-7890",
"type": "home"
}
],
"emails": [
{
"email": "hpotter@hogwarts.edu",
"type": "other"
}
],
"social_media": [
{
"url": "https://twitter.com/hp"
}
],
"websites": [
{
"url": "https://harrypotter.com",
"type": "blog"
}
],
"addresses": [
{
"address": "4 Privet Dr",
"type": "home"
}
],
"job_id": 12345,
"external_id": "24680",
"notes": "Good at Quiddich",
"prospect_pool_id": 123,
"prospect_pool_stage_id": 456,
"prospect_owner_email": "prospect_owners_email@example.com"
}
API Response
{
"id": 12345,
"application_id": 17681532,
"external_id": "24680",
"profile_url": "https://app.greenhouse.io/people/17681532?application_id=26234709"
}
Create one or more candidates or prospects
POST https://api.greenhouse.io/v1/partner/candidates
scope: candidates.create
Request Parameters
Property Name | Type | Required | Description |
---|---|---|---|
prospect | Boolean | No | True if this candidate should be a prospect. The organization must be able to create prospects to set this field. (Default: true) |
job_id | Integer | Mixed | Required only if prospect is false. The ID of the job to which this candidate or prospect should be added. |
first_name | String | Yes | |
last_name | String | Yes | |
external_id | String | Yes | The unique id of this candidate in your application’s system. |
company | String | No | Candidate's current company |
title | String | No | Candidate's current title |
resume | String | No | URL to the candidate’s resume. Greenhouse will attempt to ingest the document at this URL and add it to the candidate record. |
phone_numbers[] | Array | No | |
phone_numbers.phone_number | String | Mixed | Only required if phone_number is included. |
phone_numbers.type | String | Mixed | Must be "mobile", "home", "work", or "other." Only required if phone_number is included. |
emails[] | Array | No | |
emails.email | String | Mixed | Note: Only required if email is included. |
emails.type | String | Mixed | Must be "personal", "work", or "other". Only required if email is included. |
addresses[] | Array | No | |
addresses.address | String | Mixed | A free form block of text, which may include newlines ("\n"). Only required if addresses are included. |
addresses.type | String | Mixed | Must be "home", "work", or "other". Only required if addresses are included. |
social_media[] | Array | No | |
social_media.url | String | Mixed | Note: Only required if social media urls are included. |
websites[] | Array | No | |
websites.url | String | Mixed | Note: Only required if websites are included. |
websites.type | String | Mixed | Must be either “personal”, “company”, “portfolio”, “blog”, or “other”. Only required if websites are included. |
referrer | Object | No | If present, this value will be used to populate the "Who Gets Credit" field for the candidate’s application. If omitted, the "Who Gets Credit" field will be populated with the current user’s information. |
referrer.email | String | Mixed | Used to match this referrer with an existing Greenhouse user, if possible. Only required if referrer is included. |
referrer.first_name | String | Mixed | Used to create a new ‘Referrer’ in Greenhouse if referrer.email does not match an existing user. Only required if referrer is included. |
referrer.last_name | String | Mixed | Used to create a new ‘Referrer’ in Greenhouse if referrer.email does not match an existing user. Only required if referrer is included. |
notes | String | No | Free-form plain-text notes about this candidate. One way for this to be used is to send secondary information that our API can’t capture as structured data. For example: "Skills: Java, C++, Python" |
prospect_pool_id | Integer | Mixed | Used to put a prospect in the Prospect Pool with this id. Only required if prospect_pool_stage_id is included. "prospect" property must be set to true. |
prospect_pool_stage_id | Integer | No | Used to put a prospect in the Prospect Pool Stage with this id. The stage must belong to the prospect pool provided in prospect_pool_id. "prospect" property must be set to true. |
prospect_owner_email | String | No | Used to set the prospect owner for a prospect by providing a valid user's email that exists in Greenhouse. "prospect" property must be set to true. |
Response Parameters
The API will respond with a single object if a single object was provided or an array of objects if an array was provided.
Property Name | Type | Description |
---|---|---|
id | Integer | The ID of the newly created candidate in Greenhouse. |
application_id | Integer | The ID of the application implicitly created in Greenhouse. |
external_id | String | The external ID that was provided in your request. |
profile_url | String | A URL to the candidate’s profile within Greenhouse. The user must be signed into Greenhouse to view the profile. |
Current User
Retrieve Current User
curl 'https://api.greenhouse.io/v1/partner/current_user'
-H "Authorization: Basic MGQwMzFkODIyN2VhZmE2MWRjMzc1YTZjMmUwNjdlMjQ6"
API Response
{
"full_name": "Ron Weasley",
"first_name": "Ron",
"last_name": "Weasley",
"email": "rweasley@hogwarts.edu",
"id": 1234
}
Retrieve details about the current user
GET https://api.greenhouse.io/v1/partner/current_user
Request Parameters
This request is simply the URL. It takes no parameters.
Response Parameters
Property Name | Type | Description |
---|---|---|
full_name | String | The current user's full name |
first_name | String | The current user's first name |
last_name | String | The current user's last name |
String | The email address associated with the current user | |
id | Integer | The ID of the current user |
Jobs
Retrieve Jobs
curl 'https://api.greenhouse.io/v1/partner/jobs'
-H "Authorization: Basic MGQwMzFkODIyN2VhZmE2MWRjMzc1YTZjMmUwNjdlMjQ6"
API Response
[
{
"id": 146859,
"name": "Auror",
"status": "open",
"public": true
},
{
"id": 150050,
"name": "Professor",
"status": "open",
"public": true
},
{
"id": 147886,
"name": "Caretaker",
"status": "open",
"public": false
}
]
Retrieve jobs that are visible for the current user, including all jobs listed on their organization’s public careers page and unpublished jobs the user can access.
GET https://api.greenhouse.io/v1/partner/jobs
scope: jobs.view
Request Parameters
This request is simply the URL. It takes no parameters.
Response Parameters
Property Name | Type | Description |
---|---|---|
id | Integer | The ID of the job. |
name | String | The name as it appears in Greenhouse, NOT necessarily how it appears on the public job board. |
status | String | Always ‘open’. |
public | Boolean | True if this job has any job posts that are currently live on any job board. |
Tracking Link
Post Tracking Link
curl -X POST 'https://api.greenhouse.io/v1/partner/tracking_link'
-H "Authorization: Basic MGQwMzFkODIyN2VhZmE2MWRjMzc1YTZjMmUwNjdlMjQ6"
-H "Content-Type: application/json"
{
"job_id": 12345
}
API Response
{
"tracking_link": "http://grnh.se/yvj0bj",
"job": "Auror",
"source": "Campus Recruiting",
"referrer": "Hermione Granger"
}
Create a new tracking link for a specific job. Candidates that apply using this tracking link will automatically have their source set to your application and their referrer set to the current user.
POST https://api.greenhouse.io/v1/partner/tracking_link
Request Parameters
Property Name | Type | Required |
---|---|---|
job_id | Integer | Yes |
Response Parameters
Property Name | Type | Description |
---|---|---|
tracking_link | String | URL for newly created tracking link. |
job | String | The name of the job tied to this tracking link. |
source | String | The name of the source tied to this tracking link (e.g. the name of your application). |
referrer | String | The name of the user tied to this tracking link. |
Prospect Pools
Retrieve Prospect Pools
curl 'https://api.greenhouse.io/v1/partner/prospect_pools'
-H "Authorization: Basic MGQwMzFkODIyN2VhZmE2MWRjMzc1YTZjMmUwNjdlMjQ6"
API Response
[
{
"id": 123,
"name": "Cold Outreach: Referred",
"stages": [
{
"id": 1957,
"name": "Not Contacted"
},
{
"id": 1958,
"name": "Contacted"
},
{
"id": 1959,
"name": "1st. Follow Up Sent"
},
{
"id": 1960,
"name": "2nd Follow Up Sent"
},
{
"id": 1961,
"name": "In Discussion"
}
]
},
{
"id": 456,
"name": "Cold Outreach: Sourced",
"stages": [
{
"id": 1962,
"name": "Not Contacted"
},
{
"id": 1963,
"name": "Contacted"
},
{
"id": 1964,
"name": "1st. Follow Up Sent"
},
{
"id": 1965,
"name": "2nd Follow Up Sent"
},
{
"id": 1966,
"name": "In Discussion"
}
]
}
]
Retrieve prospect pools along with their stages for the current user's organization.
GET https://api.greenhouse.io/v1/partner/prospect_pools
scope: prospect_pools.view
Request Parameters
This request is simply the URL. It takes no parameters.
Response Parameters
Property Name | Type | Description |
---|---|---|
id | Integer | The ID of the prospect pool. |
name | String | The name of the prospect pool. |
stages | Object | The stages that belong to a prospect pool with the id and name of the stage. The list of stages will be ordered the same way that it is configured to be ordered in Greenhouse. |
Errors
{
"errors": [
{
"message": "Your request included invalid JSON.",
"field": "email"
}
]
}
Successful API responses will have a 200-level HTTP status code. If there is a problem processing your request, you will receive a response with a 4xx- or 5xx-level status code as follows:
Status Code | Description |
---|---|
400 | Your request included invalid JSON. |
401 | You have not been authenticated. |
403 | You have been authenticated, but your Greenhouse user does not have permission to the resource. |
404 | The resource you requested could not be found. |
5xx | There was an error on our end. You may retry at a later time or contact support if the problem persists. |
Error Properties
Property Name | Type | Required | Description |
---|---|---|---|
errors[] | Array | Yes | |
errors.message | String | Yes | A message describing the error. This is for debugging purposes and is not intended to be displayed to the end-user. The exact text should not be relied on programmatically. |
errors.field | String | No | The offending field in the request that caused the error, if applicable. |