Pattern

How to let an agent call the enrichment API safely

Give a coding agent the contract as one paste, write the rules it gets wrong from priors, keep a loop from overspending, and make it report provenance.

7 min read Updated 1 August 2026

An agent calling an enrichment API has two failure modes a normal client does not: it can invent fields that do not exist, and it can spend money in a loop. Both are avoidable, and neither is solved by a better prompt alone.

Give it the contract, not a description of the contract

There is no SDK and no tool server to install. It is a plain HTTP API with three GET endpoints, so what an agent needs is the contract in front of it. Two machine-readable forms exist:

WhatWhereUse it for
Plain-text briefapi.triguna.ai/llms.txtPasting into Claude, Cursor or Copilot
OpenAPI 3.1 specapi.triguna.ai/v1/openapi.yamlGenerating a typed client, or driving a tool-calling loop

The brief is the one to reach for first. It is the whole contract as one page: endpoints, auth, error semantics, both full example responses, and the parsing rules models get wrong from their priors. Every page in the reference also has a copy button that yields the same thing scoped to that page.

curl -s https://api.triguna.ai/llms.txt | pbcopy

Write down the four rules it will otherwise get wrong

Models have strong priors about what a LinkedIn API looks like, and those priors are wrong here in specific, repeatable ways. Put these where your assistant reads them, in AGENTS.md or CLAUDE.md:

# Triguna

Two GET endpoints, `ApiKey` header, plain-text errors.

- Slugs or full LinkedIn URLs, never display names. "Acme Corporation" 400s.
- `experience[0].positions[0].title` is the current job title.
  `experience[0].title` does not exist.
- Every field is nullable. Say "not returned", never invent a value.
- Report `X-Data-Source` and `X-Fetched-At` back to the user.

Rule two matters more than it looks. An agent that reads a response and reaches for experience[0].title gets undefined, and a fluent model will often fill that gap with something plausible rather than reporting nothing. It is the most common way these integrations produce confident wrong answers, which is why the reference gives experience[] its own page.

Give it a resolution task, not a search task

There is no search endpoint. An agent asked to “find the CTO of Northwind” cannot do it with this API: it can only resolve identifiers it already has. Make that explicit, or it will improvise increasingly creative slug guesses and burn credits on 404s that all bill.

Good task shape:

Here are 42 LinkedIn company URLs. For each, call /v1/companies/details and report headcount, primary industry and funding stage. If a field is not returned, say so.

Bad task shape:

Find the headcount of our top 42 accounts.

The second has an unstated resolution problem inside it, and the agent will paper over it.

Make it report provenance

$ curl -sD- -H "ApiKey: $KEY" \
    "https://api.triguna.ai/v1/people/profile?profile_id=williamhgates"

X-Data-Source: store
X-Fetched-At: 2026-07-28T09:14:22Z
X-Data-Age-Seconds: 331088
X-Credits-Charged: 1

That record is nearly four days old. An answer of “Bill Gates is Chair of the Gates Foundation” is a stronger claim than the data supports; “as of 28 July” is exactly as strong. That is what rule four is for.

X-Data-Age-Seconds measures how long ago Triguna fetched, not how old the underlying data is, so read it as a floor on staleness rather than a measure of it.

Bound the loop

  • Concurrency. Cap parallel calls. Forty simultaneous lookups is how you meet 429.
  • Attempts. Retry 429, 502 and 503 only, and only a bounded number of times. 400, 401, 402 and 404 are terminal; an agent will not work that out on its own.
  • Scope. Pass an explicit list of identifiers rather than a database it can widen.
  • Cost. Sum X-Credits-Charged rather than counting successes. It is the only figure that is not an estimate.

Evaluating the loop

Before trusting an agent workflow, run it against a fixture set with known answers and check four things: it sent slugs rather than display names, it read titles from positions[], it reported nulls as “not returned” instead of filling them, and it attached X-Data-Source and X-Fetched-At.

All four failing is not a model problem. It means the contract never reached the model.

Next

Start with one request

Free credits on signup, no card required. Usage-based pricing after that.