One company in.
A wider account in view.
Save your monitoring settings once. Submit a company, review related accounts and receive notifications when the monitored records change.
https://entityreach.com/api/v1Async jobs · JSON · Signed webhooksSet up once, then add companies
The workspace owner creates a key in API keys with Read company data + manage workflows. This grants companies:read workflows:write. Existing read-only keys keep their permissions. Activate API access and configure your allowance first. Ongoing workflows require Business, Scale or Enterprise with corporate-group and monitoring allowances.
curl --fail-with-body https://entityreach.com/api/v1/workflows \
-H "Authorization: Bearer $ENTITYREACH_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"name": "Industrial account expansion",
"monitoring": {
"scope": "group",
"fields": ["company.group_structure", "company.status"],
"cadence": "daily",
"max_companies": 100,
"auto_enrol": true
},
"webhook_url": "https://your-app.example.com/entityreach-events"
}'The response contains data.id. If you supplied a webhook, it also contains data.webhook_secret; save this on your server when creating the workflow. Other reads omit it. Omit webhook_url to use API polling alone. Manage it in Workflows, or update it through the API. PATCH the full config with expected_updated_at from the latest GET; a concurrent edit or running step returns 409. Changing a webhook destination cancels undelivered notifications and returns a new signing secret. Replay cancelled events deliberately if needed.
# Use the workflow ID returned by the creation request.
curl --fail-with-body "https://entityreach.com/api/v1/workflows/$WORKFLOW_ID/companies" \
-H "Authorization: Bearer $ENTITYREACH_API_KEY" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: your-stable-account-reference-001' \
-d '{"company":{"type":"name","value":"Mold Retail Group","country":"MD"}}'
# Use the enrolment ID from that 202 response.
curl --fail-with-body "https://entityreach.com/api/v1/workflows/$WORKFLOW_ID/companies/$ENROLMENT_ID" \
-H "Authorization: Bearer $ENTITYREACH_API_KEY"The POST returns a durable enrolment ID immediately. Matching, group retrieval and watch enrolment run in the background. Poll at 30 seconds or longer while processing, or wait for a webhook. Completion time depends on queue size, group size and data-service availability.
Accept the identifier your customer has
| Input type | Company object |
|---|---|
| Name | {"type":"name","value":"Company name","country":"MD"} |
| Registration | {"type":"registration","value":"REGISTRATION_NUMBER","country":"MD"} |
| VAT | {"type":"vat","value":"VAT_NUMBER","country":"MD"} |
| Website | {"type":"website","value":"company.example.com"} |
| Confirmed ID | {"type":"company_id","value":"123456"} |
Country is mandatory for registration and VAT inputs, and recommended for names. Name and website matches require customer confirmation even when only one candidate is returned. An exact, unique registration or VAT match in the requested country can proceed automatically. Numeric company IDs are record identifiers, distinct from registration numbers.
When status is needs_confirmation, present the returned candidates with legal name, country and registration. At most 20 candidates are returned; refine a broad search if needed. Confirm the selected ID:
curl --fail-with-body "https://entityreach.com/api/v1/workflows/$WORKFLOW_ID/companies/$ENROLMENT_ID/confirm" \
-H "Authorization: Bearer $ENTITYREACH_API_KEY" \
-H 'Content-Type: application/json' \
-d '{"company_id":"CONFIRMED_CANDIDATE_ID"}'not_found means the input did not return a match; try another identifier. It does not establish that the company or its financial information does not exist. Duplicate resolved companies in the same workflow return duplicate with result.existing_enrolment_id.
Start with group structure and status
The defaults are company.group_structure and company.status. Select scope: "group" to enrol the available group, or scope: "company" for the starting company. Explicit fields are always sent; an empty field list is rejected.
With auto_enrol: true, newly returned group members enter monitoring within the workflow and workspace limits. The default is 100 companies per enrolment, configurable from 1 to 1,000. The starting company is prioritised. Coverage in each result lists confirmed, pending and failed watches; monitoring.coverage_limited reports gaps.
Signed incoming events trigger an earlier check when the push connection is active. Watch history and the group are also reconciled daily or weekly. The usage endpoint reports whether push is connected, awaiting setup or requires forwarding from an existing shared callback. This is not a guaranteed real-time alert service. A returned group change triggers another group review. A failing company is retried independently without stopping the rest of the group. Newly observed relationships are labelled as observations; incorporation, acquisition and disposal are not inferred. Members that disappear from a returned tree remain watched until you stop their enrolment, because missing coverage is not proof of a disposal.
Full-group monitoring watches across countries within the configured company limit.
All 35 advanced fields
[
"company.name",
"company.status",
"company.registration_number",
"company.vat",
"company.address_street",
"company.email",
"company.phone",
"company.fax",
"company.website",
"company.bank",
"company.employees_number",
"company.trading_activity_export",
"company.trading_activity_import",
"company.group_structure",
"company.financial",
"office.identity",
"office.email",
"office.fax",
"office.phone",
"office.website",
"address.street",
"shareholder.holding",
"shareholder.holding_historical",
"shareholder.exit_precise",
"shareholder.exit_approximate",
"shareholder.share_type",
"shareholder.share_price",
"employee.appointment",
"employee.phone",
"employee.email",
"employee.resignation_date",
"officer.appointment",
"officer.phone",
"officer.email",
"officer.resignation_date"
]company.financial signals an annual report filing. office.identity indicates an observed office, which is not necessarily a new subsidiary. Historical shareholder updates can be backfilled. Select these deliberately to keep notifications relevant.
Company groups and clear monitoring coverage
The result includes the available corporate group, related-company identities, relationship paths, observed changes and monitoring coverage. The result.related_companies array contains company_id, company and relationship. There are no offer descriptions, commercial-fit scores or qualification questions.
Newly observed group members enter monitoring when automatic enrolment is enabled and capacity is available. Incomplete group refreshes preserve the previous baseline. The full available group remains visible even when the monitoring limit is lower.
- 60 API requests per UTC minute, shared with company data endpoints. Successful workflow calls consume one monthly API request; failed operations refund the monthly unit.
- Company matching, distinct group lookups and monitoring use their workspace allowances. These workflows do not run AI scoring or consume AI searches.
- Monitoring counts distinct companies across saved website groups and API workflows. Up to 1,000 company enrolments and 25 active or paused workflow definitions are supported per workspace.
- The company POST requires an 8–128 character
Idempotency-Key. The same input and key returns the same enrolment. A different input with that key returns 409. - Pause stops subsequent processing and delivery. A request already in flight may finish. Resume retains the baseline. Stop is terminal. Shared watches are not globally removed.
GET /workflows/{workflow_id}/usage reports monitoring coverage and push/scheduler health. Older scoring-related configuration fields are accepted for compatibility and discarded. Existing enrolments continue with group discovery and monitoring.
Receive a signed notification
Configure a public HTTPS receiver on port 443. Redirects and private destinations are rejected. Notifications contain identifiers only; retrieve event details and results through authenticated API calls.
{
"id": "evt_…",
"type": "group.change_observed",
"workflow_id": "your-workflow-id",
"enrolment_id": "your-enrolment-id",
"created_at": "2026-09-27T12:00:00.000Z"
}The header X-EntityReach-Signature has the form t=TIMESTAMP,v1=HEX_SIGNATURE. Compute HMAC-SHA256 using your webhook secret over the timestamp, a literal dot and the exact raw request body. Verify with a constant-time comparison, reject timestamps more than five minutes from your clock and deduplicate by event ID. Parse JSON only after verification.
import { verifyWebhook } from './workflow-client.mjs';
// rawBody must contain the untouched request bytes.
if (!verifyWebhook(rawBody, signatureHeader, process.env.ENTITYREACH_WEBHOOK_SECRET)) {
// Return HTTP 401.
}
// Durably enqueue the verified event, deduplicated by its id.
// Return HTTP 200 or 204 promptly; process the event asynchronously.Delivery is at least once. Non-2xx responses and timeouts retry up to eight attempts, with exponential delays starting at one minute. Failed deliveries remain visible in the event API and can be replayed. Events may arrive out of order; use the event cursor for a durable history and the latest enrolment result for current state.
Use the dashboard or POST /webhook/test to send a signed test. Check its delivery status in the event history and confirm receipt in your application. Tests are limited to one per minute per workflow. POST /webhook/rotate-secret to replace the signing secret; save the returned value and update your receiver. Rotation is rejected while a delivery is in flight.
Event types: webhook.test, monitoring.company_retry, company.confirmation_required, company.not_found, workflow.ready, workflow.updated, group.change_observed, company.field_changed, monitoring.coverage_limited and workflow.attention_required.
Endpoint reference
| Method | Path | Purpose |
|---|---|---|
GET | /workflows/fields | Supported fields and defaults. |
POST | /workflows | Create a reusable definition; returns 201. Save webhook_secret once. |
GET | /workflows | List 50 workflows; continue with ?after=next_cursor. |
GET | /workflows/{workflow_id} | Read configuration and status. |
PATCH | /workflows/{workflow_id} | Set status, or replace config with expected_updated_at. Stopped is terminal. |
GET | /workflows/{workflow_id}/usage | Monitoring coverage and push health. |
POST | /workflows/{workflow_id}/webhook/test | Queue a real signed notification; send {}. Returns 202. |
POST | /workflows/{workflow_id}/webhook/rotate-secret | Rotate the secret; send {} and save the returned replacement once. |
POST | /workflows/{workflow_id}/companies | Queue a company with an Idempotency-Key; returns 202. |
GET | /workflows/{workflow_id}/companies | List 50 enrolments; continue with ?after=next_cursor. |
GET | /workflows/{workflow_id}/companies/{enrolment_id} | Progress, candidates, complete group, relationships and watch coverage. |
POST | /workflows/{workflow_id}/companies/{enrolment_id}/confirm | Confirm a returned candidate with {"company_id":"…"}; returns 202. |
PATCH | /workflows/{workflow_id}/companies/{enrolment_id} | Pause, stop or resume a paused/failed enrolment. |
GET | /workflows/{workflow_id}/events | Read up to 100 events; persist next_cursor and pass ?after=cursor. |
POST | /workflows/{workflow_id}/events/{event_id}/replay | Requeue a webhook delivery. Send {}. |
Successful responses use {"data":…, "usage":{"used":…, "limit":…, "period":"YYYY-MM"}}. Enrolment progress uses queued, processing, needs_confirmation, ready, not_found, duplicate, failed, paused and stopped. A ready enrolment can still have limited watch coverage; inspect its monitoring records.
Errors use {"error":"…"}: 400 invalid input, 401 invalid key, 403 permission or entitlement required, 404 record not found in your workspace, 409 state/idempotency conflict, 413 oversized request and 429 allowance or rate limit. Bodies are limited to 20 KB. Background errors appear in last_error and attention events. Automatic step retries are bounded; resume a failed enrolment after resolving the cause.
Download the OpenAPI specification · Download the Node.js client and webhook verifier
Use the same workflows through MCP
The workflow MCP endpoint is https://entityreach.com/api/mcp. Use a client that supports Streamable HTTP with a configurable Bearer header and the same workflow-scoped workspace key. MCP access must also be activated for the workspace. OAuth discovery is not provided by this endpoint.
{
"url": "https://entityreach.com/api/mcp",
"transport": "streamable-http",
"headers": {
"Authorization": "Bearer YOUR_WORKFLOW_KEY",
"MCP-Protocol-Version": "2025-06-18"
}
}The endpoint supports JSON responses, stateless sessions and protocol versions 2025-06-18 and 2025-03-26. Tools: create_expansion_workflow, list_expansion_workflows, get_monitoring_fields, add_workflow_company, get_workflow_company, confirm_workflow_company, set_workflow_status get_workflow_events, get_expansion_workflow, update_expansion_workflow, get_workflow_usage and test_workflow_webhook.
Ask the agent to set up monitoring scope and fields, then submit a company. It must show ambiguous matches for your selection. The API, worker and MCP tools use the same permissions, stored workflows and allowances.