Official Java SDK for Deepgram's automated speech recognition, text-to-speech, and language understanding APIs.
Power your applications with world-class speech and language AI models.
You can learn more about the Deepgram API at developers.deepgram.com.
Add the dependency to your build.gradle:
dependencies {
implementation 'com.deepgram:deepgram-java-sdk:0.8.0'// x-release-please-version
}Add the dependency to your pom.xml:
<dependency>
<groupId>com.deepgram</groupId>
<artifactId>deepgram-java-sdk</artifactId>
<version>0.8.0</version> <!-- x-release-please-version -->
</dependency>The SDK supports API Key authentication with automatic environment variable loading:
importcom.deepgram.DeepgramClient;
// Using environment variable (DEEPGRAM_API_KEY)DeepgramClientenvClient = DeepgramClient.builder().build();
// Using API key directlyDeepgramClientexplicitClient = DeepgramClient.builder()
.apiKey("YOUR_DEEPGRAM_API_KEY")
.build();Get your API key from the Deepgram Console.
Use an access token (JWT) for Bearer authentication. When provided, the access token takes precedence over any API key:
// With access token (Bearer auth)DeepgramClientclient = DeepgramClient.builder()
.accessToken("your-jwt-token")
.build();Attach a custom session identifier sent as the x-deepgram-session-id header with every request and WebSocket connection. If not provided, a UUID is auto-generated:
// With custom session IDDeepgramClientclient = DeepgramClient.builder()
.apiKey("your-api-key")
.sessionId("my-session-123")
.build();Transcribe pre-recorded audio from files or URLs.
importcom.deepgram.DeepgramClient;
importcom.deepgram.resources.listen.v1.media.requests.ListenV1RequestUrl;
importcom.deepgram.resources.listen.v1.media.types.MediaTranscribeResponse;
importcom.deepgram.types.ListenV1AcceptedResponse;
importcom.deepgram.types.ListenV1Response;
DeepgramClientclient = DeepgramClient.builder().build();
// Transcribe from URLMediaTranscribeResponseresult = client.listen().v1().media().transcribeUrl(
ListenV1RequestUrl.builder()
.url("https://static.deepgram.com/examples/Bueller-Life-moves-pretty-fast.wav")
.build()
);
// Access transcription (MediaTranscribeResponse is a union type)result.visit(newMediaTranscribeResponse.Visitor<Void>() {
@OverridepublicVoidvisit(ListenV1Responseresponse) {
response.getResults().getChannels().get(0)
.getAlternatives().ifPresent(alts -> {
alts.get(0).getTranscript().ifPresent(System.out::println);
});
returnnull;
}
@OverridepublicVoidvisit(ListenV1AcceptedResponseaccepted) {
System.out.println("Request accepted (callback mode)");
returnnull;
}
});importjava.nio.file.Files;
importjava.nio.file.Path;
byte[] audioData = Files.readAllBytes(Path.of("audio.wav"));
MediaTranscribeResponseresult = client.listen().v1().media().transcribeFile(audioData);Convert text to natural-sounding speech.
importcom.deepgram.DeepgramClient;
importcom.deepgram.resources.speak.v1.audio.requests.SpeakV1Request;
importjava.io.InputStream;
DeepgramClientclient = DeepgramClient.builder().build();
// Generate speech audioInputStreamaudioStream = client.speak().v1().audio().generate(
SpeakV1Request.builder()
.text("Hello, world! Welcome to Deepgram.")
.build()
);
// Write audio to file or play itAnalyze text for sentiment, topics, summaries, and intents.
importcom.deepgram.DeepgramClient;
importcom.deepgram.resources.read.v1.text.requests.TextAnalyzeRequest;
importcom.deepgram.types.ReadV1Request;
importcom.deepgram.types.ReadV1RequestText;
importcom.deepgram.types.ReadV1Response;
DeepgramClientclient = DeepgramClient.builder().build();
ReadV1Responseresult = client.read().v1().text().analyze(
TextAnalyzeRequest.builder()
.body(ReadV1Request.of(
ReadV1RequestText.builder()
.text("Deepgram's speech recognition is incredibly accurate and fast.")
.build()))
.sentiment(true)
.language("en")
.build()
);Manage projects, API keys, members, usage, and billing.
importcom.deepgram.DeepgramClient;
DeepgramClientclient = DeepgramClient.builder().build();
// List projectsvarprojects = client.manage().v1().projects().list();
// List API keys for a projectvarkeys = client.manage().v1().projects().keys().list("project-id");
// Get usage statisticsvarusage = client.manage().v1().projects().usage().get("project-id");Manage voice agent configurations and models.
importcom.deepgram.DeepgramClient;
DeepgramClientclient = DeepgramClient.builder().build();
// List available agent think modelsvarmodels = client.agent().v1().settings().think().models().list();The SDK includes built-in WebSocket clients for real-time streaming.
Stream audio for real-time speech-to-text.
importcom.deepgram.DeepgramClient;
importcom.deepgram.resources.listen.v1.types.ListenV1CloseStream;
importcom.deepgram.resources.listen.v1.types.ListenV1CloseStreamType;
importcom.deepgram.resources.listen.v1.websocket.V1WebSocketClient;
importcom.deepgram.resources.listen.v1.websocket.V1ConnectOptions;
importcom.deepgram.types.ListenV1Model;
importjava.nio.file.Files;
importjava.nio.file.Path;
importjava.util.concurrent.TimeUnit;
importokio.ByteString;
DeepgramClientclient = DeepgramClient.builder().build();
byte[] audioBytes = Files.readAllBytes(Path.of("audio.wav"));
V1WebSocketClientws = client.listen().v1().v1WebSocket();
// Register event handlersws.onResults(results -> {
Stringtranscript = results.getChannel()
.getAlternatives().get(0)
.getTranscript();
System.out.println("Transcript: " + transcript);
});
ws.onMetadata(metadata -> {
System.out.println("Metadata received");
});
ws.onError(error -> {
System.err.println("Error: " + error.getMessage());
});
// Connect with options (model is required)ws.connect(V1ConnectOptions.builder()
.model(ListenV1Model.NOVA3)
.build())
.get(10, TimeUnit.SECONDS);
ws.sendMedia(ByteString.of(audioBytes));
ws.sendCloseStream(ListenV1CloseStream.builder()
.type(ListenV1CloseStreamType.CLOSE_STREAM)
.build())
.get(5, TimeUnit.SECONDS);
// Close when donews.close();Stream text for real-time audio generation.
importcom.deepgram.DeepgramClient;
importcom.deepgram.resources.speak.v1.types.SpeakV1Close;
importcom.deepgram.resources.speak.v1.types.SpeakV1CloseType;
importcom.deepgram.resources.speak.v1.types.SpeakV1Flush;
importcom.deepgram.resources.speak.v1.types.SpeakV1FlushType;
importcom.deepgram.resources.speak.v1.types.SpeakV1Text;
importcom.deepgram.resources.speak.v1.websocket.V1WebSocketClient;
importjava.io.ByteArrayOutputStream;
importjava.nio.file.Files;
importjava.nio.file.Path;
importjava.util.concurrent.TimeUnit;
DeepgramClientclient = DeepgramClient.builder().build();
ByteArrayOutputStreamaudioBuffer = newByteArrayOutputStream();
V1WebSocketClientttsWs = client.speak().v1().v1WebSocket();
// Register event handlersttsWs.onSpeakV1Audio(audioData -> {
audioBuffer.writeBytes(audioData.toByteArray());
});
ttsWs.onMetadata(metadata -> {
System.out.println("Metadata received");
});
ttsWs.onError(error -> {
System.err.println("Error: " + error.getMessage());
});
// Connect and send textttsWs.connect().get(10, TimeUnit.SECONDS);
ttsWs.sendText(SpeakV1Text.builder()
.text("Hello, this is streamed text-to-speech.")
.build())
.get(5, TimeUnit.SECONDS);
ttsWs.sendFlush(SpeakV1Flush.builder()
.type(SpeakV1FlushType.FLUSH)
.build())
.get(5, TimeUnit.SECONDS);
Thread.sleep(2000);
Files.write(Path.of("output.wav"), audioBuffer.toByteArray());
ttsWs.sendClose(SpeakV1Close.builder()
.type(SpeakV1CloseType.CLOSE)
.build())
.get(5, TimeUnit.SECONDS);
// Close when donettsWs.close();The Speak V2 WebSocket adds Flux TTS barge-in and mid-stream controls. Open the connection with V2ConnectOptions (model required; speed and expressivity are optional connect params), then:
sendConfigure(...)adjusts the speech-rate multiplier mid-stream. Accepted speeds are0.85–1.15in0.05steps; the server replies viaonConfigureSuccessor a typedonConfigureFailure(e.g.SPEED_OUT_OF_RANGE).sendInterrupt(...)stops playback (barge-in). Pass aSpeakV2InterruptPlaybackOffsetwith the audio milliseconds played so theonSpeechInterruptedevent can reportgetTextSpoken()/getTextRemaining(). The offset is cumulative from session start, and each interrupt must advance past the previous one.
importcom.deepgram.resources.speak.v2.types.SpeakV2Configure;
importcom.deepgram.resources.speak.v2.types.SpeakV2Interrupt;
importcom.deepgram.resources.speak.v2.types.SpeakV2InterruptPlaybackOffset;
importcom.deepgram.resources.speak.v2.types.SpeakV2Speak;
importcom.deepgram.resources.speak.v2.websocket.V2ConnectOptions;
importcom.deepgram.resources.speak.v2.websocket.V2WebSocketClient;
V2WebSocketClientttsWs = client.speak().v2().v2WebSocket();
// Mid-stream configure acknowledgementsttsWs.onConfigureSuccess(success -> System.out.println("configured: " + success.getApplied()));
ttsWs.onConfigureFailure(failure ->
System.out.println("rejected [" + failure.getCode() + "]: " + failure.getDescription()));
// Barge-in: reports where playback was cut off when the interrupt carried a playback offsetttsWs.onSpeechInterrupted(interrupted -> {
interrupted.getTextSpoken().ifPresent(spoken -> System.out.println("spoken: " + spoken));
interrupted.getTextRemaining().ifPresent(remaining -> System.out.println("remaining: " + remaining));
});
ttsWs.connect(V2ConnectOptions.builder().model("flux-alexis-en").build()).get(10, TimeUnit.SECONDS);
ttsWs.sendConfigure(SpeakV2Configure.builder().speed(1.05).build());
ttsWs.sendSpeak(SpeakV2Speak.builder().text("This is a longer sentence we can barge in on.").build());
// Stop playback after ~1.2s of audio has playedttsWs.sendInterrupt(SpeakV2Interrupt.builder()
.playbackOffset(SpeakV2InterruptPlaybackOffset.builder().value(1200).build())
.build());
ttsWs.close();See examples/speak/StreamingTtsV2.java for a complete, runnable barge-in example.
Connect to Deepgram's voice agent for real-time conversational AI.
importcom.deepgram.DeepgramClient;
importcom.deepgram.resources.agent.v1.types.AgentV1InjectUserMessage;
importcom.deepgram.resources.agent.v1.types.AgentV1Settings;
importcom.deepgram.resources.agent.v1.types.AgentV1SettingsAgent;
importcom.deepgram.resources.agent.v1.types.AgentV1SettingsAgentContext;
importcom.deepgram.resources.agent.v1.types.AgentV1SettingsAgentContextThink;
importcom.deepgram.resources.agent.v1.types.AgentV1SettingsAudio;
importcom.deepgram.resources.agent.v1.websocket.V1WebSocketClient;
importcom.deepgram.types.OpenAiThinkProvider;
importcom.deepgram.types.OpenAiThinkProviderModel;
importcom.deepgram.types.ThinkSettingsV1;
importcom.deepgram.types.ThinkSettingsV1Provider;
importjava.util.concurrent.TimeUnit;
DeepgramClientclient = DeepgramClient.builder().build();
V1WebSocketClientagentWs = client.agent().v1().v1WebSocket();
// Register event handlersagentWs.onWelcome(welcome -> {
System.out.println("Agent connected");
agentWs.sendSettings(AgentV1Settings.builder()
.audio(AgentV1SettingsAudio.builder().build())
.agent(AgentV1SettingsAgent.of(
AgentV1SettingsAgentContext.builder()
.think(AgentV1SettingsAgentContextThink.of(
ThinkSettingsV1.builder()
.provider(ThinkSettingsV1Provider.openAi(
OpenAiThinkProvider.builder()
.model(OpenAiThinkProviderModel.GPT4O_MINI)
.build()))
.prompt("You are a helpful voice assistant. Keep responses brief.")
.build()))
.greeting("Hello! How can I help you today?")
.build()))
.build());
});
agentWs.onSettingsApplied(applied -> {
agentWs.sendInjectUserMessage(AgentV1InjectUserMessage.builder()
.content("What is the capital of France?")
.build());
});
agentWs.onConversationText(text -> {
System.out.printf("[%s] %s%n", text.getRole(), text.getContent());
});
agentWs.onError(error -> {
System.err.println("Error: " + error.getMessage());
});
// Connect and wait for the agent to respondagentWs.connect().get(10, TimeUnit.SECONDS);
Thread.sleep(5000);
// Close when doneagentWs.close();The SDK supports pluggable transports for routing WebSocket connections through alternative infrastructure. Any class implementing DeepgramTransportFactory can replace the default OkHttp WebSocket connection.
This is primarily used for AWS SageMaker deployments where Deepgram models run on your own SageMaker endpoints.
Use the separate deepgram-sagemaker package to route audio through a SageMaker endpoint:
dependencies {
implementation 'com.deepgram:deepgram-java-sdk:0.8.0'// x-release-please-version
implementation 'com.deepgram:deepgram-sagemaker:0.1.2'
}importcom.deepgram.DeepgramClient;
importcom.deepgram.sagemaker.SageMakerConfig;
importcom.deepgram.sagemaker.SageMakerTransportFactory;
importcom.deepgram.resources.listen.v1.websocket.V1ConnectOptions;
importcom.deepgram.types.ListenV1Model;
importjava.nio.file.Files;
importjava.nio.file.Path;
importjava.util.concurrent.TimeUnit;
importokio.ByteString;
byte[] audioBytes = Files.readAllBytes(Path.of("audio.wav"));
varfactory = newSageMakerTransportFactory(
SageMakerConfig.builder()
.endpointName("my-deepgram-endpoint")
.region("us-west-2")
.build()
);
DeepgramClientclient = DeepgramClient.builder()
.apiKey("unused") // SageMaker uses AWS credentials, not Deepgram API keys
.transportFactory(factory)
.build();
// Use the SDK exactly as normal — the transport is transparentvarws = client.listen().v1().v1WebSocket();
ws.onResults(results -> { /* ... */ });
ws.connect(V1ConnectOptions.builder().model(ListenV1Model.NOVA3).build())
.get(10, TimeUnit.SECONDS);
ws.sendMedia(ByteString.of(audioBytes));See the SageMaker example for a complete walkthrough.
To implement your own transport (e.g. for proxies, test doubles, or other infrastructure):
importcom.deepgram.core.transport.DeepgramTransport;
importcom.deepgram.core.transport.DeepgramTransportFactory;
DeepgramTransportFactorymyFactory = (url, headers) -> {
// Return your DeepgramTransport implementationreturnnewMyCustomTransport(url, headers);
};
DeepgramClientclient = DeepgramClient.builder()
.apiKey("your-key")
.transportFactory(myFactory)
.build();The DeepgramTransport interface provides bidirectional messaging: sendText(), sendBinary(), and callback registration for incoming messages, errors, and close events.
DeepgramClientclient = DeepgramClient.builder()
.apiKey("YOUR_DEEPGRAM_API_KEY")
.timeout(30) // 30 seconds
.build();The SDK retries 408, 429, and 5xx responses with exponential backoff and jitter, honouring
Retry-After and X-RateLimit-Reset when the server sends them. Configure the maximum number of
retries with maxRetries:
DeepgramClientclient = DeepgramClient.builder()
.apiKey("YOUR_DEEPGRAM_API_KEY")
.maxRetries(3)
.build();Note: When providing a custom
OkHttpClient, the SDK's built-in retry interceptor is not added automatically. Add your own retry logic if needed.
importokhttp3.OkHttpClient;
importjava.util.concurrent.TimeUnit;
OkHttpClienthttpClient = newOkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.build();
DeepgramClientclient = DeepgramClient.builder()
.apiKey("YOUR_DEEPGRAM_API_KEY")
.httpClient(httpClient)
.build();For on-premises deployments or custom REST/WebSocket endpoints:
importcom.deepgram.core.Environment;
DeepgramClientclient = DeepgramClient.builder()
.apiKey("YOUR_DEEPGRAM_API_KEY")
.environment(Environment.custom()
.base("https://your-rest-endpoint.com")
.production("wss://your-listen-websocket-endpoint.com")
.agent("wss://your-agent-websocket-endpoint.com")
.build())
.build();Set your API key as an environment variable to avoid passing it in code:
export DEEPGRAM_API_KEY="your-api-key-here"// API key is loaded automatically from DEEPGRAM_API_KEYDeepgramClientclient = DeepgramClient.builder().build();DeepgramClientclient = DeepgramClient.builder()
.apiKey("YOUR_DEEPGRAM_API_KEY")
.addHeader("X-Custom-Header", "custom-value")
.build();The SDK provides a fully asynchronous client for non-blocking operations:
importcom.deepgram.AsyncDeepgramClient;
importcom.deepgram.resources.listen.v1.media.requests.ListenV1RequestUrl;
importcom.deepgram.resources.listen.v1.media.types.MediaTranscribeResponse;
importjava.util.concurrent.CompletableFuture;
AsyncDeepgramClientasyncClient = AsyncDeepgramClient.builder().build();
// Async transcriptionCompletableFuture<MediaTranscribeResponse> future = asyncClient.listen().v1().media()
.transcribeUrl(ListenV1RequestUrl.builder()
.url("https://static.deepgram.com/examples/Bueller-Life-moves-pretty-fast.wav")
.build());
future.thenAccept(result -> {
System.out.println("Transcription complete!");
});The SDK provides structured error handling:
importcom.deepgram.errors.BadRequestError;
try {
varresult = client.listen().v1().media().transcribeUrl(
ListenV1RequestUrl.builder()
.url("https://example.com/audio.mp3")
.build()
);
} catch (BadRequestErrore) {
System.err.println("Bad request: " + e.getMessage());
} catch (Exceptione) {
System.err.println("Error: " + e.getMessage());
}All client methods support raw response access via the raw client:
importcom.deepgram.core.DeepgramApiHttpResponse;
importcom.deepgram.resources.listen.v1.media.types.MediaTranscribeResponse;
// Access raw HTTP responseDeepgramApiHttpResponse<MediaTranscribeResponse> rawResponse =
client.listen().v1().media().withRawResponse().transcribeUrl(request);
varheaders = rawResponse.headers();
MediaTranscribeResponsebody = rawResponse.body();The SDK provides comprehensive access to Deepgram's APIs:
client.listen().v1().media().transcribeUrl(request) // Transcribe audio from URLclient.listen().v1().media().transcribeFile(body) // Transcribe audio from file bytesclient.listen().v1().v1WebSocket() // Real-time streaming transcriptionclient.speak().v1().audio().generate(request) // Generate speech from textclient.speak().v1().v1WebSocket() // Real-time streaming TTSclient.read().v1().text().analyze(request) // Analyze text contentclient.agent().v1().settings().think().models().list() // List available agent modelsclient.agent().v1().v1WebSocket() // Real-time agent WebSocket// Projectsclient.manage().v1().projects().list() // List all projectsclient.manage().v1().projects().get(projectId) // Get project detailsclient.manage().v1().projects().update(projectId, req) // Update projectclient.manage().v1().projects().delete(projectId) // Delete project// API Keysclient.manage().v1().projects().keys().list(projectId) // List API keysclient.manage().v1().projects().keys().create(id, req) // Create new keyclient.manage().v1().projects().keys().get(id, keyId) // Get key detailsclient.manage().v1().projects().keys().delete(id, key) // Delete key// Membersclient.manage().v1().projects().members().list(id) // List membersclient.manage().v1().projects().members().delete(p, m) // Remove member// Usageclient.manage().v1().projects().usage().get(projectId) // Get usage summary// Modelsclient.manage().v1().projects().models().list(id) // List project modelsclient.manage().v1().models().list() // List all modelsclient.auth().v1().tokens().grant(request) // Generate access tokenclient.selfHosted().v1().distributionCredentials().list(id) // List credentialsclient.selfHosted().v1().distributionCredentials().create(req) // Create credentialsclient.selfHosted().v1().distributionCredentials().get(p, id) // Get credentialsclient.selfHosted().v1().distributionCredentials().delete(p,i) // Delete credentials- Java 11 or higher (Java 17 recommended for development)
- Gradle (wrapper included)
- Deepgram API key (sign up)
# Unit tests
./gradlew unitTest
# Integration tests (requires DEEPGRAM_API_KEY)
./gradlew integrationTest
# All tests
./gradlew testmake check # lint + build + unit tests
make test-integration # integration tests only
make test-all # full test suite
make format # auto-format codeSee developers.deepgram.com for complete API documentation.
We welcome contributions! Please see CONTRIBUTING.md for details.
Please see our community code of conduct before contributing to this project.
This project is licensed under the MIT License - see the LICENSE file for details.
Built by Deepgram