Monitor named companies
Use a campaign to research a specific set of companies, then send Research Changes webhooks to your server when a company first qualifies or scheduled refresh finds a later change. For example, start with named target companies and watch whether they meet a hiring or technology signal.
This is campaign-based research, not a standalone subscription to every public event about a company. Uploading companies alone does not start recurring monitoring. Research Changes is configured in the Coldreach app; this guide does not introduce an API or MCP subscription-management operation.
1. Supply the company list
Create a campaign in Coldreach. Use an uploaded company source rather than ColdreachDB when the companies to research are already known. Supply company websites/domains so the companies can be identified. Review the imported rows before continuing. An uploaded source is finite: it does not automatically add new companies.
You can also import structured company data through an AI assistant connected to the existing /mcp server. Its importCompanies tool requires company_url for every company. company_name and company_linkedin_url are optional. Extra string fields are stored as custom fields.
Example tool arguments, not an HTTP API request:
{
"campaignId": 123,
"tableName": "Named target companies",
"companies": [
{ "company_url": "example.com", "company_name": "Example company" }
]
}
campaignId attaches the imported table to that campaign. Omit it to create a standalone table for later attachment with updateCampaignTables. A standalone table does not enable monitoring. These tool names apply to https://api.coldreach.ai/mcp; /mcp/v2 has a different tool contract. Use the connected server's tools/list to check its available tools and schemas rather than copying names between versions.
2. Define and launch the research
In the campaign, define the company signals you need. Make a signal Must Have if it should decide company qualification. Use Nice to Have for context that should not exclude a company. Make time windows explicit, such as “hiring for a security engineer in the last 30 days,” rather than “hiring recently.” Test signals against sample companies and inspect their evidence before launch.
Review the contact persona, contact limits, and outreach settings before launching. Launching a campaign can also find contacts and move them toward outreach according to its configuration. Enabling a webhook does not prevent sending or change targeting. Review the campaign's approval and sequence settings separately if the goal is research without automatic outreach.
Launch the campaign to participate in scheduled research refresh. Refresh uses the existing campaign scheduler's selected companies and research settings. This is not a promise that every imported company is checked at a fixed interval. Initial discovery can notify when a company first satisfies the complete company criteria. Initial unqualified, failed, or partial research does not notify.
3. Configure Research Changes
- An organization admin opens Settings → Developer → Webhooks → Research Changes.
- Save the HTTPS destination URL. Add authentication headers if your receiver requires them. The destination is shared by the organization.
- Use Test to send an illustrative payload. Test payloads include
test: true; they are not evidence that a real company's research changed. - In each campaign that should notify, open the campaign options menu → Notifications and enable Research change webhook. Campaign write permission is required. The switch defaults off.
Every enabled campaign uses the organization's destination. The campaign watches all company signals it uses, not a selected subset. The switch does not pause or relaunch the campaign.
What causes an event?
The event name is research-changed for both first qualification and later changes:
- First qualification: Initial discovery, or scheduled refresh with no previous complete qualification, finds that the company satisfies the complete campaign company criteria. The campaign must use at least one company criterion, and all company-criteria inputs must have usable results. A positive individual signal is not enough if the company fails the overall criteria. Initial unqualified, failed, or partial research does not notify.
- Later changes: Scheduled refresh changes the company's known qualification, or changes a company signal's YES/NO outcome or compared structured value. A later signal change can notify even if overall company qualification stays the same.
First qualification is based on the available research snapshots, not lifetime history. If earlier results become unusable or are replaced by failed research, a later successful refresh can qualify the company again.
Initial discovery only sends the first-qualified event when it newly records a previously unexplored candidate as explored. Reprocessing an already explored candidate does not send it again. This does not provide a guaranteed historical replay when notifications are enabled later. The event waits for first exploration to finish, which can include remaining configured contact research even after company criteria resolve. The qualification reported is still company-only; it does not require an eligible contact and is not an instantaneous notification.
Company qualification here does not mean a reachable contact exists or is eligible for outreach. Contact availability, contact eligibility, assignments, and outreach status do not cause these events.
A new signal's first result is not itself a signal-change event. Missing/pending/failed research, removed results, and evidence/wording-only changes do not notify. Timestamps and regenerated document IDs do not count as changes. Standalone manual research does not notify through this webhook.
Payload
Coldreach sends JSON by HTTP POST with Content-Type: application/json. One event describes one company in one campaign. This example shows company qualification and a required signal changing from false to true; evidence is illustrative.
{
"event": "research-changed",
"eventId": "workflow-run-id:company-id",
"campaign": { "id": 123, "name": "Named target companies" },
"company": { "id": 456, "domain": "example.com", "name": "Example company" },
"qualification": {
"before": false,
"after": true,
"evidence": {
"before": [
{ "id": 7, "qualified": false, "value": null, "reasoning": "No matching role found", "evidences": "Prior evidence", "updatedAt": "2026-10-26T00:00:00.000Z" }
],
"after": [
{ "id": 7, "qualified": true, "value": null, "reasoning": "Matching role found", "evidences": "Current evidence", "updatedAt": "2026-10-27T00:00:00.000Z" }
]
}
},
"signals": [
{
"id": 7,
"name": "Hiring security engineers",
"before": { "qualified": false, "value": null, "reasoning": "No matching role found", "evidences": "Prior evidence", "updatedAt": "2026-10-26T00:00:00.000Z" },
"after": { "qualified": true, "value": null, "reasoning": "Matching role found", "evidences": "Current evidence", "updatedAt": "2026-10-27T00:00:00.000Z" }
}
]
}
First-qualified payload
This initial-discovery example uses the same event, campaign, and company fields. qualification.before is null because there is no previous qualification snapshot; qualification.after is true. The before-evidence entries contain only signal IDs. No individual signal change is claimed, so signals is empty. A first qualification found by refresh can retain previous snapshots for already-known criteria and include other genuinely changed signals with successful before/after results. If one required criterion was false while another was missing or failed, the earlier overall qualification is still reported as null because the research was incomplete. Its before-evidence can contain that known false result.
{
"event": "research-changed",
"eventId": "discovery:123:2026-10-27T00:00:00.000Z:456",
"campaign": { "id": 123, "name": "Named target companies" },
"company": { "id": 456, "domain": "example.com", "name": "Example company" },
"qualification": {
"before": null,
"after": true,
"evidence": {
"before": [{ "id": 7 }],
"after": [
{ "id": 7, "qualified": true, "value": null, "reasoning": "Matching role found", "evidences": "Current evidence", "updatedAt": "2026-10-27T00:00:00.000Z" }
]
}
},
"signals": []
}
Field details
- Treat
eventIdas an opaque deduplication key. Initial discovery usesdiscovery:<campaignId>:<intent ISO timestamp>:<companyId>, where the timestamp identifies the discovery intent. Refresh uses<workflowRunId>:<companyId>, including a first qualification found by refresh. company.namecan be null.qualificationis null when only signals changed. Otherwise, itsevidencecontains the before/after company-criteria inputs, with each signal'sid. For initial discovery,beforeis null and its before-evidence entries have IDs only. Refresh can retain any known before-evidence snapshots.signalscontains only changed company signals. Each entry includesid,name,before, andafter. It is empty for initial discovery, but not necessarily for a first qualification found by refresh.- Research snapshots have
qualified,value,reasoning,evidences, andupdatedAt.reasoningandevidencescan be null. Boolean research actions usevalue: null. - Probe research, which collects matching source documents, uses
value: { "count": 2, "sources": [{ "providerId": "…", "url": "…", "payload": {} }] }. The actual source fields may be null andpayloaddepends on the source. Comparisons include count, source identity, and structured payload, not generated prose, quotes, freshness, or regenerated source IDs.
Delivery and limits
Return a 2xx response promptly and process the event asynchronously. Check any configured authentication headers at your receiver. Do not assume a separate signing header is supplied.
Queued delivery gets up to five attempts in total, with exponential retry delays starting at 30 seconds. Retries reuse the saved URL, payload, and credential version. Failed jobs are retained for 30 days. Revoked or unavailable saved credentials prevent delivery; a retry does not silently adopt replacement credentials.
Disabling the campaign switch or changing its destination or header version while refresh is running suppresses newly queued events from that refresh. Already queued events are not withdrawn by the campaign switch; they retain their saved destination and remain subject to credential revocation.
This is not a lossless change history. Refresh comparisons are held in the running process. First qualification is also not saved atomically with its delivery job. A crash before the event is queued can lose a notification. Duplicate delivery is also possible. There is no exactly-once guarantee, no guaranteed interval for every company, and no notification for every real-world event as it happens. Keep your own received-event history and inspect current research when you need the latest state.
See Webhooks for the other event types and MCP Integration for authentication and connection setup.