View as Markdown

Integration best practices

Everything on this page is optional - the API works fine call-by-call. But these are the patterns that separate an integration that is fast, cheap and robust from one that burns credits and retries blindly. If you are building an automated integration or an AI agent on top of the API, start here.

Retries and idempotency

Every v2 endpoint uses POST, but do not let the verb mislead you:

  • Search endpoints are read-only. People Search, Company Search and Enums never change anything and never spend credits - retry them freely.
  • Enrich endpoints are safe to retry too. Revealing an email or phone your workspace already unlocked is free, so replaying a successful People Enrich or Email Finder call does not double-charge you.
  • Follow the per-status guidance on Errors: retry 408 after a few minutes and 5xx with exponential backoff; never retry 400, 401 or 402 unchanged - they will fail the same way again.

Do not guess names or values

Request bodies are strictly validated: an unknown field anywhere in the body fails the whole request with 400 rather than being ignored. The two bulk endpoints are the one exception - an unknown field inside an item moves that item to the invalid bucket instead of failing the batch.

Enum-backed filters accept exact, case-sensitive values only. Read them from Enums (or GET /v2/enums at integration time) instead of inventing close-enough strings - "vp" matches nothing, "VP" does. The full request and response shapes are machine-readable in the OpenAPI specification, and every docs page has a markdown twin (append .md to its URL) indexed in llms.txt.

Control your spend

Searching is free; credits are only spent when contact data is revealed. The cheap pattern is always: search broadly, reveal narrowly.

  • Search with enrich_email off (the default on search). Every result already includes has_email and email_status for free.
  • Narrow to the people worth paying for - for example, filter contact_details.email.status to valid so you only ever reveal addresses that exist.
  • Reveal on the final subset only: re-run the narrowed search with enrich_email: true, or enrich the shortlist via People Bulk Enrich.
  • Have a list of LinkedIn URLs? Look them up for free first with People Search's person.linkedin_url filter and only enrich the people it returns.
  • When the balance hits zero, credit-gated endpoints return 402 Payment Required with X-Limit-Reached: true - treat that as a hard stop, not a retryable error.

Prefer bulk endpoints over loops

Enriching a list by looping the single endpoints works, but People Bulk Enrich and Company Bulk Enrich do up to 50 lookups per request, keep partial failures contained (one bad item never fails the batch), and echo your identifier on every outcome so results correlate back to your rows without guesswork.

Pagination and result caps

Search results come 25 per page by default and up to 100 with per_page; a query reaches 25,000 results either way (page 1000 at 25 per page, page 250 at 100). Follow the stop conditions on Pagination, and if a search reports more matches than the cap, tighten the filters and run several narrower queries (for example, split by country or headcount range) rather than trying to page past the window.

Pacing

Real API keys have no hard rate limit today - the practical limit is your credit balance. Still, keep concurrency modest (a handful of requests in flight), let the bulk endpoints replace request storms, and back off on 5xx instead of hammering.