Getting started
What is never exposed
Some data has no representation in this API at all. Not behind a scope, not for a first-party key, not in aggregate. Read this before you design a schema that assumes otherwise.
Everything below is absent by construction. There is no scope that unlocks it and no support request that will. Where a field would otherwise appear, it is named in restricted with the reason never_exposed:consent_scope — so you can tell “we will not give you this” apart from “this is empty”.
The list
| Category | Why |
|---|---|
| EEO and diversity answers | Collected under a promise that they are used for aggregate reporting and nothing else. Not exposed per candidate, and not in aggregate in v1 either — a small enough cohort makes an aggregate personally identifying. |
| Voice screening content — transcripts, recordings, decrypted answers | The disclosure the candidate heard before the call covered Tahoe screening them. It did not cover redistribution to a third party. screening:metadata:read tells you a screening happened and how it scored; the content stays where it was recorded. |
| The LinkedIn profile capture | You get has_linkedin_capture: true and nothing more. The capture itself is held under terms that do not permit re-syndication. |
| Bearer capabilities — status tokens, screening links, storage keys | Each of these is a credential that acts AS the candidate. Handing one to a partner would let them do things as that person, which no scope should be able to grant. |
| Account secrets, permission maps, and platform-wide access flags | Whether an account holds elevated access is exactly the fact an attacker wants first. |
| Search prompts, saved searches and query hashes | A customer's hiring strategy, written out in plain language. Who they are targeting and how is commercially sensitive in a way the resulting candidate list is not. |
| Billing, credits, invoices and Stripe objects | Tahoe's commercials and its customers' spend. |
| Recruiter notes, scorecards and rejection commentary | Beyond what applications:internal:read deliberately covers. Free-text notes are written by someone who did not expect the candidate to read them. |
| Another tenant, ever | Every query is scoped to a workspace your credential was granted. A handle from another workspace returns 404, indistinguishable from one that does not exist. |
Search execution is not exposed either
Running a candidate search calls an external provider and spends the customer’s credits. That makes it a write wearing a GET’s clothes, and it has no place in a read-only API — an integration bug should not be able to spend a customer’s money.
POST /pool/search is the sanctioned equivalent: the same shape to you, over profiles Tahoe already holds, spending nothing and calling nobody.
The resume paywall is mirrored, not bypassed
Resume documents and parsed profiles follow the product’s own paywall exactly. If a workspace has not purchased access to a resume, neither has your integration: the field is restricted with reason paywalled, or the download returns 403 resume_locked with the unlock cost.
The paywall is also time-based as well as purchase-based, so a resume can go from readable to locked with nothing changing at your end. Do not treat a successful read as a permanent entitlement, and re-check rather than caching the document indefinitely.
Data you do receive still carries obligations
Being able to read something is not permission to redistribute it. Pool profiles in particular come from providers whose terms forbid onward syndication, and contact details belong to people who never signed up with you.
- Do not build a public directory out of anything you read here.
- Honour erasure notices. The erasure feed is an instruction to delete your copy, and it is deliberately readable with the weakest scope in the catalogue so that narrowing your other scopes never stops you hearing it.
- Do not re-identify. Joining an aggregate against your own data to recover an individual defeats the reason it was an aggregate.
