Setup & installation
Install dependencies and configure your environment to use the SubQ API
The SubQ API is a standard REST and WebSocket API. You call it directly with an HTTP client for pre-recorded transcription and a WebSocket client for real-time streaming. No proprietary SDK is required.
In this guide, you install the dependencies, set up your API key, and verify connectivity.
Prerequisites
- A SubQ API key. If you don't have one yet, follow the Get an API key guide. Your key starts with
org_.
Install dependencies
Requirements: Python 3.8 or later.
Install the HTTP and WebSocket libraries:
pip install httpx websockets| Package | Purpose |
|---|---|
httpx | Send HTTP requests for pre-recorded transcription (POST /v1/listen). |
websockets | Connect to the WebSocket endpoint for real-time streaming (wss://stt-api.subq.ai/v1/listen). |
If you only need pre-recorded transcription, httpx alone is sufficient. If you only need streaming, install websockets alone.
Set up your API key
Store your API key in an environment variable so it isn't hardcoded in your source files:
export SUBQ_API_KEY="org_YOUR_API_KEY"To persist it, add the line to your ~/.bashrc, ~/.zshrc, or equivalent.
$env:SUBQ_API_KEY = "org_YOUR_API_KEY"To persist it, use [System.Environment]::SetEnvironmentVariable("SUBQ_API_KEY", "org_YOUR_API_KEY", "User").
set SUBQ_API_KEY=org_YOUR_API_KEYTo persist it, use setx SUBQ_API_KEY "org_YOUR_API_KEY".
Then read it in Python:
import os
SUBQ_API_KEY = os.environ["SUBQ_API_KEY"]Never commit API keys to version control. Use environment variables, .env files (with .gitignore), or a secrets manager.
Verify the setup
Run a quick test to confirm that you can reach the SubQ API. In this example, you transcribe a short public audio file:
import os
import httpx
SUBQ_API_KEY = os.environ["SUBQ_API_KEY"]
AUDIO_URL = "https://speech.subq.ai/subq_sample.wav"
# Download a sample audio file
audio = httpx.get(AUDIO_URL, follow_redirects=True).content
# Send it to the SubQ API for transcription
response = httpx.post(
"https://stt-api.subq.ai/v1/listen",
headers={"Authorization": f"Bearer {SUBQ_API_KEY}"},
content=audio,
timeout=60.0
)
result = response.json()
if response.status_code == 200:
transcript = (
result.get("results", {})
.get("channels", [{}])[0]
.get("alternatives", [{}])[0]
.get("transcript", "")
)
print(transcript)
else:
print(f"Error {response.status_code}: {result}")Run it:
python verify_setup.pyIf the setup is correct, you see a transcript printed to the console. If you get a 401 error, verify that your API key starts with org_ and that the SUBQ_API_KEY environment variable is set.
Already using the Deepgram SDK? SubQ is fully compatible. See Migrate from Deepgram for a 2-line configuration change.
Requirements: Node.js 18 or later.
Install the WebSocket library:
npm install ws| Package | Purpose |
|---|---|
ws | Connect to the WebSocket endpoint for real-time streaming (wss://stt-api.subq.ai/v1/listen). |
For pre-recorded transcription, no additional packages are needed. Node.js 18+ includes the native fetch API.
If you only need pre-recorded transcription, you can skip the ws install entirely.
Set up your API key
Store your API key in an environment variable so it isn't hardcoded in your source files:
export SUBQ_API_KEY="org_YOUR_API_KEY"To persist it, add the line to your ~/.bashrc, ~/.zshrc, or equivalent.
$env:SUBQ_API_KEY = "org_YOUR_API_KEY"To persist it, use [System.Environment]::SetEnvironmentVariable("SUBQ_API_KEY", "org_YOUR_API_KEY", "User").
set SUBQ_API_KEY=org_YOUR_API_KEYTo persist it, use setx SUBQ_API_KEY "org_YOUR_API_KEY".
Then read it in Node.js:
const SUBQ_API_KEY = process.env.SUBQ_API_KEY;Never commit API keys to version control. Use environment variables, .env files (with .gitignore), or a secrets manager.
Verify the setup
Run a quick test to confirm that you can reach the SubQ API. In this example, you transcribe a short public audio file:
const SUBQ_API_KEY = process.env.SUBQ_API_KEY;
const AUDIO_URL = "https://speech.subq.ai/subq_sample.wav";
// Download a sample audio file
const audioResponse = await fetch(AUDIO_URL);
const audioData = await audioResponse.arrayBuffer();
// Send it to the SubQ API for transcription
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);
} else {
console.error(`Error ${response.status}:`, result);
}Run it:
node verify_setup.jsIf the setup is correct, you see a transcript printed to the console. If you get a 401 error, verify that your API key starts with org_ and that the SUBQ_API_KEY environment variable is set.
Already using the Deepgram SDK? SubQ is fully compatible. See Migrate from Deepgram for a 2-line configuration change.
Requirements: Go 1.21 or later.
Install the WebSocket library (only needed for streaming):
go get github.com/gorilla/websocket| Package | Purpose |
|---|---|
github.com/gorilla/websocket | Connect to the WebSocket endpoint for real-time streaming (wss://stt-api.subq.ai/v1/listen). |
For pre-recorded transcription, no third-party packages are needed. The standard library net/http handles everything.
Set up your API key
Store your API key in an environment variable so it isn't hardcoded in your source files:
export SUBQ_API_KEY="org_YOUR_API_KEY"To persist it, add the line to your ~/.bashrc, ~/.zshrc, or equivalent.
$env:SUBQ_API_KEY = "org_YOUR_API_KEY"To persist it, use [System.Environment]::SetEnvironmentVariable("SUBQ_API_KEY", "org_YOUR_API_KEY", "User").
set SUBQ_API_KEY=org_YOUR_API_KEYTo persist it, use setx SUBQ_API_KEY "org_YOUR_API_KEY".
Then read it in Go:
apiKey := os.Getenv("SUBQ_API_KEY")Never commit API keys to version control. Use environment variables, .env files (with .gitignore), or a secrets manager.
Verify the setup
Run a quick test to confirm that you can reach the SubQ API. In this example, you transcribe a short public audio file:
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 a sample audio file
audioResp, err := http.Get(audioURL)
if err != nil {
fmt.Println("Error downloading audio:", err)
return
}
defer audioResp.Body.Close()
audioData, _ := io.ReadAll(audioResp.Body)
// Send it to the SubQ API for transcription
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.Println(result.Results.Channels[0].Alternatives[0].Transcript)
}Run it:
go run verify_setup.goIf the setup is correct, you see a transcript printed to the console. If you get a 401 error, verify that your API key starts with org_ and that the SUBQ_API_KEY environment variable is set.
Already using the Deepgram SDK? SubQ is fully compatible. See Migrate from Deepgram for a 2-line configuration change.
Requirements: Rust 1.70 or later.
Add the following dependencies to your Cargo.toml:
[dependencies]
reqwest = { version = "0.12", features = ["stream"] }
tokio = { version = "1", features = ["full"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
# Only needed for real-time streaming
tokio-tungstenite = { version = "0.24", features = ["rustls-tls-webpki-roots"] }
futures = "0.3"| Crate | Purpose |
|---|---|
reqwest | Send audio to POST /v1/listen for pre-recorded transcription. The stream feature enables streaming response bodies for URL downloads. |
tokio | Async runtime required by reqwest and tokio-tungstenite. |
serde / serde_json | Parse the JSON transcription response. |
tokio-tungstenite | Connect to wss://stt-api.subq.ai/v1/listen for real-time streaming. Only needed if you use streaming. |
futures | Provides StreamExt / SinkExt for working with async streams and WebSocket sinks. Only needed for streaming. |
Set up your API key
Store your API key in an environment variable so it isn't hardcoded in your source files:
export SUBQ_API_KEY="org_YOUR_API_KEY"To persist it, add the line to your ~/.bashrc, ~/.zshrc, or equivalent.
$env:SUBQ_API_KEY = "org_YOUR_API_KEY"To persist it, use [System.Environment]::SetEnvironmentVariable("SUBQ_API_KEY", "org_YOUR_API_KEY", "User").
set SUBQ_API_KEY=org_YOUR_API_KEYTo persist it, use setx SUBQ_API_KEY "org_YOUR_API_KEY".
Then read it in Rust:
let api_key = std::env::var("SUBQ_API_KEY").expect("SUBQ_API_KEY not set");Never commit API keys to version control. Use environment variables, .env files (with .gitignore), or a secrets manager.
Verify the setup
Run a quick test to confirm that you can reach the SubQ API. In this example, you transcribe a short public audio file:
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 a sample audio file
let audio_data = reqwest::get(audio_url).await?.bytes().await?;
// Send it to the SubQ API for transcription
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);
Ok(())
}Run it:
cargo run --bin verify_setupIf the setup is correct, you see a transcript printed to the console. If you get a 401 error, verify that your API key starts with org_ and that the SUBQ_API_KEY environment variable is set.
Next steps
- Transcribe a file - transcribe a local audio file from disk
- Transcribe from URL - transcribe a remote audio file by URL
- Real-time streaming - stream audio and receive transcripts in real time