Back to blog
7 min read

Data Enrichment API: What "Real-Time" Actually Means

By Kooperativa Engineering

Search "data enrichment API" and nearly every result on the first page uses the word "enrich" to describe three different architectures without ever naming the difference. A vendor's landing page will promise real-time updates one paragraph after describing a dataset that is unmistakably refreshed on a schedule, not because anyone is lying, but because the category has settled on marketing language that does not distinguish the thing that actually matters: where does the answer come from at the moment you ask for it.

Three architectures, one word

Database enrichment serves a stored snapshot. The provider indexed a record at some point in the past and hands it back unchanged until the next scheduled re-crawl, commonly monthly. It is fast and cheap to run at volume, and its accuracy is bounded by however long ago that crawl happened, a number the response itself rarely surfaces.

Waterfall enrichment chains several database-style providers behind one call, falling through to the next only when the previous one returns nothing. It lifts coverage on data where providers disagree about what they hold, contact details being the clearest case, but it is still serving snapshots, just from whichever snapshot happened to have a row. Ours is a different write-up: see the piece on waterfall enrichment for where that pattern earns its cost and where it is mostly ceremony.

Real-time enrichment fetches or verifies at request time, at least for records past a defined age. This is the architecture that actually matches what the word "real-time" implies, and it is the least common of the three, because holding a live connection to a source and re-fetching on demand costs more to build than serving a cache.

The tell that distinguishes them from the outside

You cannot tell which architecture you are calling from response speed. A cache lookup and a live re-fetch can both return in a few hundred milliseconds if the live fetch is fast, and a cache lookup can be slow if the provider's database is under load. The tell is in the data itself: enrich the same identifier for a person you know changed roles recently, and see whether the response reflects it.

A database-enrichment provider will keep returning the old employer until its next scheduled crawl reaches that record, which can be weeks away. A real-time provider re-checks and returns the current one. This is a two-minute test against a name you already know the right answer for, and it is more informative than any pricing page.

How the refresh actually happens, concretely

On our own detail endpoints, a record older than 90 days is refreshed inline before the response goes out, not queued for later. The 90-day threshold is not arbitrary: it is the exact refresh cycle already committed to in the terms of service, so the code enforces a number that used to only exist in prose. In practice around 3% of lookups land past that threshold and pay a latency cost, a few extra seconds, for it; the other 97% are already fresh and return immediately.

A refresh that fails, timeout, upstream outage, unparseable response, never turns a working lookup into an error. It falls back silently to the record already on file, so the response degrades from "current" to "what we had," not to a 500. That failure mode is the detail worth asking any vendor about directly, because "what happens when your real-time fetch fails" is the question that separates a real architecture from a marketing claim: if the honest answer is "the request errors," that is a real-time system with a rough edge; if the vendor has not thought about the question, it is probably not real-time at all.

What this changes about evaluating "coverage"

Coverage numbers from a database-enrichment vendor and a real-time one are not comparable even when they quote the same percentage, because they are measuring different things. A database provider's coverage is "what fraction of this population did our last crawl happen to capture." A real-time provider's coverage is closer to "what fraction of this population exists at all, right now," since a live fetch does not depend on whether a previous crawl happened to pass through that specific record.

The practical version of this: when comparing vendors, ask each one not just for a match-rate number but for the distribution of `fetched_at` ages across a real result set. A vendor that cannot produce that distribution, or whose answer is a single dataset-wide "refreshed monthly," is telling you which architecture they run without using the word.

Get started

Try Kooperativa

One API key. Person and company enrichment, structured search, and monitors under one flat license.

Keep reading