Search
Full-text search, result export, index management, saved searches, and search profiles.
Search
Overview
The Search API provides endpoints for querying the search index, exporting results, and managing the index itself. The portal API extends this with saved searches and search profiles for personalized search experiences.
Integration Developer Guide
Before diving into the endpoint reference, here are the key concepts you need to know to use search effectively in an integration:
Search Spans All Content Definitions
A search query without filters returns results across all content definitions simultaneously — assets, committee records, meeting records, and everything else in the system. In most integration scenarios, you will want to filter to a specific content type:
{ "fieldName": "contentDefinitionId", "value": "<your-content-def-id>" }Field Names Come From the Content Definition Designer
The fieldName values used in filters and sortFields must exactly match the property name of the field as configured in the Site Manager content definition designer. The property name is set when creating or editing a field — it becomes the field's permanent key in the search index.
Use GET /admin/search/mappingFieldNames to retrieve all currently indexed field names.
Start With Filters and Sort Fields
For the majority of integration use cases — syncing records, looking up items by external ID, listing content by type — the two most important SearchModel parameters are:
filters— narrow results to the records you care aboutsortFields— control ordering for consistent pagination
All other parameters (distinct values, AI-based search, deep search) are advanced options for specific use cases.
Pagination — Keyset Cursor, Not Numeric Offset
The nextPageOffset value returned in each search response is a keyset cursor (a sort-key array used as a search_after token), not a page number or record count. Pass it verbatim as pageOffset in the next request. Do not construct offsets manually.
The practical pagination loop is:
let pageOffset = null;
while (true) {
const result = await search(filters, pageOffset);
for (const item of result.items) process(item);
pageOffset = result.nextPageOffset ?? null;
if (!pageOffset || result.items.length < PAGE_SIZE) break;
}The totalItemCount reported on the first page reflects the index state at query time and can diverge from actual items fetched if documents are added or removed during a paginated sweep.
Search Index Consistency
The search index is eventually consistent. Assets created, moved, renamed, or deleted via the API are durable in the primary store immediately, but may not appear in (or disappear from) paginated search results for several seconds to minutes afterward.
Practical consequences:
- Verify a newly created folder or asset with a direct lookup (
GET /admin/asset/{id}or a targetedurl-filter search) rather than a full index sweep — direct lookups hit the primary store and are immediately consistent. - A bulk paginated scan taken shortly after a batch-create may silently miss some new items. This is not a bug in the pagination cursor; it is index ingest lag.
- Deleted assets may continue to appear in search results briefly after deletion (404 on fetch confirms the true state).
Equals Operator on the url Field — Prefix Match, Not Exact
Equals Operator on the url Field — Prefix Match, Not ExactFiltering on { fieldName: "url", operator: "Equals", values: "Content/Photo/Events/" } returns all assets whose URL starts with that string, not just the folder asset itself. This means a url-Equals search for a folder path will also return every file and sub-folder beneath it.
To look up a specific folder by path, navigate the system tree using parentId instead:
// ✗ Returns the folder AND everything inside it
{ fieldName: "url", operator: "Equals", values: "Content/Photo/Events/" }
// ✓ Returns only direct children of a known parent
{ fieldName: "parentId", operator: "Equals", values: "<parent-folder-id>" }filter_binder — AND vs OR
filter_binder — AND vs ORBy default (null or omitted), all filters in a request are AND-combined. Setting filter_binder: 1 switches the combination to OR, so any filter match returns the record. This is intentional for cases like "display name starts with X OR contains X", but applying it accidentally to an assetType filter alongside other filters will return every record that matches any single predicate — often the entire dataset.
// AND (default) — asset must match ALL filters
{ filters: [assetTypeFilter, parentIdFilter] }
// OR — asset matches if it satisfies ANY filter (use deliberately)
{ filters: [prefixFilter, containsFilter], filter_binder: 1 }Use Search for Bulk Lookups
Rather than fetching records one at a time via GET /admin/content/{defId}/{id}, use a single POST /admin/search call with a filter to retrieve many records at once. This is significantly more efficient for sync operations. See Data Synchronization for the recommended pattern.
Base Routes
| API | Route Prefix | Description |
|---|---|---|
| Admin | /admin/search | Full search, export, index management |
| Portal | /portal/search | Search queries, saved searches, search profiles, export |
Searching
Full Search (POST)
POST /admin/search
POST /portal/search
Request body: SearchModel { searchQuery, filters, sortFields, pageSize, pageOffset, ... }
Query: ?includeInternalFieldsInResults=false
Response: ListResultModel<SearchResultModel> { items, totalItemCount }
The POST-based search accepts a full SearchModel in the request body with complete control over filters, sorting, pagination, and field selection.
Simple Search (GET - Admin Only)
GET /admin/search?searchQuery=...&pageSize=...&pageOffset=...&sortField=...&sortOrder=...
Query string parameters override any values in the optional body SearchModel.
Additional query parameters are extracted as filters.
Response: ListResultModel<SearchResultModel>
Get Document by ID
GET /admin/search/{id}
GET /portal/search/{id}
Query: ?includeInternalFieldsInResults=false
Response: SearchResultModel
Retrieves a single document from the search index. In the Portal API, only Asset and Live Channel documents are accessible; other content types return 404.
Exporting
POST /admin/search/export
POST /portal/search/export
Request body: SearchModel
Query: ?background=false
Response: Excel file (XLSX) download, or 204 if no results
Exports search results as an Excel spreadsheet. If no sort fields are specified, results default to sorting by masterId.
When background=true, the export is queued as a batch job and the response returns immediately with 204. The completed file is delivered via email.
Index Management (Admin Only)
Get Field Names
GET /admin/search/mappingFieldNames
Response: string[] (list of indexed field names)
Returns all field names available in the search index schema for use in filters, sorts, and field selection.
Rebuild Index
POST /admin/search/rebuild-index/{type}
Triggers a search index rebuild. Supported types:
| Type | Description |
|---|---|
$ALL$ | Rebuild index from all data sources |
$ALL_CLEAR$ | Clear the index completely, then rebuild from all sources |
$MONGO$ | Rebuild from MongoDB source only |
$DYNAMO$ | Rebuild from DynamoDB source only |
Warning: $ALL_CLEAR$ makes search temporarily unavailable during the rebuild.
Saved Searches (Portal)
Saved searches persist search criteria for later re-execution.
| Endpoint | Method | Description |
|---|---|---|
/portal/savedsearch | POST | Create a new saved search |
/portal/savedsearch | GET | List all saved searches for the current user |
/portal/savedsearch/{id} | GET | Get a saved search by ID |
/portal/savedsearch/{id} | PATCH | Partially update a saved search (name, sequence, featured, bookmarked) |
/portal/savedsearch/{id} | PUT | Fully replace a saved search |
/portal/savedsearch/{id} | DELETE | Delete a saved search |
Executing Saved Searches
GET /portal/search-saved/{id}?returnedFieldNames=...
Executes the saved search by ID
POST /portal/search-saved
Request body: SavedSearchModel
Executes an ad-hoc saved search model without persisting changes
Both return ListResultModel<SearchResultModel>.
Search Profiles (Portal)
Search profiles store default search configurations such as filters, display columns, and sort preferences.
| Endpoint | Method | Description |
|---|---|---|
/portal/searchprofile | POST | Create a new search profile |
/portal/searchprofile | GET | List all search profiles for the current user |
/portal/searchprofile/{id} | GET | Get a search profile by ID |
/portal/searchprofile/{id} | PUT | Replace a search profile |
/portal/searchprofile/{id} | DELETE | Delete a search profile |
Common Error Responses
| Status Code | Description |
|---|---|
| 400 | Bad Request - Missing or invalid search parameters |
| 401 | Unauthorized - Missing or invalid Bearer token |
| 404 | Not Found - Document or saved search not found |
Updated about 1 month ago
