Go SDK
Official Go client for the Speech Revolutions STT API.
Source on GitHub · report an issue · pkg.go.dev
Install
go get github.com/speechrevolutions/speechrevolutions-goQuickstart
Transcribe accepts a local file path, an http(s) URL, or raw bytes (TranscribeBytes). The third argument is an optional transcription-progress callback (nil for none). Bool and tier options are pointers, so an unset field is distinct from false — leave them nil to accept the default.
package main
import (
"context"
"fmt"
"log"
stt "github.com/speechrevolutions/speechrevolutions-go"
)
func main() {
ctx := context.Background()
client, err := stt.NewClient("") // SPEECHREVOLUTIONS_API_KEY
if err != nil {
log.Fatal(err)
}
result, err := client.Transcribe(ctx, "meeting.mp3", stt.TranscribeOptions{
SpeakerLabels: stt.Bool(true),
}, nil)
if err != nil {
log.Fatal(err)
}
fmt.Println(result.Text())
for _, u := range result.Utterances {
fmt.Printf("Speaker %s: %s\n", u.Speaker, u.Text)
}
}From a URL or file
// explicit alias
result, err := client.TranscribeURL(ctx, "https://example.com/audio.mp3", stt.TranscribeOptions{}, nil)
// or, since Transcribe detects http(s):
result, err = client.Transcribe(ctx, "https://example.com/audio.mp3", stt.TranscribeOptions{}, nil)
// TranscribeFile is the same for a local path; TranscribeBytes for in-memory audio.Options
TranscribeOptions fields — an empty TranscribeOptions{} gets all defaults applied.
| Field | Type | Default | Notes |
|---|---|---|---|
OutputType | OutputType | OutputJSON | txt | json | srt | vtt | docx | pdf |
WordTimestamps | *bool | true | Per-word start/end times |
SpeakerLabels | *bool | true | Label who spoke each segment |
Diarize | *bool | — | Deepgram-compatible alias for SpeakerLabels |
NLTK | *bool | true | Restore punctuation & capitalization |
Tier | *ProcessingTier | TierStandard | TierStandard — the only tier currently available |
CustomVocabulary | []string | nil | Domain terms to bias toward |
OnUploadProgress | ProgressFunc | nil | Upload byte-progress callback |
Progress | bool | false | Render live console bars |
Live progress
Unlike AssemblyAI and Deepgram — which expose no percentage for pre-recorded audio — you get real-time progress for both the file upload and the transcription, as a console bar, callbacks, or both. They compose: the bars render and your callbacks fire for every event.
// 1. Console bars — a single stderr line, updated in place. Shows an
// "Uploading" byte bar, then a "Transcribing" bar. Off by default.
result, _ := client.Transcribe(ctx, "meeting.mp3", stt.TranscribeOptions{
SpeakerLabels: stt.Bool(true),
Progress: true,
}, nil)
// 2. Programmatic — Percent() returns (float64, bool); the bool is false when
// the total is unknown, so treat that as "unknown".
onProgress := func(e stt.ProgressEvent) { // transcription
if pct, ok := e.Percent(); ok {
fmt.Printf("%.0f%% %s\n", pct, e.Step) // e.g. 42 "transcribe"
}
}
onUpload := func(e stt.ProgressEvent) { // upload (e.Step == "upload")
if pct, ok := e.Percent(); ok {
fmt.Printf("upload %.0f%%\n", pct)
}
}
result, _ = client.Transcribe(ctx, "meeting.mp3", stt.TranscribeOptions{
OnUploadProgress: onUpload,
Progress: true, // bars AND callbacks together
}, onProgress)Building a UI? Live progress for web apps shows how to fold both callbacks into a single 0–100 bar you can serve to your frontend.
Result shape
With OutputJSON the result is parsed into a transcript-first object:
| Access | Description |
|---|---|
result.Text() | Full transcript (AssemblyAI / ElevenLabs style) |
result.TranscriptText() | Deepgram-style alias |
result.Words | Word + start / end / speaker |
result.Utterances | AssemblyAI-style speaker turns |
result.ToDeepgram() | Deepgram-shaped map |
result.ToDict() | Normalized map |
result.Content / result.Save(path) | Raw bytes / write to disk |
// Save writes output.<output_type> when the path has no extension.
out, err := result.Save("output") // -> "output.json"
if err != nil {
log.Fatal(err)
}
fmt.Println("saved to", out)Webhooks
Set CallbackURL to be notified when a job finishes instead of holding the call open. On completion or permanent failure the platform POSTs a signed JSON body {job_id, status: "completed"|"failed", download_url?, step?, reason?} to your URL, signed with HMAC-SHA256 over the raw body in the X-SR-Signature: sha256=<hex> header (plus X-SR-Event with the status and a unique X-SR-Delivery id). Verify it against the raw request bytes with hmac + crypto/subtle.ConstantTimeCompare.
jobID, err := client.Submit(ctx, "meeting.mp3", stt.TranscribeOptions{
CallbackURL: "https://you.example.com/hook",
})
if err != nil {
log.Fatal(err)
}
fmt.Println("submitted", jobID) // the hook fires when it finishesRetrieve results later
Fetch a job by id anytime — useful after a webhook, or when rebuilding state after a restart. The download URL is regenerated on demand.
// List the most-recent jobs (newest first), cursor-paginated.
page, err := client.ListJobs(ctx, 10, "") // (limit, before)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%d job(s); next_before=%q\n", len(page.Jobs), page.NextBefore)
for _, j := range page.Jobs {
fmt.Printf(" %s (%s)\n", j.JobID, j.CreatedAt)
}
// Poll a job by id, then fetch its transcript.
status, err := client.GetJobStatus(ctx, jobID)
if err != nil {
log.Fatal(err)
}
fmt.Println("status:", status.Status)
if status.IsCompleted() {
result, err := client.GetTranscript(ctx, jobID, stt.OutputJSON)
if err != nil {
log.Fatal(err)
}
fmt.Println(result.Text())
} else if status.IsFailed() {
fmt.Println(status.FailedStage, status.Reason)
}Auth
export SPEECHREVOLUTIONS_API_KEY=stt_...client, _ := stt.NewClient("") // reads the env vars above
explicit, _ := stt.NewClient("stt_...") // or pass it directlyUnder the hood
The SDK drives the /api/v1/upload flow and waits on the SSE job stream, converting the server's completed/total counts into a Percent() for you.