In this guide, we’ll show you how to use AssemblyAI’s LLM Gateway framework to process several audio files, and then format your results in JSON (JavaScript Object Notation) format. JSON allows you to programmatically format, parse, and transfer responses from LLM Gateway, which is useful for implementing LLM Gateway with a wide range of other applications. In this example, we will leverage the JSON formatting to create a .csv file from a directory of files that must be transcribed and submitted to LLM Gateway. However, you can use the same concepts in this guide to generate a JSON-formatted response, which you can then use to update a database table or interact with other APIs.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 json
import os
import csv
import time
import re
# Configuration
api_key = "<YOUR_API_KEY>"
base_url = "https://api.assemblyai.com"
headers = {"authorization": api_key}
output_filename = "profiles.csv"
def extract_json(text):
"""Extract JSON from text that might contain markdown or extra text"""
# First, try to remove markdown code blocks
text = text.strip()
# Remove ```json and ``` markers
if text.startswith("```"):
text = re.sub(r'^```(?:json)?\s*', '', text)
text = re.sub(r'\s*```$', '', text)
# Find the first { and last } to extract just the JSON object
first_brace = text.find('{')
last_brace = text.rfind('}')
if first_brace != -1 and last_brace != -1:
json_str = text[first_brace:last_brace + 1]
return json.loads(json_str)
# If that didn't work, try parsing the whole thing
return json.loads(text)
def upload_file(file_path):
"""Upload a local audio file to AssemblyAI"""
with open(file_path, "rb") as f:
response = requests.post(f"{base_url}/v2/upload", headers=headers, data=f)
if response.status_code != 200:
print(f"Error uploading {file_path}: {response.status_code}, {response.text}")
response.raise_for_status()
return response.json()["upload_url"]
def transcribe_audio(audio_url):
"""Submit audio for transcription and poll until complete"""
# Submit transcription request
data = {"audio_url": audio_url, "speech_models": ["universal-3-pro"]}
response = requests.post(f"{base_url}/v2/transcript", headers=headers, json=data)
if response.status_code != 200:
print(f"Error submitting transcription: {response.status_code}, {response.text}")
response.raise_for_status()
transcript_id = response.json()["id"]
polling_endpoint = f"{base_url}/v2/transcript/{transcript_id}"
# Poll for completion
while True:
transcript = requests.get(polling_endpoint, headers=headers).json()
if transcript["status"] == "completed":
return transcript_id
elif transcript["status"] == "error":
raise RuntimeError(f"Transcription failed: {transcript['error']}")
else:
time.sleep(3)
def process_with_llm_gateway(transcript_id, prompt):
"""Send transcript to LLM Gateway for processing"""
llm_gateway_data = {
"model": "claude-sonnet-4-5-20250929",
"messages": [
{
"role": "user",
"content": f"{prompt}\n\n{{{{ transcript }}}}"
}
],
"transcript_id": transcript_id,
"max_tokens": 1500
}
response = requests.post(
"https://llm-gateway.assemblyai.com/v1/chat/completions",
headers=headers,
json=llm_gateway_data
)
result = response.json()
if "error" in result:
raise RuntimeError(f"LLM Gateway error: {result['error']}")
return result['choices'][0]['message']['content']
# Main execution
prompt = """
You are an HR executive scanning through an interview transcript to extract information about a candidate.
You are required to create a JSON response with key information about the candidate.
You will use this template for your answer:
{
"Name": "<candidate-name>",
"Position": "<job position that candidate is applying for>",
"Past experience": "<A short phrase describing the candidate's relevant past experience for the role>"
}
Do not include any other text in your response. Only respond in JSON format that is not surrounded by markdown code, as your response will be parsed programmatically as JSON.
"""
# Get all files from interviews directory
interview_files = [os.path.join("interviews", file) for file in os.listdir("interviews")]
with open(output_filename, "w", newline="") as file:
writer = csv.writer(file)
header = ["Name", "Position", "Past Experience"]
writer.writerow(header)
print(f"Processing {len(interview_files)} interview files...")
for interview_file in interview_files:
print(f"\nProcessing: {interview_file}")
# Upload file and get URL
print(" Uploading file...")
audio_url = upload_file(interview_file)
# Transcribe audio
print(" Transcribing...")
transcript_id = transcribe_audio(audio_url)
# Process with LLM Gateway
print(" Analyzing with LLM Gateway...")
llm_response = process_with_llm_gateway(transcript_id, prompt)
# Parse JSON response
interviewee_data = extract_json(llm_response)
writer.writerow(interviewee_data.values())
print(f" Completed: {interviewee_data['Name']}")
print(f"\nCreated .csv file {output_filename}")
import { readdirSync } from "fs";
import fs from "fs";
import path from "path";
// Configuration
const apiKey = "<YOUR_API_KEY>";
const baseUrl = "https://api.assemblyai.com";
const headers = { authorization: apiKey };
const outputFilename = "profiles.csv";
function extractJson(text) {
// Extract JSON from text that might contain markdown or extra text
text = text.trim();
// Remove ```json and ``` markers
if (text.startsWith("```")) {
text = text.replace(/^```(?:json)?\s*/g, "");
text = text.replace(/\s*```$/g, "");
}
// Find the first { and last } to extract just the JSON object
const firstBrace = text.indexOf("{");
const lastBrace = text.lastIndexOf("}");
if (firstBrace !== -1 && lastBrace !== -1) {
const jsonStr = text.slice(firstBrace, lastBrace + 1);
return JSON.parse(jsonStr);
}
// If that didn't work, try parsing the whole thing
return JSON.parse(text);
}
async function uploadFile(filePath) {
// Upload a local audio file to AssemblyAI
const fileData = await fs.promises.readFile(filePath);
const res = await fetch(`${baseUrl}/v2/upload`, {
method: "POST",
headers,
body: fileData,
});
if (!res.ok) {
throw new Error(`Error uploading ${filePath}: ${res.status}`);
}
const response = await res.json();
return response.upload_url;
}
async function transcribeAudio(audioUrl) {
// Submit audio for transcription and poll until complete
const data = { audio_url: audioUrl, speech_models: ["universal-3-pro"] };
const res = await fetch(`${baseUrl}/v2/transcript`, {
method: "POST",
headers: { ...headers, "Content-Type": "application/json" },
body: JSON.stringify(data),
});
if (!res.ok) {
throw new Error(`Error submitting transcription: ${res.status}`);
}
const response = await res.json();
const transcriptId = response.id;
const pollingEndpoint = `${baseUrl}/v2/transcript/${transcriptId}`;
// Poll for completion
while (true) {
const res = await fetch(pollingEndpoint, { headers });
if (!res.ok) throw new Error(`Error: ${res.status}`);
const transcript = await res.json();
if (transcript.status === "completed") {
return transcriptId;
} else if (transcript.status === "error") {
throw new Error(`Transcription failed: ${transcript.error}`);
} else {
await new Promise((resolve) => setTimeout(resolve, 3000));
}
}
}
async function processWithLlmGateway(transcriptId, prompt) {
// Send transcript to LLM Gateway for processing
const llmGatewayData = {
model: "claude-sonnet-4-5-20250929",
messages: [
{
role: "user",
content: `${prompt}\n\n{{ transcript }}`,
},
],
transcript_id: transcriptId,
max_tokens: 1500,
};
const res = await fetch("https://llm-gateway.assemblyai.com/v1/chat/completions", {
method: "POST",
headers: { ...headers, "Content-Type": "application/json" },
body: JSON.stringify(llmGatewayData),
});
if (!res.ok) throw new Error(`Error: ${res.status}`);
const response = await res.json();
if (response.error) {
throw new Error(`LLM Gateway error: ${response.error}`);
}
return response.choices[0].message.content;
}
// Main execution
const prompt = `
You are an HR executive scanning through an interview transcript to extract information about a candidate.
You are required to create a JSON response with key information about the candidate.
You will use this template for your answer:
{
"Name": "<candidate-name>",
"Position": "<job position that candidate is applying for>",
"Past experience": "<A short phrase describing the candidate's relevant past experience for the role>"
}
Do not include any other text in your response. Only respond in JSON format that is not surrounded by markdown code, as your response will be parsed programmatically as JSON.
`;
// Get all files from interviews directory
const interviewFiles = readdirSync("interviews").map((file) =>
path.join("interviews", file)
);
const header = ["Name", "Position", "Past Experience"];
const csvRows = [header.join(",")];
console.log(`Processing ${interviewFiles.length} interview files...`);
for (const interviewFile of interviewFiles) {
console.log(`\nProcessing: ${interviewFile}`);
// Upload file and get URL
console.log(" Uploading file...");
const audioUrl = await uploadFile(interviewFile);
// Transcribe audio
console.log(" Transcribing...");
const transcriptId = await transcribeAudio(audioUrl);
// Process with LLM Gateway
console.log(" Analyzing with LLM Gateway...");
const llmResponse = await processWithLlmGateway(transcriptId, prompt);
// Parse JSON response
const intervieweeData = extractJson(llmResponse);
csvRows.push(Object.values(intervieweeData).join(","));
console.log(` Completed: ${intervieweeData["Name"]}`);
}
fs.writeFileSync(outputFilename, csvRows.join("\n"));
console.log(`\nCreated .csv file ${outputFilename}`);
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.Step-by-Step Instructions
In this guide, we will ask the same questions to LLM Gateway about multiple files. Then, we will collate the answers in a .csv file. Install the required packages:- Python
pip install requests
- Python
- JavaScript
import requests
import json
import os
import csv
import time
import re
# Configuration
api_key = "<YOUR_API_KEY>"
base_url = "https://api.assemblyai.com"
headers = {"authorization": api_key}
output_filename = "profiles.csv"
import { readdirSync } from "fs";
import fs from "fs";
import path from "path";
// Configuration
const apiKey = "<YOUR_API_KEY>";
const baseUrl = "https://api.assemblyai.com";
const headers = { authorization: apiKey };
const outputFilename = "profiles.csv";
- Python
- JavaScript
def extract_json(text):
"""Extract JSON from text that might contain markdown or extra text"""
# First, try to remove markdown code blocks
text = text.strip()
# Remove ```json and ``` markers
if text.startswith("```"):
text = re.sub(r'^```(?:json)?\s*', '', text)
text = re.sub(r'\s*```$', '', text)
# Find the first { and last } to extract just the JSON object
first_brace = text.find('{')
last_brace = text.rfind('}')
if first_brace != -1 and last_brace != -1:
json_str = text[first_brace:last_brace + 1]
return json.loads(json_str)
# If that didn't work, try parsing the whole thing
return json.loads(text)
function extractJson(text) {
// Extract JSON from text that might contain markdown or extra text
text = text.trim();
// Remove ```json and ``` markers
if (text.startsWith("```")) {
text = text.replace(/^```(?:json)?\s*/g, "");
text = text.replace(/\s*```$/g, "");
}
// Find the first { and last } to extract just the JSON object
const firstBrace = text.indexOf("{");
const lastBrace = text.lastIndexOf("}");
if (firstBrace !== -1 && lastBrace !== -1) {
const jsonStr = text.slice(firstBrace, lastBrace + 1);
return JSON.parse(jsonStr);
}
// If that didn't work, try parsing the whole thing
return JSON.parse(text);
}
- Python
- JavaScript
def upload_file(file_path):
"""Upload a local audio file to AssemblyAI"""
with open(file_path, "rb") as f:
response = requests.post(f"{base_url}/v2/upload", headers=headers, data=f)
if response.status_code != 200:
print(f"Error uploading {file_path}: {response.status_code}, {response.text}")
response.raise_for_status()
return response.json()["upload_url"]
def transcribe_audio(audio_url):
"""Submit audio for transcription and poll until complete"""
# Submit transcription request
data = {"audio_url": audio_url, "speech_models": ["universal-3-pro"]}
response = requests.post(f"{base_url}/v2/transcript", headers=headers, json=data)
if response.status_code != 200:
print(f"Error submitting transcription: {response.status_code}, {response.text}")
response.raise_for_status()
transcript_id = response.json()["id"]
polling_endpoint = f"{base_url}/v2/transcript/{transcript_id}"
# Poll for completion
while True:
transcript = requests.get(polling_endpoint, headers=headers).json()
if transcript["status"] == "completed":
return transcript_id
elif transcript["status"] == "error":
raise RuntimeError(f"Transcription failed: {transcript['error']}")
else:
time.sleep(3)
async function uploadFile(filePath) {
// Upload a local audio file to AssemblyAI
const fileData = await fs.promises.readFile(filePath);
const res = await fetch(`${baseUrl}/v2/upload`, {
method: "POST",
headers,
body: fileData,
});
if (!res.ok) {
throw new Error(`Error uploading ${filePath}: ${res.status}`);
}
const response = await res.json();
return response.upload_url;
}
async function transcribeAudio(audioUrl) {
// Submit audio for transcription and poll until complete
const data = { audio_url: audioUrl, speech_models: ["universal-3-pro"] };
const res = await fetch(`${baseUrl}/v2/transcript`, {
method: "POST",
headers: { ...headers, "Content-Type": "application/json" },
body: JSON.stringify(data),
});
if (!res.ok) {
throw new Error(`Error submitting transcription: ${res.status}`);
}
const response = await res.json();
const transcriptId = response.id;
const pollingEndpoint = `${baseUrl}/v2/transcript/${transcriptId}`;
// Poll for completion
while (true) {
const res = await fetch(pollingEndpoint, { headers });
if (!res.ok) throw new Error(`Error: ${res.status}`);
const transcript = await res.json();
if (transcript.status === "completed") {
return transcriptId;
} else if (transcript.status === "error") {
throw new Error(`Transcription failed: ${transcript.error}`);
} else {
await new Promise((resolve) => setTimeout(resolve, 3000));
}
}
}
- Python
- JavaScript
def process_with_llm_gateway(transcript_id, prompt):
"""Send transcript to LLM Gateway for processing"""
llm_gateway_data = {
"model": "claude-sonnet-4-5-20250929",
"messages": [
{
"role": "user",
"content": f"{prompt}\n\n{{{{ transcript }}}}"
}
],
"transcript_id": transcript_id,
"max_tokens": 1500
}
response = requests.post(
"https://llm-gateway.assemblyai.com/v1/chat/completions",
headers=headers,
json=llm_gateway_data
)
result = response.json()
if "error" in result:
raise RuntimeError(f"LLM Gateway error: {result['error']}")
return result['choices'][0]['message']['content']
async function processWithLlmGateway(transcriptId, prompt) {
// Send transcript to LLM Gateway for processing
const llmGatewayData = {
model: "claude-sonnet-4-5-20250929",
messages: [
{
role: "user",
content: `${prompt}\n\n{{ transcript }}`,
},
],
transcript_id: transcriptId,
max_tokens: 1500,
};
const res = await fetch("https://llm-gateway.assemblyai.com/v1/chat/completions", {
method: "POST",
headers: { ...headers, "Content-Type": "application/json" },
body: JSON.stringify(llmGatewayData),
});
if (!res.ok) throw new Error(`Error: ${res.status}`);
const response = await res.json();
if (response.error) {
throw new Error(`LLM Gateway error: ${response.error}`);
}
return response.choices[0].message.content;
}
- Python
- JavaScript
prompt = """
You are an HR executive scanning through an interview transcript to extract information about a candidate.
You are required to create a JSON response with key information about the candidate.
You will use this template for your answer:
{
"Name": "<candidate-name>",
"Position": "<job position that candidate is applying for>",
"Past experience": "<A short phrase describing the candidate's relevant past experience for the role>"
}
Do not include any other text in your response. Only respond in JSON format that is not surrounded by markdown code, as your response will be parsed programmatically as JSON.
"""
const prompt = `
You are an HR executive scanning through an interview transcript to extract information about a candidate.
You are required to create a JSON response with key information about the candidate.
You will use this template for your answer:
{
"Name": "<candidate-name>",
"Position": "<job position that candidate is applying for>",
"Past experience": "<A short phrase describing the candidate's relevant past experience for the role>"
}
Do not include any other text in your response. Only respond in JSON format that is not surrounded by markdown code, as your response will be parsed programmatically as JSON.
`;
interviews folder and create a .csv file with the results.
- Python
- JavaScript
interview_files = [os.path.join("interviews", file) for file in os.listdir("interviews")]
with open(output_filename, "w", newline="") as file:
writer = csv.writer(file)
header = ["Name", "Position", "Past Experience"]
writer.writerow(header)
print(f"Processing {len(interview_files)} interview files...")
for interview_file in interview_files:
print(f"\nProcessing: {interview_file}")
# Upload file and get URL
print(" Uploading file...")
audio_url = upload_file(interview_file)
# Transcribe audio
print(" Transcribing...")
transcript_id = transcribe_audio(audio_url)
# Process with LLM Gateway
print(" Analyzing with LLM Gateway...")
llm_response = process_with_llm_gateway(transcript_id, prompt)
# Parse JSON response
interviewee_data = extract_json(llm_response)
writer.writerow(interviewee_data.values())
print(f" Completed: {interviewee_data['Name']}")
print(f"\nCreated .csv file {output_filename}")
// Get all files from interviews directory
const interviewFiles = readdirSync("interviews").map((file) =>
path.join("interviews", file)
);
const header = ["Name", "Position", "Past Experience"];
const csvRows = [header.join(",")];
console.log(`Processing ${interviewFiles.length} interview files...`);
for (const interviewFile of interviewFiles) {
console.log(`\nProcessing: ${interviewFile}`);
// Upload file and get URL
console.log(" Uploading file...");
const audioUrl = await uploadFile(interviewFile);
// Transcribe audio
console.log(" Transcribing...");
const transcriptId = await transcribeAudio(audioUrl);
// Process with LLM Gateway
console.log(" Analyzing with LLM Gateway...");
const llmResponse = await processWithLlmGateway(transcriptId, prompt);
// Parse JSON response
const intervieweeData = extractJson(llmResponse);
csvRows.push(Object.values(intervieweeData).join(","));
console.log(` Completed: ${intervieweeData["Name"]}`);
}
fs.writeFileSync(outputFilename, csvRows.join("\n"));
console.log(`\nCreated .csv file ${outputFilename}`);
{
"Name": "John Smith",
"Position": "software engineer",
"Past experience": "three years of experience at Google"
}
profiles.csv file is generated.