> For the complete documentation index, see [llms.txt](https://docs.truedat.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.truedat.io/v8.12/api-integrations/link-manager-apis/search.md).

# Search

## Get filter values

> Returns available facet values (aggregations) for relation search UIs, scoped to the caller's permissions. The endpoint computes aggregations over the indexed relations that match the supplied criteria, without returning the documents themselves.\
> \
> \*\*Permissions:\*\* The Elasticsearch query evaluates visibility permissions on \*\*both sides\*\* of each relation (source and target). The exact set of permissions depends on the resource type of each side and on the \`linkable\` flag:\
> \- \*\*\`business\_concept\`\*\* – With \`linkable: false\`, the caller must hold at least one of the business concept view permissions on the concept's domains (own domain plus shared domains): \*\*'View published business concepts'\*\*, \*\*'View draft business concepts'\*\*, \*\*'View deprecated business concepts'\*\*, \*\*'View versioned business concepts'\*\*, \*\*'View rejected business concepts'\*\*, or \*\*'View business concepts pending approval'\*\*. Confidential concepts additionally require \*\*'Manage confidential business concepts'\*\*. With \`linkable: true\`, the filter is tightened to the linkable scope.\
> \- \*\*\`data\_structure\`\*\* – With \`linkable: false\`, the caller must hold \*\*'View structures'\*\* and \*\*'Manage confidential structures'\*\* on the structure's domains. With \`linkable: true\`, the caller must hold \*\*'Manage confidential structures'\*\* and \*\*'Link structures'\*\* instead; the view permission alone is no longer sufficient.\
> \- \*\*\`quality\_control\`\*\* – With \`linkable: false\`, the caller must hold \*\*'View quality controls'\*\*. With \`linkable: true\`, the caller must hold \*\*'Link quality controls to concepts'\*\* and \*\*'Link quality controls to structures'\*\* instead; the view permission alone is no longer sufficient.\
> \- \*\*\`ingest\`\*\* – Ingest resources are \*\*not\*\* part of the permissions filter on this endpoint.\
> \
> \*\*Request body (all fields optional):\*\*\
> \- \`query\` (string) – Free-text search across source and target names.\
> \- \`filters\` (object) – Facet filters as \`{ 'field': \['value', ...] }\`. Use \`filters.status\` to restrict the aggregation scope to a specific relation status.\
> \- \`must\` / \`must\_not\` (object) – Mandatory or exclusion filters.\
> \- \`with\` / \`without\` (string or array) – Require or exclude documents having certain fields.\
> \- \`minimum\_should\_match\` (integer) – Minimum number of \`should\` clauses that must match.\
> \- \`linkable\` (boolean) – When \`true\`, computes the aggregation scope only over relations the caller can link.\
> \
> \*\*Default filters:\*\*\
> \- No default status filter is applied. Omitting status filters includes all statuses in the aggregation scope, subject to permissions and soft-delete exclusion.\
> \- Soft-deleted relations are excluded by default.\
> \
> \*\*Response:\*\*\
> \- The response lists the distinct values the caller can still select for each facet given the current search context. Typical facets include \`status\`, \`origin\`, \`tag\_type\`, \`taxonomy\`, \`source\_taxonomy\`, \`target\_taxonomy\`, \`deleted\`, and \`disabled\`.\
> \- When the aggregation fails (for example, because of an index error), the endpoint returns \`200 OK\` with \`data: {}\` instead of an error.<br>

```json
{"openapi":"3.0.0","info":{"title":"td-lm","version":"Truedat 8.11.1"},"paths":{"/api/relations/filters":{"post":{"description":"Returns available facet values (aggregations) for relation search UIs, scoped to the caller's permissions. The endpoint computes aggregations over the indexed relations that match the supplied criteria, without returning the documents themselves.\n\n**Permissions:** The Elasticsearch query evaluates visibility permissions on **both sides** of each relation (source and target). The exact set of permissions depends on the resource type of each side and on the `linkable` flag:\n- **`business_concept`** – With `linkable: false`, the caller must hold at least one of the business concept view permissions on the concept's domains (own domain plus shared domains): **'View published business concepts'**, **'View draft business concepts'**, **'View deprecated business concepts'**, **'View versioned business concepts'**, **'View rejected business concepts'**, or **'View business concepts pending approval'**. Confidential concepts additionally require **'Manage confidential business concepts'**. With `linkable: true`, the filter is tightened to the linkable scope.\n- **`data_structure`** – With `linkable: false`, the caller must hold **'View structures'** and **'Manage confidential structures'** on the structure's domains. With `linkable: true`, the caller must hold **'Manage confidential structures'** and **'Link structures'** instead; the view permission alone is no longer sufficient.\n- **`quality_control`** – With `linkable: false`, the caller must hold **'View quality controls'**. With `linkable: true`, the caller must hold **'Link quality controls to concepts'** and **'Link quality controls to structures'** instead; the view permission alone is no longer sufficient.\n- **`ingest`** – Ingest resources are **not** part of the permissions filter on this endpoint.\n\n**Request body (all fields optional):**\n- `query` (string) – Free-text search across source and target names.\n- `filters` (object) – Facet filters as `{ 'field': ['value', ...] }`. Use `filters.status` to restrict the aggregation scope to a specific relation status.\n- `must` / `must_not` (object) – Mandatory or exclusion filters.\n- `with` / `without` (string or array) – Require or exclude documents having certain fields.\n- `minimum_should_match` (integer) – Minimum number of `should` clauses that must match.\n- `linkable` (boolean) – When `true`, computes the aggregation scope only over relations the caller can link.\n\n**Default filters:**\n- No default status filter is applied. Omitting status filters includes all statuses in the aggregation scope, subject to permissions and soft-delete exclusion.\n- Soft-deleted relations are excluded by default.\n\n**Response:**\n- The response lists the distinct values the caller can still select for each facet given the current search context. Typical facets include `status`, `origin`, `tag_type`, `taxonomy`, `source_taxonomy`, `target_taxonomy`, `deleted`, and `disabled`.\n- When the aggregation fails (for example, because of an index error), the endpoint returns `200 OK` with `data: {}` instead of an error.\n","operationId":"TdLmWeb.SearchController.filters","parameters":[],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FiltersRequest"}}},"description":"Filter request","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FiltersResponse"}}},"description":"OK"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TdLmUnauthorizedResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TdLmInternalServerErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Get filter values","tags":["Search"]}}},"components":{"schemas":{"FiltersRequest":{"additionalProperties":false,"description":"Search parameters used to compute permission-aware filter-value aggregations for relations.","properties":{"filters":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"description":"Filters to apply to the relation search query.","type":"object"},"linkable":{"description":"If true, filters values are computed for relations linkable by the current user.","type":"boolean"},"minimum_should_match":{"description":"Minimum number of optional should clauses that must match.","minimum":1,"type":"integer"},"must":{"additionalProperties":true,"description":"Mandatory filters to apply to the relation search query.","properties":{"source_type":{"description":"Source resource type.","type":"string"},"target_type":{"description":"Target resource type.","type":"string"}},"type":"object"},"must_not":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"description":"Negative filters to exclude results from the relation search query.","type":"object"},"query":{"description":"Search query string used to narrow the filter-value results.","type":"string"},"status":{"description":"Filter by status values. If no status is supplied in relation searches, the default behavior is to return approved relations only.","items":{"type":"string"},"type":"array"},"with":{"description":"Fields that must exist in the result documents.","oneOf":[{"items":{"type":"string"},"type":"array"},{"type":"string"}]},"without":{"description":"Fields that must not exist in the result documents.","oneOf":[{"items":{"type":"string"},"type":"array"},{"type":"string"}]}},"title":"FiltersRequest","type":"object"},"FiltersResponse":{"additionalProperties":false,"properties":{"data":{"additionalProperties":{"$ref":"#/components/schemas/FilterValue"},"description":"Filter keys with their possible values","type":"object"}},"required":["data"],"title":"FiltersResponse","type":"object"},"FilterValue":{"additionalProperties":true,"properties":{"values":{"description":"List of possible values for this filter","items":{"type":"string"},"type":"array"}},"required":["values"],"title":"FilterValue","type":"object"},"TdLmUnauthorizedResponse":{"properties":{"errors":{"properties":{"detail":{"type":"string"}},"type":"object"}},"title":"TdLmUnauthorizedResponse","type":"object"},"TdLmInternalServerErrorResponse":{"properties":{"errors":{"properties":{"detail":{"type":"string"}},"type":"object"}},"title":"TdLmInternalServerErrorResponse","type":"object"}}}}
```

## Search relations

> Full-text and faceted search over relations using the Elasticsearch index. The query runs against the indexed relation documents and supports pagination, sorting, scrolling, and rich filters.\
> \
> \*\*Permissions:\*\* The Elasticsearch query evaluates visibility permissions on \*\*both sides\*\* of each relation (source and target). The exact set of permissions depends on the resource type of each side and on the \`linkable\` flag:\
> \- \*\*\`business\_concept\`\*\* – With \`linkable: false\`, the caller must hold at least one of the business concept view permissions on the concept's domains (own domain plus shared domains): \*\*'View published business concepts'\*\*, \*\*'View draft business concepts'\*\*, \*\*'View deprecated business concepts'\*\*, \*\*'View versioned business concepts'\*\*, \*\*'View rejected business concepts'\*\*, or \*\*'View business concepts pending approval'\*\*. Confidential concepts additionally require \*\*'Manage confidential business concepts'\*\*. With \`linkable: true\`, the filter is tightened to the linkable scope.\
> \- \*\*\`data\_structure\`\*\* – With \`linkable: false\`, the caller must hold \*\*'View structures'\*\* and \*\*'Manage confidential structures'\*\* on the structure's domains. With \`linkable: true\`, the caller must hold \*\*'Manage confidential structures'\*\* and \*\*'Link structures'\*\* instead; the view permission alone is no longer sufficient.\
> \- \*\*\`quality\_control\`\*\* – With \`linkable: false\`, the caller must hold \*\*'View quality controls'\*\*. With \`linkable: true\`, the caller must hold \*\*'Link quality controls to concepts'\*\* and \*\*'Link quality controls to structures'\*\* instead; the view permission alone is no longer sufficient.\
> \- \*\*\`ingest\`\*\* – Ingest resources are \*\*not\*\* part of the permissions filter on this endpoint. Relations whose source or target is an ingest are not returned by this indexed search.\
> \
> \*\*Request body (all fields optional):\*\*\
> \- \`query\` (string) – Free-text search across source and target names.\
> \- \`filters\` (object) – Facet filters as \`{ 'field': \['value', ...] }\`. Use \`filters.status\` to restrict by relation status (for example, \`%{'status' => \['approved']}\`).\
> \- \`must\` / \`must\_not\` (object) – Mandatory or exclusion filters, for example \`source\_type\` or \`target\_type\`.\
> \- \`with\` / \`without\` (string or array) – Require or exclude documents having certain fields.\
> \- \`page\` (integer, default \`0\`) – Page number.\
> \- \`size\` (integer, default \`20\`) – Page size.\
> \- \`sort\` (array or map, default \`\['\_score', 'updated\_at']\`) – Sort order. For an active non-default request language, locale-aware name fields (\`source\_name\`, \`target\_name\`) are automatically adjusted.\
> \- \`scroll\` / \`scroll\_id\` (string) – Enable or continue a cursor-based scroll session for large result sets.\
> \- \`linkable\` (boolean) – When \`true\`, restricts results to relations the caller can link, not just view.\
> \
> \*\*Default filters:\*\*\
> \- No default status filter is applied. Omitting \`filters.status\` returns relations of any status, subject to permission and soft-delete rules.\
> \- Soft-deleted relations are excluded by default (\`without: 'deleted\_at'\`). Pass \`document: 'all'\` to include them.\
> \
> \*\*Response:\*\*\
> \- \`data\` – Array of indexed relation documents with enriched fields (\`source\_name\`, \`target\_name\`, \`domain\_ids\`, \`status\`, \`origin\`, \`source\_data\`, \`target\_data\`, etc.).\
> \- \`scroll\_id\` – Present when scroll mode is active. Pass it back with the next request to fetch the following page.\
> \- Header \`x-total-count\` – Total number of matching documents. May exceed the \`data\` array length when paginated.\
> \
> When \`scroll\_id\` is supplied, only \`scroll\` and \`scroll\_id\` are honored; all other parameters are ignored, matching Elasticsearch scroll semantics.<br>

```json
{"openapi":"3.0.0","info":{"title":"td-lm","version":"Truedat 8.11.1"},"paths":{"/api/relations/index_search":{"post":{"description":"Full-text and faceted search over relations using the Elasticsearch index. The query runs against the indexed relation documents and supports pagination, sorting, scrolling, and rich filters.\n\n**Permissions:** The Elasticsearch query evaluates visibility permissions on **both sides** of each relation (source and target). The exact set of permissions depends on the resource type of each side and on the `linkable` flag:\n- **`business_concept`** – With `linkable: false`, the caller must hold at least one of the business concept view permissions on the concept's domains (own domain plus shared domains): **'View published business concepts'**, **'View draft business concepts'**, **'View deprecated business concepts'**, **'View versioned business concepts'**, **'View rejected business concepts'**, or **'View business concepts pending approval'**. Confidential concepts additionally require **'Manage confidential business concepts'**. With `linkable: true`, the filter is tightened to the linkable scope.\n- **`data_structure`** – With `linkable: false`, the caller must hold **'View structures'** and **'Manage confidential structures'** on the structure's domains. With `linkable: true`, the caller must hold **'Manage confidential structures'** and **'Link structures'** instead; the view permission alone is no longer sufficient.\n- **`quality_control`** – With `linkable: false`, the caller must hold **'View quality controls'**. With `linkable: true`, the caller must hold **'Link quality controls to concepts'** and **'Link quality controls to structures'** instead; the view permission alone is no longer sufficient.\n- **`ingest`** – Ingest resources are **not** part of the permissions filter on this endpoint. Relations whose source or target is an ingest are not returned by this indexed search.\n\n**Request body (all fields optional):**\n- `query` (string) – Free-text search across source and target names.\n- `filters` (object) – Facet filters as `{ 'field': ['value', ...] }`. Use `filters.status` to restrict by relation status (for example, `%{'status' => ['approved']}`).\n- `must` / `must_not` (object) – Mandatory or exclusion filters, for example `source_type` or `target_type`.\n- `with` / `without` (string or array) – Require or exclude documents having certain fields.\n- `page` (integer, default `0`) – Page number.\n- `size` (integer, default `20`) – Page size.\n- `sort` (array or map, default `['_score', 'updated_at']`) – Sort order. For an active non-default request language, locale-aware name fields (`source_name`, `target_name`) are automatically adjusted.\n- `scroll` / `scroll_id` (string) – Enable or continue a cursor-based scroll session for large result sets.\n- `linkable` (boolean) – When `true`, restricts results to relations the caller can link, not just view.\n\n**Default filters:**\n- No default status filter is applied. Omitting `filters.status` returns relations of any status, subject to permission and soft-delete rules.\n- Soft-deleted relations are excluded by default (`without: 'deleted_at'`). Pass `document: 'all'` to include them.\n\n**Response:**\n- `data` – Array of indexed relation documents with enriched fields (`source_name`, `target_name`, `domain_ids`, `status`, `origin`, `source_data`, `target_data`, etc.).\n- `scroll_id` – Present when scroll mode is active. Pass it back with the next request to fetch the following page.\n- Header `x-total-count` – Total number of matching documents. May exceed the `data` array length when paginated.\n\nWhen `scroll_id` is supplied, only `scroll` and `scroll_id` are honored; all other parameters are ignored, matching Elasticsearch scroll semantics.\n","operationId":"TdLmWeb.SearchController.create","parameters":[],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchRequest"}}},"description":"Search parameters","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchResponse"}}},"description":"OK","headers":{}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TdLmUnauthorizedResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TdLmInternalServerErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Search relations","tags":["Search"]}}},"components":{"schemas":{"SearchRequest":{"additionalProperties":false,"description":"Search parameters for relations","properties":{"filters":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"description":"Filters to apply (e.g., status, etc.)","type":"object"},"linkable":{"description":"If true, filters results to those linkable by the user. If omitted, the results are not restricted to linkable items.","type":"boolean"},"minimum_should_match":{"description":"Minimum number of optional should clauses that must match","minimum":1,"type":"integer"},"must":{"additionalProperties":true,"description":"Mandatory filters (e.g., source_type, target_type)","properties":{"source_type":{"description":"Source resource type","type":"string"},"target_type":{"description":"Target resource type","type":"string"}},"type":"object"},"must_not":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"description":"Negative filters to exclude results","type":"object"},"page":{"description":"Starting offset for pagination. If omitted, the search starts at 0.","minimum":0,"type":"integer"},"query":{"description":"Search query string","type":"string"},"scroll":{"description":"Scroll time (e.g., '1m') to enable scrolling. If omitted, the search uses the normal paging flow.","type":"string"},"scroll_id":{"description":"Scroll ID for retrieving next page (when scrolling)","type":"string"},"size":{"description":"Number of results per page. If omitted, the default is 20.","maximum":100,"minimum":1,"type":"integer"},"sort":{"description":"Sorting criteria, either a list of sort fields or a field-order map","oneOf":[{"items":{"type":"string"},"type":"array"},{"additionalProperties":{"enum":["asc","desc"],"type":"string"},"type":"object"}]},"with":{"description":"Fields that must exist in the result documents","oneOf":[{"items":{"type":"string"},"type":"array"},{"type":"string"}]},"without":{"description":"Fields that must not exist in the result documents","oneOf":[{"items":{"type":"string"},"type":"array"},{"type":"string"}]}},"title":"SearchRequest","type":"object"},"SearchResponse":{"additionalProperties":false,"properties":{"data":{"description":"List of matching relations","items":{"$ref":"#/components/schemas/RelationSearchResult"},"type":"array"},"scroll_id":{"description":"Scroll ID for retrieving next page (if scroll requested)","nullable":true,"type":"string"}},"required":["data"],"title":"SearchResponse","type":"object"},"RelationSearchResult":{"additionalProperties":true,"description":"A relation as returned by search, including additional fields","properties":{"deleted":{"description":"Soft deletion flag","nullable":true,"type":"boolean"},"deleted_at":{"description":"Deletion timestamp","format":"date-time","nullable":true,"type":"string"},"disabled":{"description":"Disabled flag","nullable":true,"type":"boolean"},"disabled_at":{"description":"Disabled timestamp","format":"date-time","nullable":true,"type":"string"},"disabled_reason":{"description":"Reason for disabling","nullable":true,"type":"string"},"domain_ids":{"description":"All domain IDs involved in the relation","items":{"type":"integer"},"type":"array"},"id":{"description":"Relation ID","type":"integer"},"inserted_at":{"description":"Creation timestamp","format":"date-time","nullable":true,"type":"string"},"ngram_source_name":{"description":"Ngram field for source name","nullable":true,"type":"string"},"ngram_source_name_es":{"description":"Ngram field for source name (Spanish)","nullable":true,"type":"string"},"ngram_target_name":{"description":"Ngram field for target name","nullable":true,"type":"string"},"ngram_target_name_es":{"description":"Ngram field for target name (Spanish)","nullable":true,"type":"string"},"origin":{"description":"Origin of the relation (e.g., 'suggested')","nullable":true,"type":"string"},"source_data":{"additionalProperties":true,"description":"Full source resource data","nullable":true,"type":"object"},"source_domain_ids":{"description":"Domain IDs of the source resource","items":{"type":"integer"},"type":"array"},"source_id":{"description":"Source resource ID","type":"integer"},"source_name":{"description":"Name of the source resource","type":"string"},"source_name_es":{"description":"Source name in Spanish","nullable":true,"type":"string"},"source_type":{"description":"Type of the source resource","type":"string"},"status":{"description":"Status of the relation (pending, approved, rejected)","nullable":true,"type":"string"},"tag_type":{"description":"Tag type derived from tag","nullable":true,"type":"string"},"target_data":{"additionalProperties":true,"description":"Full target resource data","nullable":true,"type":"object"},"target_domain_ids":{"description":"Domain IDs of the target resource","items":{"type":"integer"},"type":"array"},"target_id":{"description":"Target resource ID","type":"integer"},"target_name":{"description":"Name of the target resource","type":"string"},"target_name_es":{"description":"Target name in Spanish","nullable":true,"type":"string"},"target_type":{"description":"Type of the target resource","type":"string"},"updated_at":{"description":"Last update timestamp","format":"date-time","type":"string"}},"required":["id","domain_ids","source_domain_ids","source_id","source_name","source_type","target_domain_ids","target_id","target_name","target_type","updated_at"],"title":"RelationSearchResult","type":"object"},"TdLmUnauthorizedResponse":{"properties":{"errors":{"properties":{"detail":{"type":"string"}},"type":"object"}},"title":"TdLmUnauthorizedResponse","type":"object"},"TdLmInternalServerErrorResponse":{"properties":{"errors":{"properties":{"detail":{"type":"string"}},"type":"object"}},"title":"TdLmInternalServerErrorResponse","type":"object"}}}}
```

## Reindex all relations

> Triggers a full asynchronous reindexing of all relations into the search index.\
> \
> Requires administrative privileges (\*\*administrator or service account\*\*).\
> \
> Does not return reindex progress; relations become searchable as the background job completes.<br>

```json
{"openapi":"3.0.0","info":{"title":"td-lm","version":"Truedat 8.11.1"},"paths":{"/api/relations/index_search/reindex_all":{"get":{"description":"Triggers a full asynchronous reindexing of all relations into the search index.\n\nRequires administrative privileges (**administrator or service account**).\n\nDoes not return reindex progress; relations become searchable as the background job completes.\n","operationId":"TdLmWeb.SearchController.reindex_all","parameters":[],"responses":{"202":{"description":"Reindexing accepted"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TdLmUnauthorizedResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TdLmForbiddenResponse"}}},"description":"Forbidden"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TdLmInternalServerErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Reindex all relations","tags":["Search"]}}},"components":{"schemas":{"TdLmUnauthorizedResponse":{"properties":{"errors":{"properties":{"detail":{"type":"string"}},"type":"object"}},"title":"TdLmUnauthorizedResponse","type":"object"},"TdLmForbiddenResponse":{"properties":{"errors":{"properties":{"detail":{"type":"string"}},"type":"object"}},"title":"TdLmForbiddenResponse","type":"object"},"TdLmInternalServerErrorResponse":{"properties":{"errors":{"properties":{"detail":{"type":"string"}},"type":"object"}},"title":"TdLmInternalServerErrorResponse","type":"object"}}}}
```
