SubQ
Integrations

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
PackagePurpose
httpxSend HTTP requests for pre-recorded transcription (POST /v1/listen).
websocketsConnect 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_KEY

To 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:

verify_setup.py
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.py

If 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
PackagePurpose
wsConnect 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_KEY

To 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:

verify_setup.js
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.js

If 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
PackagePurpose
github.com/gorilla/websocketConnect 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_KEY

To 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:

verify_setup.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 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.go

If 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:

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"
CratePurpose
reqwestSend audio to POST /v1/listen for pre-recorded transcription. The stream feature enables streaming response bodies for URL downloads.
tokioAsync runtime required by reqwest and tokio-tungstenite.
serde / serde_jsonParse the JSON transcription response.
tokio-tungsteniteConnect to wss://stt-api.subq.ai/v1/listen for real-time streaming. Only needed if you use streaming.
futuresProvides 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_KEY

To 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:

verify_setup.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 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_setup

If 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