Skip to main content
Deepgram's Docs

Search documentation

Type to search this documentation.

On this pageOverview

Audio Keep Alive

Streaming:Nova

Use the KeepAlive message to keep your WebSocket connection open during periods of silence, preventing timeouts and optimizing costs.

Send a KeepAlive message every 3-5 seconds to prevent the 10-second timeout that triggers a NET-0001 error and closes the connection. Ensure the message is sent as a text WebSocket frame—sending it as binary may result in incorrect handling and potential connection issues.

To send the KeepAlive message, send the following JSON message to the server:

JSON

JSON
{
  "type": "KeepAlive"
}

The server will not send a response back when you send a KeepAlive message. If no audio data or KeepAlive messages are sent within a 10-second window, the connection will close with a NET-0001 error.

Below are code examples to help you get started using KeepAlive.

Construct a JSON message containing the KeepAlive type and send it over the WebSocket connection in each respective language.

JavaScript

JavaScript
const WebSocket = require("ws");

// Assuming 'headers' is already defined for authorization
const ws = new WebSocket("wss://api.deepgram.com/v1/listen", { headers });

// Assuming 'ws' is the WebSocket connection object
const keepAliveMsg = JSON.stringify({ type: "KeepAlive" });
ws.send(keepAliveMsg);

Python

Python
import json
import websocket

# Assuming 'headers' is already defined for authorization
ws = websocket.create_connection("wss://api.deepgram.com/v1/listen", header=headers)

# Assuming 'ws' is the WebSocket connection object
keep_alive_msg = json.dumps({"type": "KeepAlive"})
ws.send(keep_alive_msg)

Go

Go
package main

import (
    "encoding/json"
    "log"
    "net/http"
    "github.com/gorilla/websocket"
)

func main() {
    // Define headers for authorization
    headers := http.Header{}

  	// Assuming headers are set here for authorization
    conn, _, err := websocket.DefaultDialer.Dial("wss://api.deepgram.com/v1/listen", headers)
    if err != nil {
        log.Fatal("Error connecting to WebSocket:", err)
    }
    defer conn.Close()

    // Construct KeepAlive message
    keepAliveMsg := map[string]string{"type": "KeepAlive"}
    jsonMsg, err := json.Marshal(keepAliveMsg)
    if err != nil {
        log.Fatal("Error encoding JSON:", err)
    }

    // Send KeepAlive message
    err = conn.WriteMessage(websocket.TextMessage, jsonMsg)
    if err != nil {
        log.Fatal("Error sending KeepAlive message:", err)
    }
}

C#

C#
using System;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        // Set up the WebSocket URL and headers
        Uri uri = new Uri("wss://api.deepgram.com/v1/listen");

        string apiKey = "DEEPGRAM_API_KEY";

        // Create a new client WebSocket instance
        using (ClientWebSocket ws = new ClientWebSocket())
        {
            // Set the authorization header
            ws.Options.SetRequestHeader("Authorization", "Token " + apiKey);

            // Connect to the WebSocket server
            await ws.ConnectAsync(uri, CancellationToken.None);

            // Construct the KeepAlive message
            string keepAliveMsg = "{\"type\": \"KeepAlive\"}";

            // Convert the KeepAlive message to a byte array
            byte[] keepAliveBytes = Encoding.UTF8.GetBytes(keepAliveMsg);

            // Send the KeepAlive message asynchronously
            await ws.SendAsync(new ArraySegment<byte>(keepAliveBytes), WebSocketMessageType.Text, true, CancellationToken.None);
        }
    }
}

Java

Java
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.WebSocket;
import java.util.concurrent.CompletableFuture;

// Assuming 'ws' is the WebSocket connection object
HttpClient client = HttpClient.newHttpClient();
WebSocket ws = client.newWebSocketBuilder()
    .header("Authorization", "Token DEEPGRAM_API_KEY")
    .buildAsync(URI.create("wss://api.deepgram.com/v1/listen"), new WebSocket.Listener() {})
    .join();

// Send KeepAlive message as a text frame
ws.sendText("{\"type\": \"KeepAlive\"}", true);

Make a streaming request and use KeepAlive to keep the connection open.

JavaScript

JavaScript
const WebSocket = require("ws");

const authToken = "DEEPGRAM_API_KEY"; // Replace 'DEEPGRAM_API_KEY' with your actual authorization token
const headers = {
  Authorization: `Token ${authToken}`,
};

// Initialize WebSocket connection
const ws = new WebSocket("wss://api.deepgram.com/v1/listen", { headers });

// Handle WebSocket connection open event
ws.on("open", function open() {
  console.log("WebSocket connection established.");

  // Send audio data (replace this with your audio streaming logic)
  // Example: Read audio from a microphone and send it over the WebSocket
  // For demonstration purposes, we're just sending a KeepAlive message

  setInterval(() => {
    const keepAliveMsg = JSON.stringify({ type: "KeepAlive" });
    ws.send(keepAliveMsg);
    console.log("Sent KeepAlive message");
  }, 3000); // Sending KeepAlive messages every 3 seconds
});

// Handle WebSocket message event
ws.on("message", function incoming(data) {
  console.log("Received:", data);
  // Handle received data (transcription results, errors, etc.)
});

// Handle WebSocket close event
ws.on("close", function close() {
  console.log("WebSocket connection closed.");
});

// Handle WebSocket error event
ws.on("error", function error(err) {
  console.error("WebSocket error:", err.message);
});

// Gracefully close the WebSocket connection when done
function closeWebSocket() {
  const closeMsg = JSON.stringify({ type: "CloseStream" });
  ws.send(closeMsg);
}

// Call closeWebSocket function when you're finished streaming audio
// For example, when user stops recording or when the application exits
// closeWebSocket();

Python

Python
import websocket
import json
import time
import threading

auth_token = "DEEPGRAM_API_KEY"  # Replace 'DEEPGRAM_API_KEY' with your actual authorization token
headers = {
    "Authorization": f"Token {auth_token}"
}

# WebSocket URL
ws_url = "wss://api.deepgram.com/v1/listen"

# Define the WebSocket on_open function
def on_open(ws):
    print("WebSocket connection established.")
    # Send KeepAlive messages every 3 seconds
    def keep_alive():
        while True:
            keep_alive_msg = json.dumps({"type": "KeepAlive"})
            ws.send(keep_alive_msg)
            print("Sent KeepAlive message")
            time.sleep(3)
    # Start a thread for sending KeepAlive messages
    keep_alive_thread = threading.Thread(target=keep_alive)
    keep_alive_thread.daemon = True
    keep_alive_thread.start()

# Define the WebSocket on_message function
def on_message(ws, message):
    print("Received:", message)
    # Handle received data (transcription results, errors, etc.)

# Define the WebSocket on_close function
def on_close(ws):
    print("WebSocket connection closed.")

# Define the WebSocket on_error function
def on_error(ws, error):
    print("WebSocket error:", error)

# Create WebSocket connection
ws = websocket.WebSocketApp(ws_url,
                            on_open=on_open,
                            on_message=on_message,
                            on_close=on_close,
                            on_error=on_error,
                            header=headers)

# Run the WebSocket
ws.run_forever()

Deepgram's SDKs make it easier to build with Deepgram in your preferred language. For more information on using Deepgram SDKs, refer to the SDKs documentation in the GitHub Repository.

JavaScript

JavaScript
const { DeepgramClient } = require("@deepgram/sdk");

const live = async () => {
  const deepgram = new DeepgramClient({ apiKey: "DEEPGRAM_API_KEY" });
  let connection;
  let keepAlive;

  const setupDeepgram = async () => {
    connection = await deepgram.listen.v1.connect({
      model: "nova-3",
      utterance_end_ms: "1500",
      interim_results: "true",
    });

    if (keepAlive) clearInterval(keepAlive);
    keepAlive = setInterval(() => {
      console.log("KeepAlive sent.");
      connection.sendKeepAlive({ type: "KeepAlive" });
    }, 3000); // Sending KeepAlive messages every 3 seconds

    connection.on("open", () => {
      console.log("Connection opened.");
    });

    connection.on("close", () => {
      console.log("Connection closed.");
      clearInterval(keepAlive);
    });

    connection.on("message", (data) => {
      if (data.type === "Metadata") {
        console.log(data);
      } else if (data.type === "Results") {
        console.log(data.channel);
      } else if (data.type === "UtteranceEnd") {
        console.log(data);
      } else if (data.type === "SpeechStarted") {
        console.log(data);
      }
    });

    connection.on("error", (err) => {
      console.error(err);
    });

    connection.connect();
    await connection.waitForOpen();
  };

  setupDeepgram();
};

live();

Python

Python
# For more Python SDK migration guides, visit:
# https://github.com/deepgram/deepgram-python-sdk/tree/main/docs

import os
from deepgram import DeepgramClient
from deepgram.core.events import EventType

API_KEY = os.getenv("DEEPGRAM_API_KEY")

def main():
    try:
        deepgram = DeepgramClient(
            api_key=API_KEY,
            config={"keepalive": "true"} # Comment this out to see the effect of not using keepalive
        )

        with deepgram.listen.websocket.v('1').stream(
            model="nova-3",
            language="en-US",
            smart_format=True,
        ) as dg_connection:

            def on_message(result):
                if hasattr(result, 'channel') and result.channel.alternatives:
                    sentence = result.channel.alternatives[0].transcript
                    if len(sentence) == 0:
                        return
                    print(f"speaker: {sentence}")

            def on_metadata(result):
                print(f"\n\n{result}\n\n")

            def on_error(error):
                print(f"\n\n{error}\n\n")

            dg_connection.on(EventType.MESSAGE, on_message)
            dg_connection.on(EventType.METADATA, on_metadata)
            dg_connection.on(EventType.ERROR, on_error)

            dg_connection.start_listening()

    except Exception as e:
        print(f"Could not open socket: {e}")

if __name__ == "__main__":
    main()

Go

Go
package main

import (
	"bufio"
	"context"
	"fmt"
	"os"

	interfaces "github.com/deepgram/deepgram-go-sdk/pkg/client/interfaces"
	client "github.com/deepgram/deepgram-go-sdk/pkg/client/live"
)

func main() {
	// init library
	client.InitWithDefault()

	// Go context
	ctx := context.Background()

	// set the Transcription options
	tOptions := interfaces.LiveTranscriptionOptions{
		Model="nova-3",
    Language:  "en-US",
		Punctuate: true,
	}

	// create a Deepgram client
	cOptions := interfaces.ClientOptions{
		EnableKeepAlive: true, // Comment this out to see the effect of not using keepalive
	}

	// use the default callback handler which just dumps all messages to the screen
	dgClient, err := client.New(ctx, "", cOptions, tOptions, nil)
	if err != nil {
		fmt.Println("ERROR creating LiveClient connection:", err)
		return
	}

	// connect the websocket to Deepgram
	wsconn := dgClient.Connect()
	if wsconn == nil {
		fmt.Println("Client.Connect failed")
		os.Exit(1)
	}

	// wait for user input to exit
	fmt.Printf("This demonstrates using KeepAlives. Press ENTER to exit...\n")
	input := bufio.NewScanner(os.Stdin)
	input.Scan()

	// close client
	dgClient.Stop()

	fmt.Printf("Program exiting...\n")
}

Java

Java
import com.deepgram.DeepgramClient;
import com.deepgram.resources.listen.v1.websocket.V1WebSocketClient;
import com.deepgram.resources.listen.v1.types.ListenV1KeepAlive;
import com.deepgram.resources.listen.v1.types.ListenV1KeepAliveType;
import com.deepgram.resources.listen.v1.websocket.V1ConnectOptions;
import java.util.concurrent.*;

DeepgramClient deepgram = DeepgramClient.builder().build();

V1ConnectOptions options = V1ConnectOptions.builder()
    .model("nova-3")
    .language("en-US")
    .smartFormat(true)
    .build();

V1WebSocketClient wsClient = deepgram.listen().v1().v1WebSocket();
wsClient.connect(options).get(10, TimeUnit.SECONDS);

wsClient.onResults(result -> System.out.println("Received: " + result));

// Send KeepAlive messages every 3 seconds
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleAtFixedRate(() -> {
    wsClient.sendKeepAlive(ListenV1KeepAlive.builder()
        .type(ListenV1KeepAliveType.KEEP_ALIVE)
        .build());
    System.out.println("KeepAlive sent.");
}, 3, 3, TimeUnit.SECONDS);

Word timings in streaming transcription results are based on the audio stream itself, not the lifetime of the WebSocket connection. If you send KeepAlive messages without any audio payloads for a period of time, then resume sending audio, the timestamps will continue from where the audio left off—not from when the KeepAlive messages were sent.

Here is an example timeline demonstrating the behavior.

Event Wall Time Word Timing Range on Results Response
Websocket opened, begin sending audio payloads 0 seconds 0 seconds
Results received 5 seconds 0-5 seconds
Results received 10 seconds 5-10 seconds
Pause sending audio payloads, while sending KeepAlive messages 10 seconds n/a
Resume sending audio payloads 30 seconds n/a
Results received 35 seconds 10-15 seconds

Suggest an edit

Propose a replacement for this page. The site team reviews it before applying any changes.

Export
Documentation menu