<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Sonam</title>
    <description>The latest articles on DEV Community by Sonam (@sonam_50a41a4ced7e6b4f3fa).</description>
    <link>https://dev.to/sonam_50a41a4ced7e6b4f3fa</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4004574%2Ff1f1b787-1d13-4716-b3f7-c8d2d134849c.png</url>
      <title>DEV Community: Sonam</title>
      <link>https://dev.to/sonam_50a41a4ced7e6b4f3fa</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sonam_50a41a4ced7e6b4f3fa"/>
    <language>en</language>
    <item>
      <title>Build an Edge Backend for a Telnyx AI Assistant</title>
      <dc:creator>Sonam</dc:creator>
      <pubDate>Thu, 16 Jul 2026 05:46:30 +0000</pubDate>
      <link>https://dev.to/sonam_50a41a4ced7e6b4f3fa/build-an-edge-backend-for-a-telnyx-ai-assistant-4ooi</link>
      <guid>https://dev.to/sonam_50a41a4ced7e6b4f3fa/build-an-edge-backend-for-a-telnyx-ai-assistant-4ooi</guid>
      <description>&lt;p&gt;Voice AI demos get interesting when the assistant needs real backend context.&lt;/p&gt;

&lt;p&gt;It is one thing to have an assistant answer a call. It is another thing to have that assistant greet the caller with dynamic context, collect information, call a backend tool, and read a confirmation back during the same phone call.&lt;/p&gt;

&lt;p&gt;This Go example shows how to use one Telnyx Edge Compute function as the backend for a Telnyx AI Assistant.&lt;/p&gt;

&lt;p&gt;Code: &lt;a href="https://github.com/team-telnyx/telnyx-code-examples/tree/main/edge-ai-assistant-backend-go" rel="noopener noreferrer"&gt;https://github.com/team-telnyx/telnyx-code-examples/tree/main/edge-ai-assistant-backend-go&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Full guide: &lt;a href="https://developers.telnyx.com/docs/edge-compute/guides/ai-assistant-backend" rel="noopener noreferrer"&gt;https://developers.telnyx.com/docs/edge-compute/guides/ai-assistant-backend&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What it does
&lt;/h2&gt;

&lt;p&gt;The app is a Go Edge Compute function with one public URL.&lt;/p&gt;

&lt;p&gt;That one URL handles two AI Assistant callbacks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;dynamic variables at call start&lt;/li&gt;
&lt;li&gt;a webhook tool call during the conversation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the demo, the assistant is a home-services lead screener. It can resolve a company name for the greeting, then call a &lt;code&gt;schedule_estimate&lt;/code&gt; webhook tool after collecting enough information from the caller.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I like this pattern
&lt;/h2&gt;

&lt;p&gt;Usually, the moment an AI assistant needs application context, you need to build a webhook server.&lt;/p&gt;

&lt;p&gt;That means hosting, deployment, secrets, request verification, and a public URL.&lt;/p&gt;

&lt;p&gt;With Edge Compute, that backend can live close to the Telnyx communications layer. You deploy a function, store secrets, and point the assistant callbacks to the function URL.&lt;/p&gt;

&lt;p&gt;No separate server. No Docker setup. No Kubernetes just to answer a webhook.&lt;/p&gt;

&lt;h2&gt;
  
  
  The important pieces
&lt;/h2&gt;

&lt;p&gt;The handler does three useful things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;verifies Telnyx Ed25519 signatures&lt;/li&gt;
&lt;li&gt;dispatches based on request body shape&lt;/li&gt;
&lt;li&gt;returns the right JSON format for either dynamic variables or tool results&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Dynamic variables must be returned under a &lt;code&gt;dynamic_variables&lt;/code&gt; key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"dynamic_variables"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"company_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Pinecrest Home Services"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"timeframe"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"two business days"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The webhook tool returns data the assistant can use in the live conversation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scheduled_date"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2025-04-10"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scheduled_time"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"10:00"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"confirmation_number"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"CONF-1715234567"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"estimate_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"EST-1715234567"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Run it
&lt;/h2&gt;

&lt;p&gt;Scaffold a Go function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;telnyx-edge new-func &lt;span class="nt"&gt;-l&lt;/span&gt; go &lt;span class="nt"&gt;-n&lt;/span&gt; edge-ai-assistant-backend
&lt;span class="nb"&gt;cd &lt;/span&gt;edge-ai-assistant-backend
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fetch your Telnyx public key and store it as an Edge secret:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;PUBLIC_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$TELNYX_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  https://api.telnyx.com/v2/public_key | jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'.data.public'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

telnyx-edge secrets add TELNYX_PUBLIC_KEY &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PUBLIC_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Deploy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;telnyx-edge ship
telnyx-edge list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then configure your AI Assistant so both the dynamic variables webhook URL and the &lt;code&gt;schedule_estimate&lt;/code&gt; webhook tool URL point to the same Edge Compute invoke URL.&lt;/p&gt;

&lt;p&gt;The full setup is in the guide: &lt;a href="https://developers.telnyx.com/docs/edge-compute/guides/ai-assistant-backend" rel="noopener noreferrer"&gt;https://developers.telnyx.com/docs/edge-compute/guides/ai-assistant-backend&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Where this could go
&lt;/h2&gt;

&lt;p&gt;This example uses a scheduling flow, but the backend pattern applies to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;order status lookups&lt;/li&gt;
&lt;li&gt;appointment booking&lt;/li&gt;
&lt;li&gt;account verification&lt;/li&gt;
&lt;li&gt;lead qualification&lt;/li&gt;
&lt;li&gt;dynamic greetings&lt;/li&gt;
&lt;li&gt;warm transfer decisions&lt;/li&gt;
&lt;li&gt;support ticket creation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The core idea is simple: keep the assistant conversational, and put the callback logic at the edge.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;p&gt;Edge Compute quickstart: &lt;a href="https://developers.telnyx.com/docs/edge-compute/quickstart" rel="noopener noreferrer"&gt;https://developers.telnyx.com/docs/edge-compute/quickstart&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;AI Assistant dynamic variables: &lt;a href="https://developers.telnyx.com/docs/inference/ai-assistants/dynamic-variables" rel="noopener noreferrer"&gt;https://developers.telnyx.com/docs/inference/ai-assistants/dynamic-variables&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Webhook signing: &lt;a href="https://developers.telnyx.com/development/api-fundamentals/webhooks/receiving-webhooks#webhook-signing" rel="noopener noreferrer"&gt;https://developers.telnyx.com/development/api-fundamentals/webhooks/receiving-webhooks#webhook-signing&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Telnyx AI skills and toolkits: &lt;a href="https://github.com/team-telnyx/ai" rel="noopener noreferrer"&gt;https://github.com/team-telnyx/ai&lt;/a&gt;&lt;/p&gt;

</description>
      <category>go</category>
      <category>ai</category>
      <category>serverless</category>
      <category>voice</category>
    </item>
    <item>
      <title>Build a Natural Language to SQL API in Python</title>
      <dc:creator>Sonam</dc:creator>
      <pubDate>Wed, 15 Jul 2026 23:51:45 +0000</pubDate>
      <link>https://dev.to/sonam_50a41a4ced7e6b4f3fa/build-a-natural-language-to-sql-api-in-python-11lo</link>
      <guid>https://dev.to/sonam_50a41a4ced7e6b4f3fa/build-a-natural-language-to-sql-api-in-python-11lo</guid>
      <description>&lt;p&gt;Most data questions start in plain English.&lt;/p&gt;

&lt;p&gt;"Which customers spent the most?"&lt;/p&gt;

&lt;p&gt;"How many orders are pending?"&lt;/p&gt;

&lt;p&gt;"What products generated revenue last month?"&lt;/p&gt;

&lt;p&gt;Someone can turn those questions into SQL, but that usually means waiting on a developer, analyst, or dashboard update.&lt;/p&gt;

&lt;p&gt;This Python example shows how to build a small natural language to SQL API with Telnyx AI Inference.&lt;/p&gt;

&lt;p&gt;Code: &lt;a href="https://github.com/team-telnyx/telnyx-code-examples/tree/main/sql-natural-language-python" rel="noopener noreferrer"&gt;https://github.com/team-telnyx/telnyx-code-examples/tree/main/sql-natural-language-python&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What it does
&lt;/h2&gt;

&lt;p&gt;The Flask app exposes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST /query
POST /query/sample
POST /validate
GET /queries
GET /queries/&amp;lt;id&amp;gt;
GET /health
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;POST /query&lt;/code&gt; accepts a natural-language question, SQL dialect, and schema DDL. It returns structured JSON with the generated SQL, explanation, tables used, and metadata.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;POST /query/sample&lt;/code&gt; uses a bundled SQLite sample dataset, so you can ask a question and see real rows come back without connecting a production database.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;POST /validate&lt;/code&gt; dry-runs a SQL string against the sample dataset.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why validation matters
&lt;/h2&gt;

&lt;p&gt;Natural language to SQL needs guardrails.&lt;/p&gt;

&lt;p&gt;This example asks the model for read-only SQL and then checks the generated query before execution. The validation layer rejects multiple statements, comments, and write-oriented SQL keywords.&lt;/p&gt;

&lt;p&gt;That keeps the example focused on the useful workflow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;ask a question&lt;/li&gt;
&lt;li&gt;include schema context&lt;/li&gt;
&lt;li&gt;generate a query&lt;/li&gt;
&lt;li&gt;validate the query&lt;/li&gt;
&lt;li&gt;return structured results&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The model does the language translation. The app still owns the safety checks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Run it
&lt;/h2&gt;

&lt;p&gt;Clone the examples repo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/team-telnyx/telnyx-code-examples.git
&lt;span class="nb"&gt;cd &lt;/span&gt;telnyx-code-examples/sql-natural-language-python
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create your &lt;code&gt;.env&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cp&lt;/span&gt; .env.example .env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add your Telnyx API key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TELNYX_API_KEY=your_telnyx_api_key
AI_MODEL=moonshotai/Kimi-K2.6
HOST=127.0.0.1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install and start:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
python app.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ask a question against the sample dataset:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://localhost:5000/query/sample &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"question": "Show me the top 3 customers by total order revenue"}'&lt;/span&gt; | python3 &lt;span class="nt"&gt;-m&lt;/span&gt; json.tool
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Validate a query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://localhost:5000/validate &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"sql": "SELECT * FROM orders WHERE total &amp;gt; 100"}'&lt;/span&gt; | python3 &lt;span class="nt"&gt;-m&lt;/span&gt; json.tool
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Where this could go
&lt;/h2&gt;

&lt;p&gt;This is a small API, but it maps to real internal tooling:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;analytics assistants&lt;/li&gt;
&lt;li&gt;support dashboards&lt;/li&gt;
&lt;li&gt;sales operations tools&lt;/li&gt;
&lt;li&gt;data warehouse query helpers&lt;/li&gt;
&lt;li&gt;product usage exploration&lt;/li&gt;
&lt;li&gt;internal admin tools&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The useful part is the boundary. The app does not blindly trust generated SQL. It asks for structured output, validates the query, and returns JSON that another system can inspect or display.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;p&gt;Code: &lt;a href="https://github.com/team-telnyx/telnyx-code-examples/tree/main/sql-natural-language-python" rel="noopener noreferrer"&gt;https://github.com/team-telnyx/telnyx-code-examples/tree/main/sql-natural-language-python&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Telnyx AI skills and toolkits: &lt;a href="https://github.com/team-telnyx/ai" rel="noopener noreferrer"&gt;https://github.com/team-telnyx/ai&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Telnyx AI Inference docs: &lt;a href="https://developers.telnyx.com/docs/inference" rel="noopener noreferrer"&gt;https://developers.telnyx.com/docs/inference&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Chat Completions API: &lt;a href="https://developers.telnyx.com/api/inference/chat-completions" rel="noopener noreferrer"&gt;https://developers.telnyx.com/api/inference/chat-completions&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Telnyx Portal: &lt;a href="https://portal.telnyx.com/" rel="noopener noreferrer"&gt;https://portal.telnyx.com/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>ai</category>
      <category>flask</category>
      <category>sql</category>
    </item>
    <item>
      <title>Build a Natural Language to SQL API in Python</title>
      <dc:creator>Sonam</dc:creator>
      <pubDate>Wed, 15 Jul 2026 23:21:04 +0000</pubDate>
      <link>https://dev.to/sonam_50a41a4ced7e6b4f3fa/build-a-natural-language-to-sql-api-in-python-3a7p</link>
      <guid>https://dev.to/sonam_50a41a4ced7e6b4f3fa/build-a-natural-language-to-sql-api-in-python-3a7p</guid>
      <description>&lt;p&gt;Most data questions start in plain English.&lt;/p&gt;

&lt;p&gt;"Which customers spent the most?"&lt;/p&gt;

&lt;p&gt;"How many orders are pending?"&lt;/p&gt;

&lt;p&gt;"What products generated revenue last month?"&lt;/p&gt;

&lt;p&gt;Someone can turn those questions into SQL, but that usually means waiting on a developer, analyst, or dashboard update.&lt;/p&gt;

&lt;p&gt;This Python example shows how to build a small natural language to SQL API with Telnyx AI Inference.&lt;/p&gt;

&lt;p&gt;Code: &lt;a href="https://github.com/team-telnyx/telnyx-code-examples/tree/main/sql-natural-language-python" rel="noopener noreferrer"&gt;https://github.com/team-telnyx/telnyx-code-examples/tree/main/sql-natural-language-python&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What it does
&lt;/h2&gt;

&lt;p&gt;The Flask app exposes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST /query
POST /query/sample
POST /validate
GET /queries
GET /queries/&amp;lt;id&amp;gt;
GET /health
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;POST /query&lt;/code&gt; accepts a natural-language question, SQL dialect, and schema DDL. It returns structured JSON with the generated SQL, explanation, tables used, and metadata.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;POST /query/sample&lt;/code&gt; uses a bundled SQLite sample dataset, so you can ask a question and see real rows come back without connecting a production database.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;POST /validate&lt;/code&gt; dry-runs a SQL string against the sample dataset.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why validation matters
&lt;/h2&gt;

&lt;p&gt;Natural language to SQL needs guardrails.&lt;/p&gt;

&lt;p&gt;This example asks the model for read-only SQL and then checks the generated query before execution. The validation layer rejects multiple statements, comments, and write-oriented SQL keywords.&lt;/p&gt;

&lt;p&gt;That keeps the example focused on the useful workflow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;ask a question&lt;/li&gt;
&lt;li&gt;include schema context&lt;/li&gt;
&lt;li&gt;generate a query&lt;/li&gt;
&lt;li&gt;validate the query&lt;/li&gt;
&lt;li&gt;return structured results&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The model does the language translation. The app still owns the safety checks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Run it
&lt;/h2&gt;

&lt;p&gt;Clone the examples repo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/team-telnyx/telnyx-code-examples.git
&lt;span class="nb"&gt;cd &lt;/span&gt;telnyx-code-examples/sql-natural-language-python
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create your &lt;code&gt;.env&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cp&lt;/span&gt; .env.example .env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add your Telnyx API key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TELNYX_API_KEY=your_telnyx_api_key
AI_MODEL=moonshotai/Kimi-K2.6
HOST=127.0.0.1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install and start:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
python app.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ask a question against the sample dataset:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://localhost:5000/query/sample &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"question": "Show me the top 3 customers by total order revenue"}'&lt;/span&gt; | python3 &lt;span class="nt"&gt;-m&lt;/span&gt; json.tool
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Validate a query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://localhost:5000/validate &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"sql": "SELECT * FROM orders WHERE total &amp;gt; 100"}'&lt;/span&gt; | python3 &lt;span class="nt"&gt;-m&lt;/span&gt; json.tool
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Where this could go
&lt;/h2&gt;

&lt;p&gt;This is a small API, but it maps to real internal tooling:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;analytics assistants&lt;/li&gt;
&lt;li&gt;support dashboards&lt;/li&gt;
&lt;li&gt;sales operations tools&lt;/li&gt;
&lt;li&gt;data warehouse query helpers&lt;/li&gt;
&lt;li&gt;product usage exploration&lt;/li&gt;
&lt;li&gt;internal admin tools&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The useful part is the boundary. The app does not blindly trust generated SQL. It asks for structured output, validates the query, and returns JSON that another system can inspect or display.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;p&gt;Code: &lt;a href="https://github.com/team-telnyx/telnyx-code-examples/tree/main/sql-natural-language-python" rel="noopener noreferrer"&gt;https://github.com/team-telnyx/telnyx-code-examples/tree/main/sql-natural-language-python&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Telnyx AI skills and toolkits: &lt;a href="https://github.com/team-telnyx/ai" rel="noopener noreferrer"&gt;https://github.com/team-telnyx/ai&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Telnyx AI Inference docs: &lt;a href="https://developers.telnyx.com/docs/inference" rel="noopener noreferrer"&gt;https://developers.telnyx.com/docs/inference&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Chat Completions API: &lt;a href="https://developers.telnyx.com/api/inference/chat-completions" rel="noopener noreferrer"&gt;https://developers.telnyx.com/api/inference/chat-completions&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Telnyx Portal: &lt;a href="https://portal.telnyx.com/" rel="noopener noreferrer"&gt;https://portal.telnyx.com/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>ai</category>
      <category>flask</category>
      <category>sql</category>
    </item>
    <item>
      <title>Build an AI Error Explainer in Python</title>
      <dc:creator>Sonam</dc:creator>
      <pubDate>Tue, 14 Jul 2026 20:51:36 +0000</pubDate>
      <link>https://dev.to/sonam_50a41a4ced7e6b4f3fa/build-an-ai-error-explainer-in-python-5gjn</link>
      <guid>https://dev.to/sonam_50a41a4ced7e6b4f3fa/build-an-ai-error-explainer-in-python-5gjn</guid>
      <description>&lt;p&gt;Stack traces are useful, but they are not always easy to act on quickly.&lt;/p&gt;

&lt;p&gt;When something breaks, you usually want more than the exception name. You want to know the likely root cause, how serious it is, where to look, and what fix to try first.&lt;/p&gt;

&lt;p&gt;This Python example turns a stack trace into structured debugging JSON using Telnyx AI Inference.&lt;/p&gt;

&lt;p&gt;Code: &lt;a href="https://github.com/team-telnyx/telnyx-code-examples/tree/feat/error-explainer-python/error-explainer-python" rel="noopener noreferrer"&gt;https://github.com/team-telnyx/telnyx-code-examples/tree/feat/error-explainer-python/error-explainer-python&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What it does
&lt;/h2&gt;

&lt;p&gt;The Flask app exposes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST /explain
GET /analyses
GET /analyses/&amp;lt;id&amp;gt;
GET /health
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;POST /explain&lt;/code&gt; accepts a stack trace, plus optional language and runtime context:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"language"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"python"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"context"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Flask production server with gunicorn"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"stack_trace"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Traceback (most recent call last):&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;  File &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;app.py&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;, line 42..."&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The app sends the trace to Telnyx AI Inference and asks for structured JSON:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"root_cause"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"The outbound HTTP call is failing because the downstream service is unreachable."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"severity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"high"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"confidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.91&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"likely_culprit"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"app.py:42"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"suggested_fix"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Add timeout handling and retry logic around the request."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"fix_snippet"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"resp = requests.post(url, timeout=15)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"related_errors"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"requests.exceptions.Timeout"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"prevention"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Set explicit timeouts for outbound HTTP calls."&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why this shape is useful
&lt;/h2&gt;

&lt;p&gt;Plain text explanations are nice for humans. Structured output is useful for apps.&lt;/p&gt;

&lt;p&gt;With this response shape, you could:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;show severity in a dashboard&lt;/li&gt;
&lt;li&gt;send high-severity errors to Slack&lt;/li&gt;
&lt;li&gt;attach a suggested fix to a CI failure&lt;/li&gt;
&lt;li&gt;store analyses for recurring incidents&lt;/li&gt;
&lt;li&gt;build an internal debugging assistant&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The example stores recent analyses in memory and lets you retrieve them by ID.&lt;/p&gt;

&lt;h2&gt;
  
  
  Run it
&lt;/h2&gt;

&lt;p&gt;Clone the examples repo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/team-telnyx/telnyx-code-examples.git
&lt;span class="nb"&gt;cd &lt;/span&gt;telnyx-code-examples
git switch feat/error-explainer-python
&lt;span class="nb"&gt;cd &lt;/span&gt;error-explainer-python
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create your &lt;code&gt;.env&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cp&lt;/span&gt; .env.example .env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add your Telnyx API key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TELNYX_API_KEY=your_telnyx_api_key
AI_MODEL=moonshotai/Kimi-K2.6
HOST=127.0.0.1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install and start:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
python app.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Try the health endpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://localhost:5000/health
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explain an error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://localhost:5000/explain &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "language": "python",
    "context": "Flask production server",
    "stack_trace": "KeyError: user_id"
  }'&lt;/span&gt; | python3 &lt;span class="nt"&gt;-m&lt;/span&gt; json.tool
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Where this could go
&lt;/h2&gt;

&lt;p&gt;This is a small example, but it maps pretty cleanly to real developer workflows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CI failure explanation&lt;/li&gt;
&lt;li&gt;incident triage&lt;/li&gt;
&lt;li&gt;Slack alerts&lt;/li&gt;
&lt;li&gt;support tooling&lt;/li&gt;
&lt;li&gt;internal platform dashboards&lt;/li&gt;
&lt;li&gt;framework-specific debugging assistants&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The useful part is not only that a model can explain an error. It is that the app gets back a predictable object it can route, store, display, or review.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;p&gt;Telnyx AI skills and toolkits: &lt;a href="https://github.com/team-telnyx/ai" rel="noopener noreferrer"&gt;https://github.com/team-telnyx/ai&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Telnyx AI Inference docs: &lt;a href="https://developers.telnyx.com/docs/inference" rel="noopener noreferrer"&gt;https://developers.telnyx.com/docs/inference&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Telnyx Portal: &lt;a href="https://portal.telnyx.com/" rel="noopener noreferrer"&gt;https://portal.telnyx.com/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>ai</category>
      <category>flask</category>
      <category>devtools</category>
    </item>
    <item>
      <title>Build an AI Changelog Generator in Python</title>
      <dc:creator>Sonam</dc:creator>
      <pubDate>Fri, 10 Jul 2026 00:27:18 +0000</pubDate>
      <link>https://dev.to/sonam_50a41a4ced7e6b4f3fa/build-an-ai-changelog-generator-in-python-2le9</link>
      <guid>https://dev.to/sonam_50a41a4ced7e6b4f3fa/build-an-ai-changelog-generator-in-python-2le9</guid>
      <description>&lt;p&gt;Writing changelogs is one of those developer tasks that sounds simple until you are staring at a messy commit history.&lt;/p&gt;

&lt;p&gt;Some commits matter to users. Some are internal cleanup. Some are merge commits. Some are meaningful only if you already know the codebase. I built a small Python example that turns commit messages or git diffs into structured changelog JSON using Telnyx AI Inference.&lt;/p&gt;

&lt;p&gt;Code: &lt;a href="https://github.com/team-telnyx/telnyx-code-examples/tree/main/changelog-generator-python" rel="noopener noreferrer"&gt;https://github.com/team-telnyx/telnyx-code-examples/tree/main/changelog-generator-python&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What it does
&lt;/h2&gt;

&lt;p&gt;The Flask app exposes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST /generate
POST /generate/from-diff
GET /changelogs
GET /changelogs/&amp;lt;id&amp;gt;
GET /health
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;POST /generate&lt;/code&gt; accepts a list of commit messages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"v1.4.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"repo_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"billing-service"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"commits"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"feat: add Stripe webhook retry with exponential backoff"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"fix: correct tax calculation for EU VAT exemption"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"docs: update API reference for invoice endpoint"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The app asks Telnyx AI Inference to return grouped changelog JSON with sections like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Features&lt;/li&gt;
&lt;li&gt;Bug Fixes&lt;/li&gt;
&lt;li&gt;Improvements&lt;/li&gt;
&lt;li&gt;Breaking Changes&lt;/li&gt;
&lt;li&gt;Documentation&lt;/li&gt;
&lt;li&gt;Other&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is also a &lt;code&gt;POST /generate/from-diff&lt;/code&gt; endpoint if you want to summarize a git diff instead of commit messages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why structured output matters
&lt;/h2&gt;

&lt;p&gt;For a changelog tool, plain text is useful, but structured output is more flexible.&lt;/p&gt;

&lt;p&gt;If the response comes back as JSON, you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;render it in a docs site&lt;/li&gt;
&lt;li&gt;save it in a release database&lt;/li&gt;
&lt;li&gt;post it into a PR comment&lt;/li&gt;
&lt;li&gt;send it to Slack&lt;/li&gt;
&lt;li&gt;open a release-note review workflow&lt;/li&gt;
&lt;li&gt;let a human approve it before publishing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The example stores generated changelogs in memory and gives each one an ID, so you can list recent changelogs or retrieve a specific one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Run it
&lt;/h2&gt;

&lt;p&gt;Clone the examples repo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/team-telnyx/telnyx-code-examples.git
&lt;span class="nb"&gt;cd &lt;/span&gt;telnyx-code-examples/changelog-generator-python
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create your &lt;code&gt;.env&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cp&lt;/span&gt; .env.example .env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add your Telnyx API key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TELNYX_API_KEY=your_telnyx_api_key
AI_MODEL=moonshotai/Kimi-K2.6
HOST=127.0.0.1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
python app.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Try it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://localhost:5000/generate &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "version": "v1.4.0",
    "repo_name": "billing-service",
    "commits": [
      "feat: add Stripe webhook retry with exponential backoff",
      "fix: correct tax calculation for EU VAT exemption",
      "docs: update API reference for invoice endpoint"
    ]
  }'&lt;/span&gt; | python3 &lt;span class="nt"&gt;-m&lt;/span&gt; json.tool
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Where this could go
&lt;/h2&gt;

&lt;p&gt;This is a small example, but it is a pretty practical developer tooling pattern:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;generate draft release notes from merged PRs&lt;/li&gt;
&lt;li&gt;summarize changes between two tags&lt;/li&gt;
&lt;li&gt;create changelog drafts during CI&lt;/li&gt;
&lt;li&gt;generate per-SDK release notes&lt;/li&gt;
&lt;li&gt;publish to docs after human approval&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Telnyx code examples repo is also agent-readable, so you can use this example as a starting point and ask a coding agent to add GitHub integration, tag comparison, a UI, or a docs publishing step.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Telnyx AI skills and toolkits: &lt;a href="https://github.com/team-telnyx/ai" rel="noopener noreferrer"&gt;https://github.com/team-telnyx/ai&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Telnyx AI Inference docs: &lt;a href="https://developers.telnyx.com/docs/inference" rel="noopener noreferrer"&gt;https://developers.telnyx.com/docs/inference&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>python</category>
      <category>ai</category>
      <category>flask</category>
      <category>devtools</category>
    </item>
    <item>
      <title>Build a CDR Usage Analytics Dashboard in Python</title>
      <dc:creator>Sonam</dc:creator>
      <pubDate>Thu, 09 Jul 2026 19:09:39 +0000</pubDate>
      <link>https://dev.to/sonam_50a41a4ced7e6b4f3fa/build-a-cdr-usage-analytics-dashboard-in-python-1cbh</link>
      <guid>https://dev.to/sonam_50a41a4ced7e6b4f3fa/build-a-cdr-usage-analytics-dashboard-in-python-1cbh</guid>
      <description>&lt;p&gt;Raw Call Detail Records are useful, but they are not exactly fun to read.&lt;/p&gt;

&lt;p&gt;If you are building with voice, messaging, or any communications workflow, CDR-style data can answer practical questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How many calls happened in a date range?&lt;/li&gt;
&lt;li&gt;What did usage cost?&lt;/li&gt;
&lt;li&gt;Which hours are busiest?&lt;/li&gt;
&lt;li&gt;Which routes are most active?&lt;/li&gt;
&lt;li&gt;Are short calls or failed calls increasing?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I put together a small Python example that turns Telnyx CDR data into a Flask analytics API, then uses Telnyx AI Inference to generate a short operational readout.&lt;/p&gt;

&lt;p&gt;Code: &lt;a href="https://github.com/team-telnyx/telnyx-code-examples/tree/main/cdr-usage-analytics-dashboard-python" rel="noopener noreferrer"&gt;https://github.com/team-telnyx/telnyx-code-examples/tree/main/cdr-usage-analytics-dashboard-python&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What it exposes
&lt;/h2&gt;

&lt;p&gt;The example includes these routes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET /cdrs
GET /analytics/summary
GET /analytics/peak-hours
GET /analytics/top-routes
GET /analytics/daily
GET /analytics/ai-insights
GET /health
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The analytics routes do the normal dashboard work in Python:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;total call count&lt;/li&gt;
&lt;li&gt;total, average, median, and p95 duration&lt;/li&gt;
&lt;li&gt;total, average, and max cost&lt;/li&gt;
&lt;li&gt;grouped counts by direction, call type, and status&lt;/li&gt;
&lt;li&gt;peak-hour distribution&lt;/li&gt;
&lt;li&gt;top route breakdowns&lt;/li&gt;
&lt;li&gt;daily call and cost totals&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then &lt;code&gt;/analytics/ai-insights&lt;/code&gt; takes a compact summary of the metrics and sends it to Telnyx AI Inference through the chat completions API.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why not ask the model to calculate everything?
&lt;/h2&gt;

&lt;p&gt;Because the model should not be the calculator here.&lt;/p&gt;

&lt;p&gt;For this kind of app, I like the split:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Code calculates the metrics that need to be exact.&lt;/li&gt;
&lt;li&gt;The LLM explains the trend and suggests what to investigate next.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That way, your totals and costs stay deterministic, but your dashboard can still give users a helpful plain-English summary.&lt;/p&gt;

&lt;h2&gt;
  
  
  Run it
&lt;/h2&gt;

&lt;p&gt;Clone the examples repo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/team-telnyx/telnyx-code-examples.git
&lt;span class="nb"&gt;cd &lt;/span&gt;telnyx-code-examples/cdr-usage-analytics-dashboard-python
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create your &lt;code&gt;.env&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cp&lt;/span&gt; .env.example .env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add your Telnyx API key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TELNYX_API_KEY=your_telnyx_api_key
AI_MODEL=moonshotai/Kimi-K2.6
HOST=127.0.0.1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
python app.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Test it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://localhost:5000/health
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Get a summary:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="s2"&gt;"http://localhost:5000/analytics/summary?start_date=2026-07-01&amp;amp;end_date=2026-07-08"&lt;/span&gt; | python3 &lt;span class="nt"&gt;-m&lt;/span&gt; json.tool
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ask for AI insights:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://localhost:5000/analytics/ai-insights | python3 &lt;span class="nt"&gt;-m&lt;/span&gt; json.tool
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Where this could go
&lt;/h2&gt;

&lt;p&gt;This is intentionally small, but the pattern is useful:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;add a UI for support or ops teams&lt;/li&gt;
&lt;li&gt;store daily snapshots in a database&lt;/li&gt;
&lt;li&gt;send weekly summaries to Slack&lt;/li&gt;
&lt;li&gt;alert when costs spike&lt;/li&gt;
&lt;li&gt;detect unusual short-call patterns&lt;/li&gt;
&lt;li&gt;compare usage by campaign, customer, or region&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The repo is also agent-readable, so you can point a coding agent at the example and ask it to extend the dashboard, add charts, wire in auth, or adapt the metrics to your own workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Code: &lt;a href="https://github.com/team-telnyx/telnyx-code-examples/tree/main/cdr-usage-analytics-dashboard-python" rel="noopener noreferrer"&gt;https://github.com/team-telnyx/telnyx-code-examples/tree/main/cdr-usage-analytics-dashboard-python&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Telnyx AI skills and toolkits: &lt;a href="https://github.com/team-telnyx/ai" rel="noopener noreferrer"&gt;https://github.com/team-telnyx/ai&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Telnyx AI Inference docs: &lt;a href="https://developers.telnyx.com/docs/inference" rel="noopener noreferrer"&gt;https://developers.telnyx.com/docs/inference&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Chat Completions API: &lt;a href="https://developers.telnyx.com/api/inference/chat-completions" rel="noopener noreferrer"&gt;https://developers.telnyx.com/api/inference/chat-completions&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Telnyx Portal: &lt;a href="https://portal.telnyx.com/" rel="noopener noreferrer"&gt;https://portal.telnyx.com/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>python</category>
      <category>flask</category>
      <category>ai</category>
      <category>analytics</category>
    </item>
    <item>
      <title>Build a Fax-to-JSON Pipeline in Python</title>
      <dc:creator>Sonam</dc:creator>
      <pubDate>Wed, 08 Jul 2026 01:47:48 +0000</pubDate>
      <link>https://dev.to/sonam_50a41a4ced7e6b4f3fa/build-a-fax-to-json-pipeline-in-python-4hc4</link>
      <guid>https://dev.to/sonam_50a41a4ced7e6b4f3fa/build-a-fax-to-json-pipeline-in-python-4hc4</guid>
      <description>&lt;p&gt;Fax is still part of a lot of real business workflows.&lt;/p&gt;

&lt;p&gt;Healthcare, insurance, logistics, legal, finance, and back-office teams still receive forms, invoices, purchase orders, prescriptions, claims, and signed documents by fax. The problem is what happens after the fax arrives.&lt;/p&gt;

&lt;p&gt;This Python example shows how to receive a Telnyx fax event and turn document text into structured JSON with Telnyx AI Inference:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/team-telnyx/telnyx-code-examples/tree/main/fax-to-structured-data-pipeline-python" rel="noopener noreferrer"&gt;https://github.com/team-telnyx/telnyx-code-examples/tree/main/fax-to-structured-data-pipeline-python&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What We Are Building
&lt;/h2&gt;

&lt;p&gt;The app is a small Flask API with these routes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST /webhooks/fax   # receive Telnyx fax events
POST /extract        # extract structured data from document text
GET  /faxes          # list queued fax metadata
GET  /extracted      # list recent extraction results
GET  /health         # health check
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The extraction route supports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;invoices&lt;/li&gt;
&lt;li&gt;purchase orders&lt;/li&gt;
&lt;li&gt;prescriptions&lt;/li&gt;
&lt;li&gt;auto-detected document types&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The AI call uses:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST /v2/ai/chat/completions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Run It Locally
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/team-telnyx/telnyx-code-examples.git
&lt;span class="nb"&gt;cd &lt;/span&gt;telnyx-code-examples/fax-to-structured-data-pipeline-python
&lt;span class="nb"&gt;cp&lt;/span&gt; .env.example .env
pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
python app.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Set these values in &lt;code&gt;.env&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TELNYX_API_KEY=your_telnyx_api_key
TELNYX_PUBLIC_KEY=your_telnyx_public_key
AI_MODEL=moonshotai/Kimi-K2.6
HOST=127.0.0.1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Try the Extraction Endpoint
&lt;/h2&gt;

&lt;p&gt;You do not need to send a live fax to test the extraction path. Send document text directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://localhost:5000/extract &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "type": "invoice",
    "text": "Invoice #INV-1042 from Acme Medical Supplies dated 2026-07-01. Due 2026-07-31. Bill to North Clinic. Item: Nitrile gloves, quantity 10, unit price 12.50, total 125.00. Item: Face masks, quantity 5, unit price 20.00, total 100.00. Subtotal 225.00. Tax 18.00. Total 243.00. Payment terms Net 30."
  }'&lt;/span&gt; | python3 &lt;span class="nt"&gt;-m&lt;/span&gt; json.tool
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The app asks the model for invoice-shaped JSON:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"vendor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Acme Medical Supplies"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"invoice_number"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"INV-1042"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"date"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-07-01"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"due_date"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-07-31"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"line_items"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Nitrile gloves"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"quantity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"unit_price"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;12.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"total"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;125&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"subtotal"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;225&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"tax"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"total"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;243&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"payment_terms"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Net 30"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Try Auto Detection
&lt;/h2&gt;

&lt;p&gt;Use &lt;code&gt;type: "auto"&lt;/code&gt; when you want the model to infer the document type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://localhost:5000/extract &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "type": "auto",
    "text": "Purchase Order PO-7781. Vendor: Harbor Office Supply. Ship to: 500 Market St, San Francisco, CA. SKU CHAIR-22, ergonomic chair, quantity 12, unit price 199.00. Total 2388.00. Delivery requested 2026-07-20."
  }'&lt;/span&gt; | python3 &lt;span class="nt"&gt;-m&lt;/span&gt; json.tool
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How the Fax Webhook Fits In
&lt;/h2&gt;

&lt;p&gt;The live fax route is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST /webhooks/fax
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The app verifies the Telnyx webhook signature before trusting the event. When it receives &lt;code&gt;fax.received&lt;/code&gt;, it queues metadata like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;fax ID&lt;/li&gt;
&lt;li&gt;sender&lt;/li&gt;
&lt;li&gt;recipient&lt;/li&gt;
&lt;li&gt;page count&lt;/li&gt;
&lt;li&gt;media URL&lt;/li&gt;
&lt;li&gt;status&lt;/li&gt;
&lt;li&gt;timestamp&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For local webhook testing, expose your app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ngrok http 5000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then set your Telnyx Fax Application webhook URL to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://&amp;lt;id&amp;gt;.ngrok.io/webhooks/fax
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Production Notes
&lt;/h2&gt;

&lt;p&gt;The demo keeps state in memory. For production, I would add:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;media download from the fax &lt;code&gt;media_url&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;OCR before extraction&lt;/li&gt;
&lt;li&gt;persistent storage&lt;/li&gt;
&lt;li&gt;schema validation per document type&lt;/li&gt;
&lt;li&gt;retry handling&lt;/li&gt;
&lt;li&gt;human review for regulated data&lt;/li&gt;
&lt;li&gt;audit logs and retention policies&lt;/li&gt;
&lt;li&gt;queue workers for high-volume intake&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The example repo is also agent-readable. A coding agent can inspect the README, API reference, guide, environment file, and app code, then help you add OCR, storage, tests, queue workers, or stricter validation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Code: &lt;a href="https://github.com/team-telnyx/telnyx-code-examples/tree/main/fax-to-structured-data-pipeline-python" rel="noopener noreferrer"&gt;https://github.com/team-telnyx/telnyx-code-examples/tree/main/fax-to-structured-data-pipeline-python&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Telnyx AI skills and toolkits: &lt;a href="https://github.com/team-telnyx/ai" rel="noopener noreferrer"&gt;https://github.com/team-telnyx/ai&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Telnyx Fax docs: &lt;a href="https://developers.telnyx.com/docs/programmable-fax/send-a-fax-api" rel="noopener noreferrer"&gt;https://developers.telnyx.com/docs/programmable-fax/send-a-fax-api&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Telnyx AI Inference docs: &lt;a href="https://developers.telnyx.com/docs/inference" rel="noopener noreferrer"&gt;https://developers.telnyx.com/docs/inference&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Chat Completions API: &lt;a href="https://developers.telnyx.com/api/inference/chat-completions" rel="noopener noreferrer"&gt;https://developers.telnyx.com/api/inference/chat-completions&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Telnyx Portal: &lt;a href="https://portal.telnyx.com/" rel="noopener noreferrer"&gt;https://portal.telnyx.com/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>telnyx</category>
      <category>ai</category>
      <category>python</category>
      <category>devrel</category>
    </item>
    <item>
      <title>Keep Outbound Numbers Healthy with AI</title>
      <dc:creator>Sonam</dc:creator>
      <pubDate>Tue, 30 Jun 2026 23:52:18 +0000</pubDate>
      <link>https://dev.to/sonam_50a41a4ced7e6b4f3fa/keep-outbound-numbers-healthy-with-ai-1i62</link>
      <guid>https://dev.to/sonam_50a41a4ced7e6b4f3fa/keep-outbound-numbers-healthy-with-ai-1i62</guid>
      <description>&lt;p&gt;Subtitle: Build a Python app that monitors Telnyx phone numbers, analyzes reputation risk with Telnyx AI Inference, and recommends when to keep, rotate, or retire a number.&lt;/p&gt;

&lt;p&gt;Outbound workflows depend on number health more than most teams want to admit.&lt;/p&gt;

&lt;p&gt;A number can look fine in inventory and still perform badly in the real world. Answer rates drop. Complaints increase. Campaign patterns get stale. A number that worked last month might need a cooldown, a review, or a replacement today.&lt;/p&gt;

&lt;p&gt;That is the workflow behind this example:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/team-telnyx/telnyx-code-examples/tree/main/number-reputation-monitor-auto-rotate-python" rel="noopener noreferrer"&gt;https://github.com/team-telnyx/telnyx-code-examples/tree/main/number-reputation-monitor-auto-rotate-python&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is a small Python Flask app that lists your Telnyx phone numbers, sends number-health context to Telnyx AI Inference, and records a recommendation: keep, rotate, or retire.&lt;/p&gt;

&lt;h2&gt;
  
  
  The App Shape
&lt;/h2&gt;

&lt;p&gt;The app exposes three routes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;POST /scan&lt;/code&gt; to analyze up to 20 numbers&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;GET /health-report&lt;/code&gt; to inspect tracked number health and rotation recommendations&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;GET /health&lt;/code&gt; for app health&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It uses two Telnyx APIs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET /v2/phone_numbers
POST /v2/ai/chat/completions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The current default model is set in &lt;code&gt;.env.example&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AI_MODEL=MiniMaxAI/MiniMax-M3-MXFP8
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The pattern is simple: pull number inventory, attach health metrics, ask the model for a constrained recommendation, and store the result.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Happens During a Scan
&lt;/h2&gt;

&lt;p&gt;You start the scan like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://localhost:5000/scan &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The app calls Telnyx to list phone numbers, then analyzes up to the first 20 numbers.&lt;/p&gt;

&lt;p&gt;For each number, it builds a small health payload. In the sample, the default metrics are intentionally simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"calls"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"complaints"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"answer_rate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"number"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"+12125551234"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then the app asks the model to return JSON like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"risk_level"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"warning"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"recommendation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"rotate"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"reasoning"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Answer rate is low and complaint activity is elevated"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the recommendation is &lt;code&gt;rotate&lt;/code&gt;, the app records it in a rotation log.&lt;/p&gt;

&lt;p&gt;That is important: this sample does not automatically swap live numbers. It logs the recommendation. In a real outbound system, rotation should usually include policy checks, campaign state, routing rules, and human approval.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Is Useful
&lt;/h2&gt;

&lt;p&gt;Number reputation is not a single flag.&lt;/p&gt;

&lt;p&gt;It is usually a collection of signals:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;answer rates&lt;/li&gt;
&lt;li&gt;complaints&lt;/li&gt;
&lt;li&gt;opt-outs&lt;/li&gt;
&lt;li&gt;call volume&lt;/li&gt;
&lt;li&gt;campaign history&lt;/li&gt;
&lt;li&gt;carrier filtering signals&lt;/li&gt;
&lt;li&gt;recent routing behavior&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A model is useful here when it is not asked to invent a decision from nothing. It is useful when it gets structured operational context and returns a constrained recommendation.&lt;/p&gt;

&lt;p&gt;That makes the output easier to route into a dashboard, review queue, or outbound routing system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Inspect the Health Report
&lt;/h2&gt;

&lt;p&gt;After a scan, you can inspect current state:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://localhost:5000/health-report
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response includes tracked numbers and recent rotation recommendations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"numbers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"+12125551234"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"calls"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"complaints"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"answer_rate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"analysis"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"risk_level"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"warning"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"recommendation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"rotate"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"reasoning"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Example reason"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"rotations"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That structure gives you a starting point for a real number-health dashboard.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Small Detail That Matters
&lt;/h2&gt;

&lt;p&gt;The prompt asks the model to return only JSON, with no prose and no markdown fences.&lt;/p&gt;

&lt;p&gt;The app still includes a helper to strip markdown fences and parse the JSON object. I like that pattern because AI app code should be defensive. Prompts help, but validation is what keeps the output usable as application state.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Would Add Next
&lt;/h2&gt;

&lt;p&gt;For production, I would add:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Real metrics from calls, messages, opt-outs, complaints, and campaign outcomes&lt;/li&gt;
&lt;li&gt;Persistent storage for number history&lt;/li&gt;
&lt;li&gt;Scheduled scans instead of manual scans&lt;/li&gt;
&lt;li&gt;Alerts for critical numbers&lt;/li&gt;
&lt;li&gt;Human approval before rotation or retirement&lt;/li&gt;
&lt;li&gt;Routing rules that remove risky numbers from active campaigns&lt;/li&gt;
&lt;li&gt;Warmup and cooldown policies&lt;/li&gt;
&lt;li&gt;Audit logs for every recommendation and action&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The repo is also structured to be agent-readable. Your coding agent can inspect the README, API reference, guide, environment file, and app code, then help extend it. You can ask it to add scheduled scans, persistent metrics, tests, dashboards, or real routing integration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;p&gt;Code:&lt;br&gt;
&lt;a href="https://github.com/team-telnyx/telnyx-code-examples/tree/main/number-reputation-monitor-auto-rotate-python" rel="noopener noreferrer"&gt;https://github.com/team-telnyx/telnyx-code-examples/tree/main/number-reputation-monitor-auto-rotate-python&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Telnyx AI skills and toolkits:&lt;br&gt;
&lt;a href="https://github.com/team-telnyx/ai" rel="noopener noreferrer"&gt;https://github.com/team-telnyx/ai&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;List Phone Numbers API:&lt;br&gt;
&lt;a href="https://developers.telnyx.com/api/numbers/list-phone-numbers" rel="noopener noreferrer"&gt;https://developers.telnyx.com/api/numbers/list-phone-numbers&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Telnyx AI Inference docs:&lt;br&gt;
&lt;a href="https://developers.telnyx.com/docs/inference" rel="noopener noreferrer"&gt;https://developers.telnyx.com/docs/inference&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Chat Completions API:&lt;br&gt;
&lt;a href="https://developers.telnyx.com/api/inference/chat-completions" rel="noopener noreferrer"&gt;https://developers.telnyx.com/api/inference/chat-completions&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Telnyx Portal:&lt;br&gt;
&lt;a href="https://portal.telnyx.com/" rel="noopener noreferrer"&gt;https://portal.telnyx.com/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>telnyx</category>
      <category>ai</category>
      <category>devrel</category>
    </item>
    <item>
      <title>Turn Phone Numbers into Lead Signals</title>
      <dc:creator>Sonam</dc:creator>
      <pubDate>Tue, 30 Jun 2026 22:14:22 +0000</pubDate>
      <link>https://dev.to/sonam_50a41a4ced7e6b4f3fa/turn-phone-numbers-into-lead-signals-3f7k</link>
      <guid>https://dev.to/sonam_50a41a4ced7e6b4f3fa/turn-phone-numbers-into-lead-signals-3f7k</guid>
      <description>&lt;p&gt;Subtitle: Build a Python app that combines Telnyx Number Lookup with Telnyx AI Inference to qualify leads and recommend the best follow-up channel.&lt;/p&gt;

&lt;p&gt;A lead form usually gives you just enough information to create a question.&lt;/p&gt;

&lt;p&gt;Someone enters a name, an email address, maybe a phone number, and maybe a note about what they want. Now the app has to decide what happens next. Does this lead go to sales? Should the first touch be SMS or voice? Is the phone number even usable?&lt;/p&gt;

&lt;p&gt;That is the workflow behind this example:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/team-telnyx/telnyx-code-examples/tree/main/number-lookup-lead-enrichment-python" rel="noopener noreferrer"&gt;https://github.com/team-telnyx/telnyx-code-examples/tree/main/number-lookup-lead-enrichment-python&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is a small Python Flask app that takes a phone number, enriches it with Telnyx Number Lookup, then uses Telnyx AI Inference to score the lead and recommend a follow-up channel.&lt;/p&gt;

&lt;h2&gt;
  
  
  The App Shape
&lt;/h2&gt;

&lt;p&gt;The app exposes three routes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;POST /enrich&lt;/code&gt; for one phone number&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;POST /enrich/bulk&lt;/code&gt; for up to 50 phone numbers&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;GET /health&lt;/code&gt; for app health&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It uses two Telnyx APIs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET /v2/number_lookup/{phone}
POST /v2/ai/chat/completions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The current default model is set in &lt;code&gt;.env.example&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AI_MODEL=MiniMaxAI/MiniMax-M3-MXFP8
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The pattern is simple: gather phone intelligence first, then use an inference model to turn that data into a lead-quality decision.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Goes In
&lt;/h2&gt;

&lt;p&gt;The request is intentionally small:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://localhost:5000/enrich &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "phone_number": "+12125550123"
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The app looks up the number and extracts fields like carrier name, carrier type, caller name, line type, country, and validity.&lt;/p&gt;

&lt;p&gt;Then it asks the model to return JSON like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"lead_quality"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"hot"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"reasoning"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Valid mobile number with usable carrier data"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"is_mobile"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"is_voip"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"recommended_channel"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sms"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That response is much easier to build with than a paragraph. A product can route it, store it, show it in a CRM, or use it to kick off a workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Is Useful
&lt;/h2&gt;

&lt;p&gt;Lead enrichment usually turns into a pile of small decisions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is this number valid?&lt;/li&gt;
&lt;li&gt;Is it likely mobile?&lt;/li&gt;
&lt;li&gt;Is it VoIP?&lt;/li&gt;
&lt;li&gt;Is there carrier context?&lt;/li&gt;
&lt;li&gt;Should this lead be contacted by SMS, voice, or email?&lt;/li&gt;
&lt;li&gt;Should it go into a high-priority queue?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Number Lookup gives you the underlying phone intelligence. AI Inference lets you apply a lightweight reasoning layer over that data.&lt;/p&gt;

&lt;p&gt;That is a nice AI app pattern because the model is not doing everything. It is operating on structured context from a real API.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Small Detail That Matters
&lt;/h2&gt;

&lt;p&gt;The app asks the model to return only JSON, with no prose and no markdown fences.&lt;/p&gt;

&lt;p&gt;It still includes a helper to strip markdown fences and parse the JSON object. I like that because AI app code should be defensive. Prompts reduce variance, but validation is what keeps the output safe to use in an application.&lt;/p&gt;

&lt;p&gt;The example keeps everything readable in one Flask app, which makes it easy to adapt.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Would Add Next
&lt;/h2&gt;

&lt;p&gt;For production, I would add:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;E.164 normalization before lookup&lt;/li&gt;
&lt;li&gt;Persistent storage for enriched leads&lt;/li&gt;
&lt;li&gt;Auth on the API endpoints&lt;/li&gt;
&lt;li&gt;Retry handling for lookup and inference calls&lt;/li&gt;
&lt;li&gt;CRM integration&lt;/li&gt;
&lt;li&gt;Rate limiting for bulk enrichment&lt;/li&gt;
&lt;li&gt;More explicit schemas for lead scoring&lt;/li&gt;
&lt;li&gt;Human review for ambiguous high-value leads&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The repo is also structured to be agent-readable. Your coding agent can inspect the README, API reference, guide, environment file, and app code, then help extend it. You can ask it to add CRM writes, tests, stricter validation, or a scheduled enrichment job.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;p&gt;Code:&lt;br&gt;
&lt;a href="https://github.com/team-telnyx/telnyx-code-examples/tree/main/number-lookup-lead-enrichment-python" rel="noopener noreferrer"&gt;https://github.com/team-telnyx/telnyx-code-examples/tree/main/number-lookup-lead-enrichment-python&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Telnyx AI skills and toolkits:&lt;br&gt;
&lt;a href="https://github.com/team-telnyx/ai" rel="noopener noreferrer"&gt;https://github.com/team-telnyx/ai&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Number Lookup API:&lt;br&gt;
&lt;a href="https://developers.telnyx.com/api/number-lookup/lookup" rel="noopener noreferrer"&gt;https://developers.telnyx.com/api/number-lookup/lookup&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Telnyx AI Inference docs:&lt;br&gt;
&lt;a href="https://developers.telnyx.com/docs/inference" rel="noopener noreferrer"&gt;https://developers.telnyx.com/docs/inference&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Chat Completions API:&lt;br&gt;
&lt;a href="https://developers.telnyx.com/api/inference/chat-completions" rel="noopener noreferrer"&gt;https://developers.telnyx.com/api/inference/chat-completions&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Telnyx Portal:&lt;br&gt;
&lt;a href="https://portal.telnyx.com/" rel="noopener noreferrer"&gt;https://portal.telnyx.com/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>telnyx</category>
      <category>ai</category>
      <category>devrel</category>
    </item>
    <item>
      <title>Predict Churn Before Customers Leave</title>
      <dc:creator>Sonam</dc:creator>
      <pubDate>Tue, 30 Jun 2026 21:48:29 +0000</pubDate>
      <link>https://dev.to/sonam_50a41a4ced7e6b4f3fa/predict-churn-before-customers-leave-36m6</link>
      <guid>https://dev.to/sonam_50a41a4ced7e6b4f3fa/predict-churn-before-customers-leave-36m6</guid>
      <description>&lt;p&gt;Subtitle: Build a Python app with Telnyx AI Inference that turns customer activity signals into churn risk, recommended actions, and retention next steps.&lt;/p&gt;

&lt;p&gt;Most customer churn is only surprising because the signals were scattered.&lt;/p&gt;

&lt;p&gt;Usage dropped in one place. Support tickets went up somewhere else. A renewal date got closer. A login did not happen for two weeks. Payment issues started showing up. None of those signals alone proves a customer is leaving, but together they usually tell a story.&lt;/p&gt;

&lt;p&gt;That is the workflow I wanted to make easier to build: take customer activity data, pass it through an inference model, and return a structured churn assessment that a product or customer success team can actually use.&lt;/p&gt;

&lt;p&gt;The example is here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/team-telnyx/telnyx-code-examples/tree/main/ai-customer-churn-predictor-python" rel="noopener noreferrer"&gt;https://github.com/team-telnyx/telnyx-code-examples/tree/main/ai-customer-churn-predictor-python&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is a small Flask app using Telnyx AI Inference through the chat-completions API.&lt;/p&gt;

&lt;h2&gt;
  
  
  The App Shape
&lt;/h2&gt;

&lt;p&gt;The app exposes a few routes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;POST /predict&lt;/code&gt; for one customer&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;POST /predict/batch&lt;/code&gt; for up to 20 customers&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;GET /predictions&lt;/code&gt; for recent in-memory predictions&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;GET /health&lt;/code&gt; for app health&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The current default model is set in &lt;code&gt;.env.example&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AI_MODEL=moonshotai/Kimi-K2.6
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Under the hood, the app calls:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST https://api.telnyx.com/v2/ai/chat/completions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The prompt asks the model to behave like a customer success analyst and return JSON only. That is the important part. This is not a chatbot. It is an application endpoint that produces structured output.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Goes In
&lt;/h2&gt;

&lt;p&gt;A request can look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://localhost:5000/predict &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "customer_id": "CUST-123",
    "call_volumes": [120, 105, 80, 55],
    "message_volumes": [450, 420, 300, 190],
    "support_tickets": 6,
    "account_age_months": 18,
    "renewal_days": 21,
    "last_login_days": 14,
    "payment_issues": 1
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Those fields are deliberately simple. The point is to show the pattern, not to pretend this is a full enterprise churn model.&lt;/p&gt;

&lt;p&gt;The model gets the trend data, support context, account age, renewal window, login recency, and payment issues. Then it returns risk, probability, risk factors, recommended actions, urgency, and revenue-at-risk context.&lt;/p&gt;

&lt;p&gt;That response can feed a dashboard, trigger a customer success task, create a review queue, or become part of a larger retention workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I Like This Pattern
&lt;/h2&gt;

&lt;p&gt;A lot of AI product ideas start with a blank chat box.&lt;/p&gt;

&lt;p&gt;But many useful AI apps are not blank chat boxes. They are small decision endpoints with clear inputs and clear outputs.&lt;/p&gt;

&lt;p&gt;For churn prediction, the output shape matters:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"churn_risk"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"high"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"probability"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.82&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"risk_factors"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"Usage declined over the last four months"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"Support tickets increased"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"Renewal date is approaching"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"recommended_actions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"Schedule an account review this week"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"Investigate open support ticket themes"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"urgency"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"this_week"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is easier to build with than a paragraph. You can sort it, store it, validate it, route it, or show it in a product.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Small Detail That Matters
&lt;/h2&gt;

&lt;p&gt;The app asks for JSON, but it still treats model output carefully.&lt;/p&gt;

&lt;p&gt;It includes a helper that strips markdown fences and extracts the JSON object before parsing. That is the sort of thing you want in AI apps. Prompts help, but validation still matters.&lt;/p&gt;

&lt;p&gt;The sample keeps the implementation readable so developers can inspect the whole flow in one file.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Would Add Next
&lt;/h2&gt;

&lt;p&gt;The example uses in-memory storage because it is meant to be easy to run locally. In production, I would add:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Persistent storage for predictions&lt;/li&gt;
&lt;li&gt;Auth on the API routes&lt;/li&gt;
&lt;li&gt;A real customer data source&lt;/li&gt;
&lt;li&gt;Strict schema validation&lt;/li&gt;
&lt;li&gt;Batch processing through a queue&lt;/li&gt;
&lt;li&gt;Alerting for high-risk accounts&lt;/li&gt;
&lt;li&gt;Human review before customer-facing interventions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The repo is also structured to be agent-readable. That means your coding agent can inspect the README, API reference, guide, environment file, and app code, then help you extend it. You can ask it to add persistence, write tests, connect the output to a CRM, or turn the batch endpoint into a scheduled workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;p&gt;Code:&lt;br&gt;
&lt;a href="https://github.com/team-telnyx/telnyx-code-examples/tree/main/ai-customer-churn-predictor-python" rel="noopener noreferrer"&gt;https://github.com/team-telnyx/telnyx-code-examples/tree/main/ai-customer-churn-predictor-python&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Telnyx AI skills and toolkits:&lt;br&gt;
&lt;a href="https://github.com/team-telnyx/ai" rel="noopener noreferrer"&gt;https://github.com/team-telnyx/ai&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Telnyx AI Inference docs:&lt;br&gt;
&lt;a href="https://developers.telnyx.com/docs/inference" rel="noopener noreferrer"&gt;https://developers.telnyx.com/docs/inference&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Chat Completions API:&lt;br&gt;
&lt;a href="https://developers.telnyx.com/api/inference/chat-completions" rel="noopener noreferrer"&gt;https://developers.telnyx.com/api/inference/chat-completions&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Telnyx Portal:&lt;br&gt;
&lt;a href="https://portal.telnyx.com/" rel="noopener noreferrer"&gt;https://portal.telnyx.com/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>telnyx</category>
      <category>ai</category>
      <category>devrel</category>
    </item>
    <item>
      <title>Build an AI Audio Translator in Python on Telnyx Inference</title>
      <dc:creator>Sonam</dc:creator>
      <pubDate>Fri, 26 Jun 2026 22:14:42 +0000</pubDate>
      <link>https://dev.to/sonam_50a41a4ced7e6b4f3fa/build-an-ai-audio-translator-in-python-on-telnyx-inference-5e0g</link>
      <guid>https://dev.to/sonam_50a41a4ced7e6b4f3fa/build-an-ai-audio-translator-in-python-on-telnyx-inference-5e0g</guid>
      <description>&lt;p&gt;A lot of AI apps are starting to mix voice, language models, and generated audio.&lt;/p&gt;

&lt;p&gt;I built a small Python example that shows that full loop:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;take an audio file&lt;/li&gt;
&lt;li&gt;transcribe it&lt;/li&gt;
&lt;li&gt;translate the transcript with an LLM&lt;/li&gt;
&lt;li&gt;generate translated speech&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Repo: &lt;a href="https://github.com/team-telnyx/telnyx-code-examples/tree/main/ai-content-translator-python" rel="noopener noreferrer"&gt;https://github.com/team-telnyx/telnyx-code-examples/tree/main/ai-content-translator-python&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What it does
&lt;/h2&gt;

&lt;p&gt;The app exposes a Flask API for translating spoken content.&lt;/p&gt;

&lt;p&gt;You send it an audio file and a target language. It returns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the original transcript&lt;/li&gt;
&lt;li&gt;the translated text&lt;/li&gt;
&lt;li&gt;generated translated audio&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So instead of only translating text, the example shows a practical speech-to-speech style workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this pattern is useful
&lt;/h2&gt;

&lt;p&gt;This kind of flow can be useful for apps that need multilingual voice experiences, like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;customer support tools&lt;/li&gt;
&lt;li&gt;education apps&lt;/li&gt;
&lt;li&gt;internal enablement content&lt;/li&gt;
&lt;li&gt;voice agents&lt;/li&gt;
&lt;li&gt;media localization&lt;/li&gt;
&lt;li&gt;accessibility workflows&lt;/li&gt;
&lt;li&gt;product tutorials in multiple languages&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The important part is that each step stays understandable. Speech-to-text, translation, and text-to-speech are separate pieces, so you can debug or replace one part without rewriting the whole app.&lt;/p&gt;

&lt;h2&gt;
  
  
  How the example works
&lt;/h2&gt;

&lt;p&gt;The app uses Telnyx APIs for the voice and AI parts of the workflow.&lt;/p&gt;

&lt;p&gt;At a high level:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Upload source audio&lt;/li&gt;
&lt;li&gt;Transcribe the audio&lt;/li&gt;
&lt;li&gt;Send the transcript to an LLM for translation&lt;/li&gt;
&lt;li&gt;Generate speech from the translated text&lt;/li&gt;
&lt;li&gt;Return text plus audio output&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That gives you a clean starting point for building your own multilingual AI workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;Clone the repo:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git clone https://github.com/team-telnyx/telnyx-code-examples.git&lt;br&gt;
cd telnyx-code-examples/ai-content-translator-python&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Install dependencies and set up your environment:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pip install -r requirements.txt&lt;br&gt;
cp .env.example .env&lt;br&gt;
python app.py&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then call the translation endpoint with an audio file and target language. Check the README for the exact request shape:&lt;br&gt;
&lt;a href="https://github.com/team-telnyx/telnyx-code-examples/tree/main/ai-content-translator-python" rel="noopener noreferrer"&gt;https://github.com/team-telnyx/telnyx-code-examples/tree/main/ai-content-translator-python&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I like this example
&lt;/h2&gt;

&lt;p&gt;It is a useful pattern for anyone building AI apps where the interface is not just text. Text-only LLM demos are helpful, but a lot of real user experiences involve audio: people speaking, systems responding, and content moving across languages.&lt;/p&gt;

&lt;p&gt;This example keeps the workflow small enough to understand, while still showing how speech-to-text, LLM translation, and text-to-speech can fit together in one app.&lt;br&gt;
The Telnyx code examples repo is also structured to be agent-readable, so coding agents can inspect the examples, understand the API patterns, and help you extend them into fuller applications.&lt;/p&gt;

&lt;p&gt;Resources:&lt;br&gt;
&lt;a href="https://github.com/team-telnyx/telnyx-code-examples/tree/main/ai-content-translator-python" rel="noopener noreferrer"&gt;Code example&lt;/a&gt;&lt;br&gt;
&lt;a href="https://developers.telnyx.com" rel="noopener noreferrer"&gt;Telnyx Developer Docs&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>stt</category>
      <category>tts</category>
      <category>telnyx</category>
    </item>
    <item>
      <title>Build a Simple RAG App with Telnyx AI Inference</title>
      <dc:creator>Sonam</dc:creator>
      <pubDate>Fri, 26 Jun 2026 22:11:23 +0000</pubDate>
      <link>https://dev.to/sonam_50a41a4ced7e6b4f3fa/build-a-simple-rag-app-with-telnyx-ai-inference-mfl</link>
      <guid>https://dev.to/sonam_50a41a4ced7e6b4f3fa/build-a-simple-rag-app-with-telnyx-ai-inference-mfl</guid>
      <description>&lt;p&gt;RAG is one of those patterns that sounds more complicated than it has to be.&lt;/p&gt;

&lt;p&gt;At its core, retrieval-augmented generation is just:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Store some documents&lt;/li&gt;
&lt;li&gt;Embed the user’s question&lt;/li&gt;
&lt;li&gt;Find the most relevant docs&lt;/li&gt;
&lt;li&gt;Send those docs to the model as context&lt;/li&gt;
&lt;li&gt;Return an answer with sources&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I built a small Python example that shows that flow end to end with Telnyx AI Inference.&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href="https://github.com/team-telnyx/telnyx-code-examples/tree/main/build-rag-with-telnyx-inference-python" rel="noopener noreferrer"&gt;https://github.com/team-telnyx/telnyx-code-examples/tree/main/build-rag-with-telnyx-inference-python&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What it does
&lt;/h2&gt;

&lt;p&gt;The app exposes a Flask API for asking questions against a tiny in-memory knowledge base.&lt;/p&gt;

&lt;p&gt;You send a question like:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;{&lt;br&gt;
  "question": "Production signup broke after rotating an API key. Logs show 401 errors. What should we check first?"&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The app
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;creates an embedding for the question&lt;/li&gt;
&lt;li&gt;compares it against embeddings for the sample documents&lt;/li&gt;
&lt;li&gt;retrieves the most relevant sources&lt;/li&gt;
&lt;li&gt;sends those sources to a chat model&lt;/li&gt;
&lt;li&gt;returns a grounded answer plus source titles&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why this pattern is useful
&lt;/h2&gt;

&lt;p&gt;A normal LLM call only knows what is in the prompt and the model’s training data. RAG lets your app answer with your own docs, policies, product information, support notes, or internal knowledge base. That makes it useful for things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;support assistants&lt;/li&gt;
&lt;li&gt;internal docs search&lt;/li&gt;
&lt;li&gt;onboarding copilots&lt;/li&gt;
&lt;li&gt;product Q&amp;amp;A&lt;/li&gt;
&lt;li&gt;troubleshooting workflows&lt;/li&gt;
&lt;li&gt;agent tools that need source-grounded answers&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How the example works
&lt;/h2&gt;

&lt;p&gt;The example keeps the moving parts intentionally small.&lt;br&gt;
There is an in-memory DOCUMENTS list. On the first request, the app creates embeddings for those documents and caches them. When a user asks a question, the app embeds the question, compares it to the document embeddings, and sends the best matches to the model.&lt;br&gt;
The answer response includes source titles, so you can see what context the app used instead of treating the model like a black box.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;Clone the repo:&lt;br&gt;
&lt;code&gt;git clone https://github.com/team-telnyx/telnyx-code-examples.git&lt;br&gt;
cd telnyx-code-examples/build-rag-with-telnyx-inference-python&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Install dependencies and run the app:&lt;br&gt;
&lt;code&gt;pip install -r requirements.txt&lt;br&gt;
cp .env.example .env&lt;br&gt;
python app.py&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Ask a question:&lt;br&gt;
&lt;code&gt;curl -X POST http://localhost:5000/rag/ask \&lt;br&gt;
  -H "Content-Type: application/json" \&lt;br&gt;
  -d '{&lt;br&gt;
    "question": "Production signup broke after rotating an API key. Logs show 401 errors. What should we check first?"&lt;br&gt;
  }'&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I like this example
&lt;/h2&gt;

&lt;p&gt;It is deliberately small, but it gives you the core pieces of a real RAG workflow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;embeddings&lt;/li&gt;
&lt;li&gt;retrieval&lt;/li&gt;
&lt;li&gt;source grounding&lt;/li&gt;
&lt;li&gt;chat completion&lt;/li&gt;
&lt;li&gt;a clean API surface&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;From there, you could swap the in-memory docs for a vector database, pull content from product docs, or turn it into a support assistant.&lt;br&gt;
The Telnyx code examples repo is also structured to be agent-readable, so coding agents can inspect these examples and help you extend them into fuller applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/team-telnyx/telnyx-code-examples/tree/main/build-rag-with-telnyx-inference-python" rel="noopener noreferrer"&gt;Code example &lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/team-telnyx/ai" rel="noopener noreferrer"&gt;Telnyx AI repo with skills/toolkits&lt;/a&gt; &lt;br&gt;
&lt;a href="https://developers.telnyx.com/docs/inference" rel="noopener noreferrer"&gt;Telnyx AI Inference docs&lt;/a&gt; &lt;/p&gt;

</description>
      <category>rag</category>
      <category>ai</category>
      <category>telnyx</category>
      <category>flask</category>
    </item>
  </channel>
</rss>
