diff --git a/changelog.html b/changelog.html new file mode 100644 index 0000000..9a0657b --- /dev/null +++ b/changelog.html @@ -0,0 +1,118 @@ + + + + + + + Rest API Changes by Bullhorn Release + + + + + + + + + + + + NAV + + + +
+ + + +
+
+
+
+
+ + +
+
+ + diff --git a/guide.html b/guide.html index 2cf9765..80cba4b 100644 --- a/guide.html +++ b/guide.html @@ -115,2502 +115,15 @@
-

Getting Started with the Bullhorn REST API

- -

The Bullhorn REST API gives partner a simple yet powerful way to interact with the Bullhorn system. Because it uses HTTP requests and responses and standard data structures, the REST API is accessible from many programming languages and is particularly well-suited to mobile applications and applications that use the most current web technologies.

- -

Get access to the Bullhorn REST API

- -

Bullhorn uses OAuth 2.0 as the authorization mechanism for the Bullhorn REST API. See OAuth authorization for the Bullhorn REST API for high-level information about how Bullhorn uses OAuth with the REST API. Bullhorn customers can obtain OAuth keys for developing applications with the Bullhorn REST API by creating a support ticket via the Bullhorn Resource Center.

- -

You must have a valid OAuth 2.0 API key that contains the following data before your application can perform the OAuth authorization process described below:

- - - - - - - - - - - - - - - - - - - -
parameterdescription
redirect_uriURI for the location of your application provided to Bullhorn when registered
client_idID generated by Bullhorn identifiny your account
client_secretPassword for your application to authenticate into the system
- -

Complete the authorization process

- -

Get an authorization code

- -

Your application must complete these steps to get an authorization code. These steps require Bullhorn user credentials, but may be performed programmatically or manually. Here we show the manual steps so you can quickly understand the process.

- -
    -
  1. Access the following URL, substituting your actual values for the placeholders in the query parameters:

    - -

    https://auth-east.bullhornstaffing.com/oauth/authorize?client_id={client_id}&response_type=code&redirect_uri={optional redirect_uri}&state={recommended state value}

    - -

    A login page is displayed.

    - -

    The state query parameter is recommended.The client uses this value to maintain state between the request and the callback. It should be used for preventing cross-site request forgery.

    - -

    The redirect_uri query parameter is optional. If used, the redirect_uri must match one of the redirect_uris specified in the OAuth API key.

  2. -
  3. On the login page, user enters a valid Bullhorn username/password combination and clicks the Login button. -A Terms of Service page is displayed.

  4. -
  5. User clicks the Agree button to accept the terms of service.

    - -

    The page is redirected to the redirect URI with a code query parameter on the URL. The code value is the authorization code required to get an access token, which you use to get a Bullhorn session key required for REST API calls.

  6. -
- -

Get an access token

- -

Your application uses the authorization code to get an access token. A valid access token is a required query parameter on a REST login request. This part of the process requires no direct user interaction.

- -

Note: To get an access token, your application must make a POST request. For learning purposes, you can make manual POST, PUT, and DELETE requests in your web browser after installing an extension. On Google Chrome, install the Postman extension. On Mozilla Firefox, install the HTTP Resource Test extension.

- -

Make a POST request with the following URL, substituting your actual values for the placeholders in the query parameters. If you specified a redirect_uri in the oauth/authorize request, you must specify the same redirect_uri in this request.

-
https://auth-east.bullhornstaffing.com/oauth/token?grant_type=authorization_code&code={auth_code}&client_id={client_id}&client_secret={client_secret}&redirect_uri={optional redirect_uri}
-
- -

The POST response contains an access token that you use in REST API /login requests to obtain a Bullhorn session token and a base REST URL. The access token is valid for 10 minutes.

- -

If Bullhorn has provided you with the ability to generate refresh tokens, the POST response also contains a refresh token. When the Bullhorn session expires, you use a refresh token to get a new access token without reauthorizing (getting another authorization code). A new refresh token is returned with every new access token. The refresh token has no expiration date/time, but it does expire when a new access token and refresh token are generated.

- -

Use a refresh token to get a new access token

- -

To obtain an access token with a refresh token, make a POST request with the following URL, substituting your actual values for the placeholders in the query parameters:

-
https://auth-east.bullhornstaffing.com/oauth/token?grant_type=refresh_token&refresh_token={refresh_token}&client_id={client_id}&client_secret={client_secret}
-
- -

Familiarize yourself with the REST API

- -

Making a REST call is as simple as sending an HTTP request to a server and getting an HTTP response back. Calls that get data from the server are simple URLs. The Bullhorn REST API uses JSON (JavaScript Object Notation) to structure all response data. The REST API also accepts JSON-formatted data for create, update, and delete (CRUD) requests. JSON uses a simple data structure that is very easy to read and understand.

- -

The easiest way to get started with the REST API is by making REST calls in a standard web browser. You can make REST GET calls by entering the REST URL in the browser URL field and pressing Enter. You can make PUT, POST, and DELETE calls for CRUD operations with the Postman extension on Chrome or the HTTP Resource Test extension on Firefox.

- -

The next steps are: -- Start making REST calls. -- Read the REST API Reference. -- Read the Bullhorn Style Guide for user interface design guidelines.

- -

If you have a question, you can post it on the support forums.

- -

Log in to the REST API

- -

The first call you make with the Bullhorn REST API is a login call. The login call returns a session key that you can use for subsequent requests. The login call is an HTTP GET request that looks like this:

- -

Using version=* to get the latest version:

-
POST https://rest-east.bullhornstaffing.com/rest-services/login?version=*&access_token={xxxxxxxx}
-
- -

Using version=2.0 to get the current version:

-
POST https://rest-east.bullhornstaffing.com/rest-services/login?version=2.0&access_token={xxxxxxxx}
-
- -

The login URL uses HTTPS and includes the following components:

- -

| rest-east.bullhornstaffing.com | Bullhorn server name | -| /rest-services | Context root of the Bullhorn web application | -| /login | login command | -| version=* | version query parameter:, where * indicates the latest version and 2.0 indicates the current version.|

- -

A successful login response looks like this:

-
{
-   "BhRestToken": "a33da348-d562-4211-a48c-8d8cac14a38e",
-   "restUrl": "https://rest-east.bullhornstaffing.com/rest-services/{corpToken}/"
-}
-
- -

The login response contains a session key named BhRestToken as well as the base URL for subsequent REST calls. The URL includes the Bullhorn corpToken to use with the current login.

- -

Make a REST call to get a Bullhorn entity

- -

After obtaining a session key you can make REST calls that get data or perform CRUD operations on the Bullhorn server. For example, a request to get a specific Candidate looks like this:

-
GET https://rest-east.bullhornstaffing.com/rest-services/{corpToken}/entity/Candidate/{id}?BhRestToken={session_key}&fields=firstName,lastName,address
-
- -

The get entity by id URL uses HTTPS and includes the following components:

- -

| rest-east.bullhornstaffing.com | Bullhorn server name | -| /rest-services | Context root of the Bullhorn web application | -| /entity | entity command | -| Candidate | Type of entity to get | -| {id} | id of the entity | -| BhRestToken={session_key} | Session key from successful login | -| fields=firstName,lastName,address | Entity fields to include in the response |

- -

The response to this request is in JSON format and looks like this:

-
{
-  "data" : {
-    "firstName" : "FName01",
-    "lastName" : "LName01",
-    "address" : {
-      "address1" : "123 Address1 Ave",
-      "address2" : "# suite address2",
-      "city" : "Cityville",
-      "state" : "MA",
-      "zip" : "01754",
-      "countryID" : 1
-    }
-  }
-}
-
- -

Make a REST call to create a Bullhorn entity

- -

A REST request to create a new entity is very similar to a request to get an entity. The differences are that the request is an HTTP POST rather than an HTTP GET, no id parameter is specified on the URL, and the body of the HTTP request contains field values for the new entity.

- -

For example, the URL of a PUT request to create a new Candidate entity looks like this:

-
PUT https://rest-east.bullhornstaffing.com/rest-services/{corpToken}/entity/Candidate?BhRestToken={session_key}
-
- -

The PUT request body looks like this, where the xxxx values would be real values:

-
{
-    "firstName": "xxxx",
-    "lastName": "xxxx",
-    "name": "xxxx",
-    "username": "xxxx",
-    "category": { "id": xxxx },
-    "password": "xxxx",
-    "owner": { "id": xxxxx},
-    "address": {
-        "address1" : "xxxx",
-        "address2" : "xxxx",
-        "city" : "xxxx",
-        "state" : "NY",
-        "zip" : 12345,
-        "countryID" : x
-    },
-    "secondaryAddress": {
-        "address1" : "xxxx",
-        "address2" : "xxxx",
-        "city" : "pxxxx",
-        "state" : "MA",
-        "zip" : 54321,
-        "countryID" : x
-    },
-    "customDate1": xxxx,
-    "dateAvailableEnd": xxxx,
-    "dateAdded": xxxx,
-    "ownerCorporation": { "id": xxxx },
-    "userType": { "id": xxxx }
-}
-
- -

Get more information about REST and JSON

- -

There is a great deal of introductory information about RESTful web services available online. The following articles are good starting points:

- - - -

The following articles provide good information about JSON and JSONP:

- - - -

Use the REST API with Custom Objects

- -

What are custom objects

- -

Custom objects are custom fields that extend the standard Bullhorn Candidate, ClientContact, ClientCorporation, JobOrder, Opportunity, and Placement entities. You can use custom objects to more closely match your business data requirements. These fields are entities and you can use the REST API to create, edit, and return instances of them. See the Bullhorn Resource Center for general information about custom objects.

- -

Note: Before using the REST API, you must perform authorization and authentication. See Getting Started with the Bullhorn REST API for information about obtaining an OAuth 2.0 access token and logging in to the REST API.

- -

REST API calls for custom objects

- -

The following topics provide REST API examples to get you up and running quickly with custom objects:

- - - -

Get metadata for custom objects

- -

Before working with custom objects with the REST API, you first must understand the structure of the custom objects assigned to an entity type. The REST /meta request returns information about the structure of the entity type, including its assigned custom objects.

- -

Each entity can have customObject1s through customObject10s assigned as custom objects. To determine which custom objects are assigned to an entity type, request all fields with the * character as the following example shows. Only the assigned customObjects are returned in the list of entity fields.

- -

Note: A custom object can be configured so that only users in specific departments can view that custom object or its metadata. If the current user does not have view entitlements to a custom object, a /meta call returns no metadata for that custom object.

- -

Request URI: -~~~ http -GET https://rest.bullhornstaffing.com/rest-services/{corpToken}/meta/Candidate? -fields=* -~~~

- -

Once you know the custom objects available on an entity type, you can get more information about those custom objects. You have two choices for working with custom objects: -* Use the client-defined object and field names assigned in the Bullhorn administration application; for example, $Invoice(status). -* Use the static object and field names defined in the database; for example, customObject2s(text1).

- -

Your choice depends on whether you prefer to work with names that reflect the business logic that a custom object represents. To use client-defined object and field names, the Bullhorn support team must enable “Use Client Defined Name in REST” on the custom object configuration. On the JSON response of an entity metadata call, such as meta/Candidate?fields=, the value of the JSON key “associatedEntity.label” on a customObject{#}s object is the client-defined custom object name. For example, the client-defined custom object name on this example is “ClientDefinedCO”: -~~~ json -… - { - “name” : “customObject9s”, - “type” : “TO_MANY”, - “confidential” : false, - “label” : “Custom Object9s”, - “optionsType” : “PersonCustomObjectInstance9”, - “optionsUrl” : “https://rest{swimlane#}.bullhornstaffing.com/rest-services/1yg8p/options/PersonCustomObjectInstance9”, - “hideFromSearch” : false, - “associatedEntity” : { - “entity” : “PersonCustomObjectInstance9”, - “entityMetaUrl” : “https://rest{swimlane#}.bullhornstaffing.com/rest-services/1yg8p/meta/PersonCustomObjectInstance9?fields=”, - “label” : “ClientDefinedCO”, - “dateLastModified” : “1505885678477”, - “fields” : [ { - “name” : “id”, - “type” : “ID”, - “dataType” : “Integer” - } ], - “staticTemplateName” : “ClientDefinedCO”, - “tabName” : “ClientDefinedCO” - } -… -~~~

- -

Note: You must reference the client-defined name with the $ character as a prefix.

- -

Client-defined custom object metadata

- -

The following request returns just the metadata for the custom object assigned to $ClientDefinedCO on the Candidate entity type. This is an example of working with a custom object by its client-defined name:

- -

Request URI: -~~~ http -GET https://rest.bullhornstaffing.com/rest-services/{corpToken}/meta/Candidate? -fields=$ClientDefinedCO(*) -~~~

- -

Response: -~~~ json -{ - “entity” : “Candidate”, - “entityMetaUrl” : “https://rest-test-backend.bh-bos2.bullhorn.com:8181/rest-services/1yg8p/meta/Candidate?fields=”, - “label” : “Candidate”, - “dateLastModified” : “1505885660081”, - “fields” : [ { - “name” : “$ClientDefinedCO”, - “type” : “TO_MANY”, - “confidential” : false, - “label” : “Custom Object9s”, - “optionsType” : “PersonCustomObjectInstance9”, - “optionsUrl” : “https://rest-test-backend.bh-bos2.bullhorn.com:8181/rest-services/1yg8p/options/PersonCustomObjectInstance9”, - “hideFromSearch” : false, - “associatedEntity” : { - “entity” : “$PersonClientDefinedCO”, - “entityMetaUrl” : “http://rest-test-backend.bh-bos2.bullhorn.com:8181/rest-services/1yg8p/meta/$PersonClientDefinedCO?fields=”, - “label” : “ClientDefinedCO”, - “dateLastModified” : “1505885678477”, - “fields” : [ { - “name” : “id”, - “type” : “ID”, - “dataType” : “Integer” - }, { - “name” : “dateAdded”, - “type” : “SCALAR”, - “dataType” : “Timestamp”, - “confidential” : false, - “label” : “Date Added”, - “hideFromSearch” : false - }, { - “name” : “dateLastModified”, - “type” : “SCALAR”, - “dataType” : “Timestamp”, - “confidential” : false, - “label” : “Date Last Modified”, - “hideFromSearch” : false - }, { - “name” : “person”, - “type” : “TO_ONE”, - “confidential” : false, - “label” : “Person”, - “optionsType” : “Person”, - “optionsUrl” : “https://rest{swimlane#}.bullhornstaffing.com/rest-services/1yg8p/options/Person”, - “hideFromSearch” : false, - “associatedEntity” : { - “entity” : “Person”, - “entityMetaUrl” : “https://rest{swimlane#}.bullhornstaffing.com/rest-services/1yg8p/meta/Person?fields=*”, - “label” : “Person”, - “dateLastModified” : “1505885679669”, - “fields” : [ { - “name” : “id”, - “type” : “ID”, - “dataType” : “Integer” - }, { - “name” : “_subtype”, - “type” : “SCALAR”, - “dataType” : “String”, - “maxLength” : 255 - }, { - “name” : “firstName”, - “type” : “SCALAR”, - “dataType” : “String”, - “maxLength” : 50, - “confidential” : false, - “label” : “First Name”, - “hideFromSearch” : false - }, { - “name” : “lastName”, - “type” : “SCALAR”, - “dataType” : “String”, - “maxLength” : 50, - “confidential” : false, - “label” : “Last Name”, - “hideFromSearch” : false - } ] - } - }, { - “name” : “clientDefinedTextField”, - “type” : “SCALAR”, - “dataType” : “String”, - “maxLength” : 100, - “confidential” : false, - “label” : “clientDefinedText”, - “optionsType” : “$PersonclientDefinedText”, - “optionsUrl” : “https://rest{swimlane#}.bullhornstaffing.com/rest-services/1yg8p/options/$PersonclientDefinedText”, - “hideFromSearch” : false - } ], - “staticTemplateName” : “ClientDefinedCO”, - “tabName” : “ClientDefinedCO” - } - } ] -} -~~~

- -

Static custom object metadata

- -

The following request returns just the metadata for the custom object assigned to customObject2s on the Candidate entity type. This is an example of working with a custom object by its standard name:

- -

Request URI: -~~~ http -GET https://rest.bullhornstaffing.com/rest-services/{corpToken}/meta/Candidate? -fields=customObject2s(*) -~~~

- -

Response: -~~~ json -{ - “entity” : “Candidate”, - “entityMetaUrl” : “http://rest.bullhornstaffing.com/rest-services/1yg8p/meta/Candidate?fields=”, - “label” : “Candidate”, - “fields” : [ { - “name” : “customObject2s”, - “type” : “TO_MANY”, - “confidential” : false, - “label” : “Custom Object2s”, - “optionsType” : “PersonCustomObjectInstance2”, - “optionsUrl” : “https://rest{swimlane#}.bullhornstaffing.com/rest-services/1yg8p/options/PersonCustomObjectInstance2”, - “hideFromSearch” : false, - “associatedEntity” : { - “entity” : “PersonCustomObjectInstance2”, - “entityMetaUrl” : “https://rest{swimlane#}.bullhornstaffing.com/rest-services/1yg8p/meta/PersonCustomObjectInstance2?fields=”, - “label” : “RestAutomation1”, - “fields” : [ { - “name” : “date1”, - “type” : “SCALAR”, - “dataType” : “Timestamp”, - “confidential” : false, - “label” : “date1”, - “hideFromSearch” : false - }, { - “name” : “dateAdded”, - “type” : “SCALAR”, - “dataType” : “Timestamp”, - “confidential” : false, - “label” : “Date Added”, - “hideFromSearch” : false - }, { - “name” : “float1”, - “type” : “SCALAR”, - “dataType” : “Float”, - “confidential” : false, - “label” : “float1”, - “hideFromSearch” : false - }, { - “name” : “int1”, - “type” : “SCALAR”, - “dataType” : “Integer”, - “confidential” : false, - “label” : “int1”, - “hideFromSearch” : false - }, { - “name” : “text1”, - “type” : “SCALAR”, - “dataType” : “String”, - “maxLength” : 100, - “confidential” : false, - “label” : “text1a”, - “options” : [ { - “value” : “sometext1”, - “label” : “sometext1” - }, { - “value” : “sometext2”, - “label” : “sometext2” - } ], - “hideFromSearch” : false - } ] - } - } ] -} -~~~

- -

Create custom object on new entity

- -

The following example request creates a new Candidate and also creates a new client-defined custom object and associates it with the Candidate. The custom object is assigned to the $ClientDefinedCO field on the Candidate entity type; the “clientDefinedText” field name is obtained from the field “label” on the entity metadata response.

- -

Note: A custom object can be configured so that only users in specific departments can create or edit that custom object. If the current user does not have edit entitlements to a custom object, the user cannot create or edit that type of custom object.

- -

Request URI: -~~~ http -PUT https://rest.bullhornstaffing.com/rest-services/{corpToken}/entity/Candidate -Content-Type: application/json -~~~

- -

Request body: -~~~ json -{ - “$ClientDefinedCO”:[{“clientDefinedText”:“some text”}], - “firstName”: “TestFirst”, - “lastName”: “TestLast”, - “name”: “TestFirst TestLast”, - “username”: “TestCandidatexxx”, - “status” : “active” -} -~~~

- -

Response: -~~~ json -{ - “changedEntityType”: “Candidate”, - “changedEntityId”: 31918, - “changeType”: “INSERT” - … -} -~~~

- -

Alternatively, you can use the static custom object and field names obtained from entity metadata, as the following request body shows: - ~~~ json - { - “customObject9s”:[{“text1”:“some text”}], - “firstName”: “TestFirst”, - “lastName”: “TestLast”, - “name”: “TestFirst TestLast”, - “username”: “TestCandidatexxx”, - “status” : “active” -} -~~~

- -

Update custom object on existing entity

- -

The following example request updates a client-defined custom object on a Candidate. The example updates the clientDefinedText field of the custom object that has id 3649.

- -

Note: A custom object can be configured so that only users in specific departments can create or edit that custom object. If the current user does not have edit entitlements to a custom object, the user cannot create or edit that type of custom object.

- -

Request URI: -~~~ http -POST https://rest.bullhornstaffing.com/rest-services/{corpToken}/entity/Candidate/32031 -Content-Type: application/json -~~~

- -

Request body: -~~~ json -{ - “$ClientDefinedCO”:[{“id”:3649, - “clientDefinedText”:“updated the value!”}] -} -~~~

- -

Alternatively, you can use the static custom object and field names obtained from entity metadata, as the following request body shows: -~~~ json -{ - “customObject9s”:[{“id”:3649, - “text1”:“updated the value!”}] -} -~~~

- -

Update and create custom objects on existing entity

- -

The following example request updates an existing client-defined custom object and creates a new client-defined custom object on an existing Candidate. The example updates the clientDefinedText field of the custom object that has id 3649 and also creates a new custom object and sets its clientDefinedText value.

- -

Request URI: -~~~ http -POST https://rest.bullhornstaffing.com/rest-services/{corpToken}/entity/Candidate/32039 -Content-Type: application/json -~~~

- -

Request body: -~~~ json -{ - “$ClientDefinedCO”: - [ - {“id”:3649, - “clientDefinedText”:“updated the value!”}, - {“clientDefinedText”:“Brand new custom object here!”} - ] -} -~~~

- -

Alternatively, you can use the static custom object and field names obtained from entity metadata, as the following request body shows: - ~~~ json -{ - “customObject9s”: - [ - {“id”:3649,“text1”:“updated the value!”}, - {“text1”:“Brand new custom object here!”} - ] -} -~~~

- -

Search for entity based on custom object

- -

The following example request performs a Candidate search based on the value of the clientDefinedText field of a client-defined custom object. The syntax used in the “query” parameter on the request is a lookup query, which is a SQL query on an indexed entity field; the indexed entity field is Candidate.id. The search returns all Candidates with ids where $ClientDefinedCO.clientDefinedText=‘sometext’.

- -

Request URI: -~~~ http -GET https://rest.bullhornstaffing.com/rest-services/{corpToken}/search/Candidate? -query=id:“^($ClientDefinedCO.clientDefinedText='sometext’)”&fields=id, -$ClientDefinedCO(clientDefinedText)&sort=-id&count=5 -~~~

- -

Alternatively, you can use the static custom object and field names obtained from entity metadata, as the following request URI shows: -~~~ http -GET https://rest.bullhornstaffing.com/rest-services/{corpToken}/search/Candidate? -query=id:“^(customObject9s.text1='sometext’)”&fields=id,customObject2s(text1)&sort=-id&count=5 -~~~

- -

Note: A custom object can be configured so that only users in specific departments can view that custom object. If the current user does not have view entitlements to a custom object, a search on that custom object returns no matching items.

- -

Disassociate custom object from entity

- -

The following example request disassociates an existing custom object from an existing entity in a standard disassociation request. You must use the static custom object name for this call.

- -

Request URI: -~~~ http -DELETE https://rest.bullhornstaffing.com/rest-services/{corpToken}/entity/Candidate/32056 -/customObject2s/3680 -~~~

- -

Query custom object

- -

The following example request performs a custom object query. You must use the static custom object name for this call.

- -

Note: A custom object can be configured so that only users in specific departments can view that custom object. If the current user does not have view entitlements to a custom object, a query on that custom object returns no matching items.

- -

Request URI: -~~~ http -GET https://rest.bullhornstaffing.com/rest-services/{corpToken}/query/PersonCustomObjectInstance2? -where=id=3684&fields=id&orderBy=-id&count=5 -~~~

- -

Data-center-specific API URLs

- -

API users should use the following data-center-specific base URLs for the Bullhorn OAuth, REST, and SOAP APIs.

- -

U.S. East Coast Data Center

- -

CLS5, CLS2,CLS20

- - - -

U.S. West Coast Data Center

- -

CLS30,CLS31,CLS32,CLS33,CLS34

- - - -

APAC Data Center

- -

CLS50

- - - -

UK Data Center

- -

CLS21,CLS22,CLS23

- - - -

German Data Center

- -

CLS70

- - - -

Sandbox Environments

- -

BHNEXT

- - - -

CLS91

- - - -

About Cluster IDs

- -

CLS2, CLS21 etc. are cluster IDs that are contained in a user’s browser URL (address bar) once they are logged in.

- -

Example: https://cls21.bullhornstaffing.com/BullhornSTAFFING/MainFrame.jsp?#no-ba… indicates that the logged in user is on CLS21 (therefore the appropriate API URLs to use are for the UK Data Center) -As such Cluster IDs do not change for a customer, so identifying the correct cluster ID for all users for a given customer is a one time exercise.

- -

Use the REST API with Custom Objects

- -

What are custom objects

- -

Custom objects are custom fields that extend the standard Bullhorn Candidate, ClientContact, ClientCorporation, JobOrder, Opportunity, and Placement entities. You can use custom objects to more closely match your business data requirements. These fields are entities and you can use the REST API to create, edit, and return instances of them. See the Bullhorn Resource Center for general information about custom objects.

- -

Note: Before using the REST API, you must perform authorization and authentication. See Getting Started with the Bullhorn REST API for information about obtaining an OAuth 2.0 access token and logging in to the REST API.

- -

REST API calls for custom objects

- -

The following topics provide REST API examples to get you up and running quickly with custom objects:

- - - -

Get metadata for custom objects

- -

Before working with custom objects with the REST API, you first must understand the structure of the custom objects assigned to an entity type. The REST /meta request returns information about the structure of the entity type, including its assigned custom objects.

- -

Each entity can have customObject1s through customObject10s assigned as custom objects. To determine which custom objects are assigned to an entity type, request all fields with the * character as the following example shows. Only the assigned customObjects are returned in the list of entity fields.

- -

Note: A custom object can be configured so that only users in specific departments can view that custom object or its metadata. If the current user does not have view entitlements to a custom object, a /meta call returns no metadata for that custom object.

- -

Request URI: -~~~ http -GET https://rest.bullhornstaffing.com/rest-services/{corpToken}/meta/Candidate? -fields=* -~~~

- -

Once you know the custom objects available on an entity type, you can get more information about those custom objects. You have two choices for working with custom objects: -* Use the client-defined object and field names assigned in the Bullhorn administration application; for example, $Invoice(status). -* Use the static object and field names defined in the database; for example, customObject2s(text1).

- -

Your choice depends on whether you prefer to work with names that reflect the business logic that a custom object represents. To use client-defined object and field names, the Bullhorn support team must enable “Use Client Defined Name in REST” on the custom object configuration. On the JSON response of an entity metadata call, such as meta/Candidate?fields=, the value of the JSON key “associatedEntity.label” on a customObject{#}s object is the client-defined custom object name. For example, the client-defined custom object name on this example is “ClientDefinedCO”: -~~~ json -… - { - “name” : “customObject9s”, - “type” : “TO_MANY”, - “confidential” : false, - “label” : “Custom Object9s”, - “optionsType” : “PersonCustomObjectInstance9”, - “optionsUrl” : “https://rest{swimlane#}.bullhornstaffing.com/rest-services/1yg8p/options/PersonCustomObjectInstance9”, - “hideFromSearch” : false, - “associatedEntity” : { - “entity” : “PersonCustomObjectInstance9”, - “entityMetaUrl” : “https://rest{swimlane#}.bullhornstaffing.com/rest-services/1yg8p/meta/PersonCustomObjectInstance9?fields=”, - “label” : “ClientDefinedCO”, - “dateLastModified” : “1505885678477”, - “fields” : [ { - “name” : “id”, - “type” : “ID”, - “dataType” : “Integer” - } ], - “staticTemplateName” : “ClientDefinedCO”, - “tabName” : “ClientDefinedCO” - } -… -~~~

- -

Note: You must reference the client-defined name with the $ character as a prefix.

- -

Client-defined custom object metadata

- -

The following request returns just the metadata for the custom object assigned to $ClientDefinedCO on the Candidate entity type. This is an example of working with a custom object by its client-defined name:

- -

Request URI: -~~~ http -GET https://rest.bullhornstaffing.com/rest-services/{corpToken}/meta/Candidate? -fields=$ClientDefinedCO(*) -~~~

- -

Response: -~~~ json -{ - “entity” : “Candidate”, - “entityMetaUrl” : “https://rest-test-backend.bh-bos2.bullhorn.com:8181/rest-services/1yg8p/meta/Candidate?fields=”, - “label” : “Candidate”, - “dateLastModified” : “1505885660081”, - “fields” : [ { - “name” : “$ClientDefinedCO”, - “type” : “TO_MANY”, - “confidential” : false, - “label” : “Custom Object9s”, - “optionsType” : “PersonCustomObjectInstance9”, - “optionsUrl” : “https://rest-test-backend.bh-bos2.bullhorn.com:8181/rest-services/1yg8p/options/PersonCustomObjectInstance9”, - “hideFromSearch” : false, - “associatedEntity” : { - “entity” : “$PersonClientDefinedCO”, - “entityMetaUrl” : “http://rest-test-backend.bh-bos2.bullhorn.com:8181/rest-services/1yg8p/meta/$PersonClientDefinedCO?fields=”, - “label” : “ClientDefinedCO”, - “dateLastModified” : “1505885678477”, - “fields” : [ { - “name” : “id”, - “type” : “ID”, - “dataType” : “Integer” - }, { - “name” : “dateAdded”, - “type” : “SCALAR”, - “dataType” : “Timestamp”, - “confidential” : false, - “label” : “Date Added”, - “hideFromSearch” : false - }, { - “name” : “dateLastModified”, - “type” : “SCALAR”, - “dataType” : “Timestamp”, - “confidential” : false, - “label” : “Date Last Modified”, - “hideFromSearch” : false - }, { - “name” : “person”, - “type” : “TO_ONE”, - “confidential” : false, - “label” : “Person”, - “optionsType” : “Person”, - “optionsUrl” : “https://rest{swimlane#}.bullhornstaffing.com/rest-services/1yg8p/options/Person”, - “hideFromSearch” : false, - “associatedEntity” : { - “entity” : “Person”, - “entityMetaUrl” : “https://rest{swimlane#}.bullhornstaffing.com/rest-services/1yg8p/meta/Person?fields=*”, - “label” : “Person”, - “dateLastModified” : “1505885679669”, - “fields” : [ { - “name” : “id”, - “type” : “ID”, - “dataType” : “Integer” - }, { - “name” : “_subtype”, - “type” : “SCALAR”, - “dataType” : “String”, - “maxLength” : 255 - }, { - “name” : “firstName”, - “type” : “SCALAR”, - “dataType” : “String”, - “maxLength” : 50, - “confidential” : false, - “label” : “First Name”, - “hideFromSearch” : false - }, { - “name” : “lastName”, - “type” : “SCALAR”, - “dataType” : “String”, - “maxLength” : 50, - “confidential” : false, - “label” : “Last Name”, - “hideFromSearch” : false - } ] - } - }, { - “name” : “clientDefinedTextField”, - “type” : “SCALAR”, - “dataType” : “String”, - “maxLength” : 100, - “confidential” : false, - “label” : “clientDefinedText”, - “optionsType” : “$PersonclientDefinedText”, - “optionsUrl” : “https://rest{swimlane#}.bullhornstaffing.com/rest-services/1yg8p/options/$PersonclientDefinedText”, - “hideFromSearch” : false - } ], - “staticTemplateName” : “ClientDefinedCO”, - “tabName” : “ClientDefinedCO” - } - } ] -} -~~~

- -

Static custom object metadata

- -

The following request returns just the metadata for the custom object assigned to customObject2s on the Candidate entity type. This is an example of working with a custom object by its standard name:

- -

Request URI: -~~~ http -GET https://rest.bullhornstaffing.com/rest-services/{corpToken}/meta/Candidate? -fields=customObject2s(*) -~~~

- -

Response: -~~~ json -{ - “entity” : “Candidate”, - “entityMetaUrl” : “http://rest.bullhornstaffing.com/rest-services/1yg8p/meta/Candidate?fields=”, - “label” : “Candidate”, - “fields” : [ { - “name” : “customObject2s”, - “type” : “TO_MANY”, - “confidential” : false, - “label” : “Custom Object2s”, - “optionsType” : “PersonCustomObjectInstance2”, - “optionsUrl” : “https://rest{swimlane#}.bullhornstaffing.com/rest-services/1yg8p/options/PersonCustomObjectInstance2”, - “hideFromSearch” : false, - “associatedEntity” : { - “entity” : “PersonCustomObjectInstance2”, - “entityMetaUrl” : “https://rest{swimlane#}.bullhornstaffing.com/rest-services/1yg8p/meta/PersonCustomObjectInstance2?fields=”, - “label” : “RestAutomation1”, - “fields” : [ { - “name” : “date1”, - “type” : “SCALAR”, - “dataType” : “Timestamp”, - “confidential” : false, - “label” : “date1”, - “hideFromSearch” : false - }, { - “name” : “dateAdded”, - “type” : “SCALAR”, - “dataType” : “Timestamp”, - “confidential” : false, - “label” : “Date Added”, - “hideFromSearch” : false - }, { - “name” : “float1”, - “type” : “SCALAR”, - “dataType” : “Float”, - “confidential” : false, - “label” : “float1”, - “hideFromSearch” : false - }, { - “name” : “int1”, - “type” : “SCALAR”, - “dataType” : “Integer”, - “confidential” : false, - “label” : “int1”, - “hideFromSearch” : false - }, { - “name” : “text1”, - “type” : “SCALAR”, - “dataType” : “String”, - “maxLength” : 100, - “confidential” : false, - “label” : “text1a”, - “options” : [ { - “value” : “sometext1”, - “label” : “sometext1” - }, { - “value” : “sometext2”, - “label” : “sometext2” - } ], - “hideFromSearch” : false - } ] - } - } ] -} -~~~

- -

Create custom object on new entity

- -

The following example request creates a new Candidate and also creates a new client-defined custom object and associates it with the Candidate. The custom object is assigned to the $ClientDefinedCO field on the Candidate entity type; the “clientDefinedText” field name is obtained from the field “label” on the entity metadata response.

- -

Note: A custom object can be configured so that only users in specific departments can create or edit that custom object. If the current user does not have edit entitlements to a custom object, the user cannot create or edit that type of custom object.

- -

Request URI: -~~~ http -PUT https://rest.bullhornstaffing.com/rest-services/{corpToken}/entity/Candidate -Content-Type: application/json -~~~

- -

Request body: -~~~ json -{ - “$ClientDefinedCO”:[{“clientDefinedText”:“some text”}], - “firstName”: “TestFirst”, - “lastName”: “TestLast”, - “name”: “TestFirst TestLast”, - “username”: “TestCandidatexxx”, - “status” : “active” -} -~~~

- -

Response: -~~~ json -{ - “changedEntityType”: “Candidate”, - “changedEntityId”: 31918, - “changeType”: “INSERT” - … -} -~~~

- -

Alternatively, you can use the static custom object and field names obtained from entity metadata, as the following request body shows: - ~~~ json - { - “customObject9s”:[{“text1”:“some text”}], - “firstName”: “TestFirst”, - “lastName”: “TestLast”, - “name”: “TestFirst TestLast”, - “username”: “TestCandidatexxx”, - “status” : “active” -} -~~~

- -

Update custom object on existing entity

- -

The following example request updates a client-defined custom object on a Candidate. The example updates the clientDefinedText field of the custom object that has id 3649.

- -

Note: A custom object can be configured so that only users in specific departments can create or edit that custom object. If the current user does not have edit entitlements to a custom object, the user cannot create or edit that type of custom object.

- -

Request URI: -~~~ http -POST https://rest.bullhornstaffing.com/rest-services/{corpToken}/entity/Candidate/32031 -Content-Type: application/json -~~~

- -

Request body: -~~~ json -{ - “$ClientDefinedCO”:[{“id”:3649, - “clientDefinedText”:“updated the value!”}] -} -~~~

- -

Alternatively, you can use the static custom object and field names obtained from entity metadata, as the following request body shows: -~~~ json -{ - “customObject9s”:[{“id”:3649, - “text1”:“updated the value!”}] -} -~~~

- -

Update and create custom objects on existing entity

- -

The following example request updates an existing client-defined custom object and creates a new client-defined custom object on an existing Candidate. The example updates the clientDefinedText field of the custom object that has id 3649 and also creates a new custom object and sets its clientDefinedText value.

- -

Request URI: -~~~ http -POST https://rest.bullhornstaffing.com/rest-services/{corpToken}/entity/Candidate/32039 -Content-Type: application/json -~~~

- -

Request body: -~~~ json -{ - “$ClientDefinedCO”: - [ - {“id”:3649, - “clientDefinedText”:“updated the value!”}, - {“clientDefinedText”:“Brand new custom object here!”} - ] -} -~~~

- -

Alternatively, you can use the static custom object and field names obtained from entity metadata, as the following request body shows: - ~~~ json -{ - “customObject9s”: - [ - {“id”:3649,“text1”:“updated the value!”}, - {“text1”:“Brand new custom object here!”} - ] -} -~~~

- -

Search for entity based on custom object

- -

The following example request performs a Candidate search based on the value of the clientDefinedText field of a client-defined custom object. The syntax used in the “query” parameter on the request is a lookup query, which is a SQL query on an indexed entity field; the indexed entity field is Candidate.id. The search returns all Candidates with ids where $ClientDefinedCO.clientDefinedText=‘sometext’.

- -

Request URI: -~~~ http -GET https://rest.bullhornstaffing.com/rest-services/{corpToken}/search/Candidate? -query=id:“^($ClientDefinedCO.clientDefinedText='sometext’)”&fields=id, -$ClientDefinedCO(clientDefinedText)&sort=-id&count=5 -~~~

- -

Alternatively, you can use the static custom object and field names obtained from entity metadata, as the following request URI shows: -~~~ http -GET https://rest.bullhornstaffing.com/rest-services/{corpToken}/search/Candidate? -query=id:“^(customObject9s.text1='sometext’)”&fields=id,customObject2s(text1)&sort=-id&count=5 -~~~

- -

Note: A custom object can be configured so that only users in specific departments can view that custom object. If the current user does not have view entitlements to a custom object, a search on that custom object returns no matching items.

- -

Disassociate custom object from entity

- -

The following example request disassociates an existing custom object from an existing entity in a standard disassociation request. You must use the static custom object name for this call.

- -

Request URI: -~~~ http -DELETE https://rest.bullhornstaffing.com/rest-services/{corpToken}/entity/Candidate/32056 -/customObject2s/3680 -~~~

- -

Query custom object

- -

The following example request performs a custom object query. You must use the static custom object name for this call.

- -

Note: A custom object can be configured so that only users in specific departments can view that custom object. If the current user does not have view entitlements to a custom object, a query on that custom object returns no matching items.

- -

Request URI: -~~~ http -GET https://rest.bullhornstaffing.com/rest-services/{corpToken}/query/PersonCustomObjectInstance2? -where=id=3684&fields=id&orderBy=-id&count=5 -~~~

- -

Use the REST API to create candidates and submit them for jobs

- -

In this article, we use the Bullhorn REST API to complete the following sequence of tasks:

- -
    -
  1. Get a list of jobs from Bullhorn
  2. -
  3. Get a list of tearsheets (hot lists) from Bullhorn
  4. -
  5. Create a candidate in Bullhorn
  6. -
  7. Add the candidate to a tearsheet
  8. -
  9. Submit the candidate for a job as a web response
  10. -
  11. Promote the web response to a submission
  12. -
- -

Before using the REST API, you must perform authorization and authentication. See Getting Started with the Bullhorn REST API for information about obtaining an OAuth 2.0 access token and logging in to the REST API.

- -

Get a list of jobs

- -

The first thing we want to do after logging into the REST API is get a list of jobs from Bullhorn. From this list, we can choose jobs that match potential candidates. To get a list of jobs that match our search criteria, we make a GET /search/JobOrder REST call in which we provide a search query. The query is made against an Apache Lucene search index and uses Lucene query syntax. For more information about Lucene query syntax, see:

- -

http://www.lucenetutorial.com/lucene-query-syntax.html/

- -

Here is a sample REST call where we search for jobs that are open, not deleted, and not archived. The fields parameter refines the call to return just the id, company (clientCorporation), company contact (clientContact), and description for each job that is returned. Note that the count parameter is set to 20, which is the default count for a /search call. To view additional items, you can page data by setting the start and count query parameters to match the items you want to return in subsequent REST calls.

- -

Request URI:

-
GET https://rest.bullhorn.com/rest-services/{corpToken}/search/JobOrder?query=isOpen:1 AND isDeleted:0 AND NOT status:archive&fields=id,clientCorporation,clientContact,description&count=20&start=0
-
- -

Response:

-
{
-  "total" : 1154,
-  "start" : 0,
-  "count" : 20,
-  "data" : [ {
-    "id" : 95423,
-    "clientCorporation" : {
-      "id" : 3767,
-      "name" : "General Chemical"
-    },
-    "clientContact" : {
-      "id" : 5063396,
-      "firstName" : "Chris",
-      "lastName" : "Jones"
-    },
-    "description" : "sample",
-    "_score" : 1.0
-  }, {
-    "id" : 95429,
-    "clientCorporation" : {
-      "id" : 103371,
-      "name" : "Bowlmatic, Inc."
-    },
-    "clientContact" : {
-      "id" : 5062195,
-      "firstName" : "Samual",
-      "lastName" : "Smith"
-    },
-    "description" : "sample",
-    "_score" : 1.0
-  }
-...
-]
-}
-
- -

The search call only returns jobs that the user is entitled to view. Bullhorn users have one of the following entitlement levels for viewing jobs:

- - - -

Get a list of tearsheets (hot lists)

- -

The next thing we want to do is get a list of tearsheets. You use tearsheets, also called hot lists, to group candidates, contacts, or even jobs based on any criteria you define, to save for later use. To get a list of tearsheets that match our search criteria, we make a GET /query/Tearsheet REST call in which we provide a search query. The query is made against a database and uses SQL-like syntax.

- -

Here is a sample REST call where we search for tearsheets that are public and not deleted, or are private, not deleted, and owned by the current user. Replace {currentUserId} with the actual id of the user; You can make the /settings/userId call to get the current user id. The fields query parameter returns all fields for each tearsheet that is returned. Note that the count parameter is set to 15, which is the default count for a /query call. To view additional items, you can page data by setting the start and count query parameters to match the items you want to return in subsequent REST calls.

- -

Request URI:

-
GET https://rest.bullhorn.com/rest-services/{corpToken}/query/Tearsheet?fields=id&where=(isPrivate=false AND isDeleted=false) OR (isPrivate=true ANDisDeleted=false AND owner.id={currentUserId})
-
- -

Response:

-
{
-  "start" : 0,
-  "count" : 15,
-  "data" : [ {
-    "id" : 3198,
-    "candidates" : {
-      "total" : 25,
-      "data" : [ ]
-    },
-    "clientContacts" : {
-      "total" : 0,
-      "data" : [ ]
-    },
-    "dateAdded" : 1396371363117,
-    "description" : null,
-    "isDeleted" : false,
-    "isPrivate" : false,
-    "jobOrders" : {
-      "total" : 2,
-      "data" : [ ]
-    },
-    "name" : "tearsheet1",
-    "owner" : {
-      "id" : 5119506
-    },
-    "recipients" : {
-      "total" : 0,
-      "data" : [ ]
-    }
-  }, {
-    "id" : 3197,
-    "candidates" : {
-      "total" : 6,
-      "data" : [ ]
-    },
-    "clientContacts" : {
-      "total" : 0,
-      "data" : [ ]
-    },
-    "dateAdded" : 1396365291813,
-    "description" : null,
-    "isDeleted" : false,
-    "isPrivate" : false,
-    "jobOrders" : {
-      "total" : 1,
-      "data" : [ ]
-    },
-    "name" : "tearsheet2",
-    "owner" : {
-      "id" : 5119506
-    },
-    "recipients" : {
-      "total" : 0,
-      "data" : [ ]
-    }
-  }
-...
-  } ]
-}
-
- -

Create a candidate

- -

Now that we have a lists of jobs and tearsheets, we can create a candidate, which we will add to a tearsheet and submit for a job.

- -

Here is a sample REST call where we create a candidate:

- -

Request URI:

-
PUT https://rest.bullhornstaffing.com/rest-services/{corpToken}/entity/Candidate
-{
-    "firstName": "John",
-    "lastName": "Smith",
-    "email": "jsmith@novacorp.com",
-    "description": "Resume text.",
-    "name": "John Smith",
-    "username": "user1",
-    "password": "secretPassword",
-    "category": { "id": 212822 },
-    "userType": {"id":35}
-}
-
- -

Response:

-
{
-  "changedEntityType" : "Candidate",
-  "changedEntityId" : 3747,
-  "changeType" : "INSERT"
-}
-
- -

We would want to perform duplicate checking on the following fields before sending the request to create a candidate:

- - - -

First, we make a GET /search/Candidate REST call and return the first three items, if any are found. If email or lastName is blank, we can skip this check.

- -

Here is a sample REST call that searches for duplicates based on the request above:

- -

Request URI:

-
GET https://rest.bullhornstaffing.com/rest-services/{corpToken}/search/Candidate?count=3&query=firstName:"John" AND lastName:"Smith"AND email:"jsmith@novacorp.com"&fields=id,firstName,lastName,email
-
- -

If a duplicate was found, the response might look like this:

-
{
-    "total": 1,
-    "start": 0,
-    "count": 1,
-    "data": [
-        {
-            "_score": 10.501189,
-            "id": 3082,
-            "firstName": "John",
-            "lastName": "Smith",
-            "email": "jsmith@novacorp.com"
-        }
-    ]
-}
-
- -

Note: You can use the REST API to create a candidate and related data from a resume.

- -

Add the candidate to a tearsheet

- -

Now we can add the new candidate to a tearsheet. To do this, we make a PUT /entity/Tearsheet association REST call in which we specify the id of the tearsheet, the name of the entity association field (in this case, candidates), and the id of the candidate. To add more than one candidate to a tearsheet, we use a comma-separated list as shown in this sample REST call:

- -

Request URI:

-
PUT https://rest.bullhornstaffing.com/rest-services/{corpToken}/entity/Tearsheet/7/candidates/3747,3738
-{
-    "changedEntityType": "Tearsheet",
-    "changedEntityId": 5
-    "changeType": "ASSOCIATE"
-}
-
- -

Submit the candidate for a job as a web response

- -

Next, we submit the candidate for a job as a web response. A web response is an online application for a job that has not yet been submitted. To create a web response, we make a PUT /entity/JobSubmission REST call in which we set the candidate field to the id of our candidate, the jobOrder field to the id of our job, the status field to “New Lead”, and the dateWebResponse field to the current date/time as a Unix timestamp in milliseconds.

- -

Here is a sample REST call where we create a web response:

- -

Request URI:

-
PUT https://rest.bullhornstaffing.com/rest-services/{corpToken}/entity/JobSubmission
-{
-    "candidate": {"id": 3747},
-    "jobOrder": {"id": 36},
-    "status": "New Lead",
-    "dateWebResponse": 1370522348880
-}
-
- -

Response:

-
{
-    "changedEntityType": "JobSubmission",
-    "changedEntityId": 863,
-    "changeType": "INSERT"
-}
-
- -

Promote the web response to a submission

- -

When we want to promote the web response to a submission, we make a POST /entity/JobSubmission REST call in which we update the status field to “Submitted” and the dateAdded field to the current date/time as a Unix timestamp in milliseconds.

- -

Here is a sample REST call where we create a submission:

- -

Request URI:

-
POST https://rest.bullhornstaffing.com/rest-services/{corpToken}/entity/JobSubmission/863
-{
-    "status": "Submitted",
-    "dateAdded": 1370522348880,
-}
-
- -

Response:

-
{
-    "changedEntityType": "JobSubmission",
-    "changedEntityId": 863,
-    "changeType": "UPDATE"
-}
-
- -

Note: If we decided that we never want to promote the web response to a submission, we make a POST /entity/JobSubmission REST call in which we set the isHidden field to “true”.

- -

Use the REST API to create candidate data from a resume

- -

The Bullhorn REST API provides a set of operations that parse a resume to Candidate-related data or HRXML. The API also provides operations that convert a resume to HTML or plain text. In this article, we use the REST API to complete the following sequence of tasks:

- -
    -
  1. Parse a resume
  2. -
  3. Create a candidate
  4. -
  5. Create candidate education
  6. -
  7. Create candidate work history
  8. -
  9. Add primary skills to the candidate
  10. -
  11. Attach a resume file to the candidate
  12. -
- -

Before using the REST API, you must perform authorization and authentication. See Getting Started with the Bullhorn REST API for information about obtaining an OAuth 2.0 access token and logging in to the REST API. for information about obtaining an OAuth 2.0 access token and logging in to the REST API.

- -

Parse a resume

- -

To return candidate-related data from a parsed resume, we make a POST /resume/parseToCandidate REST call.

- -

We attach a .doc resume file named candidate.doc to the request as a multipart/form attachment; in a browser form, this is <input type="file"/>. The call returns candidate, candidate education, candidate work history, and skills data.

- -

Request URI:

-
POST https://rest.bullhornstaffing.com/rest-services/{corpToken}/resume/parseToCandidate?format=DOC
-
- -

Response:

-
{
-    "candidate": {
-        "address": {
-            "address1": "123 Osoite Katu",
-            "address2": "Apartment 1",
-            "city": "Kaupunki",
-            "state": "MA",
-            "zip": "02210",
-            "countryID": 1
-        },
-        "phone": "+1 4663464663",
-        "fax": "+1 3293293290",
-        "pager": "+1 724 7727247",
-        "mobile": "+1 662 4666624",
-        "firstName": "Minun",
-        "lastName": "Nimi",
-        "nameSuffix": "DR.",
-        "email": "minun.nimi@finland.com",
-        "phone2": "+1 835 3838353x90",
-        "phone3": "+1 864 3868643",
-        "email2": "mnimi2@finland2.com",
-        "email3": "minumn3@finland3.com",
-        "workPhone": "+1 3874383874x89"
-    },
-   "candidateEducation":    [
-            {
-         "startDate": 1007226000000,
-         "endDate": 1117641600000,
-         "graduationDate": 1117641600000,
-         "school": "Berkeley State University",
-         "city": "Santa Cruz",
-         "state": "CA",
-         "degree": "B.Sc",
-         "major": "COMPUTER SCIENCE",
-         "gpa": 4
-      },
-            {
-         "endDate": 1241193600000,
-         "graduationDate": 1241193600000,
-         "school": "Boston University School of Music",
-         "city": "Boston",
-         "state": "MA",
-         "degree": "B.A",
-         "major": "ADMINISTRATION International Management",
-         "gpa": 3.87
-      }
-   ],
-   "candidateWorkHistory":    [
-            {
-         "startDate": 1015002000000,
-         "endDate": 1188662400000,
-         "companyName": "Teen Pop",
-         "title": "Pop Software Engineer",
-         "comments": "New Millennium Music Corp. Really  How  What"
-      },
-            {
-         "startDate": 665427600000,
-         "endDate": 909939600000,
-         "companyName": "Nineties Bank of Music Concord",
-         "title": "Hip Hop Software Engineer",
-         "comments": "MA    Bop  Hop  Hip"
-      },
-            {
-         "startDate": 315594000000,
-         "endDate": 628534800000,
-         "companyName": "Eighties National",
-         "comments": "New Wave Musak  Listen  Like  Learn"
-      }
-   ],
-   "skillList":    [
-      "Blowout preventer",
-      "FINANCE",
-      "MA"
-   ]
-}
-
- -

Create a candidate from the parsed resume

- -

To create a candidate from the parsed resume, we make a PUT /entity/Candidate REST call.

- -

Note: When performing this operation programmatically, you would most likely parse the /resume/parseToCandidate response to a Json object for easy manipulation. You would then write the “Candidate” section of the response to a string you can use in the body of the PUT /entity/Candidate request. -The body of this request is the Candidate section of the /resume/parseToCandidate response. No data changes are necessary.

- -

Request URI:

-
PUT https://rest.bullhornstaffing.com/rest-services/{corpToken}/entity/Candidate
-{
-    "address": {
-        "address1": "123 Osoite Katu",
-        "address2": "Apartment 1",
-        "city": "Kaupunki",
-        "state": "MA",
-        "zip": "02210",
-        "countryID": 1
-    },
-    "phone": "+1 4663464663",
-    "fax": "+1 3293293290",
-    "pager": "+1 724 7727247",
-    "mobile": "+1 662 4666624",
-    "firstName": "Minun",
-    "lastName": "Nimi",
-    "nameSuffix": "DR.",
-    "email": "minun.nimi@finland.com",
-    "phone2": "+1 835 3838353x90",
-    "phone3": "+1 864 3868643",
-    "email2": "mnimi2@finland2.com",
-    "email3": "minumn3@finland3.com",
-    "workPhone": "+1 3874383874x89"
-
-    }
-}
-
- -

Response:

-
{
-   "changedEntityType": "Candidate",
-   "changedEntityId": 2038,
-   "changeType": "INSERT"
-}
-
- -

We have successfully created a Candidate entity from the parsed resume. We can return the new Candidate entity with this request URI:

-
GET https://rest.bullhornstaffing.com/rest-services/{corpToken}/entity/Candidate/2038?fields=*
-
- -

Response:

-
{
-  "data" : {
-    "id" : 2038,
-    "address" : {
-      "address1" : "123 Osoite Katu",
-      "address2" : "Apartment 1",
-      "city" : "Kaupunki",
-      "state" : "MA",
-      "zip" : "02210",
-      "countryID" : 1
-    },
-    "businessSectors" : {
-      "total" : 0,
-      "data" : [ ]
-    },
-    "candidateID" : 871,
-    "categories" : {
-      "total" : 0,
-      "data" : [ ]
-    },
-    "category" : {
-      "id" : 431889
-    },
-    ...
-    "firstName" : "Minun",
-    "username" : "_300006637",
-    "veteran" : null,
-    "willRelocate" : false,
-    "workAuthorized" : true,
-    "workPhone" : "+1 3874383874x89"
-  }
-}
-
- -

With a slight change to the POST /resume/parseToCandidate REST call, we can return a text or HTML version of the resume in the response. We will return a text version of the resume. The only difference is that the call includes the populateDescription parameter.

- -

Request URI:

-
POST https://rest.bullhornstaffing.com/rest-services/{corpToken}/resume/parseToCandidate?format=DOC&populateDescription=text
-
- -

The response includes the text version of the resume in the description field of the Candidate data.

- -

Response:

-
{
-   "candidate": {
-      "address":       {
-         "address1": "123 Osoite Katu",
-         "address2": "Apartment 1",
-         "city": "Kaupunki",
-         "state": "MA",
-         "zip": "02210",
-         "countryID": 1
-      },
-      "phone": "+1 4663464663",
-      "fax": "+1 3293293290",
-      "pager": "+1 724 7727247",
-      "mobile": "+1 662 4666624",
-      "firstName": "Minun",
-      "lastName": "Nimi",
-      "nameSuffix": "DR.",
-      "middleName": "Keskimmäinen",
-      "email": "minun.nimi@finland.com",
-      "phone2": "+1 835 3838353x90",
-      "phone3": "+1 864 3868643",
-      "email2": "mnimi2@finland2.com",
-      "email3": "minumn3@finland3.com",
-      "description": "Dr. Minun Keskimmäinen Nimi\r\n123 Osoite Katu\r\nApartment 1\r\nKaupunki, MA
- 02210\r\nHome: 466-346-4663 Business: 387-438-3874 ext. 89 Mobile: 662-466-6624\r\nTelephone: 835-383-8353 ext.
-90 VoiceNumber: 864-386-8643\r\nFax: 329-329-3290 Pager: 724-772-7247\r\nMinun.Nimi@finland.com
- mnimi2@finland2.comminumn3@finland3.com\r\n\r\nEmployment History\r\n\r\nEighties National Music Bank Lexington,
- MA Jan. 1, 1980 - Dec. 31, 1989\r\n\r\nNew Wave Musak Software Engineer\r\n·  Listen\r\n·  Like\r\n
-Learn\r\n\r\nNineties Bank of Music Concord, MA February 1991 - November 1998\r\n\r\nHip Hop Software Engineer\r\n·
-Bop\r\n·  Hop\r\n·  Hip\r\n\r\nNew Millennium Music Corp. Bedford, MA Mar. 2002 - Sept. 2007\r\n\r\nTeen Pop Software
-Engineer\r\n·  Really\r\n·  How\r\n·  What\r\n\r\nEducation\r\n\r\nBerkeley State University, Santa Cruz, CA\r\nBachelor of
-Science, Computer Science, December 2001 - June 2005\r\n·  Cumulative GPA: 3.0/4.0; Major GPA: 4.0/4.0\r\n·  Dean's
-List - 3 Semesters\r\n\r\nBoston University School of Music; Boston, MA\r\nBachelor of Arts in Business Administration
-May 2009\r\nDual Concentration in International Management and Finance\r\nMinor in Economics\r\nCumulative GPA: 3.87\r\n
-Activities/Honors\r\nHonors Student\r\nDean s List: Fall 2005 and Spring 2006\r\n\r\n.\r\n",
-      "workPhone": "+1 3874383874x89"
-  },
-   ...
-}
-
- -

Note: The resume in the description field is a Json-encoded string. If you have parsed the POST /resume/parseToCandidate response to an object for manipulation, you must re-encode the description value before using it in a PUT /entity/Candidate call. For example, in Groovy you can use the groovy.json.JsonOutput.toJson(java.lang.String s) method to Json-encode a string.

- -

Create candidate education data from the parsed resume

- -

To create a CandidateEducation entity from the parsed resume, we make a PUT /entity/CandidateEducation REST call.

- -

The CandidateEducation section of the POST /resume/parseToCandidate response is an array of CandidateEducation objects. You must make separate PUT /entity/CandidateEducation calls for each CandidateEducation object in the array.

- -

Note: When performing this operation programmatically, you would most likely parse the /resume/parseToCandidate response to a Json object for easy manipulation. You would then write a “CandidateEducation” object from the response to a string you can use in the body of the PUT /entity/CandidateEducation request.

- -

Request URI:

-
PUT https://rest.bullhornstaffing.com/rest-services/{corpToken}/entity/CandidateEducation
-
- -

Request body: -~~~ -{ - “candidate”: {“id”: 2038}, - “startDate”: 1007226000000, - “endDate”: 1117641600000, - “graduationDate”: 1117641600000, - “school”: “Berkeley State University”, - “city”: “Santa Cruz”, - “state”: “CA”, - “degree”: “B.Sc”, - “major”: “COMPUTER SCIENCE”, - “gpa”: 4 -} -~~~

- -

The request body matches the first item in the array of returned CandidateEducation objects with the exception of one additional field, the “candidate” field, where we specify the id of the new Candidate entity.

- -

Response:

-
{
-    "changedEntityType": "CandidateEducation",
-    "changedEntityId": 657,
-    "changeType": "INSERT"
-}
-
- -

We have successfully created a CandidateEducation entity from the parsed resume. We can return the new CandidateEducation entity with this request URI:

-
GET https://rest.bullhornstaffing.com/rest-services/{corpToken}/entity/Candidate/2038?fields=id
-
- -

Response:

-
{
-  "data" : {
-    "id" : 657,
-    "candidate" : {
-      "id" : 2038,
-      "firstName" : "Minun",
-      "lastName" : "Nimi"
-    },
-    "certification" : null,
-    "city" : "Santa Cruz",
-    "comments" : null,
-    "customDate1" : null,
-     ...
-    "dateAdded" : 1369334851697,
-    "degree" : "B.Sc",
-    "endDate" : 1117641600000,
-    "expirationDate" : null,
-    "gpa" : 4.0,
-    "graduationDate" : 1117641600000,
-    "isDeleted" : false,
-    "major" : "COMPUTER SCIENCE",
-    "migrateGUID" : null,
-    "school" : "Berkeley State University",
-    "startDate" : 1007226000000,
-    "state" : "CA"
-  }
-}
-
- -

Create candidate work history from the parsed resume

- -

To create a CandidateWorkHistory entity from the parsed resume, we make a PUT /entity/CandidateWorkHistory REST call.

- -

The CandidateWorkHistory section of the POST /resume/parseToCandidate response is an array of CandidateWorkHistory objects. You must make separate PUT /entity/CandidateWorkHistory calls for each CandidateWorkHistory object in the array.

- -

Note: When performing this operation programmatically, you would most likely parse the /resume/parseToCandidate response to a Json object for easy manipulation. You would then write a “CandidateWorkHistory” object from the response to a string you can use in the body of the PUT /entity/CandidateWorkHistory request.

- -

Request URI:

-
PUT https://rest.bullhornstaffing.com/rest-services/{corpToken}/entity/CandidateWorkHistory
-{
-    "candidate":  {"id": 2038},
-        "startDate": 1015002000000,
-         "endDate": 1188662400000,
-         "companyName": "Teen Pop",
-         "title": "Pop Software Engineer",
-         "comments": "New Millennium Music Corp. Really  How  What"
-}
-
- -

The request body matches the first item in the array of returned CandidateWorkHistory objects with the exception of one additional field, the “candidate” field, where we specify the id of the new Candidate entity.

- -

Response:

-
{
-    "changedEntityType": "CandidateWorkHistory",
-    "changedEntityId": 2446,
-    "changeType": "INSERT"
-}
-
- -

We have successfully created a CandidateWorkHistory entity. We can return the new CandidateWorkHistory entity with this request URI:

-
GET https://rest.bullhornstaffing.com/rest-services/{corpToken}/entity/CandidateWorkHistory/2446?fields=*
-
- -

Response:

-
{
-  "data" : {
-    "id" : 2446,
-    "bonus" : null,
-    "candidate" : {
-      "id" : 2038,
-      "firstName" : "Minun",
-      "lastName" : "Nimi"
-    },
-    "clientCorporation" : null,
-    "comments" : "New Millennium Music Corp. Really  How  What",
-    "commission" : null,
-    "companyName" : "Teen Pop",
-    "customDate1" : null,
-     ...
-    "dateAdded" : 1369336573990,
-    "endDate" : 1188662400000,
-    "isDeleted" : false,
-    "isLastJob" : false,
-    "jobOrder" : null,
-    "migrateGUID" : null,
-    "placement" : null,
-    "salary1" : null,
-    "salary2" : null,
-    "salaryType" : null,
-    "startDate" : 1015002000000,
-    "terminationReason" : null,
-    "title" : "Pop Software Engineer"
-  }
-}
-
- -

Add primary skills from the parsed resume

- -

The SkillList section of the POST /resume/parseToCandidate response is an array of skill names. To add primary skill associations to the Candidate entity, we need to know the ids of existing Skill entities that correspond to the returned skill names. These are the skills defined in the Bullhorn private label. We call GET /options/Skill to return the full list of Skill entities.

- -

When we find matching Skill ids, we call PUT /entity/Candidate/{candidateId}/primarySkills/{skillId,skillId,…} to associate those Skill entities as primary skills for the Candidate. -Note: When performing this operation programmatically, you would most likely parse the POST /resume/parseToCandidate response to a Json object for easy manipulation.

- -

Request URI for adding Skills 260 and 964 as primary skill associations:

-
PUT https://rest.bullhornstaffing.com/rest-services/{corpToken}/entity/Candidate/2038/primarySkills/260,964
-
- -

Response:

-
{
-    "changedEntityType": "Candidate",
-    "changedEntityId": 2038,
-    "changeType": "ASSOCIATE"
-}
-
- -

We have successfully added two primary skill associations to the Candidate entity. We can see that the associations have been added with this request URI:

-
GET https://rest.bullhornstaffing.com/rest-services/{corpToken}/entity/Candidate/2038?fields=primarySkills
-
- -

Response:

-
{
-  "data" : {
-    "primarySkills" : {
-      "total" : 2,
-      "data" : [ {
-        "id" : 964
-      }, {
-        "id" : 260
-      } ]
-    }
-  }
-}
-
- -

Attach the resume file to the candidate

- -

To attach the original resume file to the Candidate entity, we call PUT /file/Candidate/{candidateId}/raw. We attach the .doc resume file to the request as a multipart/form attachment; in a browser form, this is <input type="file"/>.

- -

Request URI:

-
PUT https://rest.bullhornstaffing.com/rest-services/{corpToken}/file/Candidate/2038/raw?externalID=Portfolio&fileType=SAMPLE
-
- -

The externalID and fileType parameters are required. For externalID, use Portfolio as the value. For fileType, use SAMPLE as the value.

- -

Response:

-
{
-    "fileId" : 124523
-}
-
- -

We have successfully attached the resume file to the Candidate entity. We can see that the attachment has been added with this request URI:

-
GET https://rest.bullhornstaffing.com/rest-services/{corpToken}/entityFiles/Candidate/2038
-
- -

Response:

-
{
-  "EntityFiles" : [ {
-    "id" : 1234523,
-    "type" : "Resume",
-    "name" : "candidate.doc",
-    "description" : null,
-    "contentType" : "application/msword"
-  }]
-}
-
- -

Understanding REST Form Triggers

- -

REST form triggers let you intercept REST calls and perform additional validations or data processing before data is saved in the Bullhorn database. Because application logic for form triggers can live outside of the Bullhorn hosting facilities, you have the freedom to write your own custom logic, including accessing non-Bullhorn systems to verify or modify data.

- -

A form trigger is a web application that performs its own validation or data processing. If the form trigger responds with a value of true, the data is saved to the database. The Bullhorn support team can also configure what should happen if a form trigger fails to respond in a timely fashion. REST form triggers are configured at the corporation level.

- -

You can create REST form triggers for creating or updating entities of the following types:

- - - -

The Bullhorn support team configures your form trigger with the following information:

- - - - - - - - - - - - - - - - - - - - - - - - - - - -
FieldValue
NameName of the form trigger.
Trigger URLEndpoint to hit when the REST create or update request is sent.
Wait for ResponseWhether to wait for the response of the form trigger before proceeding.
TimeoutTime to wait for a response. Maximum of three seconds. If it takes longer, it is considered an error.
HTTP MethodWhether the trigger takes a POST or PUT.
- -

Validating and changing data

- -

Regardless of your programming environment, the remote service you use as a form trigger must provide logic for validating the data passed to it, and provide a response of true or false. The request body that is sent to the form trigger endpoint has the following structure:

-
{
-    "meta": {
-        "userId": 1 // User ID of the updating user
-    },
-    "data": { "id": 123, .... }
-}
-
- -

The form trigger endpoint response must conform to the following structure:

-
{
-    "result": true,                 // to save it or not
-    "error": "Error message",       // if result is false, reason to not save
-    "data" : { "id": 123, .... }    // the data to save if result was true
-}
-
- -

IMPORTANT: The data returned in the “data” key of the response is what will be saved. If the form trigger is performing validation with no data changes, it still must respond with the full data packet that was sent to it.

- -

Executing a form trigger on a REST call

- -

To execute a form trigger, you must pass “executeFormTriggers=true” on an entity create or update call. For example, the following REST call creates a Candidate and executes a form trigger that changes the value of the Candidate name:

-
PUT http://rest.bullhornstaffing.com/rest-services/abcde/entity/Candidate?&executeFormTriggers=true
-
- -

Body: -~~~ json -{ - “firstName”: “First”, - “lastName”: “Last”, - “name”: “FirstLast”, - “username”: “TestUserName”, - “status” : “active” -} -~~~

- -

Response: -~~~ json -{ - “changedEntityType”: “Candidate”, - “changedEntityId”: 792069, - “changeType”: “INSERT”, - “data”: { - “lastName”: “Last”, - “username”: “TestUserName”, - “status”: “active”, - “name”: “FirstLast”, - “firstName”: “First” - } -} -~~~

- -

The following REST call gets back the name field of the Candidate that was just created. Note that the name value is changed so that a timestamp precedes the value that was sent on the request to create the Candidate:

-
GET http://rest.bullhornstaffing.com/rest-services/abcde/entity/Candidate/792069?fields=name
-
- -

Body: -~~~ json -{ - “data”: { - “name”: “1503504704182 FirstLast” - } -} -~~~

- -

Bullhorn Connect

- -

Introduction

- -

Internally at Bullhorn we have to open new pages within the CRM from different contexts of the application, externally from emails, or from other products offerings. This API is publicly accessible and can be used by our partners as well.

- -

Use Cases

- -

The API lives under one endpoint, all you need to do you open a new browser window to the following urls. If Bullhorn is running in another tab then the window will close and the page will be opened within the current Bullhorn context. If Bullhorn is not running the user will be prompted to login before being brought to the page.

- -

https://www.bullhornstaffing.com/BullhornStaffing/OpenWindow.cfm

- -

Every OpenWindow calls has a few required params:

- - - - - - - - - - - - - - - -
ParamsDescription
entityDefine the Entity type for the page you want to open
viewThe tab, section, or view to open, eg. Add, Edit, Notes
- -

Opening Add Forms

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
EntityCall
Candidate:/OpenWindow.cfm?entity=Candidate&view=Add
ClientContact:/OpenWindow.cfm?entity=ClientContact&view=Add
ClientCorporation:/OpenWindow.cfm?entity=ClientCorporation&view=Add
JobOrder:/OpenWindow.cfm?entity=JobOrder&view=Add
Placement:/OpenWindow.cfm?entity=Placement&view=Add
Opportunity:/OpenWindow.cfm?entity=Opportunity&view=Add
Lead:/OpenWindow.cfm?entity=Lead&view=Add
- -

If you want to add a note to any of the top level entities you can use the AddNote view:

-
/OpenWindow.cfm?entity=Candidate&view=AddNote
-
- -

Or alternatively you can use the Note entity and pass all of the references yourself:

-
/OpenWindow.cfm
-    ?entity=Note
-    &view=Add
-    &action=Phone Call
-    &comments=Really interesting message
-    &personReferenceID=123       // About
-    &otherPersonReferenceIDs=1   // Candidate, Lead, Contact references
-    &jobOrderReferenceID=1       // Job references
-    &opportunityID=456           // Opportunity references
-    &placementReferenceID=1      // Placement references
-
- -

Overview Pages

- -

The same concept can be applied for the overview pages using the Overview view parameter, just make sure you remember to include an id parameter as well:

-
/OpenWindow.cfm?entity=Candidate&id=12345&view=Overview
-
- -

If you want to open a the activity tab on the overview you can use the Activity view parameter. Additionally you can use the expandedSection parameter to have a specific section open:

-
/OpenWindow.cfm?entity=Candidate&id=12345&view=Activity&expandedSection=Interviews
-
- -

The Edit tab can be opened with specific Edit view parameters:

-
// Edit
-/OpenWindow.cfm?entity=Candidate&id=12345&view=Edit
-
- -

Disclaimer

- -

The OpenWindow API has been changed frequently over the years as new entities and sections of the application get added or updated. The API is stable and no foreseeable changes are planned. This Article does not include all of the features in the OpenWindow API or any of the nuances that might exist just the most common use cases. If you have any question or need to open a window that is not listed please ask them in our Gitter channel.

- -

Custom components, tabs, and menu actions enable developers and partners to incorporate content and functionality from an external application into a Bullhorn entity page. Custom components are tied to field maps and you configure them with the Field Mappings tool. Custom tabs and menu actions are not tied to field maps; you configure them with the View Layout tool.

- -

Custom components appear on entity pages. There are two types of custom components within Bullhorn:

- - - -

Custom tabs appear on candidate, client, contact, job, and placement pages. The order of custom tabs matches the order specified in View Layout.

- -

Custom menu actions appear on contextual menus for candidates, clients, contacts, jobs, and placements. The order of custom menu actions matches the order specified in View Layout. A line separator appears above the first custom menu action displayed. A maximum of five custom menu actions can appear on a menu. Custom menu actions appear in the following locations:

- - - -

Custom display components can only appear on overview pages and have a limited amount of space, but they have the advantage of being immediately visible to the user when the record is opened. A custom tab or menu action can present more data than a custom display component, but users must click a custom tab or menu item to access the component. You should decide whether a custom display component, tab, or menu action makes sense based on the data it must present and how the user will interact with it. Bullhorn partners creating components for multiple customers should also provide instructions that specify where administrators can or should place their component for it to render properly.

- -

Custom components, tabs, and menu actions are all self-contained IFRAMEs hosted by the Bullhorn browser application. The IFRAME can request any URL that has been configured in Bullhorn. When the IFRAME is created, the Bullhorn application automatically appends the context data necessary for the remote server to identify the calling user and responds with the appropriate data or content for that Bullhorn record.

- -

All requests to the remote system are made from the user’s client computer, so the remote application can reside on any system to which the user can gain access. The custom component can be as simple as some customized content relevant to the current record, or it can involve multiple user interactions and component refreshes.

- -

Example

- -

The following example walks through how a fictitious company called Quick Assessments could create a custom tab that integrates Bullhorn with its service. -Although this example uses a custom tab, you could easily implement the same functionality with a custom component or menu action.

- -

Quick Assessments provides online assessments for common skill areas. Recruiters with an account can create a new assessment by providing the candidate’s key contact information and selecting the required assessment from a list of pre-configured options.

- -

To simplify the process of registering candidates for assessments, Quick Assessments has created a custom tab on the Candidate record in Bullhorn.

- -

NEW IMAGE HERE

- -

The application hosted in the tab provides a button that enables users to register a candidate for an assessment directly from the candidate record. It also presents a list of existing assessments for candidates who have already taken tests through the Quick Assessments application.

- -

NEW IMAGE HERE

- -

The following table describes how this custom tab interacts with the Bullhorn web application and the Bullhorn SOAP web services API to enable the integration.

- -

FIXTHISTABLE ==========================================

- - - - - - - - - - - - - - - - - - - - - - - - - - - -
ActionResponse
User loads the Quick Assessment tab of a Candidate record.When the user requests the Bullhorn page, an IFRAME for the Quick Assessments application makes a request for the following URL: http://quickassessments.com/bhwidget/?Key=12349876&userid=0&entitytype=candidate&entityid=99&privatelabelid=105&height=yy&width=xx). The URL and the Key attribute were configured for this tab through the Bullhorn administrator based on instructions from Quick Assessments. Quick Assessments assigns each customer a unique Key for identification purposes. The remaining URL variables are appended at runtime by the Bullhorn application based on the user’s context.
The Quick Assessments page verifies that the Key matches a valid Quick Assessments customer ID and checks to see if there are any active assessments for a candidate with a userId of 99. If there are no assessments associated with this ID, the server returns HTML that displays an Add Assessment button. This appears within the tab in Bullhorn.
User clicks the Add Assessment button.Clicking the button loads a new HTML page within the IFRAME that presents a list of assessments that are available to this customer.
User picks an assessment and clicks submit.Using the ID property for this candidate and its partner API key, the Quick Assessments application requests the necessary data from the Bullhorn SOAP web services API (name, email address, etc.). Using this data, the Quick Assessments application creates a new assessment and sends a notification to the candidate. It also stores the Bullhorn ID for future reference.
The Quick Assessment application refreshes the IFRAME and lists the current assessment with a status of ”pending.”
- -

Creating a Custom Display Component

- -

Custom display components are dedicated portions of a screen in Bullhorn that are programmed to show non-Bullhorn content that is served from a remote application or service. Building a custom display component is as simple as creating a web application that can process requests from the IFRAME component and render an HTML user interface that fits into the space allotted by the Bullhorn user interface.

- -

When a custom component is initialized in the Bullhorn application, it issues a GET request for its associated URL. The URL is configured in the Default Value property of the Custom Component field. These values must be configured by the Bullhorn administrator using the Field Mappings tool. The URL can also include any variables needed to authorize this account with the external application; for example, username, password, account number, and so forth. Each customer or private label can have a unique URL/variable combination, but all requests made from that private label contain the values configured for the custom component.

- -

If additional personalization or authorization is required, you can use the dynamically appended variables listed below or use a login screen and cookies to manage authentication. When the request is made, the following dynamic variables are appended to the component’s URL on a per request basis.

- -

Parameter Name

- -

Type

- -

Description

- -

CorporationID

- -

Integer

- -

The unique ID for the corporation of the current user.

- -

currentBullhornUrl

- -

String

- -

The URL of the Bullhorn page that is hosting the IFRAME. This value is URL encoded.

- -

EntityID

- -

Integer

- -

The unique ID for this entity instance. This can be used to retrieve the entire entity DTO using the find operation.

- -

EntityType

- -

String

- -

The name of the entity page on which this component has been placed. Possible values are Candidate, Client Contact, Client, and Job Posting.

- -

PrivateLabelID

- -

Integer

- -

The unique ID for the private label (configuration) through which the user is accessing the application.

- -

UserID

- -

Integer

- -

The unique ID for the user of the application.

- -

The page that processes the request made by the custom component should use these values to authorize the request and determine what content should be returned to the user when the component is loaded.

- -

The method for accessing these variables varies depending on your programming environment. For example, in PHP, they become accessible in the $_REQUEST variable; in ASP.NET, they become accessible in the Page.Request object.

- -

Configuring a Custom Display Component

- -

Configuring a custom display component for use in the Bullhorn application involves the View Layout and the Field Mappings tools. Each of the supported records in Bullhorn includes three fields that can be used for custom components: CustomComponent1, CustomComponent2, and CustomComponent3. To configure the URL for a custom component:

- -

On the Tools menu, select Field Mappings. -Select the entity to which you would like to add the component.

- -

Click the name of one of the available custom component fields (CustomComponent1-3).

- -

In the Hidden field, change the value to No if it is not already set to No.

- -

In the Default Value field, add the URL that should be requested for this component.

- -

Click Save.

- -

Once your custom display component has been configured in the Field Mappings tool, it is ready to be placed on either the overview tab of that record type (the default view) or on a custom tab on that record type.

- -

Placing Custom Display Components on the Overview Tab -There are five potential locations for a custom component on the overview tab. The following table and figure illustrate the available placements and the corresponding sizes for custom components. The size values will be included as URL variables (see above).

- -

Placement

- -

Height

- -

Width

- -

OverviewTop (A)

- -

150 px

- -

600 px

- -

OverviewLeft (B)

- -

150 px

- -

300 px

- -

OverviewRight ©

- -

150 px

- -

300 px

- -

OverviewBottom (D)

- -

150 px

- -

600 px

- -

SideInfo (E)

- -

150 px

- -

150 px

- -

To configure the placement of the custom component on the Overview tab of the entity page:

- -

On the Tools menu, select View Layout .

- -

Select the entity where the custom component should appear.

- -

Select the Overview Tab tab.

- -

Locate the section where you would like to include the component

- -

Select the component from the list of fields in the Exclude from View list.

- -

Click the right arrow to move this field to the Include in View list.

- -

Click Save.

- -

The custom component now appears on the Overview tab of the entity.

- -

Creating a Custom Edit Component -Custom edit components allow you to override the built-in edit controls in Bullhorn and replace them with controls that present data not managed by the Bullhorn application. When the user saves the form, Bullhorn takes the value set by the custom edit component and inserts it into the appropriate field in the Bullhorn record.

- -

Like custom display components, custom edit components are displayed within an IFRAME. The URL requested by the control includes all of the parameters listed above for custom display components. In addition, the current value for the edit control’s field will also be included in the URL, as follows:

- -

Parameter Name

- -

Type

- -

Description

- -

baseControlName

- -

String

- -

The name of the field with which this custom edit component is associated. This corresponds to the field in Bullhorn that will be updated when the form is saved.

- -

value

- -

Any

- -

The current value of the field in Bullhorn.

- -

Once they have been loaded, custom edit components communicate with the Bullhorn application form by changing the parent href property (the href of the form that launched the custom external control).

- -

The following example illustrates the HTML and JavaScript for a drop-down control that is configured for the experience property.

- -

- -

- -

- - - -

- -

- -

- -

Configuring a Custom Edit Component

- -

Configuring a custom edit component for use in the Bullhorn application involves the Field Mappings tool. To configure one of the Bullhorn fields to use a custom edit component:

- -

On the Tools menu, select Field Mappings. -Select the entity to which you would like to add the edit component.

- -

Click the name of the field whose edit control you want to replace (for example, experience). Note: You cannot use any of the customComponent1-3 fields, as these do not represent record values that are stored in Bullhorn. You must use a standard Bullhorn field, such as experience or customText1.

- -

Select Custom External Control from the Edit Type drop-down.

- -

In the Default Value field, add the URL that should be requested for this component.

- -

Click Save .

- -

Configuring the Client Browser for Custom Edit Components -To function properly, the website where the control(s) are hosted must be added to Internet Explorer 7 and 8 Trusted Sites and the Navigate sub-frames across different domains custom setting must be enabled for the trusted sites.

- -

Creating a Custom Tab or Menu Action -The amount of space available on a dedicated tab or popup window depends on the user’s screen resolution and user interface configuration. You should design the page to easily adapt to multiple widths.

- -

To ensure that no vertical scroll bars appear, the custom tab and custom menu action features provide a way for your application to communicate its height to the hosting page. To take advantage of this feature, you should add a URL variable called displayHeight to the URL when it is configured in the View Layout tool. For example, http://[baseURL]?displayHeight=3000px. If you do not provide a displayHeight value, the default height of the IFRAME is 4000px.

- -

You can also dynamically modify the height of the IFRAME by changing the displayHeight variable after Bullhorn has initialized the IFRAME. This is useful if your page dynamically shows or hides regions of the DOM, or if users will navigate through multiple pages of different heights. The following JavaScript functions can be added to any page that appears in a custom tab:

- -

function addResizeParameterToUrl()

- -

{

- -

var size = document.body.scrollHeight;

- -

var currentHref = decodeURIComponent(getQueryStringParameter(location.href,

- -

“currentBullhornUrl”).replace(/+/g, “ ”));

- -

var fragment=“displayHeight=” + size;

- -

currentHref+=“#” + fragment;

- -

parent.location.href=currentHref;

- -

}

- -

The hosting Bullhorn page listens for changes to the displayHeight URL variable and adjusts the dimensions of the IFRAME accordingly. To ensure this variable is updated, you must also attach the addResizeParameterToURL() function as a listener to the onresize and onload events on the page. You can do this by adding the following to the page’s body tag:

- -

- -

Depending on the amount of DOM scripting in your pages, you may also need to call this function from other places in your application as well.

- -

If additional personalization or authorization is required, you can use the dynamically appended variables listed below or use a login screen and cookies to manage authentication. When the request is made, the following dynamic variables are appended to the component’s URL on a per request basis.

- -

Parameter Name

- -

Type

- -

Description

- -

CorporationID

- -

Integer

- -

The unique ID for the corporation of the current user.

- -

currentBullhornUrl

- -

String

- -

The URL of the Bullhorn page that is hosting the IFRAME. This value is URL encoded.

- -

EntityID

- -

Integer

- -

The unique ID for this entity instance. This can be used to retrieve the entire entity DTO using the find operation.

- -

EntityType

- -

String

- -

The name of the entity page on which this component has been placed. Possible values are Candidate, Client Contact, Client, and Job Posting.

- -

PrivateLabelID

- -

Integer

- -

The unique ID for the private label (configuration) through which the user is accessing the application.

- -

UserID

- -

Integer

- -

The unique ID for the user of the application.

- -

authCode

- -

String

- -

An encoded value used by partner applications to authenticate the request (included only for tabs or menu actions configured for a partner application).

- -

The page that processes the request should use these values to authorize the request and determine what content should be returned to the user when the component is loaded.

- -

The method for accessing these variables varies depending on your programming environment. For example, in PHP, they become accessible in the $_REQUEST variable; in ASP.NET, they become accessible in the Page.Request object.

- -

The following table describes how a custom tab or custom menu action interacts with the Bullhorn web application and the Bullhorn SOAP web services API to enable the integration.

- -

Action

- -

Response

- -

User clicks a custom tab or a custom menu item.

- -

For a custom tab, the web page for the associated URL opens in an IFRAME that fills the tab.

- -

For a custom menu action, the web page for the associated URL opens in an IFRAME that fills a popup window.

- -

For a custom tab, the user interacts with contents of tab.

- -

For a custom menu action, the user interacts with a popup window.

- -

Configuring a Custom Tab or Menu Action -To configure a custom tab or menu action:

- -

On the Tools menu, select View Layout .

- -

Select the entity to which you want to add the custom tab or menu action.

- -

To add a custom tab, select the Custom Tabs tab. -To add a custom menu action, select the Custom Menu Actions tab.

- -

Click the Add New button.

- -

In the Name field of the new entry, enter the name to display for the custom tab or menu item.

- -

In the URL field, enter the URL you want to request.

- -

In the Partner Name field, select a partner name if desired.

- -

If you are configuring more than one custom tab or menu action, use the arrows to set the order in which the items will appear.

- -

Click Save.

- + + + + + + + + +
diff --git a/includes/changelog/changelog b/includes/changelog/changelog new file mode 100644 index 0000000..70400c6 --- /dev/null +++ b/includes/changelog/changelog @@ -0,0 +1,5 @@ +

REST API changes by Bullhorn release

+ +

Release 5.0

+ +

| ADDED | BillMaster addedByUser field |

diff --git a/index.html b/index.html index 16f20dc..0b6c4c8 100644 --- a/index.html +++ b/index.html @@ -126,7 +126,7 @@

Introduction

General Conventions