Blog
What an enrichment run costs, and how to reconcile the bill against the headers
One credit per answered lookup, no bulk endpoint, and 404s still bill. Here is how to estimate an enrichment run and reconcile it against X-Credits-Charged.
Enriching 10,000 companies is 10,000 calls and 10,000 credits, which is $50.00 at $0.005 per credit. There is no line item where that number comes out smaller than the count of answered lookups, so budgeting an enrichment run is really just counting the lookups you cannot avoid, then checking after the run that you spent what you predicted.
The bill is answered lookups, not records and not requests
Billing is one credit per answered lookup. A 200 bills, a 404 bills because searching for an identifier with no record is the same retrieval as finding one, and a cache hit bills because it is the same data delivered faster. What does not bill is a request that never resolves to an answer.
| Response | Billed |
|---|---|
200 with a record | 1 credit |
200 from a cache hit | 1 credit |
404, no record for the identifier | 1 credit |
400, 401, 402 | free |
429, 502, 503 | free |
Read that table as a budget, not a status reference. Every row that costs a credit is a lookup you asked for and got answered. Every free row is a lookup that did not complete, so a rate-limited 429 you back off and retry costs nothing until the retry succeeds. The pricing page has the same split with the per-status detail.
Estimate before you start
There is no bulk path and no search endpoint, so enriching N entities is N calls, one credit each. That makes the estimate arithmetic short. Count the unique identifiers you will resolve, multiply by how many times a month you refresh them, and you have both the credit spend and, at the published 10 requests per second, the wall-clock floor.
CREDIT_USD = 0.005
def estimate_run(unique_identifiers, refreshes_per_month):
# No bulk endpoint, so answered lookups equals calls equals credits.
lookups = unique_identifiers * refreshes_per_month
seconds = lookups / 10 # published limit is 10 rps
return lookups, round(lookups * CREDIT_USD, 2), round(seconds / 60)
calls, usd, minutes = estimate_run(10_000, refreshes_per_month=1)
print(calls, usd, minutes) # 10000 50.0 17
The single biggest lever in that formula is unique_identifiers. The only free lookup is the one you do not make, so deduplicating your input list before the run, not after, is the one optimization that reduces the credit line rather than moving it around. A list with 30% duplicates is a bill 30% larger than the work required.
The 404 tax is a real budget line
A run over dirty identifiers pays for every miss at the same rate it pays for every hit. Send a display name where a slug belongs, or feed a urn:li: prefixed value back as an input, and you buy a 404. That is money spent for nothing returned, and it is entirely avoidable by resolving identifiers before they reach the wire, which is the whole argument in why profile and company lookups return 404.
Do not model a retry as a way to recover the spend. A retried 404 bills every time, and if you retry hard enough on a depleted balance you hit the wall instead:
HTTP/1.1 402 Payment Required
content-type: text/plain; charset=utf-8
insufficient credits
The 402 itself is free, but everything you spent getting there was not. Budget an expected 404 rate as pure waste, then drive it toward zero by cleaning the input, not by retrying the output.
Reconcile after with X-Credits-Charged
Every response carries X-Credits-Charged, and it reads 1 on a hit, a 404, or a cache hit, and is absent on the free codes. Summing it across a run gives you the real bill, which you compare against the estimate to catch the config bugs an estimate cannot see.
let spent = 0;
for (const id of identifiers) {
const res = await fetch(
`https://api.triguna.ai/v1/companies/details?company_id=${encodeURIComponent(id)}`,
{ headers: { ApiKey: process.env.TRIGUNA_KEY } },
);
spent += Number(res.headers.get('X-Credits-Charged') ?? 0);
}
console.log(`spent ${spent} credits, $${(spent * 0.005).toFixed(2)}`);
When the reconciled number runs over the estimate, the cause is almost always one of two things: a retry loop that is re-buying 404s, or use_cache=false forcing fresh fetches on data a stored copy would have answered. The cache does not save the credit, but forcing it off spends one you did not budget, which is the point of why a cache hit still costs a credit. The ledger is how you notice either one on the run that caused it, not on the invoice a month later.
The levers, in the order that pays off
- Deduplicate the input. The cheapest call is the one you never send. This is the only lever that shrinks the credit line itself.
- Store what you fetch. Read your own database inside your own freshness window so the next run does not re-buy last week’s data. That storage layer, not the 24 hour API cache, is your cost control, and it is the case made in store the raw payload.
- Resolve identifiers first. Every
404you prevent is a credit kept. - Pace, do not overspend. A
429is free, so backoff is cheaper than the fetch it defers. Spread a large refresh across a schedule rather than firing it all at once, which the nightly backfill guide walks through end to end, and let a cached read or astale_fallbackkeep a synchronous path moving in enrich on signup.
Check the balance, not your assumptions
Before a large run, read the balance rather than guessing at it. GET /v1/credits returns it against the same auth header as everything else:
curl -s https://api.triguna.ai/v1/credits -H "ApiKey: $TRIGUNA_KEY"
Signup gives you five free credits with no card, which is enough to run the estimate and the reconciliation against real traffic before you commit to a number. The full billing contract, including every free status code, lives in the billing reference.
Next
- Pricing: one credit per answered lookup, and which status codes cost nothing.
- Company API: the fields
GET /v1/companies/detailsreturns, and the slug that has to be exact. - Why a 404 still costs a credit: resolve the identifier before you spend it.
- Nightly backfill: pacing N calls when every one bills, cache hit or not.
- Start with five free credits at app.triguna.ai/signup, no card.