Search namespace
Reference for federated keyword suggestions across companies, markets, taxonomy terms, blog posts, and tags.
A
JUse board.search for the search-dropdown typeahead. It returns one interleaved, server-ranked list of companies, markets, taxonomy terms, blog posts, and tags. These reads are public. Routing is the caller's decision — the API never returns an href.
Shared behavior
Every method returns the Board API wire body unchanged and throws BoardApiError for a non-2xx response. The final FetchOptions argument passes abort signals, headers, and framework cache directives through to fetch.
Order is server-ranked. Render the list as returned; do not re-sort or re-filter client-side except to hide kinds your UI does not handle.
board.search.suggest
Suggest companies, markets, categories, skills, blog posts, and tags for a keyword.
1234board.search.suggest(query?: SearchSuggestQuery,options?: FetchOptions,): Promise<SuggestResult>
| Field | Type | Behavior |
|---|---|---|
q | string | Keyword matched against company names, market names, taxonomy terms, blog posts, and tags. Queries under two characters return an empty items array. |
limit | number | Max interleaved suggestions after type filtering (1–25; default 25). |
types | ('company' | 'category' | 'skill' | 'market' | 'post' | 'tag')[] | Include only these kinds. Omit to return every kind. Serializes as repeated query keys. |
limit applies after types. { types: ['skill'], limit: 10 } returns up to ten skills — not ten items drawn from a mixed pool that happens to include skills.
12345678910111213141516171819const { items, query } = await board.search.suggest({q: 'acme',limit: 10,types: ['company', 'skill'],});for (const item of items) {if (item.type === 'company') {console.log(item.name, item.slug, item.jobCount);} else if (item.type === 'market') {console.log(item.name, item.slug, item.companyCount);} else if (item.type === 'post') {console.log(item.title, item.slug);} else if (item.type === 'tag') {console.log(item.name, item.slug);} else {console.log(item.termType, item.displayName, item.canonicalSlug);}}
Result shape
123456789101112type SuggestResult = {object: 'suggest_result';query: string;items: SuggestionItem[];};type SuggestionItem =| CompanySuggestion| MarketSuggestion| TermSuggestion| PostSuggestion| TagSuggestion;
| Kind | Discriminator | Useful fields |
|---|---|---|
| Company | type: 'company' | id, slug, name, logoUrl, jobCount |
| Market | type: 'market' | id, slug, name, companyCount |
| Term | type: 'term' | termType: 'category' | 'skill', sourceSlug, canonicalSlug, displayName |
| Post | type: 'post' | id, slug, title |
| Tag | type: 'tag' | id, slug, name |
Use canonicalSlug for URL paths and sourceSlug for job-list filters. Company slug is the public company URL identity and the value to pass as companySlug on board.jobs.list.
A missing or private board returns 404.
Routing is application-side
The same CompanySuggestion means two different things:
| Scope | Selecting a company means |
|---|---|
| companies | navigate to /companies/<slug> |
| jobs | apply companySlug as a filter on the listing |
The endpoint does not know which scope the user is searching in, so it cannot resolve a destination. Use suggestionPath from @cavuno/board/paths:
123456789101112import { suggestionPath } from '@cavuno/board/paths';const path = suggestionPath(item, {scope: 'jobs',location: activePlaceSlug,});if (path === null && item.type === 'company') {// apply companySlug filter — do not invent /jobs/companies/<slug>} else if (path) {navigate(path);}
Related methods: board.taxonomy.places.list for location autocomplete, board.jobs.list for applying filters, and the headless controller at @cavuno/board/suggest.