SubQ
Integrations

Transcribe from URL

Transcribe audio from a URL using the SubQ API

With URL transcription, you transcribe audio hosted remotely on cloud storage, a CDN, or any publicly accessible URL without downloading it to your machine first. You download the audio, send the bytes to the API, and get the transcript back.

This approach is useful when your audio files are stored in services like Amazon S3, Google Cloud Storage, or any web server.

Prerequisites

  • Python 3.8 or later
  • httpx installed. If you haven't already, follow the set up and installation guide.
  • A publicly accessible URL pointing to an audio file in a supported format

Transcribe audio from a URL

In this example, you download audio from a public URL and send it to the SubQ API for transcription:

transcribe_url.py
import os
import httpx

SUBQ_API_KEY = os.environ["SUBQ_API_KEY"]
AUDIO_URL = "https://speech.subq.ai/subq_sample.wav"

# Download the audio file
print("Downloading audio...")
audio_response = httpx.get(AUDIO_URL, timeout=30.0, follow_redirects=True)
audio_data = audio_response.content
print(f"Downloaded {len(audio_data)} bytes")

# Send the audio to the SubQ API
print("Transcribing...")
response = httpx.post(
    "https://stt-api.subq.ai/v1/listen",
    headers={"Authorization": f"Bearer {SUBQ_API_KEY}"},
    content=audio_data,
    timeout=60.0
)

result = response.json()

if response.status_code == 200:
    transcript = (
        result.get("results", {})
        .get("channels", [{}])[0]
        .get("alternatives", [{}])[0]
        .get("transcript", "")
    )
    print(f"Transcript: {transcript}")
else:
    print(f"Error {response.status_code}: {result}")

Run it:

python transcribe_url.py

How it works

To transcribe from a URL, you download the audio, send it to the API, and extract the transcript from the response:

  1. Download the audio: httpx.get() fetches the audio file from the URL. The follow_redirects=True parameter handles HTTP redirects automatically. This is important for URLs from storage services that often redirect to a CDN. The timeout=30.0 prevents the request from hanging on slow connections.

  2. POST to /v1/listen: You send the downloaded audio bytes to the SubQ API in the request body. This is the same endpoint and format used in Transcribe a file. The only difference is where the audio comes from.

  3. Parse the response: The response structure is the same as file transcription. For full field descriptions, see the response structure in Transcribe a file.

The approach is the same as Transcribe a file: you're sending audio bytes to POST /v1/listen. The difference is just where the bytes come from:

ApproachSourceWhen to use
Fileopen("audio.wav", "rb").read()Audio is on your local disk
URLhttpx.get(url).contentAudio is hosted remotely

Prerequisites

  • Node.js 18 or later
  • A publicly accessible URL pointing to an audio file in a supported format

Transcribe audio from a URL

In this example, you download audio from a public URL and send it to the SubQ API for transcription:

transcribe_url.js
const SUBQ_API_KEY = process.env.SUBQ_API_KEY;
const AUDIO_URL = "https://speech.subq.ai/subq_sample.wav";

// Download the audio file
console.log("Downloading audio...");
const audioResponse = await fetch(AUDIO_URL);
const audioData = await audioResponse.arrayBuffer();
console.log(`Downloaded ${audioData.byteLength} bytes`);

// Send the audio to the SubQ API
console.log("Transcribing...");
const response = await fetch("https://stt-api.subq.ai/v1/listen", {
  method: "POST",
  headers: { "Authorization": `Bearer ${SUBQ_API_KEY}` },
  body: audioData,
});

const result = await response.json();

if (response.ok) {
  const transcript = result?.results?.channels?.[0]?.alternatives?.[0]?.transcript ?? "";
  console.log(`Transcript: ${transcript}`);
} else {
  console.error(`Error ${response.status}:`, result);
}

Run it:

node transcribe_url.js

How it works

To transcribe from a URL, you download the audio, send it to the API, and extract the transcript from the response:

  1. Download the audio: fetch() retrieves the audio file from the URL. The response is read as an ArrayBuffer with .arrayBuffer(), which gives you the raw binary data. fetch follows redirects automatically, which is important for URLs from storage services that often redirect to a CDN.

  2. POST to /v1/listen: You send the downloaded audio bytes to the SubQ API in the request body. This is the same endpoint and format used in Transcribe a file. The only difference is where the audio comes from.

  3. Parse the response: The response structure is the same as file transcription. For full field descriptions, see the response structure in Transcribe a file.

The approach is the same as Transcribe a file: you're sending audio bytes to POST /v1/listen. The difference is just where the bytes come from:

ApproachSourceWhen to use
FilereadFileSync("audio.wav")Audio is on your local disk
URLfetch(url).arrayBuffer()Audio is hosted remotely

Prerequisites

  • Go 1.21 or later
  • A publicly accessible URL pointing to an audio file in a supported format

Transcribe audio from a URL

In this example, you download audio from a public URL and send it to the SubQ API for transcription:

transcribe_url.go
package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	apiKey := os.Getenv("SUBQ_API_KEY")
	audioURL := "https://speech.subq.ai/subq_sample.wav"

	// Download the audio file
	fmt.Println("Downloading audio...")
	audioResp, err := http.Get(audioURL)
	if err != nil {
		fmt.Println("Error downloading:", err)
		return
	}
	defer audioResp.Body.Close()
	audioData, _ := io.ReadAll(audioResp.Body)
	fmt.Printf("Downloaded %d bytes\n", len(audioData))

	// Send the audio to the SubQ API
	fmt.Println("Transcribing...")
	req, _ := http.NewRequest("POST", "https://stt-api.subq.ai/v1/listen", bytes.NewReader(audioData))
	req.Header.Set("Authorization", "Bearer "+apiKey)

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		fmt.Println("Error:", err)
		return
	}
	defer resp.Body.Close()
	body, _ := io.ReadAll(resp.Body)

	if resp.StatusCode != 200 {
		fmt.Printf("Error %d: %s\n", resp.StatusCode, string(body))
		return
	}

	var result struct {
		Results struct {
			Channels []struct {
				Alternatives []struct {
					Transcript string `json:"transcript"`
				} `json:"alternatives"`
			} `json:"channels"`
		} `json:"results"`
	}
	json.Unmarshal(body, &result)
	fmt.Printf("Transcript: %s\n", result.Results.Channels[0].Alternatives[0].Transcript)
}

Run it:

go run transcribe_url.go

How it works

To transcribe from a URL, you download the audio, send it to the API, and extract the transcript from the response:

  1. Download the audio: http.Get() fetches the audio file from the URL. Go's HTTP client follows redirects automatically, which is important for URLs from storage services that often redirect to a CDN.

  2. POST to /v1/listen: You send the downloaded audio bytes to the SubQ API in the request body. This is the same endpoint and format used in Transcribe a file. The only difference is where the audio comes from.

  3. Parse the response: The response structure is the same as file transcription. For full field descriptions, see the response structure in Transcribe a file.

The approach is the same as Transcribe a file: you're sending audio bytes to POST /v1/listen. The difference is just where the bytes come from:

ApproachSourceWhen to use
Fileos.ReadFile("audio.wav")Audio is on your local disk
URLhttp.Get(url) + io.ReadAllAudio is hosted remotely

Prerequisites

  • Rust 1.70 or later with reqwest, tokio, and serde_json in your Cargo.toml, If you haven't already, follow the set up and installation guide.
  • A publicly accessible URL pointing to an audio file in a supported format

Transcribe audio from a URL

In this example, you download audio from a public URL and send it to the SubQ API for transcription:

transcribe_url.rs
use serde_json::Value;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let api_key = std::env::var("SUBQ_API_KEY").expect("SUBQ_API_KEY not set");
    let audio_url = "https://speech.subq.ai/subq_sample.wav";

    // Download the audio file
    println!("Downloading audio...");
    let audio_data = reqwest::get(audio_url).await?.bytes().await?;
    println!("Downloaded {} bytes", audio_data.len());

    // Send the audio to the SubQ API
    println!("Transcribing...");
    let client = reqwest::Client::new();
    let response = client
        .post("https://stt-api.subq.ai/v1/listen")
        .header("Authorization", format!("Bearer {}", api_key))
        .body(audio_data)
        .send()
        .await?;

    let status = response.status();
    let text = response.text().await?;

    if !status.is_success() {
        eprintln!("Error {}: {}", status, text);
        return Ok(());
    }

    let json: Value = serde_json::from_str(&text)?;
    let transcript = json["results"]["channels"][0]["alternatives"][0]["transcript"]
        .as_str()
        .unwrap_or("");
    println!("Transcript: {}", transcript);

    Ok(())
}

Run it:

cargo run --bin transcribe_url

How it works

To transcribe from a URL, you download the audio, send it to the API, and extract the transcript from the response:

  1. Download the audio: reqwest::get(url).await?.bytes().await? fetches the audio file into memory. reqwest follows redirects automatically, which is important for URLs from storage services that often redirect to a CDN.

  2. POST to /v1/listen: You send the downloaded audio bytes to the SubQ API in the request body. This is the same endpoint and format used in Transcribe a file. The only difference is where the audio comes from.

  3. Parse the response: The response structure is the same as file transcription. For full field descriptions, see the response structure in Transcribe a file.

The approach is the same as Transcribe a file: you're sending audio bytes to POST /v1/listen. The difference is just where the bytes come from:

ApproachSourceWhen to use
Filetokio::fs::read("audio.wav")Audio is on your local disk
URLreqwest::get(url).await?.bytes()Audio is hosted remotely

The URL must be publicly accessible. If your audio is behind authentication (for example, a private S3 bucket), generate a pre-signed URL first. A pre-signed URL is a time-limited public URL that grants temporary access to a private resource.

You can customize transcriptions with query parameters for smart formatting, speaker diarization, language detection, and more.

Next steps