In this guide, we’ll show you how to use AssemblyAI’s LLM Gateway framework to process an audio file and then use LLM Gateway to automatically detect sentiment analysis from customer calls as “positive”, “negative”, or “neutral”. In addition, we will glean additional insights beyond these three sentiments and learn the reasoning behind these detected sentiments.Documentation Index
Fetch the complete documentation index at: https://assemblyai.com/docs/llms.txt
Use this file to discover all available pages before exploring further.
Quickstart
- Python
- JavaScript
import requests
import time
API_KEY = "YOUR_API_KEY"
audio_file_path = "./meeting.mp3"
# ------------------------------------------
# Step 1: Upload the audio file
# ------------------------------------------
def upload_file(filename):
with open(filename, "rb") as f:
upload_url = "https://api.assemblyai.com/v2/upload"
headers = {"authorization": API_KEY}
response = requests.post(upload_url, headers=headers, data=f)
response.raise_for_status()
return response.json()["upload_url"]
audio_url = upload_file(audio_file_path)
print(f"Uploaded audio file. URL: {audio_url}")
# ------------------------------------------
# Step 2: Request transcription
# ------------------------------------------
transcript_request = requests.post(
"https://api.assemblyai.com/v2/transcript",
headers={"authorization": API_KEY, "content-type": "application/json"},
json={"audio_url": audio_url, "speech_models": ["universal-3-pro"]},
)
transcript_id = transcript_request.json()["id"]
# Poll until completed
while True:
polling_response = requests.get(
f"https://api.assemblyai.com/v2/transcript/{transcript_id}",
headers={"authorization": API_KEY},
)
status = polling_response.json()["status"]
if status == "completed":
break
elif status == "error":
raise RuntimeError(f"Transcription failed: {polling_response.json()['error']}")
else:
print(f"Transcription status: {status}")
time.sleep(3)
print("\nTranscription complete.\n")
# ------------------------------------------
# Step 3: Define questions
# ------------------------------------------
agent_context = "The agent is trying to get the customer to go through with the update to their car."
customer_context = "The customer is calling to check how much it would cost to update the map in his car."
answer_format = "<answer in one sentence> <reason in one sentence>"
questions = [
{
"question": "What was the overall sentiment of the call?",
"context": customer_context,
"answer_format": answer_format,
},
{
"question": "What was the sentiment of the agent in this call?",
"context": agent_context,
"answer_format": answer_format,
},
{
"question": "What was the sentiment of the customer in this call?",
"context": customer_context,
"answer_format": answer_format,
},
{
"question": "What quote best demonstrates the customer's level of interest?",
"context": customer_context,
"answer_format": answer_format,
},
{
"question": "Provide a quote from the agent that demonstrates their level of enthusiasm.",
"context": agent_context,
"answer_format": answer_format,
},
]
# ------------------------------------------
# Step 4: Build prompt for the LLM
# ------------------------------------------
question_strs = []
for q in questions:
q_str = f"Question: {q['question']}"
if q.get("context"):
q_str += f"\nContext: {q['context']}"
if q.get("answer_format"):
q_str += f"\nAnswer Format: {q['answer_format']}"
question_strs.append(q_str)
questions_prompt = "\n\n".join(question_strs)
prompt = f"""
You are an expert at analyzing call transcripts.
Given the series of questions below, answer them accurately and concisely.
When context or answer format is provided, use it to guide your answers.
Transcript:
{{{{ transcript }}}}
Questions:
{questions_prompt}
"""
# ------------------------------------------
# Step 5: Query the LLM Gateway
# ------------------------------------------
headers = {"authorization": API_KEY}
response = requests.post(
"https://llm-gateway.assemblyai.com/v1/chat/completions",
headers=headers,
json={
"model": "claude-sonnet-4-5-20250929",
"messages": [{"role": "user", "content": prompt}],
"transcript_id": transcript_id,
"max_tokens": 2000,
},
)
response_json = response.json()
llm_output = response_json["choices"][0]["message"]["content"]
# ------------------------------------------
# Step 6: Parse and display the results
# ------------------------------------------
print("\n--- LLM Responses ---\n")
print(llm_output)
import fs from "fs-extra";
const API_KEY = "YOUR_API_KEY";
const audioFilePath = "./meeting.mp3";
const headers = { authorization: API_KEY };
// ------------------------------------------
// Step 1: Upload the audio file
// ------------------------------------------
const audioData = await fs.readFile(audioFilePath);
let res = await fetch("https://api.assemblyai.com/v2/upload", {
method: "POST",
headers,
body: audioData,
});
if (!res.ok) throw new Error(`Error: ${res.status}`);
const uploadResponse = await res.json();
const audioUrl = uploadResponse.upload_url;
console.log(`Uploaded audio file. URL: ${audioUrl}`);
// ------------------------------------------
// Step 2: Request transcription
// ------------------------------------------
res = await fetch("https://api.assemblyai.com/v2/transcript", {
method: "POST",
headers: { ...headers, "Content-Type": "application/json" },
body: JSON.stringify({ audio_url: audioUrl, speech_models: ["universal-3-pro"] }),
});
if (!res.ok) throw new Error(`Error: ${res.status}`);
const transcriptRequest = await res.json();
const transcriptId = transcriptRequest.id;
// Poll until completed
while (true) {
res = await fetch(`https://api.assemblyai.com/v2/transcript/${transcriptId}`, { headers });
if (!res.ok) throw new Error(`Error: ${res.status}`);
const pollingResponse = await res.json();
const status = pollingResponse.status;
if (status === "completed") {
break;
} else if (status === "error") {
throw new Error(`Transcription failed: ${pollingResponse.error}`);
} else {
console.log(`Transcription status: ${status}`);
await new Promise((resolve) => setTimeout(resolve, 3000));
}
}
console.log("\nTranscription complete.\n");
// ------------------------------------------
// Step 3: Define questions
// ------------------------------------------
const agentContext = "The agent is trying to get the customer to go through with the update to their car.";
const customerContext = "The customer is calling to check how much it would cost to update the map in his car.";
const answerFormat = "<answer in one sentence> <reason in one sentence>";
const questions = [
{
question: "What was the overall sentiment of the call?",
context: customerContext,
answer_format: answerFormat,
},
{
question: "What was the sentiment of the agent in this call?",
context: agentContext,
answer_format: answerFormat,
},
{
question: "What was the sentiment of the customer in this call?",
context: customerContext,
answer_format: answerFormat,
},
{
question: "What quote best demonstrates the customer's level of interest?",
context: customerContext,
answer_format: answerFormat,
},
{
question: "Provide a quote from the agent that demonstrates their level of enthusiasm.",
context: agentContext,
answer_format: answerFormat,
},
];
// ------------------------------------------
// Step 4: Build prompt for the LLM
// ------------------------------------------
const questionStrs = [];
for (const q of questions) {
let qStr = `Question: ${q.question}`;
if (q.context) {
qStr += `\nContext: ${q.context}`;
}
if (q.answer_format) {
qStr += `\nAnswer Format: ${q.answer_format}`;
}
questionStrs.push(qStr);
}
const questionsPrompt = questionStrs.join("\n\n");
const prompt = `
You are an expert at analyzing call transcripts.
Given the series of questions below, answer them accurately and concisely.
When context or answer format is provided, use it to guide your answers.
Transcript:
{{ transcript }}
Questions:
${questionsPrompt}
`;
// ------------------------------------------
// Step 5: Query the LLM Gateway
// ------------------------------------------
res = await fetch("https://llm-gateway.assemblyai.com/v1/chat/completions", {
method: "POST",
headers: { ...headers, "Content-Type": "application/json" },
body: JSON.stringify({
model: "claude-sonnet-4-5-20250929",
messages: [{ role: "user", content: prompt }],
transcript_id: transcriptId,
max_tokens: 2000,
}),
});
if (!res.ok) throw new Error(`Error: ${res.status}`);
const response = await res.json();
const llmOutput = response.choices[0].message.content;
// ------------------------------------------
// Step 6: Parse and display the results
// ------------------------------------------
console.log("\n--- LLM Responses ---\n");
console.log(llmOutput);
Get Started
Before we begin, make sure you have an AssemblyAI account and an API key. You can sign up for an AssemblyAI account and get your API key from your dashboard. See our pricing page for LLM Gateway pricing rates.Step-by-Step Instructions
In this guide, we will ask five questions to learn about the sentiment of the customer and agent. You can adjust the questions to suit your project’s needs.Install dependencies
Install the required packages.- Python
- JavaScript
pip install requests
npm install fs-extra
- Python
- JavaScript
import requests
import time
API_KEY = "YOUR_API_KEY"
import fs from "fs-extra";
const API_KEY = "YOUR_API_KEY";
- Python
- JavaScript
audio_file_path = "./meeting.mp3"
# ------------------------------------------
# Step 1: Upload the audio file
# ------------------------------------------
def upload_file(filename):
with open(filename, "rb") as f:
upload_url = "https://api.assemblyai.com/v2/upload"
headers = {"authorization": API_KEY}
response = requests.post(upload_url, headers=headers, data=f)
response.raise_for_status()
return response.json()["upload_url"]
audio_url = upload_file(audio_file_path)
print(f"Uploaded audio file. URL: {audio_url}")
# ------------------------------------------
# Step 2: Request transcription
# ------------------------------------------
transcript_request = requests.post(
"https://api.assemblyai.com/v2/transcript",
headers={"authorization": API_KEY, "content-type": "application/json"},
json={"audio_url": audio_url, "speech_models": ["universal-3-pro"]},
)
transcript_id = transcript_request.json()["id"]
# Poll until completed
while True:
polling_response = requests.get(
f"https://api.assemblyai.com/v2/transcript/{transcript_id}",
headers={"authorization": API_KEY},
)
status = polling_response.json()["status"]
if status == "completed":
break
elif status == "error":
raise RuntimeError(f"Transcription failed: {polling_response.json()['error']}")
else:
print(f"Transcription status: {status}")
time.sleep(3)
print("\nTranscription complete.\n")
const audioFilePath = "./meeting.mp3";
const headers = { authorization: API_KEY };
// ------------------------------------------
// Step 1: Upload the audio file
// ------------------------------------------
const audioData = await fs.readFile(audioFilePath);
let res = await fetch("https://api.assemblyai.com/v2/upload", {
method: "POST",
headers,
body: audioData,
});
if (!res.ok) throw new Error(`Error: ${res.status}`);
const uploadResponse = await res.json();
const audioUrl = uploadResponse.upload_url;
console.log(`Uploaded audio file. URL: ${audioUrl}`);
// ------------------------------------------
// Step 2: Request transcription
// ------------------------------------------
res = await fetch("https://api.assemblyai.com/v2/transcript", {
method: "POST",
headers: { ...headers, "Content-Type": "application/json" },
body: JSON.stringify({ audio_url: audioUrl, speech_models: ["universal-3-pro"] }),
});
if (!res.ok) throw new Error(`Error: ${res.status}`);
const transcriptRequest = await res.json();
const transcriptId = transcriptRequest.id;
// Poll until completed
while (true) {
res = await fetch(`https://api.assemblyai.com/v2/transcript/${transcriptId}`, { headers });
if (!res.ok) throw new Error(`Error: ${res.status}`);
const pollingResponse = await res.json();
const status = pollingResponse.status;
if (status === "completed") {
break;
} else if (status === "error") {
throw new Error(`Transcription failed: ${pollingResponse.error}`);
} else {
console.log(`Transcription status: ${status}`);
await new Promise((resolve) => setTimeout(resolve, 3000));
}
}
console.log("\nTranscription complete.\n");
- Python
- JavaScript
agent_context = "The agent is trying to get the customer to go through with the update to their car."
customer_context = "The customer is calling to check how much it would cost to update the map in his car."
const agentContext = "The agent is trying to get the customer to go through with the update to their car.";
const customerContext = "The customer is calling to check how much it would cost to update the map in his car.";
- Python
- JavaScript
answer_format = "<answer in one sentence> <reason in one sentence>"
questions = [
{
"question": "What was the overall sentiment of the call?",
"context": customer_context,
"answer_format": answer_format,
},
{
"question": "What was the sentiment of the agent in this call?",
"context": agent_context,
"answer_format": answer_format,
},
{
"question": "What was the sentiment of the customer in this call?",
"context": customer_context,
"answer_format": answer_format,
},
{
"question": "What quote best demonstrates the customer's level of interest?",
"context": customer_context,
"answer_format": answer_format,
},
{
"question": "Provide a quote from the agent that demonstrates their level of enthusiasm.",
"context": agent_context,
"answer_format": answer_format,
},
]
const answerFormat = "<answer in one sentence> <reason in one sentence>";
const questions = [
{
question: "What was the overall sentiment of the call?",
context: customerContext,
answer_format: answerFormat,
},
{
question: "What was the sentiment of the agent in this call?",
context: agentContext,
answer_format: answerFormat,
},
{
question: "What was the sentiment of the customer in this call?",
context: customerContext,
answer_format: answerFormat,
},
{
question: "What quote best demonstrates the customer's level of interest?",
context: customerContext,
answer_format: answerFormat,
},
{
question: "Provide a quote from the agent that demonstrates their level of enthusiasm.",
context: agentContext,
answer_format: answerFormat,
},
];
- Python
- JavaScript
# ------------------------------------------
# Step 4: Build prompt for the LLM
# ------------------------------------------
question_strs = []
for q in questions:
q_str = f"Question: {q['question']}"
if q.get("context"):
q_str += f"\nContext: {q['context']}"
if q.get("answer_format"):
q_str += f"\nAnswer Format: {q['answer_format']}"
question_strs.append(q_str)
questions_prompt = "\n\n".join(question_strs)
prompt = f"""
You are an expert at analyzing call transcripts.
Given the series of questions below, answer them accurately and concisely.
When context or answer format is provided, use it to guide your answers.
Transcript:
{{{{ transcript }}}}
Questions:
{questions_prompt}
"""
// ------------------------------------------
// Step 4: Build prompt for the LLM
// ------------------------------------------
const questionStrs = [];
for (const q of questions) {
let qStr = `Question: ${q.question}`;
if (q.context) {
qStr += `\nContext: ${q.context}`;
}
if (q.answer_format) {
qStr += `\nAnswer Format: ${q.answer_format}`;
}
questionStrs.push(qStr);
}
const questionsPrompt = questionStrs.join("\n\n");
const prompt = `
You are an expert at analyzing call transcripts.
Given the series of questions below, answer them accurately and concisely.
When context or answer format is provided, use it to guide your answers.
Transcript:
{{ transcript }}
Questions:
${questionsPrompt}
`;
- Python
- JavaScript
# ------------------------------------------
# Step 5: Query the LLM Gateway
# ------------------------------------------
headers = {"authorization": API_KEY}
response = requests.post(
"https://llm-gateway.assemblyai.com/v1/chat/completions",
headers=headers,
json={
"model": "claude-sonnet-4-5-20250929",
"messages": [{"role": "user", "content": prompt}],
"transcript_id": transcript_id,
"max_tokens": 2000,
},
)
response_json = response.json()
llm_output = response_json["choices"][0]["message"]["content"]
# ------------------------------------------
# Step 6: Parse and display the results
# ------------------------------------------
print("\n--- LLM Responses ---\n")
print(llm_output)
// ------------------------------------------
// Step 5: Query the LLM Gateway
// ------------------------------------------
let res = await fetch("https://llm-gateway.assemblyai.com/v1/chat/completions", {
method: "POST",
headers: { ...headers, "Content-Type": "application/json" },
body: JSON.stringify({
model: "claude-sonnet-4-5-20250929",
messages: [{ role: "user", content: prompt }],
transcript_id: transcriptId,
max_tokens: 2000,
}),
});
if (!res.ok) throw new Error(`Error: ${res.status}`);
const response = await res.json();
const llmOutput = response.choices[0].message.content;
// ------------------------------------------
// Step 6: Parse and display the results
// ------------------------------------------
console.log("\n--- LLM Responses ---\n");
console.log(llmOutput);