> ## Documentation Index
> Fetch the complete documentation index at: https://developers.telnyx.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Search

> Query a collection's documents and get back ranked, source-attributed chunks.

Search is the retrieval call that ranks a collection's documents by relevance to a query. It lives at the documents sub-resource -- a `GET` on the collection's documents with the query as a filter.

## Shape

Search is a `GET` on the documents sub-resource with the query as a query parameter. With no query it's a plain date-sorted catalog listing; with a query it's a ranked `vector` retrieval (`hybrid` and `keyword` are [coming soon](/docs/ai-search/search-modes)). The collection is addressed by `slug` (customer-facing), not `uuid`.

| Method | Path                                  | Purpose                                |
| ------ | ------------------------------------- | -------------------------------------- |
| `GET`  | `/v2/ai/collections/{slug}/documents` | Search / list a collection's documents |

A collection with no searchable sources returns `422` (see [Errors](#errors)).

## Basic vs Advanced

A search can be as simple as a plain natural-language question, or as rich as a source-scoped, filtered, paginated retrieval call. Choose the tab that matches how much control you need.

<Tabs>
  <Tab title="Basic">
    A basic search sends only the `query`. The collection's settings decide how many results come back (`top_k`, default 5) and how they are ranked (`retrieval_type`).

    ```bash theme={null}
    # Basic ranked search
    curl -H "Authorization: Bearer $TELNYX_API_KEY" \
      "https://api.telnyx.com/v2/ai/collections/support-search/documents?query=did+we+promise+Acme+a+refund"
    ```

    ```json theme={null}
    {
      "data": [
        {
          "id": "chunk_abc",
          "record_id": "rec_123",
          "chunk_index": 2,
          "chunk_total": 9,
          "text": "...full refund within 5 business days...",
          "score": 0.87,
          "record_type": "voice",
          "region": "USA",
          "record_created_at": "2026-07-10T12:15:00Z",
          "ingested_at": "2026-07-10T12:16:04Z",
          "metadata": { "call_id": "call-100" }
        }
      ],
      "meta": {
        "collection_slug": "support-search",
        "searched_sources": ["voice"],
        "retrieval_type": "vector",
        "top_k": 5,
        "total_results": 5,
        "total_pages": 1,
        "page_number": 1,
        "page_size": 5
      }
    }
    ```
  </Tab>

  <Tab title="Advanced">
    An advanced search stacks `top_k`, `sources`, `filter[field][op]`, and pagination on top of the `query`.

    ### Query Parameters

    | Param                         | Required | Meaning                                                                                                                                                             |
    | ----------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | `query`                       | optional | Relevance query. Omitted -> catalog listing (date desc). Present -> relevance-ranked.                                                                               |
    | `top_k`                       | optional | Override the collection default. 1--50; values outside the range are rejected with `422`.                                                                           |
    | `sources`                     | optional | Narrow to a subset of the collection's source types (e.g. `voice`), comma-separated.                                                                                |
    | `filter[field][op]`           | optional | Field filtering (the same `filter[field][op]=value` system described below).                                                                                        |
    | `page[number]` / `page[size]` | optional | Telnyx bracket pagination.                                                                                                                                          |
    | `retrieval_type`              | optional | Reserved for `hybrid` and `keyword` ([coming soon](/docs/ai-search/search-modes)). Searches run `vector` retrieval; `meta.retrieval_type` echoes the mode that ran. |

    ### Field Filters

    The same `filter[field][op]=value` system the search/documents endpoints already use. Operators: `eq`, `in`, `gte`, `gt`, `lte`, `lt`, `contains`. Multiple filters AND together.

    Known top-level fields: `record_type`, `record_id`, `user_id`, `record_created_at`, `ingested_at`, plus any other name -> a `metadata.*` filter (pass the bare key, e.g. `filter[call_id]=...`). `region` and `score` are not filterable -> `400`.

    For vector search the filter is applied pre-kNN, so it narrows candidates without distorting scores.

    ### Advanced Example

    ```bash theme={null}
    # Narrow to one source + a metadata filter (bare key). --globoff: the [ ] are literal.
    curl --globoff -H "Authorization: Bearer $TELNYX_API_KEY" \
      "https://api.telnyx.com/v2/ai/collections/support-search/documents?query=refund&sources=voice&filter[call_id]=call-100"
    ```
  </Tab>
</Tabs>

## Reconstructing a Document

Search and listing share one endpoint -- the presence of `query` decides the behavior. Omit `query` to get a plain, date-ordered listing instead of a ranked search.

During indexing, a transcription or file is split into multiple chunks. To retrieve every chunk that belongs to a single record -- for example to reassemble one full transcript -- omit `query` and filter by `record_id`:

```bash theme={null}
# List all chunks of one document (no query -> not ranked, not billed as a search).
# top_k governs how many chunks are returned; set it high enough to cover chunk_total.
# --globoff is required so curl does not treat the [ ] in filter/page keys as globs.
curl --globoff -H "Authorization: Bearer $TELNYX_API_KEY" \
  "https://api.telnyx.com/v2/ai/collections/support-search/documents?filter[record_id][eq]=rec_123&top_k=50&page[size]=50"
```

```json theme={null}
{
  "data": [
    { "id": "chunk_0", "record_id": "rec_123", "chunk_index": 0, "chunk_total": 3,
      "text": "Customer opened the call asking about...", "record_type": "voice" },
    { "id": "chunk_1", "record_id": "rec_123", "chunk_index": 1, "chunk_total": 3,
      "text": "...we agreed to a full refund within 5 business days...", "record_type": "voice" },
    { "id": "chunk_2", "record_id": "rec_123", "chunk_index": 2, "chunk_total": 3,
      "text": "...confirmed the mailing address before ending the call.", "record_type": "voice" }
  ],
  "meta": {
    "collection_slug": "support-search",
    "searched_sources": ["voice"],
    "top_k": 50,
    "total_results": 3,
    "total_pages": 1,
    "page_number": 1,
    "page_size": 50
  }
}
```

Without a `query`, results come back in date order rather than by relevance score, and the request is **not** billed as a search event. Each chunk carries `chunk_index` and `chunk_total`, so you can order the chunks (`chunk_index` ascending) and reassemble the complete document text.

Because a collection's sources can be stored across multiple regions, a fan-out search may return the same chunk once per region (duplicate `id` values with different `region` values). Deduplicate by `id` before sorting by `chunk_index`, otherwise reassembled text repeats sections.

<Callout type="note">
  `page[size]` is echoed in the response `meta` but does not limit how many chunks are returned -- `top_k` governs the array length. To retrieve every chunk of a record, set `top_k` high enough to cover `chunk_total` (up to the maximum of 50) rather than relying on pagination.
</Callout>

<Callout type="info">
  When copying `curl` examples that use bracketed keys like `filter[...]` or `page[...]`, pass `--globoff` (curl otherwise treats `[` and `]` as glob/range syntax and the request fails before it is sent).
</Callout>

## Errors

Search errors are returned in the standard Telnyx error envelope with a numeric code:

```json theme={null}
// 404 -- no collection with that slug
{
  "errors": [{
    "code": "10005",
    "title": "Resource not found",
    "detail": "The requested resource or URL could not be found.",
    "meta": { "url": "https://developers.telnyx.com/docs/overview/errors/10005" }
  }]
}

// 422 -- the request cannot be processed, for example a collection with no
// searchable sources, or top_k outside 1-50
{
  "errors": [{
    "code": "10027",
    "title": "Unprocessable Entity",
    "detail": "The server understood the syntax of the request but was unable to process the instructions.",
    "meta": { "url": "https://developers.telnyx.com/docs/overview/errors/10027" }
  }]
}
```

A `400` is returned for malformed requests -- for example filtering on a non-filterable field such as `region` or `score`.

## Billing

Each ranked search (a request with a `query` parameter) counts as one billable search event. Browsing a collection's documents without a query (catalog listing) is free. See [Pricing](/docs/inference/embedding-rag/pricing) for rates.
