Skip to content

Batch Requests

Description

When sending multiple related API calls, we recommend to using the **_Batch Requests_** endpoint. Batch requests enables users to send multiple API calls as one, or batched. This endpoint eliminates the need to make multiple separate requests. Some of the major benefits are highlighted below.

Sending requests as batches helps improve your application's efficiency by reducing the wait time between calls. Moreover, this method allows for interacting with and manipulating the records created earlier within the same batch by referencing the outcomes of previous calls.

Additionally, using this feature can help avoid hitting rate limits from excessive use.

Batch Requests also supports optional transactional requests/operations. Transactional requests or operations allow users the ability to abandon an entire batch should any single request fail. This means that if any request in the batch fails the entire batch can be rolled back or abandoned. Leveraging this feature can help ensure data consistency and integrity, akin to an "all or nothing" approach.

Benefits of Batch Requests

  • Improve efficiency by removing the need to wait for an API response before starting the next request.
  • Interact with previous calls in the batch by referencing their outcomes.
  • Helps avoid rate limiting your application due to excessive usage.
  • Offers optional transactional requests: abandon the batch if any call fails.

Transactional Mode

To enable this functionality, include the key IsTransaction in the request body. To set IsTransaction to true, define your batch request, like this:

json
batchBody {
	"IsTransaction": "true",
	"requests": {
		//define batch requests here
	}
}

The results of your call will depend on all requests resolving successfully.
Enabling IsTransaction can be particularly useful when leveraging the custom operator to interact with responses within the batch. In contrast, setting "IsTransaction": "false" will allow the entire batch to proceed despite their being failed requests. There are benefits to setting this key to false. For instance, if not all operations are equally critical and some progress is all that's needed. This is known as Partial Success Processing. Also, the fulfilled results will still be available and any errors will be handled appropriately.

Interacting with requests in the batch

Interacting with requests in the batch allows you to batch more requests together and reduce the need to make every API call separately. You can interact with the requests in the batch using a custom operator. This will allow you to use data from the response of any request in the batch.

Operator: $$[i].{Responsekey}

How to use the custom operator

The custom operator explained above will always start with $$ and end with $$. After the initial starting $$, you will include the index of the response in square brackets. This index will start at 0, which will be the first call in the batch request. For example, if you would like to use a value from the response of the second request in the batch you would use the number 1 in square brackets like this: [1]. After selecting your index, the last part of the operator will be the key from the response object of your selected index. For example, if you created a Candidate record and want to use the returned CandidateId, then your key will be CandidateId.

Combining our example into a usable operator, it would look like this: $$[1].CandidateId$$. This custom operator can be used in the URL or body of a request in the batch. You will see examples of how this operator is used in the examples below.

Examples

This API call is to the batch endpoint. This request will create a very basic company record as well as a candidate record and then assign that candidate record to the company that was created earlier in the batch. In this example, we have IsTransaction set to "True" as we would not like to continue in attempting to create the Candidate record if the Company record failed to get created. This will abandon the entire batch in that instance.

------------------ REQUEST -------------------

json
POST /rest/api/batch
Body: {
  "IsTransaction": true,
  "requests": [
    {
      "HttpMethod": "POST",
      "url": "https://www2.pcrecruiter.net/rest/api/companies",
      "content": {
        "CompanyName": "ABC Company"
      }
    },
    {
      "HttpMethod": "POST",
      "url": "https://www2.pcrecruiter.net/rest/api/candidates",
      "content": {
        "FirstName": "John",
        "LastName": "Doe",
        "CompanyId": "$$[0].CompanyId$$" // Use the operator to set the CompanyId to the variable from the call above
      }
    }
  ]
}

------------------ RESPONSE ------------------

json
{
  "Responses": [
    {
      "ID": 0,
      "Response": {
        "CompanyId": 1234567890
      }
    },
    {
      "ID": 0,
      "Response": {
        "CandidateId": 0987654321
      }
    }
  ]
}

TIP

Keep in mind that this example created very basic records to reduce complexity for the example. The request body and queries can be used the same as they are individually outside of the batch. This means any data you can request or provide outside of a batch request can be used within a batch request.

This example will return a Candidate Record and then search for Activities and Notes for that Candidate. This will allow us to combine three separate API requests into one singular batch. This request differs from the first example by using the custom operator in the URL of the request instead of the body. This example also shows how to add queries and restrict the returned fields in batch requests, which can be found within our first and second requests in the batch using the content key.

------------------ REQUEST -------------------

json
POST /rest/api/batch
Body: {
  "IsTransaction": false,
  "requests": [
    {
      "HttpMethod": "GET",
      "url": "https://www2.pcrecruiter.net/rest/api/candidates/9876543210",
      "content": {
        "Fields": "CandidateId, FirstName, LastName, Status" 
                 }
    },
    {
      "HttpMethod": "GET",
      "url": "https://www2.pcrecruiter.net/rest/api/candidates/$$[0].CandidateId$$/Activities",
      "content": {
        "Query": "ActivityDate ge '2024-02-12T12:50:00' AND ActivityDate le '2024-02-12T12:55:00'"
                 }
    },
    {
      "HttpMethod": "GET",
      "url": "https://www2.pcrecruiter.net/rest/api/candidates/$$[0].CandidateId$$/Notes",
    }
  ]
}

------------------ RESPONSE ------------------

json
{
  "Responses": [
    {
      "ID": 0,
      "Response": {
        "CandidateId": 9876543210,
        "FirstName": "John",
        "LastName": "Doe",
        "Status": "Candidate"
      }
    },
    {
      "ID": 0,
      "Response": {
        "TotalRecords": 1,
        "Results": [
          {
            "UserName": "SAMPLE",
            "ActivityDate": "2024-02-12T12:52:10.193",
            "ActivityId": 1234567890,
            "CandidateId": 9876543210,
            "ActivityType": "SAVENAM",
            "ActivityResult": null
          }
        ]
      }
    },
    {
      "ID": 0,
      "Response": {
        "TotalRecords": 1,
        "Results": [
          {
            "CandidateId": 9876543210,
            "Date": "2024-02-12T12:48:13",
            "UserName": "SAMPLE",
            "Method": "(API)",
            "Text": "This is an example note.",
            "NoteId": "1234567890",
            "Bookmarked": false,
            "DateBookmarked": null,
            "Edited": false
          }
        ]
      }
    }
  ]
}

WARNING

You cannot currently use the custom operator from a response that is a search result. In the above example, we are querying activities and notes. You would not be able to use data in the response of those queries in future requests in the batch as the response object is wrapped in the results array. This may be a feature available to batch requests in the future.

If you are querying for records, you can still use our batch requests feature, you will just need to query for the record outside of the batch and then use the data from the response of your query to construct your batch for all your other requests. Here is a quick example of how that can be done.

Python
import requests

#Define API URL
api_url_base = "https://www2.pcrecruiter.net/rest/api/"

#Define request headers such as Authorization token
requestheaders = {"Authorization": "BEARER " + access_token}

#Make the Query to retrieve a record
query = requests.get(url=api_url_base + "candidates?Query=FirstName eq John", headers = requestheaders)

#Convert response into JSON object
data = query.json()

#Find the ID of the Candidate we were querying for
candidateId = data['Results'][0]['CandidateId']

#Construct our Batch body and input the CandidateId from the previous API request
batchBody = {
  "IsTransaction": "false",
  "requests": [
    {
      "HttpMethod": "GET",
      "url": "https://www2.pcrecruiter.net/rest/api/candidates/"+str(candidateId)+"/Activities",
      "content": {
        "Query": "ActivityDate ge '2024-02-12T12:50:00' AND ActivityDate le '2024-02-12T12:55:00'"
                 }
    },
    {
      "HttpMethod": "GET",
      "url": "https://www2.pcrecruiter.net/rest/api/candidates/"+str(candidateId)+"/Notes",
    }
  ]
}

#Send the batch request
batch = requests.post(url=api_url_base + "batch", headers = requestheaders, json = batchBody)

#Print the response from our batch
print(batch.json())
JavaScript
import axios from 'axios';

//Define API URL
const api_url_base = "https://www2.pcrecruiter.net/rest/api/";

//Define request headers such as Authorization token
const requestheaders = { "Authorization": "BEARER " + access_token };

//Make the Query to retrieve a record
axios.get(api_url_base + "candidates?Query=FirstName eq John", { headers: requestheaders })
  .then(response => {
    const data = response.data;
    //Find the ID of the Candidate we were querying for
    const candidateId = data['Results'][0]['CandidateId'];

    //Construct our Batch body and input the CandidateId from the previous API request
    const batchBody = {
      "IsTransaction": "false",
      "requests": [
        {
          "HttpMethod": "GET",
          "url": api_url_base + "candidates/" + candidateId + "/Activities",
          "content": {
            "Query": "ActivityDate ge '2024-02-12T12:50:00' AND ActivityDate le '2024-02-12T12:55:00'"
          }
        },
        {
          "HttpMethod": "GET",
          "url": api_url_base + "candidates/" + candidateId + "/Notes",
        }
      ]
    };
    //Send the batch request
    axios.post(api_url_base + "batch", { headers: requestheaders, data: batchBody })
      .then(batchResponse => {
        //log the response from our batch to the console
        console.log(batchResponse.data);
      })
      .catch(error => {
        console.error("Error with the batch request:", error);
      });
  })
  .catch(error => {
    console.error("Error with the candidate query:", error);
  });