Find recent company moves
Required permissions: people:read.
Stateless search over our people data. Send source (the company left), destination (the company joined), or both. Or search without a company by title, the new role (same terms as /v1/find filters.title), narrowed by destinationFilters (hq.countries, headcount of the company joined); those two go only with a title search. Inclusive startedSince and exclusive startedBefore (the month the new role started, month precision) narrows any of these searches, with or without a company. One of source, destination or title is required. Returns moves observed in the last 90 days and writes nothing. One row per person per destination — we hold a row per source record, and those are collapsed; a title search returns one row per person. limit sets the page size: 25 by default, 100 at most, capped rather than rejected. hasMore says more matches may remain behind this page; send nextCursor back as cursor, verbatim and with the same search, to walk them. The walk resumes where the page stopped, so a later page neither repeats nor skips what an earlier one returned. hasMore reads the row count before duplicate records are collapsed, so a page can come back short and still be true — follow hasMore and nextCursor, never the row count. A source-only search may read a fixed sample rather than an ordered walk and cannot be paged; indexed source-only searches can page. Sending cursor on a sampled source-only search is rejected, nextCursor is null, and hasMore: true there means narrow the search. Report truncation for the requested period. Each row carries detectedAt (when we saw the move), startedAt (when the role began, to the month, often null) and startedAtPrecision (month or year). detectedSince filters detection recency: it keeps only moves with detectedAt >= the value you send — the DETECTION date, not the start date; startedSince filters the start, and both can be sent. It only narrows the 90-day window, starting at midnight UTC 90 days ago: an earlier value is clamped to that start and a future value matches nothing. Destination searches already return the newest moves first: narrowing the window does not recover omitted matches; it returns the same rows or a subset. This is a recency filter, not pagination. seniority is the second filter: it keeps only moves INTO a role at that level or above, read from the title of the role they joined — not the one they left, and not a title list you supply. The four seniority levels widen in order: cxo (the C-suite), vp (adds VP, SVP, EVP, Vice President and President), director (adds Director), head (adds Partner, Principal and Head of). With destination, it WIDENS the search rather than trimming the page — the search reads further through recent moves looking for matches instead of filtering the slice it would have read without it — and that wider read is still bounded, so a short or empty answer does not prove nobody senior joined. Source-only searches that report sampled: true filter the same fixed sample; they do not read further. Title matching is heuristic and excludes assistant/support roles. sampled: true means a source-only search read a small fixed sample of recent moves; an empty answer does not mean nobody left, and retrying gives the same answer while the underlying data is unchanged. A source-only search with sampled: false walked the newest moves out of that company instead of sampling them. With destination, sampled is false: the search reads a bounded slice of the newest moves into that company before filtering by source. hasMore: false does not prove completeness with either value of sampled. A title search reads the title index up to a cap and says sampled: true when the title is held by more people than that; each page reads a bounded number of moves, so it can come back short, even empty, with hasMore: true — follow the cursor. A company search with startedSince or startedBefore checks the start after reading each move, so it also reads a bounded number per page and pages the same way. Every row is a move between two companies; promotions and same-company title changes never appear here. For promotions, and for checks you repeat on a company over time, use the workspace job_change signal (create_signal, then run_discovery). That signal is not a departure search and does not provide a complete list of who left. A workspace can run only a few job-change searches at once. A search sent while that many are running comes back as 503 data_search_busy before anything is read: wait details.retryAfterSeconds, send it again, and send fewer at the same time.
Request
- Base URL: https://api.trayo.ai
- URL: https://api.trayo.ai/v1/job-changes/search
- Auth: HTTP bearer
Request body
Response
Changes
No recorded changes to this operation across all 1 revision of this API.