Indeed Alliances ATS Disposition Website

Overview

The disposition API expects a report file to be sent that contains information about application updates. The following fields are expected (more formally defined below) in the report:

  • Indeed ApplyId
  • Disposition Timestamp
  • Normalized Disposition Status

Full code examples for using the API are available.

Frequency

Updates should be sent daily or when an application status changes.

Typical Integration Setup

Partners should set up a scheduled job that runs daily which generates a report of status changes for applications. An example would be a csv with headers: disposition_timestamp, apply_id and status. Each row/record would then represent an application's change in application state. A single applyid can have multiple events/records per report (e.x. if an application is updated multiple times per day).

Note that the csv file should only contain applications that have h ad a change in status since last upload. Here are examples of correct and incorrect csv file uploads for a given series of application status changes.

Sample Correct CSV

Sample Correct XML

Incorrect

Day 1 - File 1
disposition_timestamp apply_id status
2019-01-01 appid001 New

Day 2 - File 2
disposition_timestamp apply_id status
2019-01-01 appid001 New
2019-01-02 appid002 New

Day 3 - File 3
disposition_timestamp apply_id status
2019-01-02 appid002 New
2019-01-03 appid001 Contacted
2019-01-03 appid003 New

Note that every apply_id is included in every day's upload even if no change was made to the application status
Correct

Day 1 - File 1
disposition_timestamp apply_id status
2019-01-01 appid001 New

Day 2 - File 2
disposition_timestamp apply_id status
2019-01-02 appid002 New


Day 3 - File 3
disposition_timestamp apply_id status
2019-01-03 appid001 Contacted
2019-01-03 appid003 New


Note that an apply_id is included only when the status has changed (e.g. appid001 is only included in day 1 and 3)

Field Definitions

Field Required? Description
apply_id Yes This is the id field in the Indeed Apply JSON application data. For more information this references the id field here: http://techdocs.indeedeng.io/json-application-data/
status Yes Normalized application status. This field requires at least one normalized status for each applyId. Over time, the same applyId may return multiple statuses. Your system should only return a finite number of statuses to describe an application. Do not send customer-specific defined application states.

The following statuses are examples of typical application stages:
Sample Application Status Condition
New The application arrived via Indeed Apply
Contacted A recruiter contacted a candidate even if they haven’t manually set a status (e.g., phone screens)
Screened An interview has been scheduled with the candidate
Offer An offer of employment has been sent to a candidate
Hired The candidate accepted an offer of employment
Rejected A candidate has been explicitly rejected or all remaining candidates rejected after the role closed
disposition_timestamp Yes A timestamp for when the status change occured in standard format ISO 8601 format with timezone information.
E.x. November 5, 1994 at 8:15 am Eastern Time would be: 1994-11-05T08:15:30-05:00

API Instructions (for daily exports)

Overview/Integration

Our API allows your organization to programmatically deposit disposition information. The integration takes two steps:

1. Obtain a presigned Amazon S3 URL by POST request to this API using the assigned API Key.

2. Make a PUT request to upload the file to the URL returned in Step 1.

Note: To prevent uploading files with the same name, use a naming convention that allows you to distinguish your files from other files in your organization.

Obtaining a signed S3 URL

To receive the signed S3 bucket URL, create a POST request to our API with the file names you are uploading. A presigned upload URL will be returned for each file. Requirements and responses are described below:

Required Request Headers

  • Content-Type: application/json
  • Accept: application/json
  • token: <YOUR API KEY>
    • Type: string, 32 characters

Parameters

  • file_names
    • Type: JSON list of file names to get an upload URL.
    • Note: Please do not pass a file path here, only the file's name
  • Accepted Extensions: xls, xlsx, csv, tsv, txt, xml

Limitations

  • Files must be no larger than 5 GB
  • The URL generated will expire 1 hour after generated by this API.
  • All files must pass extension validation. Files with unsupported extensions will not upload.

Success Response

A HTTP status of 200 and a JSON object/dictionary is returned with keys as the file_names sent and values corresponding to the presigned S3 URL. See examples below for details.

Error Response

A HTTP status non 200 and dictionary containing the keyError will be returned and give more information.

Uploading File

Once you have the presigned URL, you can upload files to the AWS Bucket using a PUT request. An example of doing so is shown below, however you may also refer to the official AWS documentation.

Examples

Click on a tab below for an example of successfully implementing the integration in a particular language.

The following examples show how to integreate with the system using only bash and unix-based curl command.

#  Get the presigned URLs
curl \
-H "Content-Type: application/json" \
-H "token: XXXXXXXXX" \
-H "Accept: application/json" \
--request POST \
--data '{"file_names":["test_file_1.csv","test_file_2.csv"]}' \
https://indeed-atsdi.com/api/get_upload_url

##### API Response #####
# {
#    "test_file_1.csv": "https://blah.s3.amazonaws.com/presigned_url_1",
#    "test_file_2.csv": "https://blah.s3.amazonaws.com/presigned_url_2"
# }
##### END Response #####

#  Upload files to S3, one at a time.

#  Put pre-signed URL in quotes.
curl -X PUT -T /path/to/test_file_1.csv \
-L "https://blah.s3.amazonaws.com/presigned_url_1"


#  Put pre-signed URL in quotes.
curl -X PUT -T /path/to/test_file_2.csv \
-L "https://blah.s3.amazonaws.com/presigned_url_2"

The following examples show how to integrate with the system using the requests library in Python2 or Python3.

import requests
import json

url = 'https://indeed-atsdi.com/api/get_upload_url'
file_paths = ['/path/to/test_file_1.csv', '/path/to/test_file_2.csv']
API_KEY = 'XXXXXXX'

# File tuple [0] = path, [1] = basename.
file_infos = [(fp, ntpath.basename(fp)) for fp in file_paths]


headers = {
    'Accept': 'application/json',
    'Content-Type': 'application/json',
    'token': API_KEY
}

#  This gets the presigned URLs
r = requests.post(url,
                  headers=headers,
                  data=json.dumps({'file_names': [fi[1] for fi in file_infos]}))
try:
    r.raise_for_status()
except:
    print("Error occurred.")
    print (r.json())

#  Upload file(s) to AWS.
s3_signed_urls = r.json()
for file_info in file_infos:
      with open(file_info[0], 'rb') as data:
          upload_result = requests.put(s3_signed_urls[file_info[1]], data=data)
          try:
              upload_result.raise_for_status()
          except:
              print("Issue uploading file to AWS.")

The following examples show how to integrate with our system using only standard library packages in Ruby.

require 'net/http'
require 'net/https'
require 'uri'
require 'json'

Tuple = Struct.new(:_1, :_2)

api_url = URI.parse('https://indeed-atsdi.com/api/get_upload_url')
file_paths = ['/path/to/test_file_1.csv', '/path/to/test_file_2.csv']
api_key = 'XXXXXXX'

names = []
file_info = []
file_paths.each do |path|
  file_info.push(Tuple.new(path, File.basename(path)))
  names.push(File.basename(path))
end

header = {'Accept': 'application/json',
          'Content-Type': 'application/json',
          'token': api_key}
data = {file_names: names}

#  Access indeed api
api_response = nil
Net::HTTP.start(api_url.host, :use_ssl => true) do |http|
  api_response = http.send_request("POST", api_url.request_uri, data.to_json, header)
end

case api_response
when Net::HTTPSuccess
  json = JSON.parse(api_response.body)

  # Upload to S3.
  file_info.each do |upload_file|
    s3_url = URI.parse(json[upload_file._2])
    file = File.open(upload_file._1, "rb")
    file_data = file.read
    file.close
    s3_response = nil
    Net::HTTP.start(s3_url.host, :use_ssl => true) do |http|
        s3_response = http.send_request('PUT', s3_url.request_uri, file_data, {
        # Content type has to be here, even if set to '', or else 403 error.
         "content-type" => '',
        })
      end
    case s3_response
    when Net::HTTPSuccess
      print 'Successfully uploaded ' + upload_file._1 + "\n"
    else
      print 'Error uploading file ' + upload_file._1 + "\n"
      print s3_response.inspect + "\n"
    end
  end
else
  print 'Bad Response from Indeed API.' + "\n"
  print api_response.inspect + "\n"
end

The following examples show how to integrate with our system using only standard library packages in PHP. This does assume you have the curl PHP module installed on the system.

<?php
class IndeeddispositionClient{
	private static $api_key = 'XXXXXXXXX';
	private static $api_url = 'https://indeed-atsdi.com/api/get_upload_url';

  static function get_s3_url($filename) {
    $url = self::$api_url;
    $data = '{"file_names":["'.$filename.'"]}';
    $headers = array(
      'Content-Type: application/json',
      'token: ' . self::$api_key,
      'Accept: application/json'
    );
    $options = array(
      CURLOPT_POST => 1,
      CURLOPT_POSTFIELDS => $data,
      CURLOPT_HTTPHEADER => $headers,
      CURLOPT_RETURNTRANSFER => 1
    );

    $curl = curl_init($url);
    curl_setopt_array($curl, $options);
    $res = curl_exec($curl);
    curl_close($curl);

    return $res;
  }

  static function upload_to_s3($file_path_string, $signed_url){
      $fh = fopen($file_path_string, 'rb');
      $options = array(
        CURLOPT_VERBOSE => 1,
        CURLOPT_POST => 1,
        CURLOPT_RETURNTRANSFER => 1,
        CURLOPT_URL => $signed_url,
        CURLOPT_INFILE => $fh,
        CURLOPT_INFILESIZE => filesize($file_path_string),
        CURLOPT_PUT => 1
      );
      $ch = curl_init();
      curl_setopt_array($ch, $options);

      $result = curl_exec($ch);
      if (curl_errno($ch)) {
          echo 'Error:' . curl_error($ch);
      }
      fclose($fh);
      curl_close($ch);
      return $result;
    }
}


$file_paths = array("test_file_1.csv","test_file_2.csv");

foreach ($file_paths as $file_path){
  if (!file_exists($file_path)) {
    print 'Cannot find file '.$file_path."\n";
    throw new Exception('File not found '.$file_path);
  }
  $file_name = basename($file_path);
  print "Uploading ".$file_name ."\n";
  print "... ".$file_name ."\n";
  $s3_url = json_decode(IndeeddispositionClient::get_s3_url($file_name), true)[$file_name];
  $result = IndeeddispositionClient::upload_to_s3($file_path, $s3_url);

  print $result;

  print "\nFinished with ".$file_name ."\n";
}

?>


Generate Partner Specific Code

Fill the fields below and click "Generate Code" to replace the above code snippets with code specific to your API key.

Generate Code

Sanitize Request API

If you need to request all dispositionr records for a certain application id to be deleted, please use the API below to make a SANITIZE request. Once received , we will delete all records from our system for this ID within 48 hours.

The following examples show how to integrate with the system using only bash and unix-based curl command.

curl \
-H "Content-Type: application/json" \
-H "token: XXXXXXXXX" \
-H "Accept: application/json" \
--request POST \
--data '{"apply_ids":["123","456"]}' \
https://indeed-atsdi.com/api/sanitize

The following examples show how to integrate with the system using the requests and json libraries in Python3.

import requests
import json


API_KEY = 'XXXXXXX'
apply_ids = ['123', '456']

headers = {
    'Accept':
    'application/json',
    'Content-Type': 'application/json',
    'token': API_KEY }

r = requests.post('https://indeed-atsdi.com/api/sanitize',
    headers=headers,
    data=json.dumps({'apply_ids':apply_ids}))


Generate Code

Request Help

To receive assistance, please contact our integration support team at: external-disposition-support@indeed.com