# Telnyx Agent Tools: AI Search — Full Documentation > Complete page content for AI Search (Agent Tools section) of the Telnyx developer docs (https://developers.telnyx.com). > This file: https://developers.telnyx.com/docs/development/llms/agent-tools-ai-search-llms-full-txt.md · Root index: https://developers.telnyx.com/llms.txt ## AI Search ### Overview > Source: https://developers.telnyx.com/docs/ai-search.md AI Search is a managed search service over the data your Telnyx account already holds. Create a **collection**, attach sources, and query them with natural language through one retrieval API. Telnyx handles embedding, indexing, and ranking. Voice call transcriptions are searchable today; meetings, messaging, and stored documents are coming soon. It is retrieval-only by design: every search returns scored, source-attributed chunks ready to ground any LLM. Generation belongs to your application -- bring your own model. ## How It Works 1. **[Create a collection](/docs/ai-search/manage-collections)** -- a named container with retrieval settings. Creating one is instant: a collection is a pointer, not a copy. 2. **[Attach sources](/docs/ai-search/sources)** -- mix voice, meeting, messaging, and bucket sources in one collection. 3. **[Configure settings](/docs/ai-search/settings)** -- retrieval mode and result count, with per-request overrides. 4. **[Search](/docs/ai-search/searching)** -- one `GET` returns ranked chunks with scores, metadata, and source attribution. For the pipeline behind this -- and how AI Search relates to the lower-level embeddings APIs -- see [How AI Search Works](/docs/ai-search/how-it-works). ## Sources A collection can include any combination of these source types: | Source type | What it indexes | | --- | --- | | [`voice`](/docs/ai-search/sources/voice) | Voice call transcriptions for the account | | `meeting_bot` Coming soon | Meeting transcriptions for the account | | `message` Coming soon | Messaging history for the account | | `bucket` Coming soon | Files in one specific Telnyx Storage bucket | Conversation-backed sources index what [conversation persistence](/docs/ai-search/sources/voice) has stored for the account -- new calls become searchable minutes after they end. ## Next Steps First collection to first search in a few minutes. Indexing, querying, and what a collection actually is. Vector, keyword, and hybrid retrieval compared. The retrieval call: parameters, filters, pagination, errors. --- ### Get Started > Source: https://developers.telnyx.com/docs/ai-search/get-started.md Create a collection, attach your voice call transcriptions as a source, and search them with natural language. This quickstart uses the REST API -- every step is a copy-paste request. ## Prerequisites - A Telnyx API key from the [portal](https://portal.telnyx.com/#/api-keys). Export it so the examples work as-is: ```bash export TELNYX_API_KEY="KEY..." ``` - Content to search. The `voice` source indexes your account's persisted voice call transcriptions -- see [how to enable persistence](/docs/ai-search/sources/voice). An account with no persisted transcriptions returns empty results, but the API calls below still work. A collection is a named search index. `name` is required; everything else has defaults. ```bash curl -X POST https://api.telnyx.com/v2/ai/collections \ -H "Authorization: Bearer $TELNYX_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Support search", "description": "Searchable support call transcripts" }' ``` ```json { "data": { "uuid": "fc96a26f-c4a1-484e-afc4-d94b903778cc", "slug": "support-search", "record_type": "ai_collection", "name": "Support search", "description": "Searchable support call transcripts", "status": "ready", "sources": [], "settings": { "retrieval": { "top_k": 5, "retrieval_type": "vector" } }, "created_at": "2026-08-07T14:56:55.558737Z", "updated_at": "2026-08-07T14:56:55.558737Z" } } ``` Two identifiers come back: the `uuid` (used by the management API) and the `slug`, derived from `name` (used by the search API). Default settings apply -- `top_k: 5`, `retrieval_type: vector`. The collection has no sources yet, so there is nothing to search. Add the `voice` source -- your account's call transcriptions: ```bash curl -X POST https://api.telnyx.com/v2/ai/collections/fc96a26f-c4a1-484e-afc4-d94b903778cc/sources \ -H "Authorization: Bearer $TELNYX_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "source_type": "voice" }' ``` ```json { "data": { "id": "source_8vkvtcksnawvbnxq48yv2l06wx", "record_type": "ai_collection_source", "collection_id": "fc96a26f-c4a1-484e-afc4-d94b903778cc", "source_type": "voice", "status": "ready" } } ``` The source is `ready` and its content is indexed for search. More source types are coming soon -- see [Sources](/docs/ai-search/sources). The search call is a `GET` on the collection's documents, addressed by slug: ```bash curl -H "Authorization: Bearer $TELNYX_API_KEY" \ "https://api.telnyx.com/v2/ai/collections/support-search/documents?query=did+we+promise+a+refund" ``` ```json { "data": [ { "id": "e30570b6-68d5-11f1-838c-02420a0ddb20:0", "record_id": "e30570b6-68d5-11f1-838c-02420a0ddb20", "chunk_index": 0, "chunk_total": 1, "text": "...The refund of $200 has been deposited back in your account...", "score": 0.904, "record_type": "voice", "region": "USA", "record_created_at": "2026-06-15T16:18:49.981698+00:00", "ingested_at": "2026-06-15T16:20:12.170251+00:00", "metadata": { "source": "Trunking" } } ], "meta": { "collection_slug": "support-search", "searched_sources": ["voice"], "retrieval_type": "vector", "top_k": 5, "total_results": 56, "total_pages": 12, "page_number": 1, "page_size": 5 } } ``` Each result is a scored chunk that says what it is and where it came from -- `record_id`, `record_type`, timestamps, and `metadata`. The match works on meaning, not exact words: "did we promise a refund" finds "the refund has been deposited". Per-request parameters override the collection defaults for that one request: ```bash # Fewer results and a date filter (--globoff: the [ ] are literal) curl --globoff -H "Authorization: Bearer $TELNYX_API_KEY" \ "https://api.telnyx.com/v2/ai/collections/support-search/documents?query=refund&top_k=3&filter[record_created_at][gte]=2026-06-01T00:00:00Z" ``` See [Search](/docs/ai-search/searching) for the full parameter and filter reference. The search response is grounding, ready to hand to any LLM as tool output -- AI Search never generates answers itself. Declare the search call as a function tool, run it when the model asks, and feed the chunks back. ## Next Steps The indexing and query pipelines, and what a collection actually is. Attach sources and enable the data behind them. Configure retrieval mode and result count per collection. Filters, pagination, document reassembly, and errors. --- ### Search > Source: https://developers.telnyx.com/docs/ai-search/searching.md 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. 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 # 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 { "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 } } ``` 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 # 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" ``` ## 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 # 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 { "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. `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. 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). ## Errors Search errors are returned in the standard Telnyx error envelope with a numeric code: ```json // 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. --- ## Concepts ### How AI Search Works > Source: https://developers.telnyx.com/docs/ai-search/how-it-works.md AI Search has two core processes: **indexing**, which turns your content into searchable chunks continuously in the background, and **querying**, which retrieves the most relevant chunks for a request. Understanding both explains why collections are cheap to create and why search results look the way they do. ## How Indexing Works Each source system owns its own ingestion -- content becomes searchable without any per-collection work: 1. **Ingest** -- a data source is enabled for indexing. Voice transcriptions flow in as calls end, controlled by [conversation persistence](/docs/ai-search/sources/voice) -- a collection can only see what persistence has stored for the account. 2. **Chunk** -- each record (a transcript, a file) is split into chunks sized for retrieval. Chunks carry `chunk_index` and `chunk_total` so a full record can be [reassembled](/docs/ai-search/searching#reconstructing-a-document) later. 3. **Embed** -- each chunk is converted into a vector that captures its meaning, and stored in the source's vector database alongside its metadata (`record_id`, timestamps, origin fields). New calls are searchable minutes after they end. There are no sync schedules to manage. ## How Querying Works When you search a collection: 1. **Resolve the collection** -- the collection's [sources](/docs/ai-search/sources) and [settings](/docs/ai-search/settings) are looked up by slug; per-request parameters override settings for that request only. 2. **Embed the query** -- the query text is embedded with the same model family used at indexing time. 3. **Filter** -- any [`filter[field][op]`](/docs/ai-search/searching#field-filters) conditions are applied before nearest-neighbor search, so filters narrow the candidate set without distorting scores. 4. **Fan out** -- the search runs against every searchable source in the collection, across all regions where content is stored. 5. **Merge** -- per-source, per-region results are merged into one list ranked by relevance `score`, capped at `top_k`. 6. **Return chunks** -- each chunk carries its text, score, and source metadata. AI Search stops here by design: generation belongs to your application. The whole fan-out counts as **one** billable search event, regardless of how many sources and regions were searched. See [Pricing](/docs/inference/embedding-rag/pricing). ## A Collection Is a Pointer Creating a collection only writes configuration rows -- it does not copy, move, or re-embed content. This has practical consequences: - Creation is instant, and a new collection over already-indexed sources is immediately searchable. - Removing a source or deleting a collection drops only collection-scoped artifacts. The underlying Telnyx data is never modified or deleted. - The same source can back many collections at no extra indexing cost. ## AI Search vs. the Embeddings APIs Telnyx also ships lower-level building blocks -- the [Embeddings API](/docs/inference/embeddings) embeds documents in a Storage bucket, and `POST /v2/ai/embeddings/similarity-search` queries one bucket directly. AI Search is the managed layer above them: | | AI Search | Embeddings API | | --- | --- | --- | | What it is | Managed search product over your Telnyx data | Bucket-level embedding primitives you compose yourself | | You give it | Sources (`voice` today, more coming soon) | One Storage bucket per request | | Scope of a query | Every source in the collection, merged and ranked | A single embedded bucket | | Ingestion | Continuous, owned by each source system | You trigger embedding per bucket | | Query surface | `GET /v2/ai/collections/{slug}/documents` | `POST /v2/ai/embeddings/similarity-search` | | Grounded chat | Bring your own LLM over search results | `retrieval` tool on [chat completions](/docs/inference/embeddings#chat-over-your-documents) | | Best when | Searching your account's conversations | You need direct control of one bucket's embeddings | If you are starting fresh, start with AI Search. Reach for the embeddings APIs when you need the primitive itself. --- ### Search Modes > Source: https://developers.telnyx.com/docs/ai-search/search-modes.md A collection's `retrieval_type` selects how queries are matched against indexed content. There are three modes. To see how each behaves, take one query a support team might run: **"error 10015 on outbound call"**. ## Vector Available The query is embedded into a vector and compared against indexed chunks by nearest-neighbor similarity. It matches on **meaning**, so wording can differ: "did we agree to a refund?" finds "we'll credit the invoice". For the example query, vector search understands the *concept* -- call failures, error handling -- and finds transcripts about failing outbound calls. Its blind spot is the literal string: the chunk containing exactly `10015` may not rank first, because digits have weak semantic neighbors. Best for natural-language questions where exact terms vary. This is the default mode. ## Keyword Coming soon Classic lexical search (BM25) -- term-frequency ranking over the actual words, no embeddings. It matches on **exact tokens**, so it finds the chunk that literally contains `10015`. Its blind spot is paraphrase: a transcript that says "the call was rejected with a billing error" but never says "10015" is invisible to it. Best for identifiers, error codes, SKUs, and names. ## Hybrid Coming soon Runs vector and keyword in parallel and fuses the two result sets into one ranking. For the example query it finds both the transcript with the literal `10015` and the ones that only describe the failure -- semantic recall plus exact-term precision in a single call, at the cost of slightly more work per request. Best when queries are mixed or unpredictable. --- ## Configuration ### Collections > Source: https://developers.telnyx.com/docs/ai-search/manage-collections.md A **collection** is the core resource in AI Search -- a named container for data sources with its own retrieval settings. This page covers the full CRUD lifecycle. [Sources](/docs/ai-search/sources) and [Settings](/docs/ai-search/settings) have their own subresources, documented separately. Management operations address a collection by `uuid`; [search](/docs/ai-search/searching) addresses it by `slug`. ## Create a Collection `name` is required. `slug` is derived from `name` when omitted and must be unique per organization. A collection may be created with or without initial `sources`. `settings` is optional -- defaults apply (`top_k = 5`, `retrieval_type = vector`). ```bash curl -X POST https://api.telnyx.com/v2/ai/collections \ -H "Authorization: Bearer $TELNYX_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Collections for personal calls", "description": "Searchable personal call transcripts", "sources": [ { "source_type": "voice" } ], "settings": { "retrieval": { "top_k": 10, "retrieval_type": "vector" } } }' ``` ```json { "data": { "uuid": "b3b1c8a2-9f4e-4d2a-9c1e-2f7a6d5b4c3a", "slug": "collections-personal-calls", "record_type": "ai_collection", "name": "Collections for personal calls", "description": "Searchable personal call transcripts", "status": "ready", "sources": [ { "id": "source_8vkvtcksnawvbnxq48yv2l06wx", "record_type": "ai_collection_source", "collection_id": "b3b1c8a2-9f4e-4d2a-9c1e-2f7a6d5b4c3a", "source_type": "voice", "status": "ready" } ], "settings": { "retrieval": { "top_k": 10, "retrieval_type": "vector" } }, "created_at": "2026-08-07T14:56:55.558737Z", "updated_at": "2026-08-07T14:56:55.558737Z" } } ``` Returns `201 Created` with the full collection record. ### Slug Conflicts If a collection with the same slug already exists for the account, the request returns `409 Conflict`: ```json { "errors": [{ "code": "collection_slug_taken", "title": "Collection slug already in use", "detail": "A collection with slug 'collections-personal-calls' already exists for this account.", "source": { "pointer": "/slug" } }] } ``` ## List Collections ```bash curl -H "Authorization: Bearer $TELNYX_API_KEY" \ "https://api.telnyx.com/v2/ai/collections" ``` Returns `200 OK` with the Telnyx V2 `data` + `meta` envelope -- each item is a full collection record: ```json { "data": [ { "uuid": "b3b1c8a2-9f4e-4d2a-9c1e-2f7a6d5b4c3a", "slug": "collections-personal-calls", "record_type": "ai_collection", "name": "Collections for personal calls", "description": "Searchable personal call transcripts", "status": "ready", "sources": [ { "id": "source_8vkvtcksnawvbnxq48yv2l06wx", "record_type": "ai_collection_source", "collection_id": "b3b1c8a2-9f4e-4d2a-9c1e-2f7a6d5b4c3a", "source_type": "voice", "status": "ready" } ], "settings": { "retrieval": { "top_k": 10, "retrieval_type": "vector" } }, "created_at": "2026-08-07T14:56:55.558737Z", "updated_at": "2026-08-07T14:56:55.558737Z" } ], "meta": { "total_pages": 1, "total_results": 1, "page_number": 1, "page_size": 20 } } ``` ### Pagination Pagination is optional. Use `page[number]`/`page[size]` query parameters (default size 20, max 100). Results are sorted by `slug` then `created_at`. ```bash # Second page (--globoff so curl does not treat [ ] as globs) curl --globoff -H "Authorization: Bearer $TELNYX_API_KEY" \ "https://api.telnyx.com/v2/ai/collections?page[number]=2&page[size]=20" ``` ## Retrieve a Collection by UUID Lookup by UUID returns the full collection record. ```bash curl -H "Authorization: Bearer $TELNYX_API_KEY" \ "https://api.telnyx.com/v2/ai/collections/b3b1c8a2-9f4e-4d2a-9c1e-2f7a6d5b4c3a" ``` If no collection exists with that UUID for the account, the request returns `404 Not Found`. ## Retrieve a Collection by Slug Lookup by slug returns the same full record. Slugs are unique per organization. ```bash curl -H "Authorization: Bearer $TELNYX_API_KEY" \ "https://api.telnyx.com/v2/ai/collections/slug/collections-personal-calls" ``` If no collection exists with that slug for the account, the request returns `404 Not Found`. ## Update Collection Metadata `PATCH` updates metadata only (`name`, `description`). Partial -- omitted fields are untouched. `slug` is immutable; renaming does not regenerate it. Sources and settings have their own subresources. ```bash curl -X PATCH https://api.telnyx.com/v2/ai/collections/b3b1c8a2-9f4e-4d2a-9c1e-2f7a6d5b4c3a \ -H "Authorization: Bearer $TELNYX_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Customer Conversation Intelligence", "description": "Calls and meetings used by the support AI" }' ``` Returns the full updated collection record with a refreshed `updated_at`. Slug is unchanged. Add, replace, and remove data sources. Configure retrieval type and top_k. ## Delete a Collection Soft delete. Sets `deleted_at` and `status = deleted`, then excludes the collection from list results and returns `404` on detail lookups. The slug is freed for reuse immediately. No external data is touched -- transcriptions, embeddings, and credential connections are not affected. Deleting an already-deleted or unknown collection returns `404`. ```bash curl -X DELETE -H "Authorization: Bearer $TELNYX_API_KEY" \ "https://api.telnyx.com/v2/ai/collections/b3b1c8a2-9f4e-4d2a-9c1e-2f7a6d5b4c3a" ``` Returns `204 No Content` -- no body. ## Related - [Get started](/docs/ai-search/get-started) -- first collection to first search - [Sources](/docs/ai-search/sources) -- add, replace, and remove data sources - [Settings](/docs/ai-search/settings) -- configure retrieval type and top_k - [Search](/docs/ai-search/searching) -- query a collection's documents --- ### Overview > Source: https://developers.telnyx.com/docs/ai-search/sources.md Sources are the data inputs a collection searches across. Each source type has its own page covering what it indexes and how to enable the underlying data: | Source type | What it indexes | | --- | --- | | [`voice`](/docs/ai-search/sources/voice) | Voice call transcriptions for the account | | `meeting_bot` Coming soon | Meeting transcriptions for the account | | `message` Coming soon | Messaging history for the account | | `bucket` Coming soon | Files in one specific Telnyx Storage bucket | Sources are managed through dedicated endpoints -- never through collection `PATCH` (which would be ambiguous about intent). When a source is added, the resource is created with `status` set to `ready` and its content is indexed for search. ## Add One Source `POST /v2/ai/collections/{uuid}/sources` adds a single source without touching the others. ```bash # Add a voice source curl -X POST https://api.telnyx.com/v2/ai/collections/b3b1c8a2-9f4e-4d2a-9c1e-2f7a6d5b4c3a/sources \ -H "Authorization: Bearer $TELNYX_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "source_type": "voice" }' ``` ```json { "data": { "id": "source_8vkvtcksnawvbnxq48yv2l06wx", "record_type": "ai_collection_source", "collection_id": "b3b1c8a2-9f4e-4d2a-9c1e-2f7a6d5b4c3a", "source_type": "voice", "status": "ready" } } ``` Returns `201 Created` with the new source object. ## Replace All Sources `PUT /v2/ai/collections/{uuid}/sources` replaces the complete source list. The server reconciles by logical identity: - `voice` -- by `source_type` Retained sources are not reindexed. Dropped sources are detached from this collection only -- replacing the list never starts physical cleanup of chunks, embeddings, or metadata, and never deletes the underlying Telnyx product data. ```bash curl -X PUT https://api.telnyx.com/v2/ai/collections/b3b1c8a2-9f4e-4d2a-9c1e-2f7a6d5b4c3a/sources \ -H "Authorization: Bearer $TELNYX_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "sources": [ { "source_type": "voice" } ] }' ``` ```json { "data": [ { "id": "source_8vkvtcksnawvbnxq48yv2l06wx", "record_type": "ai_collection_source", "collection_id": "b3b1c8a2-9f4e-4d2a-9c1e-2f7a6d5b4c3a", "source_type": "voice", "status": "ready" } ], "meta": { "added": [], "retained": [ "source_8vkvtcksnawvbnxq48yv2l06wx" ], "removed": [ "source_8atnodb2vjqlpqwm211lwo739w" ] } } ``` ## List Sources ```bash curl -H "Authorization: Bearer $TELNYX_API_KEY" \ "https://api.telnyx.com/v2/ai/collections/b3b1c8a2-9f4e-4d2a-9c1e-2f7a6d5b4c3a/sources" ``` ```json { "data": [ { "id": "source_8vkvtcksnawvbnxq48yv2l06wx", "record_type": "ai_collection_source", "collection_id": "b3b1c8a2-9f4e-4d2a-9c1e-2f7a6d5b4c3a", "source_type": "voice", "status": "ready" } ] } ``` ## Remove One Source `DELETE /v2/ai/collections/{uuid}/sources/{source_id}` removes a single source; the rest are untouched. Excluded from new searches immediately -- this detaches the collection's pointer to the source only. A source can back many collections, so detaching never starts physical cleanup of chunks, embeddings, or metadata. Never deletes the original Telnyx product data. Never disables a bucket or credential connection. ```bash curl -X DELETE -H "Authorization: Bearer $TELNYX_API_KEY" \ "https://api.telnyx.com/v2/ai/collections/b3b1c8a2-9f4e-4d2a-9c1e-2f7a6d5b4c3a/sources/source_8vkvtcksnawvbnxq48yv2l06wx" ``` Returns `204 No Content` -- no body. ## Related - [Collections](/docs/ai-search/manage-collections) -- create, list, retrieve, update, and delete collections - [Settings](/docs/ai-search/settings) -- configure retrieval type and top_k --- ### Voice > Source: https://developers.telnyx.com/docs/ai-search/sources/voice.md The `voice` source indexes your account's persisted voice call transcriptions. Calls become searchable minutes after they end -- there is nothing to sync. ## Attach the Source ```bash curl -X POST https://api.telnyx.com/v2/ai/collections/{uuid}/sources \ -H "Authorization: Bearer $TELNYX_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "source_type": "voice" }' ``` The source indexes every persisted voice transcription on the account. A collection over an account with no persisted transcriptions returns empty results -- enable persistence first. ## Enable Voice Transcript Persistence Voice transcripts are persisted per SIP connection. Set `conversation_persistence` to `true` on each connection whose calls you want transcribed, stored, and indexed: ```bash curl -X PATCH https://api.telnyx.com/v2/credential_connections/{id} \ -H "Authorization: Bearer $TELNYX_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "conversation_persistence": true }' ``` The same field exists on all supported connection types: | Connection type | Endpoint | | --- | --- | | Credential connections | `PATCH /v2/credential_connections/{id}` | | IP connections | `PATCH /v2/ip_connections/{id}` | | FQDN connections | `PATCH /v2/fqdn_connections/{id}` | Verify with a `GET` on the connection -- the response includes `conversation_persistence`. Set it to `false` to stop persisting new calls. From then on, every call handled by that connection is transcribed and indexed automatically. Persisted records include 30 days of indexed retention -- see [Pricing](/docs/inference/embedding-rag/pricing) for extended retention. ## What a Result Looks Like Voice chunks carry `record_type: "voice"` plus the call's identifiers and timestamps: ```json { "id": "e30570b6-68d5-11f1-838c-02420a0ddb20:0", "record_id": "e30570b6-68d5-11f1-838c-02420a0ddb20", "chunk_index": 0, "chunk_total": 1, "text": "...The refund of $200 has been deposited back in your account...", "score": 0.904, "record_type": "voice", "record_created_at": "2026-06-15T16:18:49.981698+00:00", "ingested_at": "2026-06-15T16:20:12.170251+00:00", "metadata": { "source": "Trunking" } } ``` Narrow searches to calls with `sources=voice` or filter on record fields -- see [Search](/docs/ai-search/searching). --- ### Settings > Source: https://developers.telnyx.com/docs/ai-search/settings.md Settings hold the collection's default retrieval configuration in their own subresource -- collection `PATCH` never touches them. Settings are accessed at `/v2/ai/collections/{uuid}/settings`, and any setting can be overridden per request at [search](/docs/ai-search/searching) time. | Field | Type | Values | Default | | --- | --- | --- | --- | | `top_k` | integer | 1--50 | 5 | | `retrieval_type` | string | `vector` (`hybrid` and `keyword` coming soon) | `vector` | `retrieval_type` selects how a query is matched against the collection's indexed content -- see [Search Modes](/docs/ai-search/search-modes) for how the modes differ and when to use each. `hybrid` and `keyword` retrieval are coming soon. Keep `retrieval_type` set to `vector` -- a collection set to `hybrid` cannot be searched yet. ## Get Settings ```bash curl -H "Authorization: Bearer $TELNYX_API_KEY" \ "https://api.telnyx.com/v2/ai/collections/b3b1c8a2-9f4e-4d2a-9c1e-2f7a6d5b4c3a/settings" ``` ```json { "data": { "record_type": "ai_collection_settings", "retrieval": { "top_k": 5, "retrieval_type": "vector" } } } ``` ## Replace Settings `PUT` replaces the entire settings object. Omitted keys reset to their defaults. ```bash curl -X PUT https://api.telnyx.com/v2/ai/collections/b3b1c8a2-9f4e-4d2a-9c1e-2f7a6d5b4c3a/settings \ -H "Authorization: Bearer $TELNYX_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "retrieval": { "top_k": 25, "retrieval_type": "vector" } }' ``` ## Merge Settings `PATCH` does a partial merge at the `retrieval` key. Unnamed fields are preserved. ```bash curl -X PATCH https://api.telnyx.com/v2/ai/collections/b3b1c8a2-9f4e-4d2a-9c1e-2f7a6d5b4c3a/settings \ -H "Authorization: Bearer $TELNYX_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "retrieval": { "top_k": 5 } }' ``` Returns the full merged settings object -- `retrieval_type` is unchanged. ## Validation Errors Unsupported `retrieval_type` values return `422`: ```json { "errors": [{ "code": "unsupported_retrieval_type", "title": "Unsupported retrieval type", "detail": "retrieval_type 'semantic' is not supported. Supported types: 'hybrid', 'vector'.", "source": { "pointer": "/retrieval/retrieval_type" } }] } ``` `top_k` outside 1--50 returns `422` with code `invalid_top_k`. Unrecognized fields in the `retrieval` object are rejected with `400`. ## Related - [Search Modes](/docs/ai-search/search-modes) -- vector, keyword, and hybrid compared - [Collections](/docs/ai-search/manage-collections) -- create, list, retrieve, update, and delete collections - [Sources](/docs/ai-search/sources) -- add, replace, and remove data sources --- ## API Reference (AI Search) ### AI Collections - [Create a collection](https://developers.telnyx.com/api-reference/ai-collections/create-a-collection.md): Creates a new collection scoped to your organization. Optionally attach sources and retrieval settings at creation time. If `slug` is omitted, one is derived f… - [List collections](https://developers.telnyx.com/api-reference/ai-collections/list-collections.md): Returns a paginated list of collections in your organization. - [Get a collection by slug](https://developers.telnyx.com/api-reference/ai-collections/get-a-collection-by-slug.md): Fetches a single collection by its `slug`. - [Get a collection](https://developers.telnyx.com/api-reference/ai-collections/get-a-collection.md): Fetches a single collection by its `uuid`. - [Update a collection](https://developers.telnyx.com/api-reference/ai-collections/update-a-collection.md): Updates a collection's metadata (`name` and/or `description`). Sources and settings are managed through their own sub-resources. - [Delete a collection](https://developers.telnyx.com/api-reference/ai-collections/delete-a-collection.md): Soft-deletes a collection. Its `slug` is freed and may be reused by a new collection. - [List collection sources](https://developers.telnyx.com/api-reference/ai-collections/list-collection-sources.md): Returns the sources attached to a collection. - [Add a collection source](https://developers.telnyx.com/api-reference/ai-collections/add-a-collection-source.md): Attaches a new source to a collection. - [Replace collection sources](https://developers.telnyx.com/api-reference/ai-collections/replace-collection-sources.md): Replaces the collection's entire source set. The response `meta` reports which sources were added, retained, and removed. - [Remove a collection source](https://developers.telnyx.com/api-reference/ai-collections/remove-a-collection-source.md): Removes a single source from a collection. - [Get collection settings](https://developers.telnyx.com/api-reference/ai-collections/get-collection-settings.md): Returns the retrieval settings for a collection. - [Replace collection settings](https://developers.telnyx.com/api-reference/ai-collections/replace-collection-settings.md): Replaces the collection's retrieval settings. - [Update collection settings](https://developers.telnyx.com/api-reference/ai-collections/update-collection-settings.md): Partially updates the collection's retrieval settings. - [Search collection documents](https://developers.telnyx.com/api-reference/ai-collections/search-collection-documents.md): Runs search over the documents in a collection, ranked by relevance to `query`. The collection's `retrieval_type` setting selects the strategy: `vector` (seman…