Every operations team has a pile of text that is useful but hard to automate: support tickets, inbound emails, incident notes, sales leads, account updates, billing questions. The information is in there, but it is trapped in paragraphs.
The usual next step is a brittle parser. You add a regex for account names, a keyword list for priority, a few string splits for error codes, and suddenly the system works for three examples and breaks on the fourth.
This example shows a better pattern: use Telnyx AI Inference to convert messy text into a predictable JSON object that your app can route, store, and act on.
The full example is a small Flask API:
POST /extractaccepts unstructured text and an optional JSON SchemaGET /samplereturns sample support text and the default schemaGET /healthreports the configured model
The app calls Telnyx AI Inference through POST /v2/ai/chat/completions and asks the model to return one valid JSON object.
Why Structured Extraction Matters
LLMs are great at reading messy language. Applications are great at acting on structured data. Structured extraction is the bridge between the two.
Given a support ticket like this:
Account: Acme Health. Production verification jobs started failing after an API key rotation. Users cannot finish signup. Logs show 401 errors.
The app returns:
{
"company": "Acme Health",
"category": "authentication",
"priority": "urgent",
"summary": "Production verification jobs are failing after an API key rotation.",
"affected_environment": "production",
"customer_impact": "Users cannot finish signup.",
"error_codes": ["401"],
"suspected_cause": "The new API key may be invalid or missing required permissions.",
"requested_action": "Check API key configuration and permissions."
}
That JSON can feed a ticket router, alerting rule, CRM enrichment step, or analytics pipeline. The model handles the language variance; your application handles the workflow.
The Architecture
Unstructured text
|
v
Flask API validates request
|
v
Telnyx AI Inference extracts JSON
|
v
Structured JSON response
There are only three moving pieces:
- A request body with
text - A schema describing the shape you want
- A Telnyx chat completion request with
response_format: {"type": "json_object"}
Clone and Run
git clone https://github.com/team-telnyx/telnyx-code-examples.git
cd telnyx-code-examples/extract-structured-json-with-ai-python
cp .env.example .env
pip install -r requirements.txt
python app.py
Set your API key in .env:
TELNYX_API_KEY=your_telnyx_api_key
AI_MODEL=moonshotai/Kimi-K2.6
HOST=127.0.0.1
PORT=5000
Then call the extraction endpoint:
curl -X POST http://localhost:5000/extract \
-H "Content-Type: application/json" \
-d '{
"text": "Account: Acme Health. Production verification jobs started failing after an API key rotation. Users cannot finish signup. Logs show 401 errors."
}'
The Core Code
The extraction function sends the target schema and the user text to Telnyx AI Inference:
response = requests.post(
"https://api.telnyx.com/v2/ai/chat/completions",
headers={
"Authorization": f"Bearer {TELNYX_API_KEY}",
"Content-Type": "application/json",
},
json={
"model": model or AI_MODEL,
"messages": [
{
"role": "system",
"content": (
"Extract structured information from the user's text. "
"Return only one valid JSON object."
),
},
{
"role": "user",
"content": (
"Use this JSON Schema as the target shape:\n"
f"{json.dumps(schema, indent=2)}\n\n"
"Text to extract:\n"
f"{text}"
),
},
],
"temperature": 0,
"response_format": {"type": "json_object"},
},
timeout=60,
)
The server validates that text is present, checks that schema is a JSON object when provided, parses the model output, and returns a clean response.
Customize the Schema
The default schema is tuned for support tickets. For sales leads, send your own:
curl -X POST http://localhost:5000/extract \
-H "Content-Type: application/json" \
-d '{
"text": "Lead from Northstar Logistics wants pricing for 20 numbers and SMS campaigns.",
"schema": {
"type": "object",
"properties": {
"company": {"type": "string"},
"intent": {"type": "string"},
"requested_products": {"type": "array", "items": {"type": "string"}}
},
"required": ["company", "intent", "requested_products"]
}
}'
This is the useful part: the same endpoint can power many workflows. Change the schema, not the parser.
Production Notes
Keep schemas small and specific. Large, ambiguous schemas make extraction harder to validate and debug.
Validate model output before writing to a database. The example parses JSON, but production systems should also validate required fields and enum values.
Do not expose the local Flask API publicly without authentication. Treat incoming text as customer data and avoid logging sensitive payloads.
Use deterministic settings for extraction. temperature: 0 is intentional here because the goal is consistency, not creativity.
Get the Code
The example is available in the Telnyx code examples repo:
https://github.com/team-telnyx/telnyx-code-examples/tree/main/extract-structured-json-with-ai-python
It includes the Flask app, quickstart, API reference, guide, requirements file, and environment template.