Data Enrichment

Status: Production. Writes to the CRM.

Purpose

Adds information that was not in the CRM, retrieved from external providers. This is the only operation that both writes to the CRM and runs to a schedule.

Providers and cadence

Two provider sweeps, each a separate service, each configured per client and each running once a day against a HubSpot list the client controls. One supplies company firmographic and technographic data; one performs contact email discovery. A provider that is not configured does not run.

Write semantics: fill, never replace

A gap is filled. An existing value is not overwritten, including when the provider returns something different. A record that already carries the field is counted as skipped and left alone. This is enforced in the sweep rather than left to configuration.

Every run reports what it wrote

A sweep ends by emitting a run summary, which is rendered and sent. A failed run reports as a failure with its own subject line, not as a quiet zero. The summary carries, per provider:

enriched / writtennot foundskipped, already had a valueduplicatesfailedtotal processedbacklog remainingprovider creditsstop reason

Rate limits and budget

Each sweep runs to a per-run call budget and a minimum-credit floor, and stops on whichever it reaches first, recording the stop reason. Provider rate limiting is retried with backoff; exhaustion is reported as its own count rather than folded into errors.

The one probabilistic input, stated plainly

Mixbound calls no language model. What a third-party provider does to produce an answer is that provider's business and is not visible to Mixbound. The provider's answer is data, not a Mixbound judgement: what Mixbound guarantees is the rule applied to it, which is fill-only, logged and reversible.

Technology

Node.js 20TheirStack APIWiza APIHubSpot API v3cron