Confirm access before sending a request
The public endpoint still requires an active paid workspace and a valid scoped API key. Marketing-page access never grants access to customer records. Treat a redirect, HTML response or authentication error as a failed API request rather than JSON data.
Use the authorised online platform to choose a workspace, inspect sample records and create a key under API keys. Owners and admins can choose these scopes:
| Scope | Allows |
|---|---|
read | Read saved companies, events and cases; call the read-only MCP tools. |
search | Run live company searches and retrievals through MCP. |
monitoring:write | Start or pause monitoring through MCP after confirmation. |
events:write | Submit company events to the ingestion endpoint. |
jobs:run | Run eligible source checks and queued delivery jobs. |
Keys belong to one workspace. Their expiry can be set to 30, 90 or 365 days, and they can be revoked. The secret is shown at creation; retain it in your server's secret store. The API examples assume it is supplied as COMPANYDELTA_API_KEY in your local environment. Never include a key in browser code, a URL or a public repository.
Make your first company data API request
Use a key with read scope from an active paid workspace. Begin by listing companies already saved in that workspace:
curl 'https://companydelta.com/api/v1/companies?limit=25' \
-H "Authorization: Bearer $COMPANYDELTA_API_KEY"A successful response has a data array and next_cursor. The excerpt below contains invented sample values and omits other company fields:
{
"data": [{
"id": "sample-company-01",
"name": "Northstar Manufacturing Ltd",
"registration": "DEMO-001",
"country": "GB",
"status": "sample",
"watches": ["ownership", "directors"],
"record": { "holding": "65%" },
"sample": 1
}],
"next_cursor": null
}Pagination and reconciliation
List endpoints use limit (default 50, maximum 100) and cursor. Pass the returned cursor as an encoded query value to request the next page. Stop when next_cursor is null.
Records are traversed by ID, not by change time. An ID cursor is not a reliable “everything since yesterday” filter: newly inserted identifiers can fall earlier in that ordering. Reconcile complete lists when necessary and deduplicate by event ID. For notifications of newly recorded events, evaluate webhooks.
Current API endpoints
| Method and path | Scope | Response or action |
|---|---|---|
GET /api/v1/companies | read | Paginated companies. Stored watches and record are returned as parsed JSON. |
GET /api/v1/events | read | Paginated saved events, with source details and available dates. |
GET /api/v1/cases | read | Paginated review cases. Join event to the event identifier. |
POST /api/v1/events | events:write | Ingest an event for a company already in this workspace. |
POST /api/v1/jobs/run | jobs:run | Process up to three eligible company checks and five eligible webhook deliveries per call. |
The jobs endpoint can trigger external data requests and outbound delivery. Run it only after configuring the sources, destinations and intended schedule. It returns separate checks and deliveries results; a successful HTTP response does not mean every individual operation succeeded.
Current source-check eligibility includes a matched, unarchived, non-sample company that is not paused and has not been checked in the preceding 24 hours. Scheduled jobs run through a separate authenticated scheduler. Usage capacity, production limits and service arrangements must be agreed before scaling an external integration.
Ingest an authorised company event
Submit an event only for a saved company in the key's workspace. The company ID is the internal CompanyDelta identifier, not the registration number. Use a stable, workspace-unique external_id so retrying the same source event does not create another event.
{
"company_id": "REPLACE_WITH_SAVED_COMPANY_ID",
"external_id": "example-ownership-2026-09-09",
"type": "ownership",
"title": "Recorded holding increased",
"previous_value": "40%",
"current_value": "65%",
"source": "Illustrative registry record",
"source_url": "",
"filed_at": "2026-09-09",
"effective_at": "2026-09-04"
}New accepted events return HTTP 201 with event_id and accepted: true. A repeated external identifier returns the existing event_id and duplicate: true. This duplicate check applies across the workspace; prefix identifiers appropriately if several source pipelines share it.
The supported type values are ownership, directors, status, financials and details. Both previous and current values must be non-empty and can contain up to 2,000 characters. A supplied source URL must use HTTPS. Filing and effective dates are optional ISO dates.
Use a sample company when testing: the event's sample indicator is inherited from its company. Event acceptance can create a review under a matching enabled workflow and queue webhook notifications. Do not submit invented events to a live company's production workflow.
MCP endpoint and tools
Connect your assistant to https://companydelta.com/api/mcp using OAuth sign-in and workspace consent, or a scoped API key.
Eight tools cover company search, live or saved company records, paginated company/event/review lists, available monitoring signals, and confirmed start/pause monitoring actions. Use read, search and monitoring:write permissions as needed.
Full MCP reference: authorization, tools, arguments and troubleshooting →
Webhook delivery contract
An owner or admin adds a destination from Notifications in the workspace. The signing secret is shown once. Destinations require a public HTTPS URL without URL credentials, a custom port or a fragment; redirects are rejected.
Each message wraps an event in {"type":"company.changed","event":{...}}. The outbound event contains id, company, company_name, type, title, previous, current, source, source_url, detected and sample. It does not include all fields returned by the events API.
| Header | Meaning |
|---|---|
X-CompanyDelta-Delivery | Stable delivery identifier. Deduplicate retries using this ID. |
X-CompanyDelta-Timestamp | Unix seconds for this attempt. |
X-CompanyDelta-Signature | sha256= followed by the hexadecimal HMAC-SHA256 signature. |
A 2xx response marks acceptance. Requests have a 10-second timeout. Failed attempts receive a future eligible retry time; job execution or an authorised retry must process them. There are up to five attempts per delivery, without a guarantee of exactly-once delivery or ordering.
Enabled destinations receive newly recorded events across the workspace. Apply company and category filtering at the receiver. Store the event durably before acknowledging it, and retain a processing record so duplicates do not repeat the downstream action.
Verify the webhook signature
Calculate the HMAC over timestamp + "." + rawBody, using the signing secret. Verify the bytes exactly as received, before JSON parsing changes their representation. This Node.js example checks the signature and a five-minute timestamp tolerance:
import { createHmac, timingSafeEqual } from 'node:crypto';
export function verifyCompanyDelta(rawBody, timestamp, signature, secret) {
if (!Buffer.isBuffer(rawBody) || typeof timestamp !== 'string' ||
!/^\d+$/.test(timestamp) || typeof signature !== 'string' ||
!/^sha256=[0-9a-f]{64}$/.test(signature) || !secret) return false;
const age = Math.abs(Date.now() / 1000 - Number(timestamp));
if (!Number.isFinite(age) || age > 300) return false;
const expected = createHmac('sha256', secret)
.update(timestamp + '.')
.update(rawBody)
.digest();
const received = Buffer.from(signature.slice(7), 'hex');
return timingSafeEqual(expected, received);
}Pass the three header values and raw request bytes from your server framework. Keep clocks synchronised. Signature verification is one part of the receiver: also validate the payload, limit request size, deduplicate deliveries and record the business action. Adjust the tolerance only with an explicit timing policy.
Troubleshooting a connection
| Result | What to check |
|---|---|
| Access page or redirect | Check the hosting access policy first. A workspace API key does not replace site access. |
| 400 | Review required fields, supported event types, valid dates and identifiers. |
| 401 | Check whether the key is valid, unexpired and not revoked. |
| 403 | Check key scopes, workspace permissions or the supplied Origin header. |
| 404 / 405 | Check the path and HTTP method against this reference. |
| 415 | Send JSON with Content-Type: application/json for body-bearing endpoints. |
| 503 | The operation could not complete. Inspect service status and retry safely; do not assume a write was confirmed. |
For missing company data, check the source connection, company match, collection result and expected field coverage. An empty successful API response is a valid result, not evidence that source collection has run. Keep sample and live records separate in downstream reporting.
For an integration review, keep the request method, path, timestamp, response status and relevant event or delivery identifier. Remove credentials and company-sensitive payloads before sharing logs.