People

Look up emails and phones for many people

Required permissions: body.fields includes email: people:enrich_email; body.fields includes phone: people:enrich_phone. All scopes for the selected fields are required. Omitting body.fields uses ["email","phone"] and requires people:enrich_email and people:enrich_phone. Malformed values: no additional scopes; unknown fields add no scopes. Request validation still applies.

Start lookups for up to 200 people in one call, with the same rules as the single route applied per person. Partial success is the contract: a person who exists gets an outcome in accepted even if every field was skipped; an id that is unknown, another workspace's, or a duplicate earlier in the batch lands in skipped by index.

This route always answers 200, never 202 or 402. A workspace allowance stop — the plan lookup limit, the workspace quota, or the daily usage limit — is reported per person rather than raised: people reached before the stop are looked up and charged, and the person that hit it and every person after it are reported in skipped with the limit as the reason. Nothing after the limit is partially run. stoppedBy says so as data: which allowance, how many people were processed and how many were not looked up.

The batch has a 120s budget for starting lookups. The whole batch starts together and normally takes a few seconds. The budget is checked once, before anything is reserved: if it has run out, the first person who needed a lookup and every person after are reported in skipped with a reason saying the call ran out of time. Nothing was started for them and nothing was spent, so send those ids again in smaller batches. Retain this request's personIds array and map skipped[].index back to it. Only re-send time-skipped rows this way: other rows in skipped may be duplicates, invalid ids, or allowance refusals that need a different remedy. Poll already-started lookups with GET /v1/people/{id}/enrich. If a retry makes no progress, stop and keep the unresolved ids for later.

A lookup is explicit, asynchronous, idempotent, and governed by your plan. Nothing is looked up on create or on read; this call is the only trigger, and it reports what it started and what it SKIPPED — a field already in progress, already found, blocked by a written email, or inside its retry cooldown is skipped with the reason, never an error — so sending it twice never double-runs or is charged twice. Poll GET /v1/people/{id}/enrich (or read the person) for the result; a lookup takes seconds to a minute.

Provenance is kept. A found value carries source, status and foundAt; a value you wrote is source: "manual" and is never overwritten by a found one — the email lookup is not even attempted while one is present.

Plan limits are checked BEFORE anything runs. Each lookup that starts counts once against a lifetime plan limit. Every response carries quota — limit, used and remaining per field, as they stand after the call, the same numbers GET /v1/whoami reports — so size each request by quota.<field>.remaining rather than learning the limit from a refusal.

post/v1/people/enrich/batch

Request

  • Base URL: https://api.trayo.ai
  • URL: https://api.trayo.ai/v1/people/enrich/batch
  • Auth: HTTP bearer

Request body

personIdsstring[] required

1 to 200 person ids. Over the cap is an error, not a clamp.

fieldsstring[]

Which values to look up. Omit for both. A field that cannot or need not run is reported in skipped, never an error.

Response

The batch was processed. Check skipped — a 200 does not mean a lookup started for every person.

Changes

No recorded changes to this operation across all 1 revision of this API.