/v1/projects/{id}/search-suggestionsAuto-suggested search angles for a project
search:readDeterministic search angles derived from the project's role config and its shortlist members' top repos, languages, and employers: a similar-companies angle, repo-seed fan-outs, technology fan-outs, and role-title prompts. Each is a SearchConfigV2 seed to adopt and edit. Free, no paid calls. Pass ?seed=N to rotate onto a different slice of the project's signals (the 'Suggest new angles' regenerate).
Path parameters
idstring requiredmax 16 chars
Query parameters
seedinteger | nullmin 0, max 99
Responses
200The suggested anglessuggestionsarray of SearchSuggestion requiredThe suggested angles. Nothing is searched and nothing is billed to produce them.
max 20 itemsidstring requiredIdentifier for this suggestion, stable within the response.
labelstring requiredA short name for the angle, for a picker.
descriptionstring requiredWhat this angle looks for and why it might be worth trying.
configobject requiredA PARTIAL search config seeding this angle. Merge it into your own config, edit the levers, then execute — it is a starting point, not a runnable config on its own.
versionnumberMarks this as a version 2 config. The only required field alongside `query`.
2querystring | nullFree-text description of who you are looking for, matched semantically. This is the one field that carries the intent; every lever below narrows it.
max 500 charsentitystring default: "auto"Which index to search. Leave `auto` to let the compiler route. Pin one when a lever you need landed in `unsupported`: `User` searches GitHub developers, `Repo` searches repositories and returns their contributors, and `LinkedInUser` searches the LinkedIn overlay, which covers only the minority of developers we hold a match for and therefore reaches a much smaller population.
autoUserRepoLinkedInUserrequiredLanguagesarray of string default: []Programming languages that MUST be present, as a hard filter on repositories. This is the only language axis that hard-filters: `levers.skills` and `levers.technologies` are semantic aims. Set it only for languages you genuinely require, since it removes everyone else.
max 20 itemsearlyCareerSignalsboolean default: falseBias the search toward people early in their career: adds a learning-in-public angle and inverts the devrank weighting, so established high-reputation accounts stop dominating the ranking.
aiFocusedSignalsboolean default: falseBias every angle toward AI, agent, LLM, retrieval and inference work.
includeUnconventionalTitlesboolean default: falseKeep people whose job title is not a conventional engineering one but who ship code anyway. Leave false and the LinkedIn lane restricts to engineering functions.
leversobject default: {}The narrowing levers. Every one is optional and every collection defaults to empty, so a query-only config is a legal search and you set only the axes you actually want to constrain. Check `appliedLevers` and `unsupported` on the response to see which of them actually bound.
skillsarray of string default: []Demonstrated abilities, matched against what the person has actually built. A semantic aim, not a hard filter — use `requiredLanguages` when something is genuinely mandatory.
max 20 itemsinterestsarray of string default: []Topics and problem areas the person works on or gravitates toward. Distinct from `skills`, which is about demonstrated ability; the two are never collapsed. Setting this routes the search toward the repository lane.
max 20 itemstechnologiesarray of stringLanguages, frameworks and systems, drawn from a CLOSED vocabulary — a value outside it is rejected rather than silently treated as free text. This is the concrete tooling axis; `skills` stays the conceptual one.
max 20 itemslocationobjectWhere the person is. Every location signal here is SELF-REPORTED by the developer and never verified.
countriesarray of string default: []Countries, matched against our geocoding of the self-reported location.
max 20 itemscitiesarray of string default: []Cities, matched against our geocoding of the self-reported location.
max 20 itemsstatesarray of string default: []States or regions, matched against our geocoding.
max 20 itemsrawarray of string default: []Raw location strings, matched against what the developer literally typed on GitHub.
max 20 itemsstrictbooleanTrue to hard-gate on location, trading recall for precision. False or unset applies it as a bias. Remember that location is self-reported and frequently stale or blank, so a hard gate drops everyone who left the field empty.
requireLinkedinbooleanReturn only developers we hold a LinkedIn match for. A severe narrowing: only a minority of the indexed GitHub population carries an overlay, so this trades most of the corpus for professional detail.
openToWorkbooleanRestrict to people flagged as open to work on their LinkedIn profile. Requires the LinkedIn overlay, so it implies the same narrowing as `requireLinkedin`.
experienceTierstringA coarse experience band to aim at.
earlyupToSeniorseniorallyoeRangeobjectA years-of-experience band, derived from the LinkedIn overlay, so it only constrains people we hold one for.
mininteger | null requiredMinimum years of experience. Null for no lower bound.
min 0maxinteger | null requiredMaximum years of experience. Null for no upper bound.
min 0
professionalobjectEmployment and education levers. Every one of these comes from the LinkedIn overlay, so setting any of them implicitly restricts the search to the minority of developers we hold a match for.
currentCompaniesarray of string default: []Companies the person works at NOW.
max 20 itemspastCompaniesarray of string default: []Companies the person used to work at.
max 20 itemsmustHaveWorkedAtarray of string default: []Companies the person must have worked at at some point, current or past. The either-or form of the two fields above.
max 20 itemsexcludeCurrentCompaniesarray of string default: []Companies to exclude people currently working at. This is how you avoid sourcing out of your own company or a client’s.
max 20 itemsschoolsarray of string default: []Institutions the person attended.
max 20 itemstitlesarray of string default: []Job titles to aim at.
max 20 itemsindustriesarray of string default: []Industries the person works in.
max 20 itemscompanySizeTierstringThe size band of the person’s current employer.
1-5051-200201-20002000+companiesModestringHow the company lists bind. `exact` matches the named companies only. `similar` expands them to comparable companies, which widens reach at the cost of precision.
exactsimilarsimilarCompaniesarray of string default: []Companies to treat as reference points for "companies like these", rather than as an allowlist in themselves.
max 20 itemsincludePastbooleanMatch against the full employment history rather than the current employer only. Defaults to true.
githubobjectGitHub-side levers: stars, followers, seed repositories, and the devrank floor.
starRangeobject | null default: nullA star band on the person’s repositories. Null, the default, means no bound at all rather than a missing value.
similarReposarray of string default: []Seed repositories, as `owner/name`. How they bind depends on `repoMode`: expanded to similar repositories, or matched exactly.
max 20 itemscontributedReposarray of string default: []Repositories the person COMMITS to rather than owns, as `owner/name`. This is how you find the people behind a repository they do not own — a company repo, or a large open-source project.
max 20 itemsminDevrankinteger | null default: nullA floor on devrank, the same 0–100 standing returned as `developer.stats.crackedScore`. Measured against the WHOLE indexed GitHub population rather than a peer group, so it is a blunt reputation gate and not a like-for-like comparison within a role. Null, the default, means no floor.
min 0, max 100hideHighProfilebooleanSuppress very high-profile accounts, which otherwise dominate a ranking without being realistic hires.
repoModestring default: "similar"How `similarRepos` binds. `similar`, the default, expands each seed to comparable repositories. `exact` matches only the repositories you named.
similarexactfollowerRangeobject | nullA band on GitHub follower count. Null bounds mean no limit on that side.
minContributionsLastYearinteger | nullTHE DEAD-ACCOUNT GATE. A floor on GitHub contributions in the trailing 365 days; ANDs with minContributionsLastMonth when both are set. Recruiter Bot ships 100 here, and the absence of this floor is the single largest source of low-signal developers in a result set. This is NOT an index filter — the serving user index carries no activity column — so it is enforced after hydrate against a LIVE contribution-calendar read of the returned window only. Two consequences worth planning for: it narrows the page rather than the corpus (a tight floor can shorten a page, and countStatus reports it), and it is the one lever that costs a GitHub call, so an unset floor costs nothing at all. A developer GitHub did not answer for is KEPT, never dropped — the gate degrades open rather than emptying a page when the upstream is slow.
min 0, max 100000minContributionsLastMonthinteger | nullThe trailing-28-day half of the dead-account gate, ANDed with minContributionsLastYear when both are set and answered by the same single live read. Recruiter Bot ships 20 here. Catches the developer who was active earlier in the year and has since gone quiet, which the yearly floor alone lets through.
min 0, max 100000
filterobjectA raw filter expression, as an escape hatch for constraints the levers do not express. Opaque here and validated by the compiler; prefer the levers.
boostarray of object default: []Signal weights that RE-RANK results. These never filter anyone out: the signals available here have too little coverage to be used as a hard gate, so they only reorder what already matched.
max 20 itemssignalstring requiredThe signal to weight. Read `GET /v1/search/capabilities` for the signals that exist and whether each can be pushed to the index.
max 200 charsweightnumber requiredIts weight. Positive favours the signal, negative penalises it.
rankobjectHow to rank the results. Ranking today is page-local (see `rankScope` on the response), so this reorders the page rather than reaching deeper into the index.
presetstringA named ranking preset.
max 200 charsweightsarray of objectExplicit per-signal weights, as an alternative to a preset.
max 20 itemssignalstring requiredThe signal to weight.
max 200 charsweightnumber requiredIts weight.
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.
403Missing project: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.
404No such project in this accountcodestring 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.