Building an Indeed Job Search Page

Using a very simple API, it's easy to add job search and listings to any site

July 7, 2014
Development, Front End

As part of launching Moore County's marketing and talent recruitment initiative we built out a simple job listing page.


The tool is being powered by a great API that Indeed provides. Indeed is a company that aggregates job postings from a large variety of sources and then makes them available in one place. The API they provide makes it really easy to grab job information for geographic regions that can also be searched. It's great because the data comes back in a consistent format that can easily be listed on a site. Each entry then can link to the original post source for complete information. Adding this tool to the Moore County site was a no-brainer.

This is the second site where we used this API. We've been happy with how simple their requests are, and how easy it is to implement. Making requests to gather job listings simple allows us the opportunity to add some fun functionality along the way.

Here are the steps we took to create the job board after registering as a publisher Indeed's Jobroll API.

1. Make an ajax call to the Indeed API

Here is a sample call and options:[PublisherID]&q=java&l=austin%2C+tx&sort=&radius=&st=&jt=&start=&limit=&fromage=&filter=&latlong=1&co=us&chnl=&userip=
  • publisher - The Publisher ID assigned during registration.
  • v - Version. Which version of the API you wish to use. All publishers should be using version 2. Currently available versions are 1 and 2. This parameter is required.
  • formatFormat. - Which output format of the API you wish to use. The options are "xml" and "json." If omitted or invalid, the XML format is used.
  • callback - Callback. The name of a javascript function to use as a callback to which the results of the search are passed. This only applies when format=json. For security reasons, the callback name is restricted letters, numbers, and the underscore character.
  • q - Query. By default terms are ANDed. To see what is possible, use our advanced search page to perform a search and then check the url for the q value.
  • l - Location. Use a postal code or a "city, state/province/region" combination.
  • sort - Sort by relevance or date. Default is relevance.radiusDistance from search location ("as the crow flies"). Default is 25.
  • st - Site type. To show only jobs from job boards use 'jobsite'. For jobs from direct employer websites use 'employer'.
  • jt - Job type. Allowed values: "fulltime", "parttime", "contract", "internship", "temporary".
  • start - Start results at this result number, beginning with 0. Default is 0.
  • limit - Maximum number of results returned per query. Default is 10
  • fromage - Number of days back to search.
  • highlight - Setting this value to 1 will bold terms in the snippet that are also present in q. Default is 0.
  • filter - Filter duplicate results. 0 turns off duplicate job filtering. Default is 1.
  • latlong - If latlong=1, returns latitude and longitude information for each job result. Default is 0.
  • co - Search within country specified. Default is us. See below for a complete list of supported countries.
  • chnl - Channel Name: Group API requests to a specific channel
  • userip - The IP number of the end-user to whom the job results will be displayed. This field is required.
  • useragent - The User-Agent (browser) of the end-user to whom the job results will be displayed. This can be obtained from the "User-Agent" HTTP request header from the end-user. This field is required.

We targeted all listings within a 50-mile radius of Pinehurst, NC for the last thirty days.

We have the results sorted by date and have seen results as soon as 15 minutes after posting. The distance parameter can be very powerful as our request returns more than 7,000 results over the past two weeks. I recommend adjusting distance and search points until you are comfortable with the volume of results.

The only other parameter we uniquely use is latlong. We wait until after we render results before using these values.

Using jQuery.ajax() to make our request,  we setup a function to perform the search:

var doSearch = function (params, done, fail) {
  $.ajax({ [Initial Parameters] }, params),
    dataType: 'jsonp',
    type: 'GET',
    timeout: 5000,
    url: ''

The function allows us the ability to call their API in a variety of ways by passing it modified parameters when necessary. Each time we need a new query we clear out their selective containers before appending the new data, which you'll see in step two. Steps three and four will show you two examples when we make new calls to the API with different parameters.

2. Render results using JS templates

Here is a sample result:

<jobtitle>Java Developer</jobtitle>
<company>XYZ Corp.</company>
<formattedLocation>Austin, TX</formattedLocation>
<date>Mon, 02 Aug 2010 16:21:00 GMT</date>
<snippet>looking for an object-oriented Java Developer... Java Servlets, HTML, JavaScript,
AJAX, Struts, Struts2, JSF) desirable. Familiarity with Tomcat and the Java...</snippet>
<formattedLocationFull>Austin, TX</formattedLocationFull>
<formattedRelativeTime>11 hours ago</formattedRelativeTime>

Using this data we can render individual items using a jQuery templating engine like JsRender.

Our template is simple to render -- creating one article block with multiple paragraphs for each value we want to display. Here is where the latlong property comes into play. We add the data attribute for latitude and longitude to an empty paragraph. After the listings and pagination links are loaded, we calculate the distance between the coordinates and Pinehurst's geo-coordinates.

3. Loading pagination links

Part of the result request includes a total number of results. Using the result, we can calculate number of pages based on the limit parameter:

var drawPaginationLinks = function (result) {
  var totalResults = result.totalResults,
  perPage = 10,
  numPages = Math.ceil(totalResults / perPage),
  $links = $('<ul></ul>');
  for ( var i = 1; i <= numPages; i++ ) {
    $links.append('<li><a href="#job-search">' + i + '</a></li>');

We can target click or touch events for each link, we can calculate the start page based on index value supplied as a text link. Then we can submit a new query by calling our doSearch function and supply it a new start parameter.

4. Setup Search

Just like the pagination links, we added click and touch events on a search form to capture input. We supply the input value as the q parameter in a new query and run it just like any others.

That's it! Give it a shot on your own or get in contact to have a helpful job search tool on your own site!



herman taylor's avatar
herman taylor
Would like website redesign
Elliot's avatar
Would it be possible for you to provide an example of the params parameter in use for the doSearch function in 2)? Am I supposed to include the =?'s that are separate each value of the simple AJAX call under 1)? If so, how should do I do this while making use of the params parameter?
RIck's avatar
Hi Patrick, Thanks for this write up it has been awesome. I have implemented almost every thing and I have it working however I am having two issues. First I would love the results that appear as soon as you load the page to be focused on the key workd "Univeristy" I have added it to the q paramater and it works however then the keyword search var get mess up and the serach button does work. any thought that may help me here ?

John's avatar
I am trying to implement the API and although I am getting the feed with the ads I wanted I don't understand how to use the onmousedown element in order for Indeed to register clicks on the jobs.
Brad Crawford's avatar
Brad Crawford
Great writeup Patrick. Unfortunately for me I know nothing about jQuery. I have a similar tutorial using PHP to display the results. Where are you seeing the total results in the XML feed? I thought Indeed limited results to 25? I can see how you could add the variable "&start=11" to the feed but how do you know the total results so you know when to end pagination? Thanks.

Leave a comment