BASE URLhttps://entityreach.com/api/v1HTTPS · JSON · Bearer authentication
Create your API key
API access is included with every plan. Request activation from Dashboard → API keys to confirm your monthly request allowance. Your workspace must have API access enabled before keys can be created. The workspace owner creates keys in Dashboard → API keys. Read-only keys have the companies:read scope and are shown only once. Choose the additional workflow permission to use the Workflow API.
Store the secret on your server as ENTITYREACH_API_KEY. Send it in Authorization: Bearer YOUR_ENTITYREACH_KEY on every request. Keys begin with er_live_; a provider API key cannot be substituted.
You can hold up to five active keys. Choose an expiry of 30, 90 or 365 days; the default is 90 days. To rotate, create a new key, update your server and verify a request, then revoke the old key. Revocation takes effect immediately. Keep keys out of browser code, URLs and repositories.
Make your first request
Set the server environment variable securely, then search for a company. The cURL examples use your shell’s environment variable; replace the query and country for your account.
# Set COMPANY_ID to the confirmed ID from your search result.
curl --fail-with-body "https://entityreach.com/api/v1/companies/$COMPANY_ID" \
--header "Authorization: Bearer $ENTITYREACH_API_KEY"
curl --fail-with-body "https://entityreach.com/api/v1/companies/$COMPANY_ID/group" \
--header "Authorization: Bearer $ENTITYREACH_API_KEY"
Endpoints and response structure
These are the company data and contact discovery endpoints. The Workflow API adds reusable expansion analysis, company matching and monitoring. All use GET, accept the inputs below and return application/json. Company search and group responses have no pagination or batch parameter on these endpoints. Unknown routes return 404; unsupported HTTP methods return 405.
Every successful response contains data and usage. Company fields can be missing or null; keep IDs as strings when storing or comparing them. The examples below are fictional and abbreviated to show the response structure, not current company reports.
Find company contacts
GET /companies/{id}/contacts?page=1&role=Sales%20Director
Uses the verified company ID. Optional page is 1–10; role is a job title up to 100 characters. Returns up to five contacts plus page, pages and email/mobile usage. Search returns previews without spending email or mobile credits. Previously revealed values are included when allowed by the active plan; unrevealed fields remain null. Use Find contacts on the website to reveal a selected email or mobile. Repeated reveals of the same contact in a calendar month do not consume another credit. Only confirmed mobile numbers are returned in phone. API activation and the companies:read scope are required.
Required query parameters: q is a legal name, website or registration number of 2–200 characters after trimming; country is an uppercase two-letter country code, such as GB. Optional kind: auto, name, website, registration or vat. The result is an array of ranked candidates with resolution status (matched, needs_confirmation or not_found) and partial-result information. An empty array is a successful search with no matches. Confirm the legal name, country and registration number before choosing an ID.
Use a company ID returned by search: a numeric string of 1–20 digits. This is not the company registration number. Provenance is requested automatically. Available fields are grouped under basic, address, contact, market and lei; each section may include its own source. Add include=full to receive financials, directors, shareholders and explicit retrieval status for each section. The MCP profile tool uses this full response. Use section=financials, directors or ownership to retry only that dataset. For lists, request page=nextPage from the retrieval metadata until nextPage is null.
Use the same confirmed company ID. With provenance, data.data contains the tree roots and data.source contains the relationship source. Some upstream results are root arrays directly. Follow children recursively, and use selected to locate the requested entity. Preserve the parent-child relationships when an entity occurs more than once.
For a group response, obtain the roots with Array.isArray(response.data) ? response.data : response.data.data. An empty hierarchy or missing relationship does not establish that a company has no subsidiaries. Read source categories and retain provenance with your results.
Usage and limits
60 valid requests per UTC minute per workspace, shared across all API keys. Failed provider calls still count toward this minute limit. A minute-limit response includes Retry-After: 60.
One monthly unit per successful request, including an empty search result. Failed requests refund the reserved monthly unit. The monthly allowance resets on the first day at 00:00 UTC.
usage.used is the workspace’s reserved monthly count at the time this request was admitted; concurrent calls can finish out of order. usage.limit is the agreed allowance; usage.period is the UTC calendar month in YYYY-MM format.
X-RateLimit-Remaining reports the remaining monthly allowance on successful responses. It is not a per-minute counter.
API responses use Cache-Control: no-store. Website search, provider API and MCP allowances are separate.
Full profile retrieval has a 20-second overall budget, with independent recovery of missing sections. Other provider requests have a 45-second timeout. Use a longer client timeout, for example 60 seconds. A retry after a lost response can consume another unit; no idempotency key or automatic retry is provided.
Errors and recovery
JSON · error example
{
"error": "API key is invalid, expired or revoked."
}
Status
Meaning
What to do
400
Invalid query or company ID
Correct the parameters before retrying.
401
Missing, invalid, expired or revoked key
Create or rotate your EntityReach key.
403
Workspace API access or scope unavailable
Ask your workspace owner to confirm API access and the key’s scope.
404
Unknown endpoint or unavailable company
Check the path and the ID returned by search.
429
Minute limit, monthly allowance or provider capacity reached
Read the error message. Wait for Retry-After when supplied; monthly exhaustion requires a reset or allowance change.
502
Upstream failure or invalid response
Retry with bounded exponential backoff and jitter.
503
Workspace service or provider dataset unavailable
Retry briefly; contact support if access remains unavailable.
504
Provider timeout
Retry with bounded backoff. The upstream timeout is 45 seconds.
Read the HTTP status and error field. Do not repeatedly retry invalid inputs, credentials, disabled access or monthly exhaustion. Framework-level responses such as 405 may not use the JSON error envelope.
Run the examples in your application
The dependency-free Node.js helper covers company search, profile and group reads and requires Node 20 or newer. Call the documented contacts endpoint separately; it returns previews without spending monthly contact-reveal credits. It validates the response, exposes HTTP status and retryAfter on errors, and makes no automatic retries.
Shell · Node.js quick start
curl --fail --output entityreach-client.mjs https://entityreach.com/docs/entityreach-client.mjs
node entityreach-client.mjs search "Tesco" GB
# After confirming the returned company identity:
node entityreach-client.mjs profile "$COMPANY_ID"
node entityreach-client.mjs group "$COMPANY_ID"
JavaScript · import the client
import {searchCompanies, getCompany, getCompanyGroup} from './entityreach-client.mjs';
const {data: candidates, usage} = await searchCompanies('Tesco', 'GB');
// Review candidates before choosing an ID; do not automatically select the first match.
console.log(candidates, usage);
Python 3 · standard library
import json, os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError
url = 'https://entityreach.com/api/v1/companies?' + urlencode({'q': 'Tesco', 'country': 'GB'})
request = Request(url, headers={'Authorization': 'Bearer ' + os.environ['ENTITYREACH_API_KEY']})
try:
with urlopen(request, timeout=60) as response:
result = json.load(response)
print(result['data'], result['usage'])
except HTTPError as error:
print(error.code, error.read().decode(), error.headers.get('Retry-After'))
raise
Advanced provider integrations use their own base URLs, credentials and entitlements. EntityReach keys authorize the company endpoints documented here and, with workflow permission, the Workflow API and MCP tools.