Discovery and signals

Find companies that match your ideal customer, and turn buying signals into timeline events and actions.

Company discovery

Discovery finds companies that match your workspace's ideal customer profile (ICP) and explains why each one fits. The Prospector agent runs it.

  1. An admin starts a run with POST /api/v1/discovery/runs (202, queued). The server takes a snapshot of the ICP.
  2. In the background, the AI service turns the ICP into search queries, runs them through the search provider (when one is configured, within a daily budget), crawls the candidates' sites politely and scores them against the ICP.
  3. Candidates wait for review: GET /api/v1/discovery/candidates lists them, best score first.
  4. A member accepts a candidate (POST /discovery/candidates/{candidate_id}/accept), which creates or links the company, or rejects it (.../reject).

Nothing is imported until a person accepts a candidate. Other rules:

  • There is one candidate per domain per workspace, ever: a rejected domain is never proposed again.
  • Suppressed domains are never added. Accepting checks again.
  • One run at a time per workspace: starting another answers 409.
  • At most 3 runs per workspace per UTC day by default (429 above).
  • 422 when there is no ICP to search for and no seed websites or directory pages.
  • 503 when discovery is turned off on the server.

The Prospector can also run on a weekly schedule, set in the Agents hub (days and hour in the workspace's time zone).

Buying signals

Signals are buying signals about a company: hiring, funding, news, tech stack and website changes.

  • Detection: a periodic job asks the AI service to check a small batch of companies at a time. You can also scan one company now with POST /api/v1/signals/scan. Each new signal is stored once.
  • Processing: each new signal adds a signal_detected event to the timeline of the company's leads (up to a cap per signal). A signal for a company without leads is emitted once as a company-level event instead. Either way, a webhook hears about each signal exactly once (signal.detected).
  • Memory: signals also add facts to the company in ZeroReach's memory (for example hiring_for, uses_tool, funding_event).

GET /api/v1/signals lists signals.

Trigger rules

Admins can create rules (/api/v1/signal-rules) that act on new signals. A rule matches on:

  • kind (none means any kind);
  • keywords (none means any; case-insensitive, matched in the title, detail or evidence).

A matching rule then does one of two things:

ActionEffect
notifyMarks the signal and emits a signal.triggered webhook event.
enrollEnrolls up to max_leads of the company's leads into the rule's active sequence.

Enrolling goes through the normal path: reachability, consent and suppressions are checked per lead, and contact pressure, calling windows and send caps are checked again when each step runs. What a rule did is recorded on the signal, as counts only.