Keyword search is useful until users describe the same problem ten different ways.
"International SMS is failing."
"Texts to Germany are not going through."
"Messages to +49 numbers are stuck."
Those might all point to the same issue, but exact keyword matching may not connect them.
This Python example builds semantic search for support tickets using Telnyx AI Inference embeddings.
Code: https://github.com/team-telnyx/telnyx-code-examples/tree/main/semantic-search-python
What the app does
The Flask app lets you:
- index a bundled support-ticket dataset
- search tickets by meaning
- add a new ticket to the index
- fetch a ticket by ID
- inspect index stats
- check health
Routes:
POST /index
POST /search
POST /tickets
GET /tickets/<id>
GET /stats
GET /health
The app calls the Telnyx embeddings endpoint:
POST /v2/ai/openai/embeddings
Default model:
EMBEDDING_MODEL=thenlper/gte-large
How it works
For each support ticket, the app combines the subject and body:
"{subject}. {body}"
Then it:
- sends those strings to the Telnyx embeddings API
- stores the returned vectors in a numpy matrix
- embeds the search query
- calculates cosine similarity
- returns the top matching tickets
That gives you meaning-based search without introducing a full vector database for the first version.
Run it
Clone the repo:
git clone https://github.com/team-telnyx/telnyx-code-examples.git
cd telnyx-code-examples/semantic-search-python
Create your .env:
cp .env.example .env
Add your Telnyx API key:
TELNYX_API_KEY=your_telnyx_api_key
EMBEDDING_MODEL=thenlper/gte-large
HOST=127.0.0.1
PORT=5000
Install and start:
pip install -r requirements.txt
python app.py
Check the service:
curl http://localhost:5000/health
Build the index:
curl -X POST http://localhost:5000/index
Search by meaning:
curl -X POST http://localhost:5000/search \
-H "Content-Type: application/json" \
-d '{
"query": "I cannot send text messages to international phone numbers",
"top_k": 3
}' | python3 -m json.tool
Example result:
{
"query": "I cannot send text messages to international phone numbers",
"model": "thenlper/gte-large",
"total_indexed": 15,
"results": [
{
"ticket_id": "TKT-1002",
"subject": "International SMS routing issue",
"category": "messaging",
"priority": "high",
"score": 0.9077
}
]
}
Try more queries
curl -X POST http://localhost:5000/search \
-H "Content-Type: application/json" \
-d '{"query":"audio quality problems on calls","top_k":3}' | python3 -m json.tool
curl -X POST http://localhost:5000/search \
-H "Content-Type: application/json" \
-d '{"query":"my API key stopped working after I changed it","top_k":3}' | python3 -m json.tool
curl -X POST http://localhost:5000/search \
-H "Content-Type: application/json" \
-d '{"query":"phone number transfer is taking too long","top_k":3}' | python3 -m json.tool
Add a new ticket
curl -X POST http://localhost:5000/tickets \
-H "Content-Type: application/json" \
-d '{
"subject": "Cannot receive faxes",
"body": "Inbound faxes from certain senders are failing to render.",
"category": "fax",
"priority": "medium"
}'
The app embeds the new ticket and appends it to the in-memory vector index.
Where this fits
This pattern is useful for:
- support-ticket search
- duplicate ticket detection
- incident triage
- internal knowledge search
- agent assist tools
- routing similar issues to the right team
For production, you would probably swap the in-memory numpy store for pgvector, Qdrant, Weaviate, Pinecone, Redis, or another persistent vector store. You could also combine semantic search with filters for category, priority, date, account, or product.
The core idea stays simple: Telnyx turns text into vectors, and your app decides how to rank and return the results.
Resources
Code: https://github.com/team-telnyx/telnyx-code-examples/tree/main/semantic-search-python
Telnyx AI skills and toolkits: https://github.com/team-telnyx/ai
Telnyx AI Inference docs: https://developers.telnyx.com/docs/inference
Embeddings API: https://developers.telnyx.com/api/inference/create-embeddings
Telnyx Portal: https://portal.telnyx.com/
Top comments (0)