stt

package module
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 22, 2026 License: MIT Imports: 17 Imported by: 0

README

go-sdk

Official Go client for the Speech Revolutions speech-to-text API.

Install

go get github.com/speechrevolutions/speechrevolutions-go
import stt "github.com/speechrevolutions/speechrevolutions-go"

Quick start

client, _ := stt.NewClient("") // reads SPEECHREVOLUTIONS_API_KEY
ctx := context.Background()

sl := true
result, err := client.Transcribe(ctx, "meeting.mp3", stt.TranscribeOptions{
    SpeakerLabels: &sl,
}, 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)
}

Every call takes a context.Context first, so you can cancel or deadline any request. Transcribe accepts a local file path, an http(s) URL, or raw bytes (TranscribeBytes). The last argument is an optional transcription-progress callback (nil for none).

From a URL (Deepgram-style)
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)

The platform fetches the URL itself — the audio never passes through this process.

TranscribeFile is the same for a local path.

Options

TranscribeOptions fields (bool/tier fields are pointers so unset ≠ false — leave them nil to accept the default):

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 standard | economy
CustomVocabulary []string nil domain terms to bias toward
OnUploadProgress ProgressFunc nil upload byte-progress callback
Progress bool false render live console bars

An empty TranscribeOptions{} gets all defaults applied.

Live progress

Unlike AssemblyAI/Deepgram (which give 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 line on stderr, updated in place. Shows an
//    "Uploading" byte bar, then a "Transcribing" bar. Off by default.
sl := true
result, _ := client.Transcribe(ctx, "meeting.mp3", stt.TranscribeOptions{
    SpeakerLabels: &sl,
    Progress:      true,
}, nil)

// 2. Programmatic — read ProgressEvent.Percent() (0–100) to drive your own UI.
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,
}, onProgress)

ProgressEvent.Percent() returns (float64, bool); the bool is false when the percentage can't be computed yet (total unknown), so treat it as "unknown".

Webhooks & retrieving results later

Submit uploads and enqueues a job and returns its id without waiting — ideal for batch/background work. Collect the result later via a webhook (CallbackURL, a signed POST — verify X-SR-Signature: sha256=… against the raw body) or by polling. See examples/retrieve:

jobID, _ := client.Submit(ctx, "meeting.mp3", stt.TranscribeOptions{}) // returns immediately
// ...or notify a webhook instead of polling:
client.Transcribe(ctx, path, stt.TranscribeOptions{CallbackURL: "https://you.example.com/hook"}, nil)

st, _ := client.GetJobStatus(ctx, jobID)     // st.Status: processing|completed|failed
if st.IsCompleted() {
    result, _ := client.GetTranscript(ctx, jobID, stt.OutputJSON) // downloads + parses
}
page, _ := client.ListJobs(ctx, 50, "")      // page.Jobs, page.NextBefore

Result shape

Default OutputType is json, parsed into a transcript-first object:

Access Like
result.Text() AssemblyAI / ElevenLabs
result.TranscriptText() Deepgram alias
result.Words word + start/end/speaker
result.Utterances AssemblyAI speaker turns
result.ToDeepgram() Deepgram-shaped map
result.ToDict() normalized map
result.Content / result.Save(path) raw bytes / write to file
dg := result.ToDeepgram()
chans := dg["results"].(map[string]any)["channels"].([]map[string]any)
fmt.Println(chans[0]["alternatives"].([]map[string]any)[0]["transcript"])

// Save writes output.<output_type> when the path has no extension.
out, _ := result.Save("output") // -> "output.json"
fmt.Println("saved to", out)

Timeouts and retries

Every method takes a context.Context, so cancelling or deadlining a call is the caller's choice:

ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
defer cancel()
result, err := client.Transcribe(ctx, "meeting.mp3", stt.TranscribeOptions{}, nil)

JSON API requests that fail to connect or return 429/500/502/503/504 are retried with exponential backoff, honoring Retry-After. Uploads and the progress stream have their own retry loops.

client.Timeout = 10 * time.Minute // whole-job wait (SSE + polling)
client.MaxRetries = 3             // extra attempts per API request
client.RetryBackoff = 500 * time.Millisecond
client.HTTP = &http.Client{Transport: myTransport} // proxies, tracing, etc.

Auth

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

See examples/main.go for a full run that shows progress and saves the result. Also see examples/retrieve for submit-and-poll, and examples/progress for wiring progress into a web app.

License

MIT — see LICENSE.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Bool

func Bool(b bool) *bool

TranscribeOptions controls how audio is transcribed. Bool returns a pointer to b, for the optional *bool fields on TranscribeOptions. Without it every call site needs a throwaway variable:

opts := stt.TranscribeOptions{SpeakerLabels: stt.Bool(true)}

Types

type APIError

type APIError struct {
	// contains filtered or unexported fields
}

func (*APIError) Error

func (e *APIError) Error() string

type AuthenticationError

type AuthenticationError struct {
	// contains filtered or unexported fields
}

func (*AuthenticationError) Error

func (e *AuthenticationError) Error() string

type Client

type Client struct {
	APIKey  string
	BaseURL string
	// Timeout bounds a whole transcription wait (SSE + polling). Individual
	// HTTP calls have their own shorter deadlines.
	Timeout time.Duration
	HTTP    *http.Client
	// Multipart prefers S3 multipart uploads and falls back to a single presigned
	// PUT if the server has multipart disabled or a multipart upload fails
	// mid-flight. Defaults to true (set by NewClient).
	Multipart bool
	// MaxRetries is the number of extra attempts for a JSON API request that
	// fails to connect or returns 429/5xx. Uploads and SSE have their own loops.
	MaxRetries int
	// RetryBackoff is the first retry delay; it doubles per attempt, capped at 30s.
	RetryBackoff time.Duration
}

Client talks to the Speech Revolutions STT API.

func NewClient

func NewClient(apiKey string) (*Client, error)

NewClient creates a Client. If apiKey is empty, it reads SPEECHREVOLUTIONS_API_KEY from the environment.

func (*Client) CancelJob

func (c *Client) CancelJob(ctx context.Context, jobID string) error

CancelJob calls POST /api/v1/jobs/cancel.

func (*Client) CheckFailed

func (c *Client) CheckFailed(ctx context.Context, jobIDs []string) ([]bool, error)

CheckFailed calls POST /api/v1/jobs/check-failed.

func (*Client) CompleteUpload

func (c *Client) CompleteUpload(ctx context.Context, jobID string) error

CompleteUpload calls POST /api/v1/upload/complete.

func (*Client) CreateUploadJob

func (c *Client) CreateUploadJob(ctx context.Context, fileSize int, opts TranscribeOptions) (*UploadJob, error)

CreateUploadJob calls POST /api/v1/upload.

func (*Client) DownloadResult

func (c *Client) DownloadResult(ctx context.Context, downloadURL string) ([]byte, error)

DownloadResult GETs the result bytes from a download URL.

func (*Client) GetJobStatus

func (c *Client) GetJobStatus(ctx context.Context, jobID string) (*JobStatus, error)

GetJobStatus calls GET /api/v1/jobs/{id} for the current status (and a fresh download URL once the job has completed).

func (*Client) GetTranscript

func (c *Client) GetTranscript(ctx context.Context, jobID string, outputType OutputType) (*Transcript, error)

GetTranscript fetches and parses a completed job's transcript by id. It returns a JobFailedError if the job failed, or an error if it is still processing (poll GetJobStatus for that case). Pass "" for outputType to default to JSON.

func (*Client) ListJobs

func (c *Client) ListJobs(ctx context.Context, limit int, before string) (*JobList, error)

ListJobs calls GET /api/v1/jobs — the caller's most-recent jobs, newest first, cursor-paginated. Pass the returned NextBefore as before for the next page; limit <= 0 defaults to 50.

func (*Client) Submit

func (c *Client) Submit(ctx context.Context, audioPath string, opts TranscribeOptions) (string, error)

Submit uploads and enqueues a job, returning its job_id WITHOUT waiting for the result. Collect it later via a webhook (opts.CallbackURL) or by polling GetJobStatus / GetTranscript. Ideal for batch workloads. audioPath may be a local path or an http(s) URL.

func (*Client) SubmitBytes

func (c *Client) SubmitBytes(ctx context.Context, data []byte, opts TranscribeOptions) (string, error)

SubmitBytes is like Submit but accepts raw audio bytes.

func (*Client) SubmitURL

func (c *Client) SubmitURL(ctx context.Context, audioURL string, opts TranscribeOptions) (string, error)

SubmitURL enqueues audio the platform fetches from a public http(s) URL.

func (*Client) TouchUploadProgress

func (c *Client) TouchUploadProgress(ctx context.Context, jobID string) error

TouchUploadProgress calls POST /api/v1/upload/progress.

func (*Client) Transcribe

func (c *Client) Transcribe(ctx context.Context, audioPath string, opts TranscribeOptions, onProgress ProgressFunc) (*Transcript, error)

Transcribe uploads audio, waits for completion, and returns a Transcript. audioPath may be a local filesystem path or an http(s) URL; a URL is handed to the platform to fetch, so nothing is uploaded from here.

func (*Client) TranscribeBytes

func (c *Client) TranscribeBytes(ctx context.Context, data []byte, opts TranscribeOptions, onProgress ProgressFunc) (*Transcript, error)

TranscribeBytes is like Transcribe but accepts raw audio bytes.

func (*Client) TranscribeFile

func (c *Client) TranscribeFile(ctx context.Context, path string, opts TranscribeOptions, onProgress ProgressFunc) (*Transcript, error)

TranscribeFile is an alias for Transcribe with a local path.

func (*Client) TranscribeURL

func (c *Client) TranscribeURL(ctx context.Context, audioURL string, opts TranscribeOptions, onProgress ProgressFunc) (*Transcript, error)

TranscribeURL transcribes audio the platform fetches from a public http(s) URL, then waits for the result.

func (*Client) UploadAudio

func (c *Client) UploadAudio(ctx context.Context, uploadURL string, data []byte, jobID string) error

UploadAudio streams bytes to the presigned URL, with progress heartbeats.

func (*Client) WaitForResult

func (c *Client) WaitForResult(ctx context.Context, jobID, downloadURL string, onProgress ProgressFunc) ([]byte, string, error)

WaitForResult waits via SSE (with polling fallback) and downloads the result.

type JobFailedError

type JobFailedError struct {
	Step   string
	Reason string
	// contains filtered or unexported fields
}

func (*JobFailedError) Error

func (e *JobFailedError) Error() string

type JobList

type JobList struct {
	Jobs       []JobSummary `json:"jobs"`
	NextBefore string       `json:"next_before,omitempty"`
}

JobList is a page of jobs from GET /api/v1/jobs.

type JobNotFoundError

type JobNotFoundError struct {
	// contains filtered or unexported fields
}

func (*JobNotFoundError) Error

func (e *JobNotFoundError) Error() string

type JobStatus

type JobStatus struct {
	JobID       string `json:"job_id"`
	Status      string `json:"status"` // "processing" | "completed" | "failed"
	DownloadURL string `json:"download_url,omitempty"`
	FailedStage string `json:"failed_stage,omitempty"`
	Reason      string `json:"reason,omitempty"`
}

JobStatus is the result of GET /api/v1/jobs/{id}.

func (JobStatus) IsCompleted

func (s JobStatus) IsCompleted() bool

IsCompleted reports whether the job finished successfully.

func (JobStatus) IsFailed

func (s JobStatus) IsFailed() bool

IsFailed reports whether the job failed.

type JobSummary

type JobSummary struct {
	JobID     string `json:"job_id"`
	CreatedAt string `json:"created_at"`
}

JobSummary is one entry in a ListJobs page.

type LanguageSegment

type LanguageSegment struct {
	Start    float64 `json:"start"`
	End      float64 `json:"end"`
	Language string  `json:"language"`
}

LanguageSegment is a contiguous time range spoken in a single detected language.

type OutputType

type OutputType string

OutputType is the transcription result format.

const (
	OutputTXT  OutputType = "txt"
	OutputJSON OutputType = "json"
	OutputSRT  OutputType = "srt"
	OutputVTT  OutputType = "vtt"
	OutputDOCX OutputType = "docx"
	OutputPDF  OutputType = "pdf"
)

type ProcessingTier

type ProcessingTier string

ProcessingTier selects pricing / scheduling.

const (
	TierStandard ProcessingTier = "standard"
	TierEconomy  ProcessingTier = "economy"
)

func Tier

Tier returns a pointer to t, for TranscribeOptions.Tier.

type ProgressEvent

type ProgressEvent struct {
	Completed      *int
	Total          *int
	Step           string
	ElapsedSeconds float64
	Raw            map[string]any
}

ProgressEvent is a single progress update.

func (ProgressEvent) Percent

func (e ProgressEvent) Percent() (float64, bool)

Percent returns completion as a 0–100 value, clamped to [0,100]. The second return value is false when it can't be computed yet (Completed or Total is nil, or Total is 0) — treat that as "unknown".

type ProgressFunc

type ProgressFunc func(ProgressEvent)

ProgressFunc is called on each progress event.

type RateLimitError

type RateLimitError struct {
	RetryAfter float64
	// contains filtered or unexported fields
}

RateLimitError carries the server's Retry-After hint in seconds, when one was sent in delta-seconds form.

func (*RateLimitError) Error

func (e *RateLimitError) Error() string

type TimeoutError

type TimeoutError struct {
	// contains filtered or unexported fields
}

func (*TimeoutError) Error

func (e *TimeoutError) Error() string

type TranscribeOptions

type TranscribeOptions struct {
	OutputType       OutputType
	WordTimestamps   *bool
	SpeakerLabels    *bool
	Diarize          *bool // alias for SpeakerLabels
	NLTK             *bool
	Tier             *ProcessingTier
	CustomVocabulary []string
	// CallbackURL, if set, is an http(s) webhook POSTed a signed
	// completion/failure notification (X-SR-Signature: sha256=...).
	CallbackURL string

	// OnUploadProgress, if set, is called with a ProgressEvent (Step == "upload")
	// for every byte-level upload update. Read Percent() for a 0–100 value.
	OnUploadProgress ProgressFunc
	// Progress, when true, renders live single-line progress bars to os.Stderr:
	// an "Uploading" byte bar, then a "Transcribing" bar. Off by default. It
	// composes with the callbacks — the bars render and your callbacks still fire.
	Progress bool
}

type Transcript

type Transcript struct {
	JobID       string
	Content     []byte
	DownloadURL string
	OutputType  OutputType
	Words       []Word
	Utterances  []Utterance
	Languages   []LanguageSegment
	Raw         map[string]any
	// contains filtered or unexported fields
}

Transcript is the high-level transcription result.

func (Transcript) Save

func (t Transcript) Save(path string) (string, error)

Save writes the raw result bytes to disk and returns the path written. If path has no file extension, "."+OutputType is appended (e.g. "output" -> "output.json"). The client never writes files on its own — call this.

func (Transcript) Text

func (t Transcript) Text() string

Text returns the full transcript (AssemblyAI / ElevenLabs-style).

func (Transcript) ToDeepgram

func (t Transcript) ToDeepgram() map[string]any

ToDeepgram returns a rough Deepgram pre-recorded response shape.

func (Transcript) ToDict

func (t Transcript) ToDict() map[string]any

ToDict returns an AssemblyAI-inspired normalized map.

func (Transcript) TranscriptText

func (t Transcript) TranscriptText() string

TranscriptText is a Deepgram-compatible alias for Text.

type TranscriptResult

type TranscriptResult = Transcript

TranscriptResult is kept as an alias for backwards compatibility.

type UploadError

type UploadError struct {
	// contains filtered or unexported fields
}

func (*UploadError) Error

func (e *UploadError) Error() string

type UploadJob

type UploadJob struct {
	JobID       string
	UploadURL   string
	DownloadURL string
	ContentType string
	ExpiresIn   int
}

UploadJob is the result of POST /api/v1/upload.

type Utterance

type Utterance struct {
	Text    string   `json:"text"`
	Speaker string   `json:"speaker,omitempty"`
	Start   *float64 `json:"start,omitempty"`
	End     *float64 `json:"end,omitempty"`
	Words   []Word   `json:"words"`
}

Utterance is a contiguous speaker turn.

type Word

type Word struct {
	Word       string   `json:"word"`
	Start      *float64 `json:"start,omitempty"`
	End        *float64 `json:"end,omitempty"`
	Speaker    string   `json:"speaker,omitempty"`
	Confidence *float64 `json:"confidence,omitempty"`
	Language   string   `json:"language,omitempty"`
}

Word is a single transcribed word.

func (Word) Text

func (w Word) Text() string

Text is an AssemblyAI-compatible alias.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL