Search API - Using the REST API

The iCIMS API now supports the ability to query (search) for System IDs matching a given set of criteria. Up to 1,000 matching results will be returned at a time, and more can be fetched using paging filters. The ability to Search via the iCIMS API will work for the Person, Job, Company, Recruiting Workflow and iForm searches.

Important Notes:

  • In order to utilize the Search API, a user must be part of the Integration User group.
  • The results of the search will return System IDs. iCIMS cannot customize the result set (i.e. custom response payloads).
  • Search API supports the ability to search for the text value of a list item (rather than requiring the Node ID of that particular list item).  
  • All requests are parsed and all responses are created using the JSON standard Java library, which can be found at http://json.org/java/. Using libraries from json.org will ensure compatibility, even if you integrate using a different language.
  • At this time, iCIMS does not support real-time usage of the Search API.  The Search API is currently optimized for synching data between two different systems in the background. (For example, to create a customizable Career Portal, job information should be synced from iCIMS into a database or content repository.  Then, the external repository could provide data for a Portal.)

 

Caching and the Staleness Parameter

The URL also takes an optional GET parameter called "staleness." The staleness argument takes a positive integer number of minutes. This indicates how old the search results may be when returning results. For example, using a staleness of 5 means that the returned results may be up to 5 minutes out of date. If there are already recent enough results in our internal cache, those will be returned; otherwise, a new search will be run and return new results. If no staleness is specified, it will default 15 minutes.

Search API Endpoints

The following endpoints have been set-up to support Person, Job, Company, Recruiting Workflow and iForm API Searches.

Person Searches

  • /search/people           
  • Example: https://api.icims.com/customers/<customerID>/search/people

Job Searches             

  • /search/jobs
  • Example: https://api.icims.com/customers/<customerID>/search/jobs

Company Searches  

  • /search/companies   
  • Example: https://api.icims.com/customers/<customerID>/search/companies

Recruit Workflow Searches

  • /search/applicantworkflows    
  • Example: https://api.icims.com/customers/<customerID>/search/applicantworkflows

iForm Searches

  • /search/forms            
  • Example: https://api.icims.com/customers/<customerID>/search/forms

All above search endpoints support both GET requests and POST requests. The POST method is provided for convenience to avoid escaping, unicode, and data length issues, but otherwise functions the same as the GET method. 

URL: 

https://api.icims.com/customers/{customerID}/search/{profiletype}?searchJson={searchQueryHere}

Action
Definition
Get: 

The format for a GET request is: /search/<profiletype>?searchJson=<searchQueryHere>

The searchJson parameter must be URL-encoded for GET requests due to illegal URL characters in the JSON string. POST requests should not URL-encode the payload.

The GET request search query must be encoded before passing the query within the request.

All Search API endpoints expect the search query to be in JSON format and must always specify at least one search filter.

The format of the JSON request for the API is as follows and includes the following types of elements:

  • Filter group (JSON Object)
    • Possible attributes for the filter group are:
      • data: Takes a JSON Array of filters.
      • operator (optional): Takes either '&' or '|'. Dictates whether to combine filters in this group using an AND or OR operation. If it's omitted, '&' is assumed.
      • children: Takes a JSON Array of filter groups.
  • Filter (JSON Object)
    • Possible attributes for the filter are:
      • data: The friendly name of the filter.
      • value: The value to compare against for determining what results to return.
      • secondaryValue (optional): Some filters (particularly date filters) require two values. This attribute is for the second one.
      • operator (optional): Takes '=', '<', '<=', '>', '>=', or '!='. Defines what operation to perform for the comparison. Not all filter types support all of these options.

The query is a JSON Object representing a single top-level filter group, which may contain more filter groups as children.

Note: For a full list of currently available filters and operators, please review the lists below.

Available Filters

In addition to standard fields being allowed as search filters, custom fields and custom collections can also be used as search filters. The comprehensive list of search filters that exist in the search API schema list are below. Four hash signs (####) designates the custom field ID (i.e., RCF, JCF).

person

  • id
  • firstname
  • middlename
  • lastname
  • email
  • folder
  • externalid
  • addresszip
  • addresscountry
  • addresscity
  • addressstate
  • createddate
  • updateddate
  • employeeinfo (relation)
  • customfield#### (relation)
  • collectionfield####text
  • collectionfield####number
  • collectionfield####date
  • collectionfield####listnode
  • collectionfield####person
  • collectionfield####job

employeeinfo

  • startdate
  • hiredate
  • enddate

job

  • id
  • folder
  • jobnumber
  • externalid
  • jobtitle
  • jobtype
  • numberofpositions
  • numberofpositionsremaining
  • hiretype
  • startdate
  • duedate
  • positionlevel
  • positiontype
  • positioncategory
  • createddate
  • updateddate
  • customfield#### (relation)
  • collectionfield####text
  • collectionfield####number
  • collectionfield####date
  • collectionfield####listnode
  • collectionfield####person
  • collectionfield####job
  • job.jobpost.enddate
  • job.jobpost.isposted
  • job.jobpost.postdate
  • job.jobpost.postedtohub
  • job.jobpost.status
  • job.jobpost.type
  • job.joblocation.addresscity
  • job.joblocation.addressstate
  • job.joblocation.addressstatetext
  • job.joblocation.addresscountry
  • job.joblocation.addresscountrytext
  • job.joblocation.zipradius
  • job.joblocation.companyid
  • job.postedto

company

  • id
  • name
  • addresscity
  • addresszip
  • addresscountry
  • addressstate
  • createddate
  • updateddate
  • customfield#### (relation)
  • collectionfield####text
  • collectionfield####number
  • collectionfield####date
  • collectionfield####listnode
  • collectionfield####person
  • collectionfield####job

applicantworkflow

  • bin
  • status
  • updateddate
  • person (relation)
  • job (relation)
  • customfield#### (relation)
  • collectionfield####text
  • collectionfield####number
  • collectionfield####date
  • collectionfield####listnode
  • collectionfield####person
  • collectionfield####job

formdata

  • id (Backend Note: Schema - FormDataIDNumeric, alias FormDataID - label="Form Data ID")
  • formid (Schema - FormID - label="Form Name")
  • formstatus
  • updateddate
  • completeddate
  • form (relation) (
    • Example: {"name":"formdata.form.formname","value":['[form name]']

form

  • formname

customfield####

  • text (this includes single select drop down type)
  • number
  • date
  • listnode
  • person
  • job

Note: All ID filters must be added manually to the query JSON. In addition, password and custom password fields are not supported through the Search API and cannot be used as filter criteria.

Available Filter Operators

The following list of filter operators that can be used within a given Search Query is below. (Note: If none is specified, '=' is assumed. These are not all valid for all filter types.)

  • '='
  • '!='
  • '<'
  • '>'
  • '<='
  • '>='
Basic Example

In following example, the "operator" for the filter group is omitted. It is assumed to be "&", but in this case it makes no difference, since there is only one filter.

{

     "filters": [

           {

                "name": "person.firstname",

                "value": ["Mike"],

                "operator": "="

           }

     ]

}

Multiple Filters

In the following example, the "operator" for the filters are omitted. They are assumed to be "=".

The operator for the filter group is explicitly included and set to "&". It could also be "|".

{

     "filters": [

           {

                "name": "person.firstname",

                "value": ["Mike"]

           },

           {

                "name": "person.lastname",

                "value": ["Smith"]

           }

     ],

     "operator": "&"

}

Custom Field Filters

Assume that person profiles have a custom field, "rcf2145," that stores text data; the following example will demonstrate how to query on this custom field data. Other custom field types can be queried using "number", "date""listnode""person", or "job" filters, if the field supports those filter types.

{

     "filters": [

           {

                "name": "person.customfield2145.text",

                "value": ["test"]

           }

     ]   

}

Collections are similar, however, they do not get a dot. The same arguments are valid: "text", "number", "date", "listnode", "person", or "job". Assume now that there is a numerical custom field "rcf2231" that exists within a collection on the person profile; the following example will demonstrate how to query on this data, as well as how to specify a ">" operator. Note that this operator only works with numerical field types.

{

     "filters": [

           {

                "name": "person.collectionfield2231number",

                "value": ["1234"],

                "operator": ">"

           }

     ]

}

Date Filters

Dates in the Search API may be in either a yyyy-MM-dd hh:mm a or a  yyyy-MM-dd format (with no time added). All dates in the Search API will be assumed to be in the UTC time zone, regardless of user settings; if no time is specified, Midnight UTC will be assumed. If a date is not formatted properly, it will be ignored. This is in line with the core Search Engine. This brings Search API dates in line with dates elsewhere in the API.

If a date is used via the Search API that is in a format that is not recognized, then the search will assume the most lenient date range, allowing all results through. Date filters also do not support blank searches; i.e. a data must be specified when using the value or secondary value search filter.

For custom date ranges, the JSON will take a VALUE parameter as the initial start date and SECONDARYVALUE as the end date. An example of a Date search request is below:

{
    "filters": [
        {
            "secondaryValue": [
                "2013-06-10 11:59 PM"
            ],
            "name": "person.updateddate",
            "value": [
                "2013-05-01 12:00 AM"
            ],
            "operator": "="
        }
    ],
    "operator": "&"
}

Using the Get SQL button on the search engine will now show dates in the correct format and time zone to match what you selected as your filter.

Date filters use the "secondaryValue" of the filter. A date filter may omit either the value or the secondaryValue. Searches that include valid values for both will be constrained only to entries between those times. If a date is invalid or omitted, then that boundary is removed and the search will extend indefinitely.

The following example search will find all entries between midnight June 10th and June 17th of 2013:

{

     "filters": [

           {

                "name": "person.updateddate",

                "value": ["2013-06-10"],

                "secondaryValue": ["2013-06-17"]

           }

     ]

}

If the end date is omitted, the search will find all entries starting at 5:00 PM on September 5th, with no end boundary:

{

     "filters": [

           {

                "name": "person.updateddate",

                "value": ["2013-09-05 05:00 PM"]

           }

     ]

}

To get all entries before the specified date, omit the value and specify a secondaryValue.

And/Or Nesting

To combine filters in a more complicated way, use the "children" attribute on the filter group. For example, the following query could be used to find a person with a first name of "John" or "Jane", but always with a last name of "Doe".

{

     "filters": [

           {

                "name": "person.lastname",

                "value": ["Doe"]

           }

     ],

     "operator": "&",

     "children": [

          {

                "filters": [

                     {

                           "name": "person.firstname",

                           "value": ["John"]

                     },

                     {

                           "name": "person.firstname",

                           "value": ["Jane"]

                     }

                ],

                "operator": "|"

           }

     ]

}

This query uses a child grouping that contains the filters for checking the first name of John or Jane, using the "|" operator on the filter group. The top level filter group uses the "&" operator to compare the results of the child groups to the native filter it has in the top group.

Paging

Results are always sorted in ascending order by System ID. If there are more than 1000 results, only the first 1000 will be displayed. To fetch the next 1000 results, appending a filter on the ID. For example, assume the following query returns more than 1000 results:

{

     "filters": [

           {

                "name": "person.lastname",

                "value": ["Smith"]

           }

     ]

}

When reading through the results, keep track of the last system ID that is returned, which is guaranteed to be the greatest one.

Assume for the following example that the highest system ID returned by the above query is 1234. By modifying the query in the following way, the next 1000 results will be fetched:

{

     "filters": [

           {

                "name": "person.lastname",

                "value": ["Smith"]

           },

           {

                "name": "person.id",

                "value": ["1234"],

                "operator": ">"

           }

     ]

}

To fetch subsequent pages, replace the "1234" value with the new highest system ID from the previous page's results.

Responses

Links to the search endpoint should be added to the generic API information request results.

All profile and form references returned by the API will now include a "self" attribute that contains a link to the current profile via the API. All links that appear in the headers for all API integrations will now also appear in the JSON response body. The headers are not removed from API requests that already have them; the new "self" attributes exist in addition to the headers for previously existing requests.

The results will be in a standardized format, also formatted as JSON.

{

     "searchResults": [

           {

                "id": "1",

                "self": "LINK"

           },

           {

                "id": "2",

                "self": "LINK"

           }

     ]

}

The "id" is the System ID, which is useful for paging and making API requests to get more information about a specific profile. The "self" attribute provides a direct link to make a request for more information from that profile as a convenience, so you won't have to generate it yourself. The results will always be ordered by "id" in ascending order, so for paging, you only have to look at the last result in the JSON array.

If the search has no results, it will return an empty searchResults array:

{

     "searchResults": []

}

Any errors will be returned in the following format. The error message is an English-readable message that will contain information on what went wrong with your query. For more on error handling, please see the following section of this webpage.

{

     "errors": [

           {

                "errorMessage": "MESSAGE",

                "errorCode": "CODE"

           }

     ]

}

Error Handling

The following error messages can be sent as a response when searching the API:

  • Scenario: Must specify at least one filter.
  • Error Message: At least one filter must be specified
  • Scenario: Invalid filter or hidden filter
  • Error Message: The following filter is either not valid or hidden: [filter]
  • Scenario: Invalid filter operator
  • Error Message: The following filter operator is not valid in the given context: [operator]
  • Scenario: Invalid group operator
  • Error Message: The following group operator is not valid in the given context: [operator]
  • Scenario: Unrecognized filter attribute
  • Error Message: The following filter attribute is unrecognized: [attribute]
  • Scenario: Unrecognized group attribute: xxxx
  • Error Message: The following group attribute is unrecognized: [attribute]
  • Scenario: Unknown parsing error.
  • Error Message: An unknown parsing error occurred

Any invalid filters added into the API search query will be rejected and an error will be shown indicating which one is invalid. Blank filter names will be rejected and filter names that include criteria for the wrong search type. For example, the following are now invalid:

  • A filter where name is not defined at all.
  • A filter where name is defined as ''.
  • A filter on a person search that has a name of 'job.*' or vice versa.

When specifying an altogether invalid operator, the request will be denied. If you choose the wrong operator for a specific filter, however, it will still be allowed through. If the query specifies an attribute with an unrecognized name (e.g., 'name1' instead of 'name'), the entire query will be rejected (even if the rest of the query is fine).

Valid operators for filters are different than for groups, and it validates based on context.

When specifying an invalid list node id, all results will be filtered out. Searches that do not specify at least one filter are rejected.