NAV
Examples

Introduction

Our Greenhouse Onboarding API allows you to query and modify your employee, and query company information.

If you are not using our Onboarding product and would like to know more, please visit our site.

This documentation is open source! Feel free to leave feedback as issues in the GitHub repo or fork it and contribute changes!

GraphQL

Greenhouse Onboarding only supports GraphQL; we do not have a traditional REST API.
We made the decision to use GraphQL because it allows us you to:

General Concepts

TermMeaning
QuerySimilar to GET requests, queries return data (the return type is in parentheses). They can take arguments (listed in a table under the Query name).
MutationsMutate data (similar to POST, PUT, PATCH, DELETE). They also return data (type in parentheses). They can also take arguments (listed in table under the Mutation name).
TypeEach type describes an object in GHO (e.g. Employee or Department). Each type has its own set of fields which contain the information (e.g. Employee has a first name, Department contains a description).
Input ObjectsQueries and Mutations take input objects as arguments. These arguments have names and values. The value will either be a scalar or a more complex structured input.
ScalarsThe most basic data type. All types (e.g. Employee) have fields that contain scalars or other types that eventually boil down to scalars.
EnumsENUMs are hard-coded values. They are strings that must be a certain value. E.g. an Employee’s “employmentStatus” can only be one of [CONTRACTOR FULL_TIME INTERN PART_TIME TEMPORARY TERMINATED].

Authentication

$ curl https://onboarding-api.greenhouse.io/graphql \
  -X POST \
  -u your_access_key:your_secret_key \
  -d '{"query":"{\n  rateLimit {\n    limit\n  }\n}"}' \
  -H "Content-Type: application/json"

...

> GET /graphql HTTP/1.1
> Host: onboarding-api.greenhouse.io
> Authorization: Basic eW91cl9hY2Nlc3Nfa2V5OnlvdXJfdmFsdWU=

The Greenhouse Onboarding API is secured with HTTP Basic Authentication over HTTPS. Clients are required to supply both a username and password. Credentials can be generated inside of the Greenhouse Onboarding product on the Settings > API Management screen. Only Super Admins can generate or revoke API keys. Use the Access Key field as the username and the Secret Key field as the password.

API Management

Using the Greenhouse Onboarding API provides access to all of your company’s information. There is no way to limit the scope of an API key. Only share your API key with people that you trust. API keys can be revoked at any time on the API Management screen.

Rate Limiting

# When the rate limit is reached, ensuing requests will result 
# in the following response (until the next time period begins):
{
  "errors": [
    {
      "message": "Rate limit reached.",
      "limit": 100,
      "remaining": 0,
      "resetAt": "2018-01-01T01:00:00Z"
    }
  ]
}

The Greenhouse Onboarding API imposes limits on the amount of data a single client can request over time, as well as the complexity of individual requests. This is done to ensure our servers can always service requests as quickly as possible.

Request Limits

# To request the current rate limit information:
{
  rateLimit {
    resetAt
    limit
    remaining
  }
}

# rateLimit response:
{
  "data": { 
    "rateLimit": {
      "resetAt": "2018-09-12T18:00:00Z",
      "limit": 100,
      "remaining": 99
    }
  }
}

In order to ensure API stability, we limit the number of requests that can made within a given time window. Consumers can access this rate limit information by querying the rateLimit type (see example to the right). The number of remaining requests is indicated by the value in the remaining field. When this request limit has been reached, every ensuing request will fail until the next time window begins (indicated by the resetAt field). Then, once the next time window starts, the number of requests will be replenished (to the number indicated by the limit property).

Maximum Complexity

# Say we had the following query:
{
  employee(id: 25) {
    email
  }
}

# To request the complexity score of this query, simply 
# include complexityInfo as such:
{
  employee(id: 25) {
    email
  }
  complexityInfo {
    score
    maximum
  }
}

# The response:
{
  "data": {
    "employee": {
      "email": "email_address@example.com"
    },
    "complexityInfo": {
      "score": 1,
      "maximum": 2500
    }
  }
}

In addition to limiting the number of requests used in a given time period, we limit the “complexity” of any given request. If this score exceeds our maximum, the request will be rejected and an error response will be returned.

We reserve the right to adjust the complexity score of any given field at any time. However, for the time being, a query’s complexity score can be estimated like so:

Clients can also determine a query’s complexity score by requesting the complexityInfo object (see example to the right).

A Basic Request

# If we wanted to retrieve the email address of the employee 
# with ID 25, the GraphQL query would look like this:

{
  employee(id: 25) {
    email
  }
}
# We then pack this query into a JSON object as a string

{
    "query": "{\n  employee(id: 25) {\n    email\n  }\n}"
}
# Here's what the final cURL request would look like

curl 'https://onboarding-api.greenhouse.io/graphql' \
  -X POST \
  -u your_access_key:your_secret_key \
  -d '{"query":"{\n  employee(id: 25) {\n    email\n  }\n}"}' \
  -H 'content-type: application/json'

# and here's what the response would look like

{"data":{"employee":{"email":"employee_25_email@example.com"}}}

GraphQL requests are simply POSTs made to our API endpoint. In its most simple form, the request payload consists of a JSON object with a single key: “query”. The corresponding value for the “query” key is the GraphQL query itself, and it is expressed as a string.

Pagination

{
  employees(first: 2, after: "NQ==") { # Please fetch the next 2 records, starting after the "NQ==" cursor
    pageInfo {
      endCursor
      hasNextPage
    }
    edges {
      node {
        email
      }
    }
  }
}

# Returns:

{
  "data": {
    "employees": {
      "pageInfo": {
        "endCursor": "MTA=",
        "hasNextPage": true
      },
      "edges": [
        {
          "node": {
            "email": "kima@example.com"
          }
        },
        {
          "node": {
            "email": "omar@example.com"
          }
        }
      ]
    }
  }
}

For performance reasons, some result sets will be limited in size. For example, when requesting employee profile information we limit the number of employees returned in a single query. The API will return a “page” of records along with an object that describes how to get the next page.

We are using the pagination system recommended by the GraphQL documentation. Paginated connections return the following pieces of information:

To fetch the next page of information, pass the endCursor value into the after filter on the connection. To the right you can see an example on how to fetch employees via the employees connection.

When requesting a paginated resource, you will always need to provide a value for either the first or last arguments. You’ll use these arguments to specify the number of records that should be included on a page. If you provide a value larger than our maximum, you will receive the maximum number of records.

As a general rule, we attempt to avoid nested sets of pagination. For example, the list of CustomFieldValue records for each employee will be a simple array instead of another paginated connection.

Errors and Validation

{
  employee(id: 100000000) {
    email
  }
}
{
  "data": {
    "employee": null
  },
  "errors": [
    {
      "message": "Unable to find Employee with id 100000000",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ],
      "path": [
        "employee"
      ],
      "errorCode": "NotFound"
    }
  ]
}

Unlike REST APIs, GraphQL will return an HTTP status of 200, even in cases where there are errors. You can see an example of an error message to the right. The data and errors properties are siblings. It’s possible for a request to generate a response that has both data and errors. However, if there is ever an errors key in the response, the request failed (despite the return code of 200).

The message will let you know what’s wrong. The locations property has the line number and column where the error starts. In this example, it’s the 2nd line, 3rd column, which is the start of the word employee. The fields property is a breadcrumb trail of how to get to the problem. Here, the problem can be found on the top-most employee selection.

When we can, we’ll also provide an errorCode key for every entry in the errors list. Here’s a table of current errorCodes:

Error ScenarioError Code
Authentication FailureAuthentication
Validation FailureValidation
Resource Not FoundNotFound
Server ErrorServer
Rate Limit ExceededRateLimit

There are undefined error scenarios in which we’re unable to provide a code. In these cases, refer to the contents of the error list.

Queries

complexityInfo (ComplexityInfo)

The complexity information for the current query

contactRelationships ([String])

The list of valid options for the ‘Contact’ custom field type

countries ([Country])

The list of countries

ArgumentTypeDescriptionRequired
countryCodes[String]

customField (CustomField)

A custom field

ArgumentTypeDescriptionRequired
idID

customFields (CustomFieldConnection)

A collection of custom fields

ArgumentTypeDescriptionRequired
afterStringReturns the elements in the list that come after the specified global ID.
beforeStringReturns the elements in the list that come before the specified global ID.
fieldTypes[CustomFieldTypes]
firstIntReturns the first n elements from the list.
ids[ID]
lastIntReturns the last n elements from the list.

department (Department)

A single department

ArgumentTypeDescriptionRequired
idInt

departments (DepartmentConnection)

All departments

ArgumentTypeDescriptionRequired
afterStringReturns the elements in the list that come after the specified global ID.
beforeStringReturns the elements in the list that come before the specified global ID.
firstIntReturns the first n elements from the list.
lastIntReturns the last n elements from the list.

employee (Employee)

# Request an employee but limit their customFieldValues to those of specific customFields.
# The customFieldIds argument can be used when you are interested in only getting a specific
# customFieldValues for the employee.
{
  employee(id: 20) {
    customFieldValues(customFieldIds: ["emergency_contact", "favorite_food"]) {
      customField {
        id
        fieldType
      }
      value
    }
  }
}

# Request an employee and limit their signatureRequests to those that are waiting on a signature or being processed
{
  employee(id: 20) {
    signatureRequests(statuses: [WAITING_FOR_SIGNATURE, BEING_PROCESSED]) {
      counterSigner {
        id
        email
      }
      file {
        fileUrl
      }
      signatureRequestTemplate {
        publicName
      }
    }
  }
}

An Onboarding employee record

ArgumentTypeDescriptionRequired
idInt

employees (EmployeeConnection)

# Request only those employees that have title "Account Manager". For each employee that fits the criteria,
# return their id and email
{
  employees(first: 25, titleFilter: { titles: ["Account Manager"] }) {
    pageInfo {
      hasNextPage
      endCursor
    }
    edges {
      node {
        id
        email
      }
    }
  }
}

# Request only those employees that have a department set (department is not null). For each employee that fits the criteria,
# return their id and email
{
  employees(first: 25, departmentFilter: { anyValue: true }) {
    pageInfo {
      hasNextPage
      endCursor
    }
    edges {
      node {
        id
        email
      }
    }
  }
}

# Request only those employees that lack a department (department is null). For each employee that fits the criteria,
# return their id and email
{
  employees(first: 25, departmentFilter: { noValue: true }) {
    pageInfo {
      hasNextPage
      endCursor
    }
    edges {
      node {
        id
        email
      }
    }
  }
}

# Request only those employees that have a startDate between 2017-03-25 and 2018-03-25.
# These dates are exclusive (e.g. someone who started on 2017-03-25 or 2018-03-25 would not be included.
{
  employees(first: 25, startDateFilter: { dateFilter: { after: "2017-03-25", before: "2018-03-25" } }) {
    pageInfo {
      hasNextPage
      endCursor
    }
    edges {
      node {
        id
        email
        startDate
      }
    }
  }
}

# Request only those employees that have a value (ANY value) set for the "favorite_food" Custom Field. For these employees, return
# ALL of their customFieldValues.
{
  employees(first: 25, customFieldValues: [{id: "favorite_food"}]) {
    pageInfo {
      hasNextPage
      endCursor
    }
    edges {
      node {
        id
      }
    }
  }
}

# Request only those employees that have "Hot Dogs" or "Chicken Nuggets" set for their "favorite_food" Custom Field.
# Because the "favorite_food" Custom Field is of type text, we provide the "textValues" argument (as opposed to
# dateValues or idValues)
{
  employees(
    first: 25,
    customFieldValues: [{id: "favorite_food", textValues: ["Hot Dogs", "Chicken Nuggets"]}]
  ) {
    pageInfo {
      hasNextPage
      endCursor
    }
    edges {
      node {
        customFieldValues {
          customField {
            id
          }
          value
        }
      }
    }
  }
}

# Request only those employees that have a value set for their "favorite_food" Custom Field and "Blue" for their
# "favorite_color" Custom Field. For each of these employees, return their ID and email address.
{
  employees(
    first: 25,
    customFieldValues: [{id: "favorite_food"}, {id: "favorite_color", textValues: ["Blue"]}]
  ) {
    pageInfo {
      hasNextPage
      endCursor
    }
    edges {
      node {
        id
        email
        }
    }
  }
}

# Request employees that have a value set for the "favorite_food" Custom Field. Return each employee's ID and
# customFieldValues, but only return the customFieldValue for the "favorite_food" customField.
{
  employees(
    first: 25,
    customFieldValues: [{ id: "favorite_food" }]
  ) {
    pageInfo {
      hasNextPage
      endCursor
    }
    edges {
      node {
        id
        customFieldValues(customFieldIds: ["favorite_food"]) {
          customField {
            id
          }
          value
        }
      }
    }
  }
}

# Request employees that have a date value between "2017-04-13" and "2018-04-13" (exclusive) for the
# "1_year_anniversary" Custom Field. For each of these employees, return their ID and
# the value for the "1_year_anniversary" Custom Field (and only the value for this Custom Field).
{
  employees(
    first: 25,
    customFieldValues: [{ id: "1_year_anniversary", dateValue: { after: "2017-04-13", before: "2018-04-13" } }]
  ) {
    pageInfo {
      hasNextPage
      endCursor
    }
    edges {
      node {
        id
        customFieldValues(customFieldIds: ["1_year_anniversary"]) {
          customField {
            id
          }
          value
        }
      }
    }
  }
}

# Request employees that have Employee 35 or Employee 40 set as the value for the "mentor" Custom Field. For each of
# these employees, return their id, email address, and "about me" text.
{
  employees(
    first: 25,
    customFieldValues: [{id: "mentor", idValues: [35, 40]}]
  ) {
    pageInfo {
      hasNextPage
      endCursor
    }
    edges {
      node {
        id
        email
        about
      }
    }
  }
}

A collection of Onboarding employee records. The following arguments are depreacated and should be avoided as support for them will be dropped: dateOfBirth, departmentIds, emails, employmentStatuses, hrManagerIds, locationIds, managerIds, personalEmails, startDate, titles, and workCountryCodes. Each of these arguments has a newer, more powerful companion named *Filter. For example, departmentIds has been replaced by the argument departmentFilter - which allows for the specification of department IDs, but also allows for more flexibility (e.g. filtering by lack/presence of a given field - as opposed to filtering by specific values).

ArgumentTypeDescriptionRequired
afterStringReturns the elements in the list that come after the specified global ID.
beforeStringReturns the elements in the list that come before the specified global ID.
customFieldValues[CustomFieldValuesInput]filter employees by their custom field values
dateOfBirthDateFilterDEPRECATED. Use dateOfBirthFilter instead
dateOfBirthFilterDateOfBirthFilterfilter employees by their date of birth
departmentFilterDepartmentFilterfilter employees by their department
departmentIds[Int]DEPRECATED. Use departmentFilter instead
emailFilterEmailFilterfilter employees by their email
emails[String]DEPRECATED. Use emailFilter instead
employmentStatusFilterEmploymentStatusFilterfilter employees by their employment status
employmentStatuses[EmploymentStatus]DEPRECATED. Use employmentStatusFilter instead
firstIntReturns the first n elements from the list.
hrManagerFilterHrManagerFilterfilter employees by their hr manager
hrManagerIds[Int]DEPRECATED. Use hrManagerFilter instead
lastIntReturns the last n elements from the list.
locationFilterLocationFilterfilter employees by their location
locationIds[Int]DEPRECATED. Use locationFilter instead
managerFilterManagerFilterfilter employees by their manager
managerIds[Int]DEPRECATED. Use managerFilter instead
personalEmailFilterPersonalEmailFilterfilter employees by their personal email
personalEmails[String]DEPRECATED. Use personalEmailFilter instead
startDateDateFilterDEPRECATED. Use startDateFilter instead
startDateFilterStartDateFilterfilter employees by their start date
titleFilterTitleFilterfilter employees by their title
titles[String]DEPRECATED. Use titleFilter instead
updatedAtDateTimeFilterfilter employees based on when they were last updated
workCountryCodeFilterWorkCountryCodeFilterfilter employees by their work country code
workCountryCodes[String]DEPRECATED. Use WorkCountryCodeFilter instead

location (Location)

A single location

ArgumentTypeDescriptionRequired
idInt

locations (LocationConnection)

All locations

ArgumentTypeDescriptionRequired
afterStringReturns the elements in the list that come after the specified global ID.
beforeStringReturns the elements in the list that come before the specified global ID.
firstIntReturns the first n elements from the list.
lastIntReturns the last n elements from the list.

otherCriteria (OtherCriterionConnection)

All other criteria

ArgumentTypeDescriptionRequired
afterStringReturns the elements in the list that come after the specified global ID.
beforeStringReturns the elements in the list that come before the specified global ID.
firstIntReturns the first n elements from the list.
lastIntReturns the last n elements from the list.

otherCriterion (OtherCriterion)

A single other criterion

ArgumentTypeDescriptionRequired
idInt

rateLimit (RateLimit)

Information about your current API quota

team (Team)

A single team

ArgumentTypeDescriptionRequired
idInt

teamCategories (TeamCategoryConnection)

All team categories

ArgumentTypeDescriptionRequired
afterStringReturns the elements in the list that come after the specified global ID.
beforeStringReturns the elements in the list that come before the specified global ID.
firstIntReturns the first n elements from the list.
lastIntReturns the last n elements from the list.

teamCategory (TeamCategory)

A single team category

ArgumentTypeDescriptionRequired
idInt

teams (TeamConnection)

All teams

ArgumentTypeDescriptionRequired
afterStringReturns the elements in the list that come after the specified global ID.
beforeStringReturns the elements in the list that come before the specified global ID.
firstIntReturns the first n elements from the list.
lastIntReturns the last n elements from the list.

Mutations

addDepartment (AddDepartmentPayload)

Add a new Department

ArgumentTypeDescriptionRequired
addDepartmentInputAddDepartmentInput!Required

addLocation (AddLocationPayload)

Add a new Location

ArgumentTypeDescriptionRequired
addLocationInputAddLocationInput!Required

addPendingHire (PendingHire)

# Create a PendingHire with required information as well as a value for a text Custom Field (long text, confirmable,
# and multiple_choice Custom Fields also take Strings as the "value").
mutation {
  addPendingHire(
    pendingHireInfo: {
      firstName: "Joe"
      lastName: "Schmoe"
      email: "joe123@example.com"
      workCountryCode: "USA"
      customFieldValues: [
        { customFieldId: "favorite_food", value: "Egg McMuffins" }
      ]
    }
  ) {
    firstName
    lastName
    email
    workCountryCode
    customFieldValues(customFieldIds: ["favorite_food"]) {
      customField { id }
      value
    }
  }
}

# Create a PendingHire with required information as well as a value for a Multiple Select Custom Field. These Custom
# Fields require a JSON Array-formatted string (including escaped quotes) for the "value". Also of note, each of the
# elements in the array must be a valid option for the given Custom Field.
mutation {
  addPendingHire(
    pendingHireInfo: {
      firstName: "Joe"
      lastName: "Schmoe"
      email: "joe123@example.com"
      workCountryCode: "USA"
      customFieldValues: [
        { customFieldId: "required_equipment", value: "[\"Ergonomic Keyboard\", \"Standing Desk\"]" }
      ]
    }
  ) {
    firstName
    lastName
    email
    workCountryCode
    customFieldValues(customFieldIds: ["required_equipment"]) {
      customField { id }
      value
    }
  }
}

# Create a PendingHire with required information as well as a value for a Team Custom Field. These Custom Fields
# require an ID for the "value."
mutation {
  addPendingHire(
    pendingHireInfo: {
      firstName: "Joe"
      lastName: "Schmoe"
      email: "joe123@example.com"
      workCountryCode: "USA"
      customFieldValues: [
        { customFieldId: "primary_social_club", value: 14 }
      ]
    }
  ) {
    firstName
    lastName
    email
    workCountryCode
    customFieldValues {
      customField { id }
      value
    }
  }
}

# Create a PendingHire with required information as well as a value for an Address Custom Field. These Custom
# Fields require a JSON Object-formatted string (including escaped quotes) for the "value".
mutation {
  addPendingHire(
    pendingHireInfo: {
      firstName: "Joe"
      lastName: "Schmoe"
      email:"joe123@example.com"
      workCountryCode: "USA"
      customFieldValues: [
        {
          customFieldId: "address",
          value: "{\"address_line_1\":\"123 Test Street\",\"address_line_2\":\"Apartment 1\",\"city\":\"Pawnee\", \"state\":\"IN\", \"zipcode\":\"12345\",\"country\":\"USA\"}"
        }
      ]
    }
  ) {
    firstName
    lastName
    email
    workCountryCode
    customFieldValues(customFieldIds: ["address"]) {
      customField { id }
      value
    }
  }
}

# Create a PendingHire with required information as well as a value for a Contact Custom Field. These Custom
# Fields require a JSON Object-formatted string (including escaped quotes) for the "value".
mutation {
  addPendingHire(
    pendingHireInfo: {
      firstName: "Joe"
      lastName: "Schmoe"
      email:"joe123@example.com"
      workCountryCode: "USA"
      customFieldValues: [
        {
          customFieldId: "emergency_contact",
          value: "{\"first_name\": \"Joe\", \"last_name\": \"Schmoe\", \"email\":\"jschmoe@aol.com\", \"phone\": \"123.456.7890\", \"relationship\": \"Other\"}" }
      ]
    }
  ) {
    firstName
    lastName
    email
    workCountryCode
    customFieldValues(customFieldIds: ["emergency_contact"]) {
      customField { id }
      value
    }
  }
}

# Create a PendingHire with required information as well as a value for a Date Custom Field. These Custom Fields
# require a String formatted as such: YYYY-MM-DD.
mutation {
  addPendingHire(
    pendingHireInfo: {
      firstName: "Joe"
      lastName: "Schmoe"
      email:"joe123@example.com"
      workCountryCode: "USA"
      customFieldValues: [
        { customFieldId: "fully_vested", value: "2019-12-12" }
      ]
    }
  ) {
    firstName
    lastName
    email
    workCountryCode
    customFieldValues(customFieldIds: ["fully_vested"]) {
      customField { id }
      value
    }
  }
}

Add a Pending Hire to Greenhouse Onboarding

ArgumentTypeDescriptionRequired
pendingHireInfoAddPendingHireInput!Required

deleteDepartment (DeleteDepartmentPayload)

Delete a Department

ArgumentTypeDescriptionRequired
deleteDepartmentInputDeleteDepartmentInput!Required

deleteLocation (DeleteLocationPayload)

Delete a Location

ArgumentTypeDescriptionRequired
deleteLocationInputDeleteLocationInput!Required

updateDepartment (UpdateDepartmentPayload)

Update a Department

ArgumentTypeDescriptionRequired
updateDepartmentInputUpdateDepartmentInput!Required

updateEmployeeProfile (Employee)

# Update an employee's email address, date of birth, and department. Return these fields to confirm the change.
mutation {
  updateEmployeeProfile(
    id: 25,
    employeeUpdates: {
      email: "new_email_address@example.com"
      dateOfBirth: "1985-04-07"
      department: 1
    }
  ) {
    email
    dateOfBirth
    department {
      id
    }
  }
}

# Update/create the value for a text, long text, confirmable, or multiple_choice Custom Field. For Custom Fields of
# these types, provide a string for the value. Here we update the "favorite_food" Custom Field Value (a text Custom
# Field) to "Egg McMuffins". We ask for the employee's customFieldValues, but we limit them to those that
# belong to the "favorite_food" Custom Field. E.g. we filter out the irrelevant customFieldValues.
mutation {
  updateEmployeeProfile(
    id: 20,
    employeeUpdates: {
      customFieldValues: [
        { customFieldId: "favorite_food", value: "Egg McMuffins" }
      ]
    }
  ) {
    customFieldValues(customFieldIds: ["favorite_food"]) {
      customField {
        id
      }
      value
    }
  }
}

# Update/create the value for a Multiple Select Custom Field. For these Custom Fields, "value" must be a string
# representing a JSON Array (including escaped quotation marks).  Also of note, each of the values of this array must
# be one of the pre-defined values for the given Custom Field.  Here, we set the "required_equipment" Custom Field Value
# to contain "Ergonomic Keyboard" and "Standing Desk". We then request the updated Employee's value for this Custom Field
# to confirm the change.
mutation {
  updateEmployeeProfile(
    id: 20,
    employeeUpdates: {
      customFieldValues: [
        { customFieldId: "required_equipment", value: "[\"Ergonomic Keyboard\", \"Standing Desk\"]" }
      ]
    }
  ) {
    customFieldValues(customFieldIds: ["required_equipment"]) {
      customField {
        id
        fieldType
      }
      value
    }
  }
}

# Update/create the value for a Team Custom Field. For Custom Fields of type "Team" we provide an ID as the
# value.  This value represents the ID of the new Team.  Here we change the this employees "primary_social_club" to be
# Team 14.  These Team IDs can be found by utilizing the team query.
mutation {
  updateEmployeeProfile(
    id: 20,
    employeeUpdates: {
      customFieldValues: [
        { customFieldId: "primary_social_club", value: 14 }
      ]
    }
  ) {
    customFieldValues(customFieldIds: ["primary_social_club"]) {
      customField {
        id
        fieldType
      }
      value
    }
  }
}

# Update/create the value for an Address Custom Field. These Custom Fields require a String value.  This String value
# must be a JSON Object (with quotes escaped accordingly).
mutation {
  updateEmployeeProfile(
    id: 20,
    employeeUpdates: {
      customFieldValues: [
        {
          customFieldId: "address",
          value: "{\"address_line_1\":\"123 Test Street\",\"address_line_2\":\"Apartment 1\",\"city\":\"Pawnee\", \"state\":\"IN\", \"zipcode\":\"12345\",\"country\":\"USA\"}"
        }
      ]
    }
  ) {
    customFieldValues(customFieldIds: ["address"]) {
      customField {
        id
      }
      value
    }
  }
}

# Update/create the value for a Contact Custom Field. These Custom Fields require a String value. This String value
# must be a JSON Object (with quotes escaped accordingly).
mutation {
  updateEmployeeProfile(
    id: 20,
    employeeUpdates: {
      customFieldValues: [
        {
          customFieldId: "emergency_contact",
          value: "{\"first_name\": \"Joe\", \"last_name\": \"Schmoe\", \"email\":\"jschmoe@aol.com\", \"phone\": \"123.456.7890\", \"relationship\": \"Other\"}" }
      ]
    }
  ) {
    customFieldValues(customFieldIds: ["emergency_contact"]) {
      customField {
        id
        fieldType
      }
      value
    }
  }
}

# Update/create the value for a date Custom Field. These Custom Fields require a String formatted as such: YYYY-MM-DD
mutation {
  updateEmployeeProfile(
    id: 20,
    employeeUpdates: {
      customFieldValues: [
        { customFieldId: "fully_vested", value: "2019-12-12" }
      ]
    }
  ) {
    customFieldValues(customFieldIds: ["fully_vested"]) {
      customField {
        id
        fieldType
      }
      value
    }
  }
}

Update an employee’s profile

ArgumentTypeDescriptionRequired
employeeUpdatesUpdateEmployee!Required
idID!Required

updateLocation (UpdateLocationPayload)

Update a Location

ArgumentTypeDescriptionRequired
updateLocationInputUpdateLocationInput!Required

Types

AddDepartmentPayload

The result of running an addDepartment mutation

FieldTypeDescription
departmentDepartmentThe new department

AddLocationPayload

The result of running an addLocation mutation

FieldTypeDescription
locationLocationThe new location

ComplexityInfo

Information about the current request’s complexity. If the complexity exceeds the maxium, the request will fail

FieldTypeDescription
maximumInt
scoreInt

Country

A country

FieldTypeDescription
countryCodeString
nameString
states[State]

CustomField

Represents a single CustomField record for your company. CustomFields can be stored and displayed in a variety of ways. The types are described via the CustomFieldTypes enum.

FieldTypeDescription
createdAtDateTime
customFieldGroupCustomFieldGroup
fieldTypeCustomFieldTypesThe field type determines how users input and view the data for this field.
idStringA unique identifier for this CustomField.
multipleChoiceOptions[String]
nameStringThe name of this custom field as users would see it inside Greenhouse Onboarding.
teamCategoryTeamCategory
updatedAtDateTime

CustomFieldConnection

The connection type for CustomField.

FieldTypeDescription
edges[CustomFieldEdge]A list of edges.
pageInfoPageInfo!Information to aid in pagination.

CustomFieldEdge

An edge in a connection.

FieldTypeDescription
cursorString!A cursor for use in pagination.
nodeCustomFieldThe item at the end of the edge.

CustomFieldGroup

A Group of Custom Field

FieldTypeDescription
idID
nameString

CustomFieldValue

A Custom Field Value Record

FieldTypeDescription
createdAtDateTime
customFieldCustomField
updatedAtDateTime
valueValueA different type of value will be stored based upon the field type of the CustomField. Some types have the data stored as a nested object. Note that the type is a scalar named Value. Even though it appears to be an object, you are not able to use GraphQL to determine its shape.
valueUpdatedAtDateTimeThe time of the most recent update to this field.

DeleteDepartmentPayload

The result of running an deleteDepartment mutation

FieldTypeDescription
deletedDepartmentIdIDThe ID of the department that was just deleted

DeleteLocationPayload

The result of running an deleteLocation mutation

FieldTypeDescription
deletedLocationIdIDThe ID of the location that was just deleted

Department

Represents a single department in your company. Employees may belong to zero or one department. Departments are used in a variety of ways in Greenhouse Onboarding, including permissions and onboarding plans.

FieldTypeDescription
createdAtDateTime
departmentLeadEmployee
descriptionString
emailString
idID
nameString
updatedAtDateTime

DepartmentConnection

The connection type for Department.

FieldTypeDescription
edges[DepartmentEdge]A list of edges.
pageInfoPageInfo!Information to aid in pagination.

DepartmentEdge

An edge in a connection.

FieldTypeDescription
cursorString!A cursor for use in pagination.
nodeDepartmentThe item at the end of the edge.

Document

Represents a single document attached to an Employee.

FieldTypeDescription
createdAtDateTime
fileFileContains the file payload.
idID
updatedAtDateTime

Employee

A single Employee that works for your company.

FieldTypeDescription
aboutStringA brief description of the employee. This information is displayed on both the employee’s profile and is also featured prominently in the Welcome Experience for any new hires that report to this employee.
createdAtDateTime
customFieldValues[CustomFieldValue]A list of all other profile information for this employee. Administrators can configure these fields on the Settings > Custom Fields page.
dateOfBirthDateNote that only administrators can see the birth year for employees
dateOfTerminationDateThis information is only available on terminated employees
departmentDepartment
documents[Document]These are documents that came over from Greenhouse Recruiting, were attached directly to the employee profile, or attached to a task. This does not include E-Signature requests.
emailStringThe employee’s work email. They need this in order to sign in
employmentStatusEmploymentStatus
firstNameString
hrManagerEmployeeThe employee’s HR Manager.
idID
lastNameString
locationLocation
managerEmployeeThis employee’s direct manager.
middleNameString
otherCriteria[OtherCriterion]
personalEmailStringThe employee’s personal email.
phoneNumberString
preferredFirstNameStringThis is the name that your employee prefers to go by. If this value is set, Greenhouse Onboarding will display this name everywhere in the product instead of the employee’s legal name.
preferredLastNameString
profileImageFileA file containing the employee’s profile image. This image is displayed in emails, reports and directory pages.
signatureRequests[SignatureRequest]These are E-Signature requests initiated through Greenhouse Onboarding. Keep in mind that these requests can be in a number of different states in their lifecycle and may not always have a signed document available to download.
startDateDate
suffixString
titleStringThe employee’s job title.
updatedAtDateTime
workCountryCodeString

EmployeeConnection

The connection type for Employee.

FieldTypeDescription
edges[EmployeeEdge]A list of edges.
pageInfoPageInfo!Information to aid in pagination.

EmployeeEdge

An edge in a connection.

FieldTypeDescription
cursorString!A cursor for use in pagination.
nodeEmployeeThe item at the end of the edge.

File

A File record

FieldTypeDescription
expiresAtDateTimeThe time when the URL will expire. After this time, you will need to generate a new URL.
fileNameStringThe original name of the file.
fileSizeIntThe file size, in bytes
fileUrlStringAn expiring URL you can use to download the file.

Location

Represents a single location in your company. Employees may belong to zero or one location. Locations are used in a variety of ways in Greenhouse Onboarding, including permissions and onboarding plans.

FieldTypeDescription
addressString
createdAtDateTime
descriptionString
emailString
idID
locationLeadEmployee
nameString
updatedAtDateTime

LocationConnection

The connection type for Location.

FieldTypeDescription
edges[LocationEdge]A list of edges.
pageInfoPageInfo!Information to aid in pagination.

LocationEdge

An edge in a connection.

FieldTypeDescription
cursorString!A cursor for use in pagination.
nodeLocationThe item at the end of the edge.

Mutation

FieldTypeDescription
addDepartmentAddDepartmentPayloadAdd a new Department
addLocationAddLocationPayloadAdd a new Location
addPendingHirePendingHireAdd a Pending Hire to Greenhouse Onboarding
deleteDepartmentDeleteDepartmentPayloadDelete a Department
deleteLocationDeleteLocationPayloadDelete a Location
updateDepartmentUpdateDepartmentPayloadUpdate a Department
updateEmployeeProfileEmployeeUpdate an employee’s profile
updateLocationUpdateLocationPayloadUpdate a Location

OtherCriterion

A tag that can be used to refine on onboarding plan

FieldTypeDescription
createdAtDateTime
idID
nameString
updatedAtDateTime

OtherCriterionConnection

The connection type for OtherCriterion.

FieldTypeDescription
edges[OtherCriterionEdge]A list of edges.
pageInfoPageInfo!Information to aid in pagination.

OtherCriterionEdge

An edge in a connection.

FieldTypeDescription
cursorString!A cursor for use in pagination.
nodeOtherCriterionThe item at the end of the edge.

PageInfo

Information about pagination in a connection.

FieldTypeDescription
endCursorStringWhen paginating forwards, the cursor to continue.
hasNextPageBoolean!When paginating forwards, are there more items?
hasPreviousPageBoolean!When paginating backwards, are there more items?
startCursorStringWhen paginating backwards, the cursor to continue.

PendingHire

A Pending Hire Record

FieldTypeDescription
aboutString
createdAtDateTime
customFieldValues[CustomFieldValue]
dateOfBirthDate
departmentDepartment
emailString
employmentStatusEmploymentStatus
firstNameString
hrManagerEmployee
idID
lastNameString
locationLocation
managerEmployee
personalEmailString
phoneNumberString
preferredFirstNameString
preferredLastNameString
startDateDate
titleString
updatedAtDateTime
workCountryCodeString

RateLimit

Information about your current API quota

FieldTypeDescription
costIntThe cost of this query. This amount was deducted from your previous quota.
limitIntYour quota for the given period.
remainingIntThe remaining balance for your quota. Any calls that exceed this value will be throttled.
resetAtDateTimeThe time when your quota is reset to its maximum value.

SignatureRequest

An E-Signature Request for assigned to an Employee.

FieldTypeDescription
counterSignerEmployeeThe employee responsible for counter-signing this document, if applicable.
createdAtDateTime
fileFileThis is available only for completed signatures.
idID
signatureRequestTemplateSignatureRequestTemplate!
statusSignatureRequestStatus
updatedAtDateTime

SignatureRequestTemplate

A template used when assigning signature requests.

FieldTypeDescription
counterSignerEmployeeThe default employee responsible for counter-signing documents created from this template, if applicable. Individual SignatureRequest objects can override the counter signer.
createdAtDateTime
nameStringThe name of the template. This is the label administrators will see.
publicNameStringThe public-facing name of the template. This is the name the new hire will see. If this is null, new hires will see the name field.
updatedAtDateTime

State

A state

FieldTypeDescription
countryCountry
nameString
stateCodeString

Team

A Team record

FieldTypeDescription
descriptionString
emailString
idID
locationString
nameString
teamCategoryTeamCategory

TeamCategory

A Team Category Record

FieldTypeDescription
idID
nameString

TeamCategoryConnection

The connection type for TeamCategory.

FieldTypeDescription
edges[TeamCategoryEdge]A list of edges.
pageInfoPageInfo!Information to aid in pagination.

TeamCategoryEdge

An edge in a connection.

FieldTypeDescription
cursorString!A cursor for use in pagination.
nodeTeamCategoryThe item at the end of the edge.

TeamConnection

The connection type for Team.

FieldTypeDescription
edges[TeamEdge]A list of edges.
pageInfoPageInfo!Information to aid in pagination.

TeamEdge

An edge in a connection.

FieldTypeDescription
cursorString!A cursor for use in pagination.
nodeTeamThe item at the end of the edge.

UpdateDepartmentPayload

The result of running an updateDepartment mutation

FieldTypeDescription
departmentDepartmentThe updated department

UpdateLocationPayload

The result of running an updateLocation mutation

FieldTypeDescription
locationLocationThe updated location

Input Objects

AddDepartmentInput

The input object used to add a Department.

ArgumentTypeDescriptionRequired
departmentLeadID
descriptionString
emailString
nameString

AddLocationInput

The input object used to add a Location.

ArgumentTypeDescriptionRequired
addressString
descriptionString
emailString
locationLeadID
nameString

AddPendingHireInput

Specify the properties of a new PendingHire

ArgumentTypeDescriptionRequired
aboutString
customFieldValues[UpdateCustomFieldValue]
dateOfBirthDate
departmentID
emailString
employmentStatusEmploymentStatus
firstNameString!Required
hrManagerID
lastNameString!Required
locationID
managerID
middleNameString
personalEmailString
phoneNumberString
preferredFirstNameString
preferredLastNameString
startDateDate
suffixString
titleString
workCountryCodeString!Required

CustomFieldValuesInput

Limit employees to those that satisfy the specified CustomFieldValue criteria

ArgumentTypeDescriptionRequired
dateValueDateFilter
idString!Required
idValues[Int]
textValues[String]

DateFilter

Specify a range of dates using after (exclusive >), before (exclusive <), or on (exact match)

ArgumentTypeDescriptionRequired
afterDate
beforeDate
onDate

DateOfBirthFilter

Filter employees based on their date of birth

ArgumentTypeDescriptionRequired
anyValueBoolean
dateFilterDateFilter
noValueBoolean

DateTimeFilter

Specify a range of datetimes using after (exclusive >), before (exclusive <)

ArgumentTypeDescriptionRequired
afterDateTime
beforeDateTime

DeleteDepartmentInput

The input object used to delete a Department.

ArgumentTypeDescriptionRequired
idID!Required

DeleteLocationInput

The input object used to delete a Location.

ArgumentTypeDescriptionRequired
idID!Required

DepartmentFilter

Filter employees based on their department

ArgumentTypeDescriptionRequired
anyValueBoolean
departmentIds[Int]
noValueBoolean

EmailFilter

Filter employees based on their email address

ArgumentTypeDescriptionRequired
anyValueBoolean
emails[String]
noValueBoolean

EmploymentStatusFilter

Filter employees based on their Employment Status

ArgumentTypeDescriptionRequired
anyValueBoolean
employmentStatuses[EmploymentStatus]
noValueBoolean

HrManagerFilter

Filter employees based on their HR Manager

ArgumentTypeDescriptionRequired
anyValueBoolean
hrManagerIds[Int]
noValueBoolean

LocationFilter

Filter employees based on their location

ArgumentTypeDescriptionRequired
anyValueBoolean
locationIds[Int]
noValueBoolean

ManagerFilter

Filter employees based on their Manager

ArgumentTypeDescriptionRequired
anyValueBoolean
managerIds[Int]
noValueBoolean

PersonalEmailFilter

Filter employees based on their personal email address

ArgumentTypeDescriptionRequired
anyValueBoolean
noValueBoolean
personalEmails[String]

StartDateFilter

Filter employees based on their start date

ArgumentTypeDescriptionRequired
anyValueBoolean
dateFilterDateFilter
noValueBoolean

TitleFilter

Filter employees based on their title

ArgumentTypeDescriptionRequired
anyValueBoolean
noValueBoolean
titles[String]

UpdateCustomFieldValue

Used to update an employee’s Custom Field Value

ArgumentTypeDescriptionRequired
customFieldIdID!Required
valueValue

UpdateDepartmentInput

The input object used to update a Department.

ArgumentTypeDescriptionRequired
departmentLeadID
descriptionString
emailString
idID!Required
nameString

UpdateEmployee

The input object used to update an Employee.

ArgumentTypeDescriptionRequired
aboutString
customFieldValues[UpdateCustomFieldValue]
dateOfBirthDate
departmentID
emailString
employmentStatusEmploymentStatus
firstNameString
hrManagerID
lastNameString
locationID
managerID
middleNameString
otherCriteria[ID]
personalEmailString
phoneNumberString
preferredFirstNameString
preferredLastNameString
profileImageURL
startDateDate
suffixString
titleString
workCountryCodeString

UpdateLocationInput

The input object used to update a Location.

ArgumentTypeDescriptionRequired
addressString
descriptionString
emailString
idID!Required
locationLeadID
nameString

WorkCountryCodeFilter

Filter employees based on their work country code

ArgumentTypeDescriptionRequired
anyValueBoolean
noValueBoolean
workCountryCodes[String]

Scalars

Boolean

Represents true or false values.

Date

Representation of a date in YYYY-MM-DD format.

DateTime

Representation of datetime in ISO8661.

Float

Represents signed double-precision fractional values as specified by IEEE 754.

ID

Represents a unique identifier that is Base64 obfuscated. It is often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as "VXNlci0xMA==") or integer (such as 4) input value will be accepted as an ID.

Int

Represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1.

String

Represents textual data as UTF-8 character sequences. This type is most often used by GraphQL to represent free-form human-readable text.

URL

A URL-formatted String

Value

The actual value of a Custom Field Value. This type is capable of holding both Strings and Integers. Its content will depend on the fieldType of its corresponding customField.

text, long_text, confirmable

multiple_choice

multiple_select

team

employee

address

contact

date

Enums

NOTE: Enums are unquoted in user input but quotes in API output.

CustomFieldTypes

Possible type values for CustomFieldValues

ValueDescription
ADDRESSDisplayed as group of inputs. Stored as JSON.
CONFIRMABLEDisplayed as a text field where the user has to enter the value twice. Stored as a String.
CONTACTDisplayed as group of inputs. Stored as JSON.
DATEDisplayed as a datepicker. Stored as a DateTime
EMPLOYEEDisplayed as a dropdown of employees. Stored as an Employee ID.
LONG_TEXTDisplayed as a multiline text box. Stored as a String.
MULTIPLE_CHOICEDisplayed as a dropdown. Stored as a String.
MULTIPLE_SELECTDisplayed as a tag field. Stored as an Array of Strings.
TEAMDisplayed as a dropdown of teams. Stored as a Team ID.
TEXTDisplayed as a single line text field. Stored as a String.

EmploymentStatus

Possible employment statuses for an employee

ValueDescription
CONTRACTOR
FULL_TIME
INTERN
PART_TIME
TEMPORARY
TERMINATED

SignatureRequestStatus

Possible status values for a Signature Request

ValueDescription
BEING_PROCESSEDDocument is being processed by our E-Signature Vendor.
CANCELEDSignature request has been terminated.
COMPLETEDDocument has been successfully signed and verified.
ERRORCould not be completed due to an error processing the E-Signature.
WAITING_FOR_COUNTER_SIGNATUREDocument awaiting counter-signer signature.
WAITING_FOR_SIGNATUREWaiting for the employee to sign the document.