Leadspace is offering an enrichment service through its API. This article presents the technical specifications and requirements in order to send enrichment request to Leadspace using Bulk API requests.
Setup
As part of the setup process, Leadspace provides an API key (textual) and a program ID.
The key authenticates the program, and if needed, Leadspace can provide several unique API keys, one for each program.
Please store the API key and the program ID in a secured manner.
Transport
All API calls use HTTPS protocol.
Encoding
Most of the requests and responses are textual. The encoding is UTF-8 to represent Unicode based text.
Data format
API calls and requests: JSON (as defined in RFC 7159).
Date and timestamps: ISO 8601 format, in UTC - Example: 2015-05-03T15:38:45Z.
Endpoint
The Base URL is https://apigw.leadspace.com.
All the additional endpoints will be variations on the above URL.
Authentication
The requests to Leadspace's API should include the standard HTTP Authorization header and use the HTTP Basic Authentication.
The Authorization header should be set in the following format:
'Authorization':'Bearer API_KEY’
The username (program ID) and the secret (token\API_KEY) will be provided by an email.
Leadspace offers two authentication methods:
- Perpetual token
- Oauth 2.0
Perpetual Token Rotation
- Due to security reasons, it is highly recommended to replace the API perpetual token every six months, starting from the completion of the integration period (or, “token lifecycle”).
- Leadspace will generate a new token and provide it by an email.
- Leadspace will send a notification before the end of the token life cycle that the rotation of tokens is expected.
- Once successfully migrated to the new API token, Leadspace will deprecate the old token.
API - Bulk Enrichment
Request
URL - https://apigw.leadspace.com/enrichment/enrich/bulk
HTTP Method
POST
Request body
In the request body, please make sure to supply data with the following structure:
Property name |
Value |
Description |
Notes |
data |
list |
The list of objects (defined below). |
max. 500 items |
data[] |
nested object |
||
data[].person |
nested object |
||
data[].person.first_name |
string |
First name |
|
data[].person.last_name |
string |
Last name |
|
data[].person.email |
string |
Email address |
|
data[].person.title |
string |
Job title |
|
data[].person.phone |
string |
If provided, Phone Validation fields will be provided in the Response. |
|
data[].linkedinUrl |
string |
If provided, can be used for person enrichment matching. |
|
person.address.country |
string |
If provided, used for the Phone Validation fields will be provided in the Response. | |
data[].company |
nested object |
||
data[].company.name |
string |
The name of the company |
|
data[].company.lsid |
string |
The LSID of the company |
OPTIONAL - if sent will use LSID to match first. |
data[].company.website |
string |
The URL of the company's website |
|
data[].company.phone |
string |
If provided, Phone Validation fields will be provided in the Response. |
|
data[].company.address |
nested object |
||
data[].company.address.country |
string |
||
data[].company.address.state |
string |
||
data[].company.address.city |
string |
||
company.address.street |
string |
||
company.address.postalcode |
string |
||
company.duns |
string |
||
data[].custom_fields |
list |
||
data[].custom_fields[] |
nested object |
||
data[].custom_fields[].name |
string |
||
data[].custom_fields[].value |
string |
|
|
data[].external_id |
string |
An external identifier for the request. If provided, the same value will be provided in the "external_id" field in the body of the result. This input is not used for the processing and enrichment. |
|
external_bulk_id |
string |
The external identifier for the entire request. If provided, the same value will be provided in the "external_bulk_id" field in the body of the result. This input is not used for the processing and enrichment. |
|
callbackUrl |
string |
The URL Leadspace will call back when the bulk processing will be completed |
Optional |
Sample Bulk REQUEST (2 records):
Possible Responses
Status code |
Scenario |
Description |
Retrievable |
202 |
The Bulk job has successfully accepted |
A link with polling endpoint URI |
N/A |
400 |
The request failed due to insufficient basic input, or JSON format is invalid |
If the JSON format is valid, please make sure you provide the following fields for the enrichment: For Account enrichment: Company Name For Person (Lead/Contact) enrichment: First Name Last Name Company Name/Email Address/Website |
No |
401 |
Unauthorized request (wrong credentials or credentials have expired) |
Credentials are required to access this resource. |
No |
427 |
Insufficient credits or program ID is invalid |
Please reach out to the Customer Success Manager and the Support team (at support@leadspace.com) for credits allocation |
No |
5XX |
Server error |
The error will contain the following details: Error code, timestamp, tracking id, details Please reach out to the Support team for assistance. |
Yes |
The response for the status code 202 ("Accepted")
The response body contains the polling endpoint URL in the following format:
Property name |
Value |
Description |
id |
/<apiversion>/enrichment/results/<Leadspace bulk ID> |
The polling endpoint URI to extract the bulk results |
Callback URL JSON response format
In case the callback URL was used and implemented in the request, the callback URL response format will be in the following format:
Property name | Value | Description |
bulkId | string | The bulk ID |
callbackMethod | nested object | |
callbackMethod.callbackUrl | string | The URL the API is calling back |
callbackMethod.pollingUrl | string | URL for polling the bulk once it’s completed processing |
bulkStatus | string | Retrieves the detailed status of the bulk. |
Property values:
|
||
successRecords | integer | The number of records that were processed successfully |
personEnriched | integer | The number of records where the person was enriched successfully |
companyEnriched | integer | The number of records where the company was enriched successfully |
General JSON response format
The body of the response may or may not exist in a JSON format.
In case it exists in a JSON format, it is structured using the following schema:
Property name |
value |
description |
error |
string |
Error description |
tracking_id |
string |
Leadspace tracking identifier, for further inspection of this request |
request_timestamp |
timestamp |
The timestamp assigned to the given request once reached Leadspace's servers. |
details |
string |
The details of an error |
Rate Limiting Policy
Default rate limit for our API service is 30 TP/s or transactions per second, with one transaction being a single API up to 500 records. This means that theoretically, you can send 15,000 records per second using the Bulk API.
However, the Leadspace API V3 service doesn't enforce any limitations to the number of concurrent connections to the API. The rate limit of the Bulk API is the rate in which Leadspace will start processing the leads in the Bulk request. Leadspace can keep up to 100000 leads in the backlog, while other requests are being processed.
API - Bulk Enrichment - Polling
Request
URL
/v3/enrichment/results/<Leadspace bulk ID>
HTTP Method
GET
The Authentication Header should include the API key.
Possible Responses
Status code |
Scenario |
Body |
200 |
The request is done |
See detailed schema below |
204 |
The request is still processing |
|
401 |
Unauthorized request |
- |
404 |
The results are not found |
- |
500-504 |
Server error |
Error code, timestamp, tracking id |
The Response for Status code 200
The response of the status code 200, as listed above, has the following schema:
Property name |
value |
description |
results |
list |
|
results[] |
nested object |
|
results[].status |
string |
Can be one of the following:
|
results[].errors |
list |
Leadspace errors for the current record (see record-level error section below). |
results[].errors[] |
nested object |
|
results[].errors[].code |
integer |
Leadspace error code |
results[].errors[].description |
string |
Additional information about the error. Might be null. |
results[].external_id |
string |
The corresponding external_id from the request's object |
results[].data |
nested object |
See schema below |
external_bulk_id |
string |
If provided |
Schema definitions for a single element in the results list
Property name |
Value |
Description |
Notes |
enrichment_status |
string |
The status of enrichment process, can be one of the following values:
|
|
person |
nested object |
||
person.address |
nested object |
||
person.address.country |
string |
||
person.address.state |
string |
||
person.address.city |
string |
||
person.address.region |
string |
|
|
person.verification_status |
string |
The verification status of the input person, if given. Can be one of the following values:
|
|
person.verification_source |
string |
If verification_status is "Verified", this field holds the source type of the verification. Can be one of the following values:
|
|
person.original_email |
string |
||
person.original_email_verification_status |
string |
Can be one of the following values:
|
|
person.first_name |
string |
First name |
|
person.last_name |
string |
Last name |
|
person.title |
string |
Job title |
|
person.department |
string |
Job department |
|
person.level |
string |
Job level, can be one of the following values:
|
|
person.data_validation |
nested object |
|
|
person.data_validation.phone |
nested object |
|
|
person.data_validation.phone.status |
string |
Can be one of the following values:
|
|
person.data_validation.phone.normalize_value |
string |
|
|
company.data_validation.address |
nested object |
|
|
company.data_validation.address.status |
string |
Possible values: - Unknown - Invalid |
|
company.data_validation.address.normalize_value |
string |
The normalized company address |
|
person.linkedin_profile |
string |
The lead's LinkedIn profile URL |
|
person.phone |
string |
Phone |
|
person.email |
string |
||
person.analytics |
nested object |
||
person.analytics.job_functions |
list |
||
person.analytics.job_functions[] |
string |
||
person.analytics.technologies |
list |
||
person.analytics.technologies[] |
string |
||
person.analytics.scores |
list |
||
person.analytics.scores[] |
nested object |
||
person.analytics.scores[].profile_name |
string |
The profile which is used for this analytics item |
|
person.analytics.scores[].score |
nested object |
||
person.analytics.scores[].score.value |
decimal |
Nullable |
|
person.analytics.max_positive_score_profiles |
string |
||
company |
nested object |
||
company.name |
string |
The name of the company |
|
company.original_name |
string |
||
company.ls_id |
string |
Leadspace's company identifier |
|
company.description |
string |
Company description |
|
company.address |
nested object |
||
company.address.country |
string |
||
company.address.state |
string |
||
company.address.city |
string |
||
company.address.street |
string |
The value might also be PO box |
|
company.address.zipcode |
string |
||
company.address.region |
string |
||
company.phone |
string |
||
company.industry |
string |
||
company.sub_industry |
string |
||
company.linkedin_profile |
string |
||
company.facebook_url |
string |
||
company.twitter_url |
string |
||
company.ticker |
string |
||
company.website |
string |
||
company.sic |
string |
||
company.naics |
string |
||
company.size |
nested object |
||
company.size.range |
string |
Free text describing company size in a human readable range. Can be one of the following values:
|
|
company.size.exact |
Unsigned integer |
The exact number of company size. |
|
company.revenue |
nested object |
||
company.revenue.range |
string |
Free text describing company's revenue in a human readable range. Can be one of the following values:
|
|
company.revenue.exact |
unsigned integer |
The exact amount of company's revenue |
No currency symbol |
company.ownership |
string |
||
company.data_validation |
nested object |
||
company.data_validation.phone |
nested object |
||
company.data_validation.phone.status |
string |
Can be one of the following values:
|
|
company.data_validation.phone.normalize_value |
string |
||
company.signals.fortune_500_rank |
number |
1-500 | |
company.signals.g2k_rank |
number |
1-2000 | |
company.matching_confidence.score |
string |
Range will be between 5-95 in increments of 10. |
This feature would need to be enabled. Please reach out to your CSM for more information. NOTE: This score will be sunsetting soon. |
company.matching_confidence.level |
string |
Can be one of the following values:
|
|
company.analytics |
nested object |
||
company.analytics.installed_base_technologies |
array |
||
company.analytics.installed_base_technologies[] |
string |
||
company.analytics.web_site_technologies |
array |
||
company.analytics.web_site_technologies[] |
string |
||
company.analytics.customTechnologiesCategories |
array |
||
company.analytics.customTechnologiesCategories[] |
string |
||
company.analytics.company_technologies_categories |
array |
||
company.analytics.company_technologies_categories[] |
string |
||
company.domain_intent |
string |
Company's top surging intent topics | This feature would need to be enabled. Please reach out to your CSM for more information. |
company.intent_modeling.project_name |
string |
Project name would be the name of the intent model. | |
company.intent_modeling.project_score |
string |
Project score will be one of the following options: High Medium Low No Intent Not Available |
|
company.intent_modeling.new_high_intent_flag |
string |
No Yes |
|
company.intent_modeling.surging_topics[] |
array |
There will be based on per topic basis. | |
company.intent_modeling.surging_topics |
string |
||
company.alternateCompanyDomains |
string |
Company additional/alternate domains |
|
company.family_tree |
nested object |
The company's hierarchies in addition to the matched company above |
Nullable |
company.family_tree.companies |
list |
Not nullable, may be empty |
|
company.family_tree.companies[] |
nested object |
||
company.family_tree.companies[].type |
string |
The company type. Can be one of the following values:
|
DU = Domestic Ultimate GU = Global Ultimate |
company.family_tree.companies[].name |
string |
The name of the company |
|
company.family_tree.companies[].ls_id |
string |
Leadsapce's company identifier |
|
company.family_tree.companies[].address |
nested object |
||
company.family_tree.companies[].address.country |
string |
||
company.family_tree.companies[].address.state |
string |
||
company.family_tree.companies[].address.city |
string |
||
company.family_tree.companies[].address.street |
string |
The value might also be PO box |
|
company.family_tree.companies[].address.zipcode |
string |
||
company.family_tree.companies[].address.region |
string |
||
company.family_tree.companies[].phone |
string |
||
company.family_tree.companies[].website |
string |
||
company.family_tree.companies[].sic |
string |
||
company.family_tree.companies[].naics |
string |
||
company.family_tree.companies[].size |
nested object |
||
company.family_tree.companies[].size.range |
string |
Free text describing company size in a human readable range. Can be one of the following values:
|
|
company.family_tree.companies[].size.exact |
Unsigned integer |
The exact number of company size. |
Numeric field |
company.family_tree.companies[].revenue |
nested object |
||
company.family_tree.companies[].revenue.range |
string |
Free text describing company's revenue in a human readable range. Can be one of the following values:
|
|
company.family_tree.companies[].revenue.exact |
unsigned integer |
The exact amount of company's revenue |
No currency symbol |
total_scores |
list |
||
total_scores[] |
nested object |
||
total_scores[].profile_name |
string |
||
total_scores[].score |
nested object |
||
total_scores[].score.value |
decimal |
Nullable |
|
total_scores[].score.predictiveSignalsSummary |
string |
|
|
total_scores[].score.topPositivePredictiveSignals |
string |
|
|
total_scores[].score.topNegativePredictiveSignals |
string |
|
|
max_positive_total_score_profiles |
list |
|
|
max_positive_total_score_profiles |
string |
||
company.location_type |
string |
Can hold one of the following 4 values: 2.Branch. Secondary location to a headquarters location 3.Single Location. No other entities report to the business 4.Blank |
|
company.eight_digit_sic |
string |
If customer requires a more detailed SIC codes |
|
company.ein |
string |
|
|
company.specialties |
nested object |
||
company.fiscal_year_end |
date |
Format is mm/dd | |
ingested_data |
nested object |
||
ingested_data.Data Set Name |
nested object |
||
ingested_data.Data Set Name.ingestion.field_name |
string |
Taken from the customer CSV file header. | |
ingested_data.Data Set Name.ingestion.field_name.value |
string |
Value is according to the data in the column. |
Record-Level Errors
The record-level error will appear when the bulk request was valid, but the process failed for an individual record. Record-level errors may contain the following values:
Error code |
Error description |
Comment |
1100 |
Internal Error |
Leadspace internal error. |
1200 |
Invalid Input |
Record did not pass advanced input validations. For example, records for which the First and Last Names were not provided will be tagged as "Invalid Input" |
For your convenience, please find below links to other articles regarding the Leadspace API v3, that will help you through the integration process:
Leadspace API - Format Changes v2 vs v3
API V3 OAuth 2.0 Diagram