Blog
Clay vs a direct enrichment API: when a data marketplace and a single contract each fit
Clay is a data marketplace that runs waterfalls across many providers. A direct enrichment API is one documented contract. Here is when each one fits.
If you are weighing Clay against a direct enrichment API, the first thing to settle is that they are not the same kind of tool. Clay is a workspace that orchestrates data from many providers at once. A direct enrichment API is one endpoint you call from your own code. The question is not which is better. It is which job you are doing.
What each one actually is
Clay is a data marketplace and a GTM workspace. It advertises that you can buy data from 200 or more providers in one place and combine multiple data providers for the best coverage. Its signature move is the waterfall: you stack several providers behind one column, and Clay tries them in order until one returns a result. It is built for coverage and for building lists inside a spreadsheet style workspace, without writing code.
A direct enrichment API is the opposite shape. It is one documented contract you call from your
own application. Triguna is exactly this: two endpoints, GET /v1/people/profile and
GET /v1/companies/details, plus GET /v1/credits for balance. There is no marketplace, no
waterfall, no workspace, and no list builder. You send an identifier, you get that record back,
and the call lives in your pipeline rather than in a canvas.
| Axis | Clay | Direct enrichment API |
|---|---|---|
| Shape | Workspace and data marketplace | One documented API contract |
| Sourcing | 200+ providers, waterfalled | Two endpoints, one source you call |
| Where it runs | A no-code canvas | Your own code |
| Sized for | Coverage and list building | A named record you already have |
Pick Clay when the job is discovery and coverage
If you do not yet know who you are enriching, Clay is the stronger tool. You start from a search or an import, fan a row out across many providers, and let the waterfall fill whatever it can. The breadth is the point. A single documented API cannot do this, because it has no search path and no list path, so it is the wrong instrument for finding people or companies you cannot name yet.
Pick a direct API when you already have the identifier
The other job starts later. You already have an entity_urn or a company slug, and what you need
is the current record for that one entity, retrieved now, inside a service you run. That is one
call with a contract you can read in a sitting.
curl "https://api.triguna.ai/v1/companies/details?company_id=acme-corp" \
-H "ApiKey: $TRIGUNA_KEY" -i
HTTP/1.1 200 OK
X-Data-Source: live
X-Fetched-At: 2026-09-19T09:14:22Z
X-Data-Age-Seconds: 0
X-Credits-Charged: 1
The company_id takes the URL slug, acme-corp, not the display name. Send “Acme Corporation”
and you get a 404, which is the first of the
identifier traps worth fixing before your first call.
There is no bulk endpoint, so enriching N entities is N calls, a pattern covered in
enriching a list without a bulk endpoint.
Two differences that decide it before you write any code
Billing on a miss runs the other way. Clay states that
if an enrichment returns no result, you are not charged data credits or actions.
A direct enrichment API prices the opposite way, and it is worth saying plainly. Triguna charges
one credit for a 404, because a lookup that turns out to have no record is still a real
retrieval that ran. If most of your keys are going to miss, the no-charge-on-miss model is
genuinely friendlier for that shape of work, and you should know it going in. The full picture is
in what an enrichment run costs.
Provenance is a header, not a guess. When a waterfall answers, the value arrives without the
retrieval context attached to the row by default. A direct API puts provenance on every response:
X-Data-Source says whether the row was fetched live, served from a store under 24 hours old, or
returned as a stale_fallback during an outage, and X-Fetched-At and X-Data-Age-Seconds say
exactly how old it is. Provenance lives in the headers, never as a "source" field in the body.
The caching and provenance reference has the detail, and
the response headers explained walks each one.
A short decision list
- You are building a list from a search or import. A workspace with a waterfall fits, because coverage across many providers is the job.
- You want a no-code canvas your GTM team runs. That is Clay’s home ground, not an API’s.
- You already have the identifier and want the current record. Call a direct endpoint and read the source and age out of the headers.
- You want a surface small enough to hold in your head and hand to an agent. Two documented endpoints is a contract you can read once, which is the point of the why two endpoints argument.
Nothing stops you from doing both: many teams discover in a workspace and then wire a direct API into the product for the enrich-on-every-signup path, where a documented contract inside your own code matters more than breadth. That pattern, calling the API once at account creation without slowing a new user down, is in enrich on signup.
Start on the five free credits before you wire up billing. What each answered lookup costs, and which status codes are free, is on the pricing page.
Next
- Person API: what
GET /v1/people/profilereturns and the identifier it expects. - Company API: the company fields, and why
company_idtakes the slug rather than the name. - Coresignal vs People Data Labs: the same dataset-versus-on-demand fork, for two other providers.
- Enrich on signup: calling the API once at account creation without blocking a new user.
- Pricing: one credit per answered lookup, and the status codes that cost nothing. Sign up for five free credits at app.triguna.ai/signup.