/v1/developers/lookupReverse developer lookup (deprecated alias of POST /v1/developers)
search:readDEPRECATED — use POST /v1/developers. Bulk resolve identity inputs and/or hydrate already-resolved developerIds, and (optionally) return a facet selection inline. An input is any human identifier: a handle, github url, @handle, linkedin url, a person NAME, or a repo (owner/name or repo url, resolved to its owning developer). Each input result carries a status of resolved (one developer), ambiguous (a name matched several — ranked candidates are returned, no single developer), or not_found (a miss is always visible, never a silent empty). The identity skeleton costs 1 credit per DEVELOPER handed back, and it costs that at every door: here, through search (1 credit per delivered result) and through GET /v1/developers/{id}. ambiguous and not_found inputs are free, unknown ids are free, and two inputs that resolve to the same person are one charge. Results are positional: inputs first (1..25, resolved worker-side), then developerIds (up to 200, hydrated directly — a bad or unknown id degrades to a not_found result for that item, never a 400 for the batch). Each result also carries this account's relationship with the developer, and any email address this account has already paid to reveal. Set garden true to get each developerIds result back with its contribution garden and live GitHub stats, which is what lets a set of developers be rendered from this one call instead of one request per developer; it is free, and off by default because it costs one batched GitHub request per 25 developers. When facets is present, a flat facets block returns one cell per resolved developer × facet: sync and cached facets return inline (status ok), billed per cell; a compute facet that is NOT cached returns status report_required (billed 0) — request it via POST /v1/developers/reports and poll GET /v1/developers/reports/{reportId}. Which facets those are is not something you have to discover by spending: every facet in the free GET /v1/pricing/catalog carries requiresReport — false means this route always answers inline, true means it answers inline only from cache and otherwise report_required. This surface never goes pending. (report_required is an open-enum member for generated clients: treat an unknown cell status as not-yet-available.) A facet selection is EXPANDED before it is billed: bundle macros expand to their keys, and every facet is resolved together with the facets it cannot be computed without, which are billed at their own catalog price. Asking for ai.person_summary therefore also resolves and bills ai.repo_summaries. The expansion is echoed back on facets.plan: requested is what you named, added is what the dependency graph added and charged. There is no opt out, because a dependency is not an upsell: the facet you asked for does not exist without it. Read the whole table, including each facet's requires, from the free public GET /v1/pricing/catalog and you can price any selection exactly before you send it. Reconcile the bill on facets.billing.totalCredits, which is the per-developer base plus the facet cells and matches the x-cost response header; facets.billing.total counts facet cells only.
Request body DeveloperLookupRequest
inputsarray of stringHuman identifiers to resolve, up to 25: a GitHub handle, a github.com URL, an @handle, a LinkedIn URL, a person’s name, or a repository (`owner/name` or its URL, which resolves to the owner). You are billed 1 credit per DEVELOPER this call hands back; ambiguous and not-found inputs are free, and two inputs that resolve to the same developer are one charge. At least one of `inputs` or `developerIds` is required.
min 1 items, max 25 itemsdeveloperIdsarray of stringDeveloper ids you already hold, up to 200, hydrated directly. Billed the same 1 credit per developer as every other door, so 200 ids cost 200 credits. An unknown id is free and degrades to a `not_found` result for that entry rather than failing the batch.
min 1 items, max 200 itemsgardenbooleanReturn each `developerIds` result with its contribution garden and live GitHub stats, which is what lets you render a whole set of developer cards from this one request instead of one request each. Free, and off by default only because it costs one extra upstream request per 25 developers in latency. `inputs` results always carry a garden regardless.
facetsarray of one ofFacets (or bundle macros) to resolve inline for every developer that resolves, billed per cell. Only synchronous and already-cached facets can be served here: a facet needing background compute comes back `report_required` and costs nothing, and you request it through `POST /v1/developers/reports` instead. `GET /v1/pricing/catalog` marks those facets `requiresReport: true` (they can still come back inline when already cached), so you can tell which is which before you send. This endpoint never returns a pending cell.
min 1 items, max 27 itemsOption 1stringindexsketchportraitreachOption 2stringid.coreprofile.basicscore.crackedgithub.gardentags.matchedsignals.archetypesignals.signature_techsignals.builder_scopescore.gemsignals.ai_usagesignals.commit_factsactivity.contributionssignals.coreai.repo_summariesai.person_summaryidentity.linkedincontact.socialscontact.emailsfit.match_rationalefit.score_vs_jddossier.coredossier.contextualdossier.pitch_sheetcontextRefstringA registered job-description context, required for facets that judge a developer against a role rather than describing them in isolation.
max 200 chars
Responses
200Positional results plus the optional inline facets blockresultsarray of object requiredResults in a fixed order: every `inputs` result first, positionally, then every `developerIds` result, positionally. A miss is always a result with a status, never a gap in the array.
max 225 itemsinputstring requiredThe input string this result answers, echoed back verbatim.
max 2048 charsstatusstring required`resolved` = exactly one developer matched and `developer` is populated. `ambiguous` = more than one developer plausibly matched (a common name, a repository with an unclear owner), so `developer` is null and `candidates` holds the ranked possibilities for you to disambiguate. `not_found` = nothing matched. A miss is always one of these three and never a silent empty result.
resolvedambiguousnot_founddeveloperobject | null requiredThe resolved developer. Null unless `status` is `resolved`.
developerIdstring requiredThe stable Vamo identifier for this developer (GitHub's numeric user id, stringified). This is the id every other endpoint takes: facets, reports, contacts, shortlists, steering. Use it, not `login` — a login can be renamed and then belongs to someone else.
max 64 charsloginstring requiredThe GitHub handle as of the last snapshot. Display it, do not key on it: handles are renameable and reusable.
max 200 charsnamestring | null requiredDisplay name as the developer set it on GitHub. Null when they set none.
max 200 charsavatarUrlstring | null requiredGitHub avatar image URL. Null when absent.
max 2048 charscurrentRolestring | null requiredA single free-text role line for the developer. Best-effort and unverified; `professional.title` is the LinkedIn-sourced equivalent when we hold a LinkedIn overlay.
max 200 charsorganizationobject | null requiredThe developer's current employer, when one is known. Null means we hold no employer, NOT that they are unemployed.
namestring requiredThe organization name as recorded.
max 200 charslogoUrlstring | null requiredOrganization logo URL, null when absent.
max 2048 chars
universitystring | null requiredMost recent institution, when the LinkedIn overlay carries education. Null when unknown.
max 200 charsprofilesobject requiredWhere this developer can be found, plus the addresses if you have already bought them.
githubstring requiredThe developer’s github.com profile URL. Always present — GitHub is the identity anchor for every developer in the index.
max 2048 charslinkedinstring | null requiredLinkedIn profile URL when we hold a GitHub↔LinkedIn match for this person. Null for the large majority of developers: only a minority of the indexed GitHub population carries a LinkedIn overlay, so null means "no match held", never "no LinkedIn account".
max 2048 charsemailsarray of stringEvery email address we hold for this developer. Present ONLY when this account has already paid to reveal them and the purchase is still within its cache window; a base search or profile read never populates it. ABSENT is not the same as "no email": absent means you have not bought it, while `hasEmail: false` means we hold none. These are addresses we have OBSERVED — from public commit metadata and cached GitHub profile data — and we do not check deliverability, so treat the order as meaningless and expect some to bounce. Buy them with the `contact.emails` facet.
max 50 items
hasEmailboolean requiredWhether we hold at least one email address for this developer. It says we have an address on file, not that the address works — we do not check deliverability. The addresses themselves are never returned by a search or a base profile read: this boolean is the free signal, and the paid `contact.emails` facet is the only way to get them. Use `hasEmail` on a search request to filter to developers we hold an address for, without paying.
biostring | null requiredThe developer’s GitHub bio, verbatim. Null when empty.
max 5000 charslocationobject | null requiredSelf-reported location, plus our geocoding of it. Self-reported and never verified against anything: a developer can leave it stale or blank. Null when we hold nothing at all.
rawstring | null requiredThe location string exactly as the developer typed it on GitHub ("SF / remote").
max 200 charscitystring | null requiredCity resolved from `raw` by geocoding. Null when `raw` was empty or unresolvable.
max 200 charscountrystring | null requiredCountry resolved from `raw`. Null when `raw` was empty or unresolvable.
max 200 chars
joinedAtstring | null requiredWhen the GitHub account was created, as an ISO 8601 instant. Null when unknown.
max 40 charsstatsobject | null requiredSnapshot counts and standing for this developer. These are from our index and go stale between refreshes; `GET /v1/developers/{id}` returns live GitHub equivalents alongside the contribution garden when you need current numbers. Null when we hold no stats at all.
followersinteger | null requiredGitHub follower count at snapshot time.
min 0, max 100000000followinginteger | null requiredHow many accounts this developer follows, at snapshot time.
min 0, max 100000000totalStarsinteger | null requiredSum of stargazers across the repositories ATTRIBUTED to this developer — the same set as `repos`, so the count can never contradict the list. Owned and contributed-to repositories both count; forks do not.
min 0, max 100000000crackedScorenumber | null requiredDevrank: a 0–100 standing for this developer within the WHOLE indexed GitHub developer population (tens of millions of accounts), not within a language, region, or seniority peer group — so it is not a like-for-like comparison between two candidates for the same role. It is derived from the follower/contribution graph, is recomputed upstream on its own schedule, and carries no version on the wire, so the same developer can read differently across two snapshots. It contributes one term to the page-local `score` and backs the `levers.github.minDevrank` filter. Null when the developer is not in the devrank table.
tierstring | null requiredThe upstream provider’s own coarse label for `crackedScore` (for example "Elite"). The label set is the provider’s and is not a Vamo-stable vocabulary — treat it as display text and branch on `crackedScore` if you need a threshold. Null when the developer is not in the devrank table.
max 200 chars
reposarray of object requiredThe developer’s top ATTRIBUTED public repositories — owned or authored-into, forks excluded — stars descending, capped at 12. This is a sample of their best work, not a complete repository list, and it is not an answer to "why did this person match my query" — read `evidence.matchedRepos` for that.
max 12 itemsnamestring requiredThe repository name alone, without the owner (`linux`).
max 200 charsfullNamestring requiredGitHub `owner/name`. This is the join key: an evidence repo and a profile repo describing the same repository carry the same `fullName`.
max 200 charsdescriptionstring | null requiredThe repository's own GitHub description, verbatim. Null when it has none.
max 5000 charslanguagestring | null requiredGitHub's primary language for the repository. Null when GitHub reports none (an empty or docs-only repo); never inferred from the code.
max 200 charsstarsinteger requiredStargazer count at the time this profile was snapshotted, not at request time.
min 0, max 100000000commitsintegerHow many commits THIS developer authored to this repository over the trailing year. This is the difference between a project they wrote and a project they landed one drive-by fix in — a 385k-star repository with 4 of their commits is not their work. Absent when no commit signal was captured; 0 means none in the trailing year, which for older dormant work is not the same as none ever.
min 0, max 100000000ownedbooleanTrue when the repository sits under the developer's own account, false when it is someone else's (an organisation's or another person's) and they are a contributor to it. This is the difference between "they built this" and "they committed to this", and it is the ONLY honest basis for crediting a repository's stars to a person. Absent when no ownership signal was captured; treat absent as unknown, never as false.
urlstring requiredThe public github.com URL of the repository.
max 2048 chars
languagesarray of string requiredDistinct primary languages across the developer’s repositories, at most 8. Presence means they have shipped public code in it; the list is not ranked by proficiency and carries no line counts.
max 8 itemsexperiencearray of object requiredEmployment history from the LinkedIn overlay, newest first. Empty for any developer we hold no LinkedIn match for, which is most of them.
max 25 itemstitlestring | nullJob title, on an experience entry.
max 200 charscompanystring | nullEmployer name, on an experience entry.
max 200 charsschoolstring | nullInstitution name, on an education entry.
max 200 charsdegreestring | nullDegree awarded, on an education entry.
max 200 charsfieldOfStudystring | nullField of study, on an education entry.
max 200 charsstartDatestring | nullStart date exactly as the source rendered it. Free text, NOT a normalised date: expect "2019", "Jan 2019" and "2019-01" from different records. Parse defensively.
max 200 charsendDatestring | nullEnd date in the same unnormalised free-text form as `startDate`. Absent or null on a current role.
max 200 charscurrentboolean | nullThe source's own "still there" flag. Set on experience entries; null on education entries.
educationarray of object requiredEducation history from the LinkedIn overlay. Empty for any developer we hold no LinkedIn match for.
max 25 itemstitlestring | nullJob title, on an experience entry.
max 200 charscompanystring | nullEmployer name, on an experience entry.
max 200 charsschoolstring | nullInstitution name, on an education entry.
max 200 charsdegreestring | nullDegree awarded, on an education entry.
max 200 charsfieldOfStudystring | nullField of study, on an education entry.
max 200 charsstartDatestring | nullStart date exactly as the source rendered it. Free text, NOT a normalised date: expect "2019", "Jan 2019" and "2019-01" from different records. Parse defensively.
max 200 charsendDatestring | nullEnd date in the same unnormalised free-text form as `startDate`. Absent or null on a current role.
max 200 charscurrentboolean | nullThe source's own "still there" flag. Set on experience entries; null on education entries.
professionalobject | nullLinkedIn-sourced professional scalars, present only when we hold a LinkedIn match for this developer. Absent or null for the majority of developers, which says nothing about their employment — only that we hold no overlay.
headlinestring | null requiredThe LinkedIn headline, verbatim.
max 5000 charstitlestring | null requiredCurrent job title per LinkedIn, e.g. "Chief Technology Officer".
max 200 charscompanystring | null requiredCurrent employer per LinkedIn. Distinct from the GitHub-sourced `organization` field, and the two disagree often — LinkedIn is usually the fresher of the two.
max 200 charssenioritystring | null requiredA coarse seniority label from the LinkedIn overlay ("c-level", "senior", …). Free text from the source, not a Vamo enum; do not switch on the exact string.
max 200 charsexpertisearray of string requiredSelf-declared skill tags from the LinkedIn profile. Claimed, not demonstrated — the demonstrated equivalent is the repositories under `repos` and `evidence`.
max 25 items
gardenobject | null requiredThe developer’s contribution garden. Null on a miss, and also null when the garden fetch itself failed — a garden failure never fails the lookup, it lands in `warnings` instead.
daysarray of object requiredOne entry per day for the trailing ~12 months, oldest first. Days with no contributions are present with a count of 0.
max 366 itemsdatestring requiredThe calendar day, `YYYY-MM-DD`, in the timezone GitHub renders the contribution calendar in.
max 10 charscountinteger requiredContributions GitHub counted on that day. GitHub’s own definition: commits to default branches, opened issues and pull requests, and reviews. It is not a measure of effort or of lines written.
min 0, max 1000000
totalinteger requiredTotal contributions across `days`. Public activity only: work in private repositories is invisible here, so a low total is not evidence of a low output.
min 0, max 1000000fetchedAtstring requiredWhen this garden was read from GitHub, as an ISO 8601 instant. Gardens are cached, so this can be older than your request.
max 40 charsliveStatsobjectLive GitHub counts fetched alongside the calendar. Absent on a garden cached before this field existed.
followersinteger requiredCurrent GitHub follower count, live.
min 0, max 100000000followinginteger requiredHow many accounts they currently follow, live.
min 0, max 100000000totalStarsinteger requiredSum of stargazers across the repositories this developer OWNS (`repos[].owned === true`), forks excluded, computed live. Stars on repositories they merely contribute to are NOT counted: those stars were earned by whoever built the project. Read this as "stars on their own work", never as their total reach. Never a provider-reported aggregate.
min 0, max 100000000reposarray of object requiredTheir attributed repositories as they exist right now — owned plus the org-owned projects they author commits and pull requests into, each flagged by `owned` — ordered by how much of the work is theirs, weighing their own commit count against the repository’s stars rather than stars alone, with a modest weight toward what they own. Same shape as the profile’s snapshot repos, so one renderer handles both.
max 12 itemsnamestring requiredThe repository name alone, without the owner (`linux`).
max 200 charsfullNamestring requiredGitHub `owner/name`. This is the join key: an evidence repo and a profile repo describing the same repository carry the same `fullName`.
max 200 charsdescriptionstring | null requiredThe repository's own GitHub description, verbatim. Null when it has none.
max 5000 charslanguagestring | null requiredGitHub's primary language for the repository. Null when GitHub reports none (an empty or docs-only repo); never inferred from the code.
max 200 charsstarsinteger requiredStargazer count at the time this profile was snapshotted, not at request time.
min 0, max 100000000commitsintegerHow many commits THIS developer authored to this repository over the trailing year. This is the difference between a project they wrote and a project they landed one drive-by fix in — a 385k-star repository with 4 of their commits is not their work. Absent when no commit signal was captured; 0 means none in the trailing year, which for older dormant work is not the same as none ever.
min 0, max 100000000ownedbooleanTrue when the repository sits under the developer's own account, false when it is someone else's (an organisation's or another person's) and they are a contributor to it. This is the difference between "they built this" and "they committed to this", and it is the ONLY honest basis for crediting a repository's stars to a person. Absent when no ownership signal was captured; treat absent as unknown, never as false.
urlstring requiredThe public github.com URL of the repository.
max 2048 chars
warningsarray of string requiredNon-fatal problems with this input: a malformed identifier, a failed garden fetch. A warning never means the result is invalid.
max 8 itemscandidatesarray of objectRanked possible matches, best first, when `status` is `ambiguous`. Empty or absent on every other status.
max 10 itemsdeveloperIdstring requiredThe stable Vamo identifier for this developer (GitHub's numeric user id, stringified). This is the id every other endpoint takes: facets, reports, contacts, shortlists, steering. Use it, not `login` — a login can be renamed and then belongs to someone else.
max 64 charsloginstring requiredThe GitHub handle as of the last snapshot. Display it, do not key on it: handles are renameable and reusable.
max 200 charsnamestring | null requiredDisplay name as the developer set it on GitHub. Null when they set none.
max 200 charsavatarUrlstring | null requiredGitHub avatar image URL. Null when absent.
max 2048 charscurrentRolestring | null requiredA single free-text role line for the developer. Best-effort and unverified; `professional.title` is the LinkedIn-sourced equivalent when we hold a LinkedIn overlay.
max 200 charsorganizationobject | null requiredThe developer's current employer, when one is known. Null means we hold no employer, NOT that they are unemployed.
namestring requiredThe organization name as recorded.
max 200 charslogoUrlstring | null requiredOrganization logo URL, null when absent.
max 2048 chars
universitystring | null requiredMost recent institution, when the LinkedIn overlay carries education. Null when unknown.
max 200 charsprofilesobject requiredWhere this developer can be found, plus the addresses if you have already bought them.
githubstring requiredThe developer’s github.com profile URL. Always present — GitHub is the identity anchor for every developer in the index.
max 2048 charslinkedinstring | null requiredLinkedIn profile URL when we hold a GitHub↔LinkedIn match for this person. Null for the large majority of developers: only a minority of the indexed GitHub population carries a LinkedIn overlay, so null means "no match held", never "no LinkedIn account".
max 2048 charsemailsarray of stringEvery email address we hold for this developer. Present ONLY when this account has already paid to reveal them and the purchase is still within its cache window; a base search or profile read never populates it. ABSENT is not the same as "no email": absent means you have not bought it, while `hasEmail: false` means we hold none. These are addresses we have OBSERVED — from public commit metadata and cached GitHub profile data — and we do not check deliverability, so treat the order as meaningless and expect some to bounce. Buy them with the `contact.emails` facet.
max 50 items
hasEmailboolean requiredWhether we hold at least one email address for this developer. It says we have an address on file, not that the address works — we do not check deliverability. The addresses themselves are never returned by a search or a base profile read: this boolean is the free signal, and the paid `contact.emails` facet is the only way to get them. Use `hasEmail` on a search request to filter to developers we hold an address for, without paying.
biostring | null requiredThe developer’s GitHub bio, verbatim. Null when empty.
max 5000 charslocationobject | null requiredSelf-reported location, plus our geocoding of it. Self-reported and never verified against anything: a developer can leave it stale or blank. Null when we hold nothing at all.
rawstring | null requiredThe location string exactly as the developer typed it on GitHub ("SF / remote").
max 200 charscitystring | null requiredCity resolved from `raw` by geocoding. Null when `raw` was empty or unresolvable.
max 200 charscountrystring | null requiredCountry resolved from `raw`. Null when `raw` was empty or unresolvable.
max 200 chars
joinedAtstring | null requiredWhen the GitHub account was created, as an ISO 8601 instant. Null when unknown.
max 40 charsstatsobject | null requiredSnapshot counts and standing for this developer. These are from our index and go stale between refreshes; `GET /v1/developers/{id}` returns live GitHub equivalents alongside the contribution garden when you need current numbers. Null when we hold no stats at all.
followersinteger | null requiredGitHub follower count at snapshot time.
min 0, max 100000000followinginteger | null requiredHow many accounts this developer follows, at snapshot time.
min 0, max 100000000totalStarsinteger | null requiredSum of stargazers across the repositories ATTRIBUTED to this developer — the same set as `repos`, so the count can never contradict the list. Owned and contributed-to repositories both count; forks do not.
min 0, max 100000000crackedScorenumber | null requiredDevrank: a 0–100 standing for this developer within the WHOLE indexed GitHub developer population (tens of millions of accounts), not within a language, region, or seniority peer group — so it is not a like-for-like comparison between two candidates for the same role. It is derived from the follower/contribution graph, is recomputed upstream on its own schedule, and carries no version on the wire, so the same developer can read differently across two snapshots. It contributes one term to the page-local `score` and backs the `levers.github.minDevrank` filter. Null when the developer is not in the devrank table.
tierstring | null requiredThe upstream provider’s own coarse label for `crackedScore` (for example "Elite"). The label set is the provider’s and is not a Vamo-stable vocabulary — treat it as display text and branch on `crackedScore` if you need a threshold. Null when the developer is not in the devrank table.
max 200 chars
reposarray of object requiredThe developer’s top ATTRIBUTED public repositories — owned or authored-into, forks excluded — stars descending, capped at 12. This is a sample of their best work, not a complete repository list, and it is not an answer to "why did this person match my query" — read `evidence.matchedRepos` for that.
max 12 itemsnamestring requiredThe repository name alone, without the owner (`linux`).
max 200 charsfullNamestring requiredGitHub `owner/name`. This is the join key: an evidence repo and a profile repo describing the same repository carry the same `fullName`.
max 200 charsdescriptionstring | null requiredThe repository's own GitHub description, verbatim. Null when it has none.
max 5000 charslanguagestring | null requiredGitHub's primary language for the repository. Null when GitHub reports none (an empty or docs-only repo); never inferred from the code.
max 200 charsstarsinteger requiredStargazer count at the time this profile was snapshotted, not at request time.
min 0, max 100000000commitsintegerHow many commits THIS developer authored to this repository over the trailing year. This is the difference between a project they wrote and a project they landed one drive-by fix in — a 385k-star repository with 4 of their commits is not their work. Absent when no commit signal was captured; 0 means none in the trailing year, which for older dormant work is not the same as none ever.
min 0, max 100000000ownedbooleanTrue when the repository sits under the developer's own account, false when it is someone else's (an organisation's or another person's) and they are a contributor to it. This is the difference between "they built this" and "they committed to this", and it is the ONLY honest basis for crediting a repository's stars to a person. Absent when no ownership signal was captured; treat absent as unknown, never as false.
urlstring requiredThe public github.com URL of the repository.
max 2048 chars
languagesarray of string requiredDistinct primary languages across the developer’s repositories, at most 8. Presence means they have shipped public code in it; the list is not ranked by proficiency and carries no line counts.
max 8 itemsexperiencearray of object requiredEmployment history from the LinkedIn overlay, newest first. Empty for any developer we hold no LinkedIn match for, which is most of them.
max 25 itemstitlestring | nullJob title, on an experience entry.
max 200 charscompanystring | nullEmployer name, on an experience entry.
max 200 charsschoolstring | nullInstitution name, on an education entry.
max 200 charsdegreestring | nullDegree awarded, on an education entry.
max 200 charsfieldOfStudystring | nullField of study, on an education entry.
max 200 charsstartDatestring | nullStart date exactly as the source rendered it. Free text, NOT a normalised date: expect "2019", "Jan 2019" and "2019-01" from different records. Parse defensively.
max 200 charsendDatestring | nullEnd date in the same unnormalised free-text form as `startDate`. Absent or null on a current role.
max 200 charscurrentboolean | nullThe source's own "still there" flag. Set on experience entries; null on education entries.
educationarray of object requiredEducation history from the LinkedIn overlay. Empty for any developer we hold no LinkedIn match for.
max 25 itemstitlestring | nullJob title, on an experience entry.
max 200 charscompanystring | nullEmployer name, on an experience entry.
max 200 charsschoolstring | nullInstitution name, on an education entry.
max 200 charsdegreestring | nullDegree awarded, on an education entry.
max 200 charsfieldOfStudystring | nullField of study, on an education entry.
max 200 charsstartDatestring | nullStart date exactly as the source rendered it. Free text, NOT a normalised date: expect "2019", "Jan 2019" and "2019-01" from different records. Parse defensively.
max 200 charsendDatestring | nullEnd date in the same unnormalised free-text form as `startDate`. Absent or null on a current role.
max 200 charscurrentboolean | nullThe source's own "still there" flag. Set on experience entries; null on education entries.
professionalobject | nullLinkedIn-sourced professional scalars, present only when we hold a LinkedIn match for this developer. Absent or null for the majority of developers, which says nothing about their employment — only that we hold no overlay.
headlinestring | null requiredThe LinkedIn headline, verbatim.
max 5000 charstitlestring | null requiredCurrent job title per LinkedIn, e.g. "Chief Technology Officer".
max 200 charscompanystring | null requiredCurrent employer per LinkedIn. Distinct from the GitHub-sourced `organization` field, and the two disagree often — LinkedIn is usually the fresher of the two.
max 200 charssenioritystring | null requiredA coarse seniority label from the LinkedIn overlay ("c-level", "senior", …). Free text from the source, not a Vamo enum; do not switch on the exact string.
max 200 charsexpertisearray of string requiredSelf-declared skill tags from the LinkedIn profile. Claimed, not demonstrated — the demonstrated equivalent is the repositories under `repos` and `evidence`.
max 25 items
relationshipobject requiredinContactsboolean requiredTrue when your account already holds this developer as a contact, hidden ones included.
projectsinteger requiredHow many live projects this contact is a candidate of.
sequencesintegerHow many ACTIVE outreach sequences this contact is in: not yet replied, not past the final step. A finished sequence does not count. Absent under the withholding rule described on this object.
doNotContactAtstring | null requiredWhen this contact was marked do-not-contact, as an ISO 8601 instant. Non-null means outreach to them is suppressed. Null when they are contactable or not a contact at all.
lastContactedAtstring | nullWhen outreach last reached them. Null means never; absent means withheld.
touchCountintegerHow many outreach touches they have received. Absent means withheld.
projectNamesarray of string requiredNames of the projects they are a candidate of, for display.
sequenceNamesarray of stringNames of the active sequences they are in. Absent means withheld.
addedAtstring | null requiredWhen they became a contact, as an ISO 8601 instant. Null when they are not a contact.
addedBystring | null requiredWho added them: a member id, or an API key id when an agent did. Null when they are not a contact.
addedByEmailstring | null required`addedBy` resolved for display: a member’s email address, the literal "API key", or the raw id when neither resolves.
facetsobjectThe inline enrichment block. Present only when `facets` was requested.
cellsarray of object requiredOne cell per resolved developer per requested facet. Check each cell’s `status` before reading its value.
developerIdstring requiredThe developer this cell is about.
max 64 charsfacetKeystring requiredWhich facet this cell answers.
id.coreprofile.basicscore.crackedgithub.gardentags.matchedsignals.archetypesignals.signature_techsignals.builder_scopescore.gemsignals.ai_usagesignals.commit_factsactivity.contributionssignals.coreai.repo_summariesai.person_summaryidentity.linkedincontact.socialscontact.emailsfit.match_rationalefit.score_vs_jddossier.coredossier.contextualdossier.pitch_sheetstatusstring requiredThe outcome for this one (developer × facet) pair. Exactly one status is billed: `ok`. `ok` = delivered, `value` is populated, and you were charged for it (or you already owned it). `pending` = a background job is computing it; poll the report until it settles. Not charged now; the charge is settled by the job. `unavailable` = we ran and there is genuinely nothing to return for this developer, including the case where the source answered with an empty result. Not charged. `failed` = the attempt errored. Not charged, and never retried inside the same report. `report_required` = this facet needs background compute and you asked on a synchronous endpoint that does not dispatch jobs. Not charged; request it via `POST /v1/developers/reports` to get it. Treat every status other than `ok` as "no data", not as a value.
okpendingunavailablefailedreport_requiredvalueobjectThe facet payload. Present only when `status` is `ok`; its shape is specific to the facet key, so read it against the facet you asked for. A cell whose payload came back with nothing in it is downgraded to `unavailable` rather than returned as an empty `ok`, so an `ok` cell always carries at least one real field.
jobIdstringThe background compute job producing this cell. Present only when `status` is `pending`.
planobject requiredWhat you named versus what the dependency graph added and charged on top. There is no opt out of a dependency: the facet you asked for does not exist without it.
requestedarray of string requiredThe facet keys you asked for, with any bundle macro expanded into its members.
addedarray of string requiredFacets that were resolved and CHARGED on top because a facet you requested cannot be computed without them. This is why a bill can exceed the price of the keys you named.
billingobject requiredThe itemised bill. Reconcile on `billing.totalCredits`, which is the per-developer base plus the facet cells.
itemsarray of object requiredOne line per (developer × facet) cell, including the ones that cost nothing.
developerIdstring requiredThe developer this line item is for.
max 64 charsfacetKeystring requiredThe facet this line item is for.
id.coreprofile.basicscore.crackedgithub.gardentags.matchedsignals.archetypesignals.signature_techsignals.builder_scopescore.gemsignals.ai_usagesignals.commit_factsactivity.contributionssignals.coreai.repo_summariesai.person_summaryidentity.linkedincontact.socialscontact.emailsfit.match_rationalefit.score_vs_jddossier.coredossier.contextualdossier.pitch_sheetcreditsinteger requiredCredits charged for this one cell. Zero unless `state` is `billed`.
min 0statestring required`billed` = charged on this call. `owned` = you had already paid for this cell and it is still within its cache window, so it cost 0 and you still get the value. `included` = a sibling key of the same SKU carried this call's charge, so this cell cost 0 and is fully yours: you buy the SKU, not the key. `not_billed` = the cell did not resolve (failed, unavailable, or report_required), so it cost 0 and you got nothing. A failed cell can never be reported as billed.
ownedbilledincludednot_billed
totalinteger requiredThe sum of `items`, so FACET CELLS ONLY. This is NOT what the call cost — it excludes the route’s own charge. Reconciling a finance integration on this field under-reports every bill. Use `totalCredits`.
min 0baseCreditsinteger requiredThe route’s own charge, separate from enrichment: one credit per developer returned on a search, one per input resolved on a lookup, 0 on a route that is free.
min 0totalCreditsinteger requiredWhat this call actually cost you: `baseCredits + total`. This is the number that matches the `x-cost` response header and the ledger entry. Reconcile on this.
min 0
400Neither inputs nor developerIds, too many, or a malformed selectioncodestring requiredStable machine-readable error code. Branch on this, never on the numeric status.
bad_requestunauthorizedsignature_requiredpayment_requiredforbiddennot_foundconflictgonepayload_too_largeunprocessable_entitytoo_many_requestsinternal_errornot_implementedbilling_unavailablenot_contactablemailbox_link_unavailablemailbox_requiredmail_engine_unavailablewebhook_publisher_unavailabledatabase_unavailableclient_errormessagestring requiredHuman-readable explanation of the refusal.
statusinteger requiredThe HTTP status code, repeated in the body.
remedyobjectA self-serve path forward, when one exists (a 402 points at the credit top-up).
kindstring requiredWhat kind of remedy this is, so a client can route it: whether the caller can clear the condition through the API, or a person must act in the web app.
topupconnect_mailboxurlstring requiredWhere to go to clear the condition: an API path, or a web app page when only a person can.
401No or invalid credentialcodestring requiredStable machine-readable error code. Branch on this, never on the numeric status.
bad_requestunauthorizedsignature_requiredpayment_requiredforbiddennot_foundconflictgonepayload_too_largeunprocessable_entitytoo_many_requestsinternal_errornot_implementedbilling_unavailablenot_contactablemailbox_link_unavailablemailbox_requiredmail_engine_unavailablewebhook_publisher_unavailabledatabase_unavailableclient_errormessagestring requiredHuman-readable explanation of the refusal.
statusinteger requiredThe HTTP status code, repeated in the body.
remedyobjectA self-serve path forward, when one exists (a 402 points at the credit top-up).
kindstring requiredWhat kind of remedy this is, so a client can route it: whether the caller can clear the condition through the API, or a person must act in the web app.
topupconnect_mailboxurlstring requiredWhere to go to clear the condition: an API path, or a web app page when only a person can.
402Plan lacks the capability, or the credit balance is emptycodestring requiredStable machine-readable error code. Branch on this, never on the numeric status.
bad_requestunauthorizedsignature_requiredpayment_requiredforbiddennot_foundconflictgonepayload_too_largeunprocessable_entitytoo_many_requestsinternal_errornot_implementedbilling_unavailablenot_contactablemailbox_link_unavailablemailbox_requiredmail_engine_unavailablewebhook_publisher_unavailabledatabase_unavailableclient_errormessagestring requiredHuman-readable explanation of the refusal.
statusinteger requiredThe HTTP status code, repeated in the body.
remedyobjectA self-serve path forward, when one exists (a 402 points at the credit top-up).
kindstring requiredWhat kind of remedy this is, so a client can route it: whether the caller can clear the condition through the API, or a person must act in the web app.
topupconnect_mailboxurlstring requiredWhere to go to clear the condition: an API path, or a web app page when only a person can.
403Missing search:readcodestring requiredStable machine-readable error code. Branch on this, never on the numeric status.
bad_requestunauthorizedsignature_requiredpayment_requiredforbiddennot_foundconflictgonepayload_too_largeunprocessable_entitytoo_many_requestsinternal_errornot_implementedbilling_unavailablenot_contactablemailbox_link_unavailablemailbox_requiredmail_engine_unavailablewebhook_publisher_unavailabledatabase_unavailableclient_errormessagestring requiredHuman-readable explanation of the refusal.
statusinteger requiredThe HTTP status code, repeated in the body.
remedyobjectA self-serve path forward, when one exists (a 402 points at the credit top-up).
kindstring requiredWhat kind of remedy this is, so a client can route it: whether the caller can clear the condition through the API, or a person must act in the web app.
topupconnect_mailboxurlstring requiredWhere to go to clear the condition: an API path, or a web app page when only a person can.
429Rate limit exceededcodestring requiredStable machine-readable error code. Branch on this, never on the numeric status.
bad_requestunauthorizedsignature_requiredpayment_requiredforbiddennot_foundconflictgonepayload_too_largeunprocessable_entitytoo_many_requestsinternal_errornot_implementedbilling_unavailablenot_contactablemailbox_link_unavailablemailbox_requiredmail_engine_unavailablewebhook_publisher_unavailabledatabase_unavailableclient_errormessagestring requiredHuman-readable explanation of the refusal.
statusinteger requiredThe HTTP status code, repeated in the body.
remedyobjectA self-serve path forward, when one exists (a 402 points at the credit top-up).
kindstring requiredWhat kind of remedy this is, so a client can route it: whether the caller can clear the condition through the API, or a person must act in the web app.
topupconnect_mailboxurlstring requiredWhere to go to clear the condition: an API path, or a web app page when only a person can.