Go SDK

Official Go client for the Speech Revolutions STT API.

Source on GitHub · report an issue · pkg.go.dev

Install

bash
go get github.com/speechrevolutions/speechrevolutions-go

Quickstart

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.

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

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

FieldTypeDefaultNotes
OutputTypeOutputTypeOutputJSONtxt | json | srt | vtt | docx | pdf
WordTimestamps*booltruePer-word start/end times
SpeakerLabels*booltrueLabel who spoke each segment
Diarize*boolDeepgram-compatible alias for SpeakerLabels
NLTK*booltrueRestore punctuation & capitalization
Tier*ProcessingTierTierStandardTierStandard — the only tier currently available
CustomVocabulary[]stringnilDomain terms to bias toward
OnUploadProgressProgressFuncnilUpload byte-progress callback
ProgressboolfalseRender 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.

go
// 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:

AccessDescription
result.Text()Full transcript (AssemblyAI / ElevenLabs style)
result.TranscriptText()Deepgram-style alias
result.WordsWord + start / end / speaker
result.UtterancesAssemblyAI-style speaker turns
result.ToDeepgram()Deepgram-shaped map
result.ToDict()Normalized map
result.Content / result.Save(path)Raw bytes / write to disk
go
// 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.

go
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 finishes

Retrieve 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.

retrieve.go
// 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

bash
export SPEECHREVOLUTIONS_API_KEY=stt_...
go
client, _ := stt.NewClient("")           // reads the env vars above
explicit, _ := stt.NewClient("stt_...")  // or pass it directly

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.