Summary
Bullhorn Data Hub is a flexible data structure to store data for reporting and analytics across Bullhorn, marketplace partners, and external sources.
Prerequisites
All Data Hub API calls must be made with a valid BH REST Token (either via OAuth client API authentication or within a valid Bullhorn REST API Session within the ATS application).
Schema definition and setup must be enabled for the Bullhorn corporation that is sending data (whether data is sent via client or directly from a custom application owned by the client).
API Endpoints
Type | Endpoint | Inputs (request body or url params) | Description |
---|---|---|---|
POST | data-hub/data | Request Body: - sourceSystem - entityType - schemaVersion - Items (Up to 100 items allowed in payload) |
Upserts data to datahub. Payload must be formatted according to schema definition setup for that corp. |
POST | data-hub/data/find | Request Body: - sourceId - entityType.name or entityType.id Must be built using Adaptive Query format, see example |
Find is used to query data for viewing with adaptive query constraints. |
Using Data Hub
Endpoint
Type: POST
- {rest-url}/data-hub/data
Example Request Body:
[
{
"sourceSystem": "sourceSystemName",
"entityType": "entityTypeName",
"schemaVersion": "schemaVersionName",
"items": [
{
"sourceId": 1,
"dateAddedInSourceSystem": "2024-11-31T17:48:17.182+00:00",
"dateLastModifiedInSourceSystem": "2024-11-31T17:48:17.182+00:00",
"payload": "{ \"name\": \"bob\", \"age\": 25, \"address\": { \"street\": \"789 Main St\", \"city\": \"New York\", \"state\": \"NY\", \"postalCode\": \"10001\" }, \"hobbies\": [\"reading\", \"running\"] }",
"isDeleted": false,
"placementId": 107,
"candidateId": 123,
"clientContactId": 55,
"clientCorporationId": 55,
"jobOrderId": 123,
"jobSubmissionId": 123,
"leadId": 123,
"opportunityId": 465,
"corporateUserId": 123,
"noteId": 123,
"appointmentId": 123,
"payableChargeId": 123,
"billableChargeId": 134
// up to 100 items
}
]
}
]
Example 200 Response:
{
"statusCode": 200,
"messages": [],
"data": [
{
"entityType": "entityTypeName",
"sourceSystem": "sourceSystemName",
"totalSuccessfulItems": 1,
"successfulItems": [
{
"sourceId": "1",
"dataId": 1234
}
]
}
]
}
Endpoint
Type: POST
- {rest-url}/data-hub/data/find
Example Request Body:
{
"criteria": {
"and": [
{
"entityType.name": {
"equalTo": "entityTypeName"
}
},
{
"sourceId": {
"in": ["2","7"]
}
},
{
"entityType.sourceSystem.name": {
"equalTo": "sourceSystemName"
}
// add whatever other constraints you want
}
]
}
}
Example 200 Response:
{
"statusCode": 200,
"messages": null,
"data": {
"start": 0,
"count": 1,
"total": 1,
"data": [
{
"dataId": 1234,
"sourceId": "2",
"entityType": {
"entityTypeId": 241,
"name": "sourceSystemName"
},
"entityTypeSchemaVersion": {
"entityTypeSchemaVersionId": 441,
"name": "schemaVersionName"
},
"dateAdded": "2025-01-10T22:56:18.012+00:00",
"dateLastModified": "2025-01-10T22:56:18.012+00:00",
"dateAddedInSourceSystem": "2024-12-01T17:48:17.000+00:00",
"dateLastModifiedInSourceSystem": "2024-12-01T17:48:17.000+00:00",
"payload": "{ \"name\": \"Update Again\", \"age\": 25, \"address\": { \"street\": \"789 Main St\", \"city\": \"New York\", \"state\": \"NY\", \"postalCode\": \"10001\" }, \"hobbies\": [\"reading\", \"running\"] }",
"isDeleted": false,
"candidateId": 123,
"clientContactId": 10,
"clientCorporationId": 1105,
"jobOrderId": 123,
"jobSubmissionId": 123,
"placementId": 123,
"leadId": 123,
"opportunityId": 123,
"corporateUserId": 123,
"noteId": 123,
"appointmentId": 123,
"payableChargeId": 123,
"billableChargeId": 134,
"entityId": 1234
}
]
}
}
By following these steps, Data Hub can effectively be used, assuming the schema is already set up for the user’s corporation.
Data Hub Error Scenarios
Below are some examples of error scenarios that can occur when making the POST /data-hub/data request.
206 Status Code
The request has only partially succeeded. One or more of the records in the request failed to be stored in Data Hub.
Example 206 Response:
{
"statusCode": 206,
"messages": [
"Some items were successfully processed, but there were also some errors persisting data. One or more items were not processed due to an error, see ‘failedItems’ attribute for more details",
"Total Item Failures: 2",
"Failing Entity Types: [entityTypeName]"
],
"data": [
{
"entityType": "entityTypeName",
"sourceSystem": "sourceSystemName",
"totalBatchFailures": 2,
"totalSuccessfulItems": 1,
"successfulItems": [
{
"sourceId": "3",
"dataId": 5678
}
],
"failedItems": [
{
"errorType": "SCHEMA_VALIDATION",
"errorMessage": "[$: required property 'name' not found]",
"failingSourceIds": [
"1"
]
},
{
"errorType": "MISSING_REQUIRED_FIELD",
"errorMessage": "Missing payload",
"failingSourceIds": [
"2"
]
}
]
}
]
}
400 Status Code
All records failed to be processed.
Example 400 Response:
{
"statusCode": 400,
"messages": [
"There were errors persisting data. One or more batches were not processed due to an error, see ‘failedItems’ attribute for more details",
"Total Item Failures: 3",
"Failing Entity Types: [entityTypeName]"
],
"data": [
{
"entityType": "entityTypeName",
"sourceSystem": "sourceSystemName",
"totalBatchFailures": 3,
"totalSuccessfulItems": 0,
"successfulItems": [],
"failedItems": [
{
"errorType": "SCHEMA_VALIDATION",
"errorMessage": "[$: required property 'name' not found]",
"failingSourceIds": [
"1"
]
},
{
"errorType": "MISSING_REQUIRED_FIELD",
"errorMessage": "Missing payload",
"failingSourceIds": [
"2"
]
},
{
"errorType": "MISSING_REQUIRED_FIELD",
"errorMessage": "Missing dateAddedInSourceSystem",
"failingSourceIds": [
"3"
]
}
]
}
]
}
413 Status Code
The request has more than 100 items and Data Hub will only process 100 records at a time.
Example 413 Response:
{
"statusCode": 413,
"messages": [
"Please send 100 or less records per API call"
],
"data": null
}