Accounts

Create an account

Required permissions: accounts:write.

An account is a name, an optional URL and an optional LinkedIn handle. That is the whole record — see AccountDto for what reads back. name is the only required field: an account you have no website for is created with url: null rather than refused, the same way POST /v1/people treats a company with no domain. Send url whenever you have it — it is this route's deduplication key. Supply linkedinHandle whenever you know the company page: use the bare handle (for example stripe), not the full LinkedIn URL. It is the strongest way to identify the company and takes precedence over the website and name.

You can start discovery immediately after creating an account. These outcomes apply to every signal type, including news. While a run is active, keep polling the same run. account_not_ready means Trayo could not search the account this time. After the run settles, retry the affected account IDs. company_not_found means Trayo could not identify the company from the supplied details. For company_not_found, check the named accounts before starting another discovery. If an identity is wrong, send the correct linkedinHandle with trayo_update_account over MCP, or with PATCH /v1/accounts/{id} and a workspace API key over REST. When no handle is known, send a corrected website url instead. Both need accounts:write. trayo_update_account also reports whether Trayo can now identify the company. Importing the same hostname again skips the existing account and does not update it. After the current run settles, start a new discovery for the corrected account IDs.

Public REST and MCP usage is recorded without daily usage caps, workspace quota cutoffs or lookup quotas for now. Workspace request pacing still applies. This call adds the account only, never people. Finding people and adding them are separate steps: search with POST /v1/find as many times as you need, then add the people you chose with POST /v1/people/batch.

To attach people to future events, first set the workspace stakeholder definition with PATCH /v1/workspace, then start discovery with people: "add". This definition does not add people to older events.

A POST /v1/find company row is NOT postable verbatim. Its id, website, linkedinUrl, industry, headcount, hq, fundingStage, foundedYear, companyType, description, why, known, state fields are all refused with validation_failed, and the message names the offending keys. They are refused rather than accepted-and-dropped on purpose: these company details cannot be saved through this route. Select the accepted fields first: jq '.data[] | select(.state == "selectable" and .url) | {name, url}'.

post/v1/accounts

Request

  • Base URL: https://api.trayo.ai
  • URL: https://api.trayo.ai/v1/accounts
  • Auth: HTTP bearer

Request body

namestring required

The company's display name. Matching falls back to this only after linkedinHandle and url, so supply the stronger identifiers whenever you have them. It is also this account's LAST deduplication key on POST /v1/accounts/batch, and it counts only against a stored account that has neither a usable website nor a handle — two companies that share a name but each have a website are both created.

urlstring uri nullable

The company website. Must include a scheme when given, e.g. https://stripe.com — stripe.com alone is rejected. The hostname is also this account's deduplication key on POST /v1/accounts/batch. A row WITHOUT a url is deduplicated by NAME instead (case-insensitive, within your workspace), so it is not created twice — but a url is the stronger key, because two different companies can share a name. After linkedinHandle, this is the next way to identify the company: send it whenever you have it.

OPTIONAL since TRA-2077. An account you only have a NAME for is created with no website (url: null on reads) rather than refused — the same thing POST /v1/people does with a company that carries no domain, and the same thing Trayo's own importer has always done. Two enforcement levels for one policy was the bug: this route refused rows the people route created.

linkedinHandlestring

linkedinHandle is the bare LinkedIn company handle, e.g. stripe from https://www.linkedin.com/company/stripe/. Supply it whenever known: it is the strongest way to identify the company and is tried before url and name. It is also this account's SECOND deduplication key on POST /v1/accounts/batch, checked when the hostname does not match, so a row whose website is new to this workspace can still be skipped as a duplicate on its handle alone.

Response

Account created.

idstring uuid required
namestring required
urlstring uri nullable required

The company's website as an absolute HTTP or HTTPS URL, or null when this workspace does not know one. null is expected rather than exceptional: an account created from a company NAME alone — by POST /v1/people with a company carrying no domain, or by a Trayo import — has no website until one is supplied. Set it with PATCH /v1/accounts/{id} (trayo_update_account over MCP). logoUrl is null for exactly these accounts, because it is derived from this field.

logoUrlstring nullable required

The account's logo URL. Derived from url, so it is present for every account whose url is a usable domain and null otherwise. Cannot be set through this API. The URL returns image bytes (200) or redirects to them (302), so it is usable directly as an <img src>; it answers 404 when no logo resolves for the domain. Fetching it needs no API key.

linkedinHandlestring nullable required
starredboolean required
createdAtstring date-time required
updatedAtstring date-time required

Changes

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