NAV
shell

Introduction

Greenhouse integrates with many candidate testing platforms, including code testing, video interviewing, personality testing, and more. We've created the Assessment Partner API to allow our customers to seemlessly integrate our Partners' assessments into their Greenhouse interview workflow. This document outlines the end-user experience with the integration and the technical details of how to implement it.

Working with Greenhouse to implement the integration

To begin the integration process, please send the following information to us at partners@greenhouse.io:

  1. URL for your list_tests API call
  2. URL for your send_test API call
  3. URL for your test_status API call
  4. URL for your response_error API call
  5. A sample API key

The Partnerships team will configure endpoint URLs for creating assessment stages and provide next steps on receiving access to a Sandbox account to test the integration. If you are building an integration for use by mutual customers, we will need documentation on the integration for the Greenhouse Help Center.

Workflow

The Assessment Partner will provide an org-level API key to the customer. The organization will provide this API key to their Greenhouse Account Manager, who will input it into our system.

Selecting the Test

Once Greenhouse enters the API key for the organization, a new partner interview stage will be available for use. The user can add this stage to the Hiring Plan of any job that has access to the new Assessment Partner stage. Greenhouse will then make an API call to the List Tests endpoint to determine what tests the organization has configured.

Add Stage Image

Sending the Test

When a candidate reaches this Interview Stage, the user will click the "Send Test" button to send the test to the candidate via the Send Test endpoint. Greenhouse will send the Test ID and candidate email to the Assessment Partner, who will email the test to the candidate. The Assessment Partner will then send Greenhouse the ID for this unique test instance.

Add Stage Image

Receiving the Test Results

Greenhouse will periodically poll the Test Status endpoint to retrieve the candidate's test status and results. When the candidate completes the test, Greenhouse will notify the appropriate user that the test is complete. The user will be able to view the candidate's score, navigate to the partner site to see more details, and make an advance or reject decision within Greenhouse. The user will also be able to filter candidates by score and advance or reject candidates in bulk.

Alternatively, Greenhouse's Assessment API now includes the ability to notify Greenhouse of completed tests via the PATCH - Mark Test as Completed endpoint to avoid long polling!

Note: You can only update test statuses for active, unhired candidates.

Authentication

Every request Greenhouse sends to a Assessment Partner’s API will utilize HTTP Basic Authentication over HTTPS. As such, we require each of the API endpoints to use HTTPS.

When an organization decides to utilize a Assessment Partner’s integration, they will provide their Greenhouse Account Manager with their API key for that Assessment Partner.

Greenhouse will then make all requests for the organization using that API key as the username in Basic Authentication. Greenhouse will append a : (colon) to the API token and then Base64 encode the resulting string.

Note: The API key sent to Greenhouse must be less than 171 characters.

Upon receiving a request, the Assessment Partner should inspect the API key to determine whether the request should be permitted and which data should be returned.

Example Situation

General considerations

Unless otherwise specified, API methods generally conform to the following:

Assessment API Change Log

The timestamps below are Eastern Time.

Date Description
Oct 4, 2024 3:30:00PM Updated guidelines around API key character length in Introduction
Sep 18, 2024 10:45:00AM Added sent_by to the Send Test request example
Oct 19, 2023 12:30:00PM Clarified use of Assessment API for active, unhired candidates in Introduction and Test Status
Oct 13, 2023 3:00:00PM Added URL for response_error as a requirement in Introduction
Aug 22, 2023 3:00:00PM Fixed URL expiry timing in Send Test
Aug 21, 2019 2:00:00PM Added Change Log and General Consideration sections to the Assessment API documentation
Aug 21, 2019 2:00:00PM Added PATCH - Mark Test as Completed endpoint

List Tests

Greenhouse will first need to retrieve the list of tests from the Assessment Partner using the list_tests API endpoint. We will show the list of available tests to the user, who will to select the appropriate test for a given candidate.

GET https://www.testing-partner.com/api/list_tests

curl 'https://www.testing-partner.com/api/list_tests'
-H "Authorization: Basic MGQwMzFkODIyN2VhZmE2MWRjMzc1YTZjMmUwNjdlMjQ6"

Request

Greenhouse will make a GET request to the list_tests endpoint specified by the Assessment Partner.

Response

API Response

[
    {
        "partner_test_id": "12345",
        "partner_test_name": "My First Test" 
    },
    {
        "partner_test_id": "54321",
        "partner_test_name": "My Second Test"
    }
]

The Assessment Partner’s response should include a JSON payload containing a list of test objects for the organization. Each test object should contain the keys partner_test_id and partner_test_name.

Property Name Type Required Description
partner_test_id String Yes Identifies a test available to an organization.
partner_test_name String Yes A descriptive title for the test. We will use this value our UI as the test’s label.

Send Test

When a Greenhouse user sends a test to a candidate, Greenhouse will send a request to the Assessment Partner's send_test API endpoint. The Assessment Partner will then email the specified candidate the specified test.

Request

curl -X POST 'https://www.testing-partner.com/api/send_test'
-H "Authorization: Basic MGQwMzFkODIyN2VhZmE2MWRjMzc1YTZjMmUwNjdlMjQ6"
{
  "partner_test_id": "12345",
  "candidate": {
    "first_name": "Harry",
    "last_name": "Potter",
    "resume_url": "https://hogwarts.com/resume",
    "phone_number": "123-456-7890",
    "email": "hpotter@hogwarts.edu",
    "greenhouse_profile_url": "https://app.greenhouse.io/people/17681532?application_id=26234709"
  },
  "sent_by": "test_sender@example.org",
  "url": "https://app.greenhouse.io/integrations/testing_partners/take_home_tests/12345"
}

Greenhouse will initiate the process by sending a POST request to the send_test endpoint specified by the Assessment Partner. The body of the POST request will contain a JSON payload.

Property Name Type Required Description
partner_test_id String Yes Identifies a test available to an organization. Initially provided as a response to the List Tests request.
first_name String Yes The first name of the candidate.
last_name String Yes The last name of the candidate.
resume_url String No A URL to the candidate’s resume. This URL will expire 7 days after the request.
phone_number String No The candidate’s phone number.
email String Yes The candidate’s email address. The test should be sent to this address.
greenhouse_profile_url String Yes URL to the candidate’s Greenhouse application. Allows the partner to link back to Greenhouse.
sent_by String No Test sender's email address
url String Yes URL to which to send the PATCH Completed Test request, if using

Response

The API Response

{
  "partner_interview_id": "98765"
}

The response to the send_test request should contain a JSON payload in its body. This payload should be a single object that contains a single key: partner_interview_id.

Property Name Type Required Description
partner_interview_id String Yes Identifies a candidate’s test.

PATCH - Mark Test as Completed

When a candidate completes a test, send this request to the URL sent in the initial Send Test request to signal Greenhouse that the test has been completed. Upon this, Greenhouse will send a request to your Test Status endpoint.

PATCH https://app.greenhouse.io/integrations/testing_partners/take_home_tests/12345

Request

curl -X PATCH 'https://app.greenhouse.io/integrations/testing_partners/take_home_tests/12345'

-H "Authorization: Basic MGQwMzFkODIyN2VhZmE2MWRjMzc1YTZjMmUwNjdlMjQ6"

No parameters are necessary with this request.

Response

The response will return only the HTTP status code.

Sending Updates to Greenhouse

If you have implemented the polling option:

After a successful send_test request, Greenhouse will check whether the test instance has been completed by polling the test_status endpoint hourly. We will discontinue polling the test_status endpoint after the candidate is marked as hired, after we receive a partner_status of complete, or after 8 weeks have passed since the test was sent.

If you have implemented the PATCH Completed Test option:

After a successful send_test request, you can alert Greenhouse to updates of the test's status by sending a PATCH Completed Test request to the URL found in the url field of the send_test request. This will trigger a Test Status request from Greenhouse. Active, unhired candidates will show the completed test status.

Test Status

Tells Greenhouse the current status of a take home test.

GET https://www.testing-partner.com/api/test_status?partner_interview_id=12345

Request

curl 'https://www.testing-partner.com/api/test_status?partner_interview_id=12345'

-H "Authorization: Basic MGQwMzFkODIyN2VhZmE2MWRjMzc1YTZjMmUwNjdlMjQ6"

Greenhouse will send a GET request to the test_status endpoint provided by the Assessment Partner. The GET request will contain a single query string parameter: partner_interview_id.

Parameter Name Type Required Description
partner_interview_id String Yes Identifies a test instance for a candidate. Initially provided as a response to the Send Test request.

Response

API Response

{
    "partner_status": "complete",
    "partner_profile_url": "http://example.com/tests/12345",
    "partner_score": 81,
    "metadata":
        {
            "Started At": "10:15 AM 26 March 2014",
            "Completed At": "10:15 AM 26 March 2014",
            "Notes": "This candidate did extremely well!"
        }

}

The response to a test_status request should contain a JSON object in its body with up to four keys: partner_status, partner_profile_url, partner_score, and metadata.

Property Name Type Required Description
partner_status String Yes Describes the current state of the test instance. If the test has been completed and results are available, this value should be "complete". We will continue to poll until the status is "complete", or until 8 weeks has passed since the test was sent.
partner_profile_url String Required only if status is complete. URL to the candidate’s page on the Test Partner’s website.
partner_score Number No Numerical score reflecting the candidate’s performance on the test.
metadata Object No A non-nested object containing keys and values that will be displayed in our test results. All of the values must be Javascript primitives.

Response Error

When Greenhouse receives a malformed response for any of Assessment Partner's API endpoints, we would like to report the errors to the Assessment Partner. As such, each Assessment Partner should provide an API endpoint to ingest this information.

POST https://www.testing-partner.com/api/request_errors

Request

curl -X POST 'https://www.testing-partner.com/api/request_errors'
-H "Authorization: Basic MGQwMzFkODIyN2VhZmE2MWRjMzc1YTZjMmUwNjdlMjQ6"
{
    "api_call": "test_status",
    "errors": ["partner_status is 'complete' but partner_profile url is missing"],
    "partner_test_id" : "12345",
    "partner_test_name": "Personality Test",
    "partner_interview_id": "299506",
    "candidate_email": "hpotter@hogwarts.edu"
}

After receiving a malformed response, Greenhouse will provide the Assessment Partner with the details of the failed response. Each time an invalid response arrives, Greenhouse will send a POST request to the response_error API endpoint.

The body of the request will contain as much information as Greenhouse has at the moment of failure.

For example, if a list_tests request fails, Greenhouse can only provide the api call (in this case, ‘list_tests’) and the assorted errors (missing keys, unexpected data types, etc.). However, if a test_status request fails, we can provide more information (partner_test_id, partner_interview_id, etc.) that may prove useful for debugging purposes. Assessment Partners can always expect to receive api_call and errors in the JSON body.

Property Name Value Required Description
api_call String Yes The name of the API call that generated the malformed response.
errors Array Yes An array of strings which describe an error that prevented the response from validating.
partner_test_id String No Identifies a test available to an organization. Initially provided as a response to the List Tests request.
partner_test_name String No A human-readable string that identifies the test. Initially provided as a response to the List Tests request.
partner_interview_id String No Identifies a candidate’s test.
candidate_email String No The candidate’s email address. The test should be sent to this address.

Response

API Response

{
    "status": 200
}

The response to a successful response_errors request should contain a response code of 200.

Errors

Successful requests should generate a response with a 200-level status code. Unsuccessful requests should generate a response with one of the following responses:

Status Code Description
401 Unsuccessful authentication with the provided API key.
404 The requested resource could not be found.