Guidelines
Please note that the HTTP specification dictates that all URLs, URIs, and parameters are case sensitive. In order to avoid confusion, iCIMS has made all URLs, URIs, parameters, headers, and JSON field names lowercase. The JSON document structure and metadata is lowercase, but the data contained within the JSON document is of mixed case. Users should always assume that they should be using entirely lowercase letters.
Backwards Compatibility
iCIMS may add JSON fields (or HTTP headers) at any time, but we will not change or remove existing JSON fields. This type of change should not cause issues to any existing integrations. As such, iCIMS recommends that partners design each integration with these guidelines in mind to avoid any break in the event that iCIMS makes these benign changes. iCIMS recommends that developers treat the JSON payloads as a map of key value pairs and ignore new keys that appears in the map. iCIMS discourages the use of strict schema validation of JSON messages in our API to allow the future enrichment of our API with new pieces of information.
API Endpoints
iCIMS maintains two endpoints for its customers’ integration traffic: api.icims.com and api-eu.icims.com.
Customers and vendors working with customers hosted in iCIMS’ EU database must use api-eu.icims.com to ensure that API requests are routed to the customer using infrastructure hosted within the EU, allowing the customer to meet their EU regulatory obligations.
HTTP Transport Policy
iCIMS has guidelines regarding the transport settings used while interacting with iCIMS Web Service endpoints. All API Web Service traffic is required to use the HTTPS protocol. iCIMS will include a Strict Transport Security Header with each response with a maximum age of 90 days.
iCIMS only supports HTTP version 1.1, and all other HTTP versions will be rejected with a 505-HTTP Status Code.
By default and unless otherwise specified, an HTTP response and request should specify a valid Content-Length Header. All URL endpoints will reject request bodies greater than 2MB in size, except for exceptional endpoints such as those dealing with documents. If a client request is rejected, a 413-Request Entity Too Large Status Code is returned.
The default character encoding for JSON is UTF8 and the iCIMS API supports this specification.
Sample Request Headers
Host:api.icims.com
Connection: Keep-Alive
Content-Encoding:gzip
Accept-Encoding:gzip
Accept-Language:en-US
Sample Response Headers
Strict-Transport-Security:max-age=7776000
Connection:Keep-Alive
Content-Encoding: gzip
Allow:GET,POST,PATCH,DELETE,HEAD.
X-Content-Type-Options:nosniff
IP Address Restrictions
The Platform requires the use of IP address-based restrictions to restrict the range of network addresses allowed to use a set of credentials. In the event that an API request is made from an IP address not part of the configured IP Address range, a 403 Forbidden response code will be returned along with a specific error code such as 26:You may not access this services. Your IP address <Your IP Address> is not allowed.
Rate Limits
iCIMS enforces a rate limit on its Web Services API to ensure continuity of service for all customers. API clients are limited to 10,000 API calls per day per customer by default. As part of each Platform response, iCIMS includes the current rate limit set for the customer’s system, the number of available calls left for the day, and the number of seconds until the rate limits are reset. The rate limits are daily, and iCIMS treats the end of day as 12:00AM UTC. In the event an API client exceeds the rate limit for a given customer, a 429-Too Many Requests Status Code will be returned along with the X-RateLimit-* HTTP headers. API resources can enforce their own rate limit as a subset of the iCIMS global rate limit.
Sample Rate Limits Message:
X-RateLimit-Limit:10000
X-RateLimit-Remaining:9893
X-RateLimit-Reset:28800
Security
Beginning March 30, 2017, all integration traffic must use TLS 1.2 (or higher) encryption. Traffic utilizing SSL or TLS 1.0 (or lower) will not be allowed.
OAuth 2.0
Important Note: iCIMS recommends that all partners adopt OAuth 2.0 as their authentication method to authenticate API users. For information regarding Basic HTTP Authentication, review the Legacy API Authentication page.
iCIMS REST APIs are protected using the standards based OAuth 2.0 security protocol. In order for partners to access iCIMS APIs, they must establish an identity for the service calling the API, obtain permission to call the API by obtaining an access token, and use the access token as proof of authorization and identity to call APIs. Please review the Authenticating API Calls with OAuth 2.0 section for full details.
HMAC
The iCIMS Talent Platform also allows users to authenticate using HMAC. Please review Authenticating Requests Using HMAC for full details.
Authenticating API Calls with OAuth 2.0
Service Identity
In OAuth 2.0, the service's identity is represented by a client_id and a client_secret. The partner uses the client_id as a kind of username for their service; it acts as a public identifier. The partner uses the client_secret as a kind of password for their service; it must be kept confidential and never be exposed or stored in an unencrypted medium. The partner’s organization can have multiple credentials associated with it, but this is typically for when separate security contexts are necessary for separate products, services, or code bases.
Important Note: The partner should not have a credential for each iCIMS customer or tenant but instead should re-use their credentials and submit a request to their iCIMS Integration Specialist to grant their client_id access to a specific customer.
Obtaining Service Identity Credentials
To access an iCIMS API, the partner must obtain identity credentials for their service. If the partner’s service does not have a client_id and client_secret, the partner is required to:
- Request credentials from their organization’s iCIMS Integration Specialist.
- Obtain authorized credentials from the Integration Specialist securely through email.
- Use the authorized credentials to access the iCIMS API.
If the partner’s service does have a client_id and client_secret, these credentials must be authorized by their organization’s iCIMS Integration Specialist before they can access the iCIMS API.
The authorization process is described in the sections below.
Calling ICIMS APIs with an Access Token
iCIMS requires that the partner utilizes the OAuth 2.0 Client Credentials Grant flow to obtain access tokens for calling an iCIMS API. iCIMS has multiple authorization servers, each allocated for specific regions. The partner must use the appropriate authorization server based on their region and the region of the resources they are accessing. See the table below for a list of iCIMS authorization servers by region.
Region | Authorization Server |
---|---|
US | https://login.icims.com |
EU | https://login.icims.eu |
CA | https://login.icims.ca |
ISV | https://login-isv.icimsmco.net/ |
Client Credentials Authorization Flow
The following diagram describes the authorization workflow for an application accessing an iCIMS API endpoint.
- The application sends the authorization request including the application's credentials to the authorization server.
- The authorization server validates the credentials and responds with an access token.
- The application calls the iCIMS API (resource server) using the access token.
The Authorization Request
A sample access token request for the client credentials grant type follows, with parameter definitions. In the following example, the application authenticates with a client_ID and client_secret registered at a specific regional iCIMS authorization server.
POST https:///oauth/token Content-Type: application/x-www-form-urlencoded audience=https://api.icims.com/v1/ &grant_type=client_credentials &client_id= &client_secret=
The Authorization Response
The iCIMS Authorization server responds with a JSON payload that includes an access token. The access token can be re-used until the token expires after the expires_in time in seconds has elapsed.
HTTP/1.1 200 OK Content-Type: application/json { "access_token":"eyJz93a...k4laUWw", "token_type":"Bearer", "expires_in":86400 }
Note: Services are required to cache and re-use access tokens between API calls. iCIMS will throttle or disable access for clients that request more than 500 access tokens in 10 minutes. Access tokens are valid for 24 hours. |
Calling the ICIMS API Request
The partner provides the access token retrieved in the Authorization response as part of all future iCIMS API calls. The partner must provide the access token in the Authorization header as a bearer token, as demonstrated in the following example.
GET /api-endpoint HTTP/1.1 Host: api.icims.com Authorization: Bearer
Common Errors
Error | HTTP Status | Error Message | Solution |
---|---|---|---|
Missing Bearer Token | 401 - Unauthorized |
|
The access token is missing from the Authorization bearer header. Include the access token in the request as a header:
|
Forgot to provide an audience parameter | 401 - Unauthorized |
|
The audience was not specified when the access token was requested. In this case, the Auth0 Authorization server does not return an access token; it returns an opaque string, invalid as an access token. Specify the audience when requesting the access token. |
Wrong JWT token provider environment | 401 - Unauthorized |
|
The access token was created by the wrong regional authorization server. Use an access token created by the appropriate server for your region. |
Token expired | 401 - Unauthorized |
|
The access token is expired. Request a new token. |
No access provisioned | 403 - Forbidden |
|
Contact iCIMS technical support to request access to the API resource you are trying to access. |
Credentials invalid | 401 - Unauthorized |
When trying to get an access token from an authorization server:
|
Contact iCIMS technical support to request your API credentials, your current credentials are not valid. |
Code Samples & Libraries
iCIMS recommends that partners reference OAuth.net, the OAuth 2.0 RFC, or Auth0 for more details on the OAuth 2.0 protocol.
For language specific libraries, iCIMS recommends the Auth0 OAuth2.0 SDK Client libraries.
Using Postman to Call iCIMS APIs
In order to use Postman to call iCIMS APIs, the partner must use the latest version. The partner can import their OpenAPI specification into Postman. Since Postman does not support providing an audience parameter when retrieving access tokens, iCIMS recommends that the partner uses a pre-request script to fetch the access tokens prior to making the API calls. iCIMS also recommends that the partner selects the Bearer Token Authentication type referencing the token environmental variable reference by the script. The steps below provide more details for setting up Postman to call iCIMS APIs:
1.The partner imports their API documentation (optional).
2. The partner updates their collection base url (optional).
3. The partner adds a currentAccessToken variable to their collection.
4. The partner adds a pre-request script to fetch an access token to their imported collection.
5. The partner updates their authentication type to Bearer Token.
6. The partner calls their API locally.
Authenticating Calls with HMAC
Overview
Using the HTTP Authorization header is the most common method of providing authentication information. The header value contains the algorithm and few other information that is used to calculate the signature. Below is the example of an Authorization header value. Please note that line breaks have been added to this example for readability.
x-icims-v1-hmac-sha256 user=testuser,
signedheaders=host;x-icims-date,
signature=bcb37825f5d7e08e222da05cc0776355e3c69f94144d754a75326b8a4b2cde73
Note there is a space between the first two components, x-icims-v1-hmac-sha256 and user, and that the subsequent components, signedheaders and signature, are separated by comma.
The following table describes the various components of the Authorization header value.
Component | Description |
---|---|
x-icims-v1-hmac-sha256 | The algorithm that is used to calculate the signature. The string specifies iCIMS signature version 1 (x-icims-v1) and the signing algorithm HMAC-SHA256. |
user | Username of the integration user sending the request. |
signedheaders |
A semicolon-separated list of requested headers that you used to compute the Signature. The list includes header names only. The header names must be in lowercase. For example:
|
signature |
The 256-bit signature expressed as 64 lowercase hexadecimal characters. For example:
|
Upon receiving the request, iCIMS recreates the string to sign using the information in the Authorization header and the date header. It then verifies whether the calculated signature matches the signature in the Authorization header. The request date can be specified by using the x-icims-date header.
Calculating a Signature
To calculate a signature, you first need a string to sign. You then calculate a HMAC-SHA256 hash of the string to sign by using a signing key. The diagram below illustrates this process. (The computation of various components of the string that you create for signing is denoted in subsequent sections.)
When iCIMS receives a request, it computes its own signature for the request and compares it to the signature provided in the request. Because of this, both ends (sender and receiver) should use the same method for signature computation.
1. Canonical Request
The first step for computing a signature is to create a string that includes the request information in standard (canonical) format. The steps below indicate the steps to create a canonical version of the request.
<HttpMethod>\n
<CanonicalURI>\n
<CanonicalQueryString>\n
<CanonicalHeaders>\n
<SignedHeaders>
To better understand the construction of the canonical form of HTTP or HTTPS request, review the following sample request:
POST https://api.icims.com/people HTTP/1.1
Host: api.icims.com
Content-Type: application/json
X-Icims-Date: 2014-09-03T15:23+0000
X-Icims-Content-SHA256: 2d911cf32ef8c5e9de94c79edf62f2fec33091a7cd8c561bc9d19623b0146ce4
{“firstname”:“abc”,“lastname”:”xyz”,”email”:”abcxyz@icims.com”}
HTTPMethod: one of the HTTP methods, such as GET, POST, PUT, etc.
POST
CanonicalURI: the URI-encoded version of the absolute path component of the URI (i.e., everything starting with the “/” that follows the domain name and up to the end of string or to the question mark character (‘?’), if you have query string parameters). So in URI https://api.icims.com/people, /people is the absolute path. URI paths should be normalized based on RFC 3986 by removing redundant and relative path components. If the absolute path is empty, use a forward slash (/).
/people
CanonicalQueryString: specifies the query string parameters. Each parameter name and value should be URI-encoded individually. After encoding the name and value, all of the parameters should be sorted based on parameter name before creating the canonical query string.
The steps to compute the canonical query string are as follows:
- URI-encode each parameter name and value according to the following rules:
- Do not URL-encode any of the unreserved characters that RFC 3986 defines: A-Z, a-z, 0-9, hyphen (-), underscore (_), period (.), and tilde (~).
- Percent-encode all other characters with %XY, where X and Y are hexadecimal characters (0-9 and uppercase A-F). For example, the space character must be encoded as %20 (not using '+', as some encoding schemes do), asterisk as %2A and not as ‘*’. Extended UTF-8 characters must be in the form %XY%ZA%BC.
- Sort the encoded parameter names by character code (that is, in strict ASCII order). For example, a parameter name that begins with the uppercase letter F (ASCII code 70) precedes a parameter name that begins with a lowercase letter b (ASCII code 98). If the parameter names are equals, sort based on value
- Build the canonical query string by starting with the first parameter name in the sorted list.
- For each parameter, append the URI-encoded parameter name, followed by the character '=' (ASCII code 61), and then followed by the URI-encoded parameter value. (Use an empty string for parameters that have no value.)
- Append the character '&' (ASCII code 38) after each parameter value except for the last value in the list.
For example, in the URL:
https://api.icims.com/people?lastname=xyz&firstname=abc
The query string is lastname=xyz&firstname=abc. The canonical query string is as follows:
URI-encode(“firstname”) + “=” + URI-encode(“abc”) + “&” + URI-encode(“lastname”) + “=” + URI-encode(“xyz”)
Note: If the request does not include a query string, set this value in the canonical query to an empty string.
CanonicalHeaders: a list of request header entries, sorted by lowercased header names. Each header entry is computed using lowercased header name and trimmed value, separated by a colon and followed by a newline character, as shown below:
Lowercase(<HeaderName>)+":"+Trim(<value>)+"\n"
If there are multiple headers with the same header name, all the header values should be combined into single value. The single value can be obtained by first sorting the values and then combining them, each separated by comma. For example,
Content-Disposition: test.doc
Content-Disposition: attachement; filename=testfile
is changed to
Content-Disposition: attachement; filename=testfile,test.doc
The CanonicalHeaders list must include the following headers:
- X-Icims-Date, indicating the timestamp when the request was made. iCIMS accepts date-time in the following format, YYYY-MM-DDThh:mm:ssTZD. All requests older than 5 minutes will be rejected.
- YYYY: four digit year
- MM: two-digit month (01 through 12)
- DD: two-digit day of month (01 through 31)
- hh: two digits of hour (00 through 23; am/pm not allowed)
- mm: two digits of minute (00 through 59)
- ss: two digits of second (00 through 59)
- TZD: time zone designator (Z or +hh:mm or –hh:mm)
- X-Icims-Content-SHA256, indicating the SHA256 hash of the request payload. If the payload is empty, send the SHA256 hash of empty string.
Note: Newline character is required even for the last header.
For the example introduced above, the following CanonicalHeaders would be included:
content-type:application/json
host:api.icims.com
x-icims-content-sha256: 2d911cf32ef8c5e9de94c79edf62f2fec33091a7cd8c561bc9d19623b0146ce4
x-icims-date:2014-09-03T15:23+0000
SignedHeaders: alphabetically sorted, semicolon-separated list of lowercase request header names. The request headers in this list are the request headers that we included in the CanonicalHeaders string. This string should only contain the headers that were used to calculate the canonical headers string. This list is also send as part of the Authorization Header as discussed below in Authorization Header section of this page.
For the example above, the SignedHeaders string would look like:
content-type;host;x-icims-content-sha256;x-icims-date
So the resulting CanonicalRequest string for the example request would look like:
POST
/people
content-type:application/json
host:api.icims.com
x-icims-content-sha256:2d911cf32ef8c5e9de94c79edf62f2fec33091a7cd8c561bc9d19623b0146ce4
x-icims-date:2014-09-03T15:23+0000
content-type;host;x-icims-content-sha256;x-icims-date
2. StringToSign
The second step is to create a string to sign. This string contains the meta information about the request and the canonical request string created above in Step 1: Canonical Request.
x-icims-v1-hmac-sha256 + “\n” +
TimeStamp + “\n” +
HEX (SHA256Hash (CanonicalRequest))
Start with the algorithm used to calculate the digests in the canonical request. (ie., x-icms-hmac-sha256)
x-icims-v1-hmac-sha256\n
Append the TimeStamp when the request was initiated. This is the value of the header x-icims-date in ISO 8601 format
2014-09-03T15:23+0000\n
Append the hash of the canonical request string you created in Step 1. Note that this value is not followed by newline character. The hash should be lowercased base-16 encoded
fc9f4e23ef1b2584106a1187f95c95618439ae0d090605c5526abb3878fce0dc
The following is the StringToSign for the example request introduced above:
x-icims-v1-hmac-sha256
2014-09-03T15:23+0000
fc9f4e23ef1b2584106a1187f95c95618439ae0d090605c5526abb3878fce0dc
3. Calculating the Signature
The last step is to sign the string created in Step 2: StringToSign using the shared secret key and the HMAC-SHA256 algorithm defined in RCF 2104.
Signature = HMAC-SHA256 (SigningSecret, StringToSign)
For example, using the test secret key “wbVAAhyNDxK8kU/dk0qyd1g6hzmGtkZc8j6tB112J0c=” to sign the above StringToSign using HMAC-SHA256 algorithm would result in the following signature:
0e8ca243f3a0ba75d47d906adbc9e2e4abe68877d406944d5a4dc4635e7a3a20
Authorization Header
After completing the 3 steps described above (1. Canonical Request, 2. StringToSign, and 3. Calculating the Signature), the Authorization header value is generated, as shown below.
x-icms-v1-hmac-sha256 user=, signedheaders=, signature=
- The user is the username/login id of the user that is making this request.
- SignedHeaders is the signed headers string that was computed above.
- Signature is the final signature computed using the procedure above.
The Final Authorization header value for the example above would be:
x-icims-v1-hmac-sha256 user=testuser,signedheaders=content-type;host;x-icims-content-sha256;x-icims-date,signature= 0e8ca243f3a0ba75d47d906adbc9e2e4abe68877d406944d5a4dc4635e7a3a20
This Authorization header should be included in the request. The receiving end should use the same procedure described above to calculate its own Signature and verify it with the signature present in the authorization header to validate the authenticity.