People

Update a person

Required permissions: people:write.

Only the fields present in the body change; everything else is left alone.

note is yours to rewrite. Send a string to replace it (there is no append), send null to clear it, omit it to leave it untouched. It is stored and returned verbatim and never interpreted by Trayo, which is what makes it the right home for sourcing, confidence and "unverified" — title is the published job title and is the wrong place for any of that.

patch/v1/people/{id}

Request

  • Base URL: https://api.trayo.ai
  • URL: https://api.trayo.ai/v1/people/{id}
  • Auth: HTTP bearer

Path parameters

idstring uuid required

Request body

fullNamestring
titlestring

The person's JOB TITLE — nothing else. It is a published field: it is shown to humans as a job title and read as one by everything downstream, so a value like "VP Sales (UNVERIFIED, sourced from LinkedIn)" is a wrong job title for every reader of it, not an annotated one.

Sourcing, confidence, dates and "unverified" go in note, which exists for exactly that, holds 1000 characters, and is never interpreted by Trayo.

Omit it and Trayo may fill it for you: a row carrying a LinkedIn identity and no title takes one from the profile Trayo has on file — the current role's title, or the profile headline when there is no current role. Send the field to keep that from happening.

notestring nullable

Free text that is YOURS. Trayo stores it, returns it, and never reads it — it is not parsed, not indexed, not searchable, not shown in the Trayo UI, and nothing in the product branches on it. No structure is imposed: "sourced from LinkedIn, unverified, 2026-09-02" is exactly the intended use.

Yours, not PRIVATE: it is stored on the person record, so anyone with access to your workspace can read it back. Do not put secrets in it.

This is where provenance, sourcing, confidence and "unverified" go. Putting them in title instead corrupts a published field that humans and downstream systems read as a job title.

Up to 1000 characters; longer is validation_failed, not a truncation.

Send null to CLEAR the note; omit the field to leave whatever is there untouched. Sending a string replaces the whole note — there is no append.

emailstring email
linkedinUsernamestring

Response

The person after the update.

idstring uuid required
accountIdstring uuid nullable required
fullNamestring required
titlestring nullable required

The person's JOB TITLE — nothing else. It is a published field: it is shown to humans as a job title and read as one by everything downstream, so a value like "VP Sales (UNVERIFIED, sourced from LinkedIn)" is a wrong job title for every reader of it, not an annotated one.

Sourcing, confidence, dates and "unverified" go in note, which exists for exactly that, holds 1000 characters, and is never interpreted by Trayo.

Omit it and Trayo may fill it for you: a row carrying a LinkedIn identity and no title takes one from the profile Trayo has on file — the current role's title, or the profile headline when there is no current role. Send the field to keep that from happening.

notestring nullable required

Free text that is YOURS. Trayo stores it, returns it, and never reads it — it is not parsed, not indexed, not searchable, not shown in the Trayo UI, and nothing in the product branches on it. No structure is imposed: "sourced from LinkedIn, unverified, 2026-09-02" is exactly the intended use.

Yours, not PRIVATE: it is stored on the person record, so anyone with access to your workspace can read it back. Do not put secrets in it.

This is where provenance, sourcing, confidence and "unverified" go. Putting them in title instead corrupts a published field that humans and downstream systems read as a job title.

Up to 1000 characters; longer is validation_failed, not a truncation.

null when you have never set one. It reads back exactly as you wrote it — Trayo does not normalize, trim or rewrite it, and nothing in the product will ever change it.

emailstring nullable required

The email to use. A value you wrote (here or in the app) always wins; otherwise the one POST /v1/people/{id}/enrich found; otherwise null. emailSource says which. A found email that later bounced is withheld — see GET /v1/people/{id}/enrich for the reason.

emailSource'manual' | 'enrichment' nullable required

manual = written by a caller or in the app; enrichment = found by a lookup.

phonestring nullable required

The phone number a lookup found, or null. Phones are only ever FOUND — there is no way to write one — so this is always a found value. Ask for one with POST /v1/people/{id}/enrich, or with trayo_enrich_phones on the MCP server.

linkedinUsernamestring nullable required
linkedinUrlstring nullable required

Their LinkedIn profile URL, when Trayo has it. Send it to POST /v1/contacts/lookup, POST /v1/research/person, or as linkedinUrl to POST /v1/people.

profileImageUrlstring nullable required

The stored photo value, as written. Render photoUrl instead: it is the same photo under the name every person-returning route uses, with placeholders removed.

photoUrlstring nullable required

The person's profile photo, as a directly loadable image URL. Null when Trayo holds no real photo for them — show initials then. Every route that returns a person carries this field under this name.

isRepVisibleboolean required

Whether Trayo shows this person to a sales rep. Derived by the system and not settable — you cannot send this field, and a value you do send is ignored.

A person is rep-visible if ANY of these holds: they are linked to a completed event; Trayo attached them to an account; or somebody deliberately added them, which is what POST /v1/people is. So a person you create here comes back true — creating a person through this API is treated as the same deliberate act as adding one by hand in the app, and it surfaces the same way.

What it is NOT: it is not "has an email", and it is not a quality or confidence score. Adding an email, a linkedinUsername or a title neither sets it nor changes it.

false is what you will see on people Trayo collected while searching but never surfaced — profiles no completed event and nothing else ever picked up. Filter them with GET /v1/people?isRepVisible=false; adding one with POST /v1/people turns it true on the same record.

lastEventAtstring date-time nullable required
createdAtstring date-time required
updatedAtstring date-time required
stakeholderReportstring nullable

WHY THIS PERSON MATTERS — the stakeholder report Trayo generates for them: who they are, what they own, and how they relate to what you sell. Markdown, the same report the Trayo app shows on the person, and the same text POST /v1/people/{id}/ask reasons over.

null until stakeholder research has run for this person — it is not produced on create, and a person you added through this API has none until it does. Never an empty string: a blank report reads as null, so a caller can test === null and never has to trim.

Present on GET /v1/people/{id}, and on GET /v1/people only when expand is sent. Without it the KEY is absent, which is not the same as null.

Changes

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