Global search — the ⌘K palette/drill-down endpoint.
Full-text (Postgres websearch_to_tsquery + ts_rank_cd) and trigram typo-tolerant search over dvt objects, grouped by kind. Slice B1 (DVT-1814) covered dashboards only; slice B2 (DVT-1816) adds the synced warehouse catalog's catalog_object (tables/views) and schema (distinct database + schema pairs) kinds. A requested kind this server build doesn't recognize at all returns an empty group rather than an error, so clients can roll out a new kind ahead of server support. catalog_column is deliberately never a top-level kind — a column match always folds into its parent catalog_object result (see matchedIn below) — so requesting it also resolves to an empty group, permanently, not a gap to be filled later.
The catalog_object/schema kinds additionally require the API key's data:query scope (same requirement as GET /v1/connections/{id}/catalog — synced catalog names/comments may be warehouse PII). An API key missing that scope gets an empty group for just those kinds, not a 403 for the whole request; cookie/browser-session and unscoped-key callers are unaffected.
Two modes, selected by which kind parameter is present:
- Palette mode (no kind, optional kinds): returns up to limit top-ranked results per requested kind (default: every supported kind). cursor is not valid in this mode.
- Drill-down mode (kind present): returns one page of up to limit results for that single kind, in keyset order; pass a group's nextCursor back as cursor to continue.
Ranking blends, per kind:
- dashboard: full-text rank over a weighted tsvector (title > description/ brief > tags/keyQuestions > audience), a trigram typo-tolerance bonus against the title, and a bonus for dashboards whose comment thread (not the dashboard itself) matches — which is why a hit can appear even when q doesn't appear in its title/description. Read-visibility matches GET /v1/dashboards exactly (owner, public, ACL-granted, or role-shared in snowflake mode) — a result is never returned for an object the caller cannot read.
- catalog_object: full-text rank over a weighted tsvector (table/view name
its schema+database > its comment), a trigram typo-tolerance bonus against the name, and a bonus when at least one child column matches — a matching column is folded into the table/view's own result rather than ever appearing as its own row; matchedIn carries a "column:<name>" entry per matching column (capped at 5).
- schema: trigram-only (no tsvector) match against the schema name and/or its parent database name.
snippet is HTML in every kind, uniformly: a ts_headline excerpt with matched term(s) wrapped in <b>...</b> for dashboard; for catalog_object / schema it is the object's comment (if the sync captured one) or else its dotted database.schema context path, HTML-escaped server-side — plain text content, no highlight markup of its own, but escaped so a client that treats every snippet as HTML (e.g. sanitizes it) never misinterprets a warehouse comment containing <, >, or & as markup.
Request
- Base URL: http://localhost:8080
- URL: http://localhost:8080/v1/search
- Auth: one of:
- API key in cookie dvt_session
- HTTP bearer
Query parameters
The search text. Empty/missing is rejected with 400. Capped at 200 characters — longer is rejected with 400 (a query that long has no legitimate search use and is a DB-scan amplification vector against the typo-tolerance ranking's word_similarity call).
Comma-separated object kinds for palette mode (top-N per kind). Omit for every kind this server build supports (today: dashboard, catalog_object, schema). Mutually exclusive with kind — when both are present, kind wins. Deduplicated server-side into an ordered set (a repeated kind issues one query, not one per occurrence); naming more distinct kinds than this server build supports is rejected with 400 rather than silently narrowed.
A single object kind for drill-down mode. Required alongside cursor — a cursor is only meaningful within one kind's keyset order.
Per-kind page size. Default 8, clamped (not rejected) to [1, 25] — an out-of-range value is silently clamped rather than a 400. Only a non-integer limit is rejected with 400.
Opaque keyset cursor from a prior single-kind response's group.nextCursor. Requires exactly one requested kind (via kind, or kinds narrowed to one value) — otherwise rejected with 400. A malformed cursor is rejected with 400.
Response
Search results grouped by kind.
Example response
{
"data": {
"groups": [
{
"kind": "dashboard",
"results": [
{
"kind": "dashboard",
"matchedIn": [
"title"
],
"link": {
"kind": "dashboard"
}
}
]
}
]
}
}Changes
No recorded changes to this operation across all 1 revision of this API.