An Independent Development Company


Integrating Greenhouse HR With WordPress

The Many Ad Agency wanted to upgrade their careers page which was currently using a simple embedded version of the Greenhouse Job Board on their website. They wanted the job board to better integrate with their website and brand to help fill a large number of job openings.


The goal was to allow The Many to continue to curate and post job openings on Greenhouse and have these posts automatically update on their website, which is built with WordPress.


Here’s how we did it:

Project Overview

Greenhouse has an API and webhooks that we utilized to automatically create, delete and update posts on wordpress. The webhooks fired any time a new job post was created, when a job post was updated and when one was removed. These webhooks triggered several functions that then used the Greenhouse API to check the current status, then made the appropriate updates to the WordPress posts.


You can read about how to create your API credentials and how to use the Greenhouse API here:

Information about webhooks can be found here:

Jobs Custom Post Type

We created a custom post type of “Careers” on WordPress which will have one post for every job opening shown in Greenhouse. The challenge here was mapping the data from Greenhouse to custom fields created with Advanced Custom Fields. Some of the data from Greenhouse could be “repeating data”, nested, etc. We had to study the way Greenhouse had organized their data in their API payload, then build fields that matched these.


This is a fairly tedious process – and to save you the trouble, you snag our ACF JSON, which can then be uploaded via ACF Tools tab to build your fields automatically below. Copy the code, paste into a JSON doc and upload.

Checking In With Greenhouse

Just to be sure our data is in sync with Greenhouse, we run a cron task every 6 hours to check in with their API. Greenhouse does say in their docs that the Webhooks won’t always fire, so this is a good practice. Granted, from our experience they are pretty reliable.


Setup the cron job:

Call Greenhouse API

In the cron job above, you’ll see we are calling a function called gh_get_all_jobs(). This function is what calls the API. Below you can see the code, remember to replace “[your_board_name]” in the CURLOPT_URL line.

Working With The Data

We now have all of the job data from Greenhouse via the API call in the last step. Now we must process this data, and you’ll see we call “gh_process_job_posts” and pass the data.


Below you’ll see we first determine the number of jobs in the data we received from Greenhouse, then we loop through all of these, and do the following:

  • Create an array of job IDs which we’ll later use to compare to the posts currently in the system to ensure we are in sync.
  • Check if the job currently exists. If it doesn’t we call a function to create the post.
  • If the post does exist, we then check the last update time to the post and see if this post needs to be updated.
  • Use the array of job IDs and compare with the careers posts – delete any that no longer exist.

That last step might not be obvious in terms of the why. But here’s the deal – the webhook should get triggered and automatically delete the post, but if this for some reason fails – during this 6 hour check the API simply won’t contain that job ID – thus we need to create the array of job IDs from Greenhouse, then compare those with what we have. If we have any job posts that don’t match the live job IDs from Greenhouse, then we need to delete it.

Get Detailed Data For Ind Job

Before we update or create a post, we’ll want to do another API call – this time to get detailed data about this individual job post. The previous API call that gives us information about all the active job openings doesn’t include all of the details we need.


Additionally we need to add a query param to the request, ?questions=true. This tells Greenhouse to provide application questions – which we can then use when building the application form.


In the code below you’ll see where we’ve passed 3 parameters to the function, $job_id, $action, $post_id. The $job_id is used in the API call. The $action is either “create” or “update”, this determines what is done with the data after it’s fetched. The $post_id is passed if the action is “update”.


Remember to change [your_board_name].

Create The Job Post

Okay finally, we can now create a job post after all of that. In the code below you’ll see where we loop through some of the data up top to standardize the formatting. From there, we’re using WordPress’s API to create a post. You’ll need to update the domain name, username, and application password to be your own.


As a bonus, if you are using the plugin All In One SEO and wish to customize the SEO headline and description for the post, you’ll see how you can do so. Otherwise, delete or comment out those lines as you won’t need them.

Updating The Job Post

The function for updating the job post is almost identical to the function for creating the job post. You can see the code here:


Finally, the last piece of the puzzle, setting up the webhooks. You’ll see in the code, first we register the webhook, then we used the function greenhouse_webhooks to determine what the webhook contained based on the “action” and then make the appropriate adjustments based on the action type.


Hi. I’m trying to setup this up for a WordPress site using the info you provided in this post. When you mention this: //setup your application username and application password here $username = ‘[your_user_name]’; // site username $application_password = ‘[your_application_password]’; Are you referring to the Greenhouse log in credentials or the WordPress log in credentials? Also, does this automatically fire up every six hours and any publish jobs that aren’t already in your Jobs custom post type? Thanks!

Posted by Dave on March 5, 2024 Reply

Replying to @Dave

Hi There- This is WordPress credentials – the application password can be set for any user. Recommend using an admin account here.

Posted by dave on March 5, 2024 Reply

Replying to @dave

Thanks Dave!

Posted by Dave on March 5, 2024 Reply

Join The Discussion:

Your email address will not be published. Required fields are marked *

Hire Us To Integrate Your Website with Greenhouse

    We Value Your Privacy. We’ll never sell or share your data.