Global Search API
Global search finds work items, knowledge and inventory across nine entity types in a single query — the data source of the command palette (Ctrl+K) and the search page. It is an overview endpoint: counters per type plus a short preview. Filtered, paginated search runs through the per-entity list endpoints.
The split matters for your own clients: this endpoint answers "where are there hits at all, and how many" — it knows neither pages nor filters nor sorting. As soon as you need a complete, filtered result list, the entity list endpoint is the right address (/api/tickets?q=…, /api/incidents?q=…, each using the FilterSpec query syntax). The application search page is exactly that: a wrapper around those nine lists.
Endpoint
| Method | Endpoint | Description |
|---|---|---|
GET | /api/search?q= | Overview across nine entity types (counters + top-3 preview). Logged-in users only; API keys cannot reach this route. |
Query Parameters
| Parameter | Type | Description |
|---|---|---|
q | String, 2–200 characters, required | Search term (case-insensitive). Trimmed before the length check: missing, shorter than two characters or whitespace only returns 400 VALIDATION_ERROR with path ["q"]. |
There are no further parameters: the preview is always limited to three rows per entity type.
Searchable Entities (9)
| Entity | Searched Fields | Permission |
|---|---|---|
tickets | ticketNumber, title, description, customer.name | tickets.viewAll ‖ viewOwn |
incidents | number, title, description, businessImpact | incidents.viewAll ‖ viewOwn |
problems | problemNumber, title, description | problems.viewAll ‖ viewOwn |
changes | number, title, description | changes.viewAll ‖ viewPendingApprovals ‖ viewOwn |
articles | title, summary, content, tag names (full text) | always searchable — hits follow the article visibility and status |
assets | assetTag, name, serialNumber, description | assets.viewAll ‖ viewOwn |
contracts | contractNumber, name, vendor, publisher, description | contracts.viewAll ‖ viewOwn |
licenses | name, description, serialNumber, product name, publisher | licenses.viewAll ‖ viewOwn |
elibrary | title, publisher | elibrary.view (archived documents stay hidden) |
One source for search and list: Both the searched fields and the row-level visibility come from the FilterSpec schema of the entity — the same schema the list endpoint uses. The overview counter therefore shows exactly as many hits as the user finds again in the entity tab: permissions such as viewOwn apply identically in both cases.
Example query
// Global search across all entities
const response = await fetch('/api/search?q=laptop', {
credentials: 'include'
});
const results = await response.json();
// {
// "typeCounts": {
// "tickets": 15, "incidents": 0, "problems": 0, "changes": 0,
// "articles": 3, "assets": 8,
// "contracts": 0, "licenses": 0, "elibrary": 0
// },
// "preview": {
// "tickets": [
// {
// "id": "ticket-uuid",
// "entityType": "tickets",
// "number": "TKT-000123",
// "title": "Laptop won't start",
// "status": "IN_PROGRESS",
// "priority": "HIGH",
// "category": "Hardware",
// "customerName": "John Doe",
// "assigneeName": "Jane Smith",
// "updatedAt": "2026-01-28T10:00:00Z"
// }
// ],
// "assets": [
// {
// "id": "asset-uuid",
// "entityType": "assets",
// "number": "00042",
// "title": "Dell XPS 15 Laptop",
// "status": "DEPLOYED",
// "assetTypeName": "Notebook",
// "category": "Hardware",
// "locationName": "Erdgeschoss",
// "assigneeName": "John Doe",
// "updatedAt": "2026-01-28T09:12:00Z"
// }
// ]
// },
// "totalResults": 26
// }
typeCounts— always carries all nine keys; a type without read permission reads 0.preview— only types WITH hits, at most three rows each, ordered by last change.status,priority,changeType— as the enum values of the respective entity in uppercase, identical to the list endpoints.- One field per term:
assetTypeName(asset type, always set for assets),changeType(change type),vendor(contracts) andpublisher(licenses, documents).
Behavior & performance
- Concurrent execution: the sub-queries run in two batches of five so the connection pool is not exhausted
- Error isolation: if one sub-query fails it returns 0 hits — the remaining entity types still answer
- Full text for the knowledge base: PostgreSQL tsvector (german configuration, GIN index) with stemming and umlaut handling; the other eight types compare substrings case-insensitively
- Soft-delete filter: deleted rows are excluded automatically
Related pages
- API Overview — the FilterSpec query syntax of the list endpoints that serve filtered search
- Permissions & RBAC — the read permissions and visibility rules that decide which rows can be a hit
- Knowledge Base — visibility, status and tags of the searchable articles
- Saved Views — stored list cuts including sharing and result counters
- Settings — system settings, numbering, integrations