
To get started with the AIOZ Stream Go SDK, run go get on the v3 module and build a client from your keys. Then create a media object and upload the file. We ran each step on Oct 19, 2026 against v3.0.4, and this guide shows the real output.
TL;DR:
go get github.com/AIOZNetwork/aioz-stream-go-client/v3. On Oct 19, 2026 that resolved to v3.0.4, released Oct 5.aiozstreamsdk.ClientBuilder(apiCreds).Build(), then create a video with client.Media.Create and a CreateMediaRequest.client.Video.Create and CreateVideoRequest, and neither exists in v3.0.4, so that sample fails to compile.client.UploadVideo splits your file into 50 MB parts, posts each one, then calls the complete endpoint for you.WithContext variant for timeouts.Updated Oct 19, 2026: we installed and built against SDK v3.0.4, fixed the create call to client.Media.Create, added real terminal output and an upload flow diagram, and shortened the sentences.
Start in a Go module and fetch the v3 package; this is the output we got on Oct 19, 2026 with Go 1.22.2:
$ go mod init example.com/srbgoclient
go: creating new go.mod: module example.com/srbgoclient
$ go get github.com/AIOZNetwork/aioz-stream-go-client/v3@latest
go: downloading github.com/AIOZNetwork/aioz-stream-go-client/v3 v3.0.4
go: downloading github.com/AIOZNetwork/aioz-stream-go-client v1.0.19
go: added github.com/AIOZNetwork/aioz-stream-go-client/v3 v3.0.4
$ go list -m -versions github.com/AIOZNetwork/aioz-stream-go-client/v3
github.com/AIOZNetwork/aioz-stream-go-client/v3 v3.0.3 v3.0.4Two v3 tags exist, v3.0.3 and v3.0.4, and the changelog dates both to Oct 5, 2026. Keep the /v3 suffix in your import path, because the AIOZ docs page for Go still shows the older path without it, which pulls a v1 release instead.
The client uses a builder rather than a plain constructor: you fill an AuthCredentials struct with your public and secret key and pass it to ClientBuilder(apiCreds).Build(). Before Build(), the builder also takes optional settings such as BaseURL, BearerToken and HTTPClient, while the Node.js SDK does the same job with new StreamClient({ publicKey, secretKey }).
The flow has two steps, as in the Node.js SDK: create the media object, then upload the file to it. The program below is the one we compiled, and it reads your keys from environment variables and takes the file path as its first argument:
package main
import (
"context"
"fmt"
"os"
aiozstreamsdk "github.com/AIOZNetwork/aioz-stream-go-client/v3"
)
func main() {
apiCreds := aiozstreamsdk.AuthCredentials{
PublicKey: os.Getenv("AIOZ_PUBLIC_KEY"),
SecretKey: os.Getenv("AIOZ_SECRET_KEY"),
}
client := aiozstreamsdk.ClientBuilder(apiCreds).Build()
title := "Sample Video Title"
createResult, err := client.Media.Create(aiozstreamsdk.CreateMediaRequest{Title: &title})
if err != nil {
fmt.Fprintf(os.Stderr, "Error creating video: %v\n", err)
os.Exit(1)
}
videoId := createResult.Data.Id
videoFile, err := os.Open(os.Args[1])
if err != nil {
fmt.Fprintf(os.Stderr, "Error opening video file: %v\n", err)
os.Exit(1)
}
defer videoFile.Close()
fileInfo, err := videoFile.Stat()
if err != nil {
fmt.Fprintf(os.Stderr, "Error getting file info: %v\n", err)
os.Exit(1)
}
err = client.UploadVideo(context.Background(), *videoId, fileInfo.Name(), videoFile, fileInfo.Size())
if err != nil {
fmt.Fprintf(os.Stderr, "Error uploading video: %v\n", err)
os.Exit(1)
}
fmt.Println("Video uploaded:", *videoId)
}
Inside UploadVideo, the SDK cuts the file into 50 MB parts and posts each one to /media/{id}/part. When the last part lands, it calls /media/{id}/complete, so you don't have to. The API docs allow parts of 50 to 200 MB, but v3.0.4 fixes the size at 50 MB inside the upload code. The ChunkSize setter isn't read on this path. If you need control over part boundaries, call client.Media.UploadPart yourself, as our chunked upload tutorial describes.
We ran go vet and go build on the program, then ran it with placeholder keys and a 1 MB test file. The API rejected the keys, and the result shows you the error format you will handle in production:
$ go vet ./... && echo "vet ok"
vet ok
$ go build -o upload . && echo "build ok"
build ok
$ AIOZ_PUBLIC_KEY=pk_invalid AIOZ_SECRET_KEY=sk_invalid ./upload ./sample.mp4; echo $?
Error creating video: [401]: POST https://api.aiozstream.network/api/media/create
{
"message": "API key not found.",
"reason": "api-key-not-found",
"request_id": "01a15367-cb1c-78d5-9dc4-1f1297999c63",
"status": "fail"
}
1The error string carries the HTTP status, the method and URL, and the JSON body with a machine-readable reason. In your own code, you can branch on that field instead of parsing the message text. With real keys from an AIOZ Stream API key, the same program prints the new video ID.
The README sample fails earlier, at compile time. When we built our program with the README's create call in place of client.Media.Create, Go reported:
./main.go:19:30: client.Video undefined (type *aiozstreamsdk.Client has no field or method Video)
./main.go:19:57: undefined: aiozstreamsdk.CreateVideoRequestIn v3.0.4 the client's services are Analytics, ApiKey, LiveStream, Media, MediaChapter, Players, Playlist, User and Webhook, and video calls live under Media. CreateMediaRequest also has a Type field that takes video or audio, with video as the default.
First, every call returns an error value, and you check it with if err != nil on the next line. A failed create can't fall through to the upload, because videoId would be nil and the program stops first.
Second, the client supports context.Context, and UploadVideo takes one as its first argument. Each service method also has a WithContext twin, such as CreateWithContext. context.Background() has no deadline, which is fine for a script. In a service, pass a context with a timeout so a stalled upload can't hang forever.
Third, request structs use pointer fields for optional values, with generated GetX, GetXOk and SetX methods for each field. That pattern comes from OpenAPI code generators, and the repository's docs folder has one file per request and response type.
The README says chunking, pagination and token refresh are "handled for you," so we checked each claim against the v3.0.4 source:
UploadVideo splits the file into 50 MB parts and completes the upload.GetMediaList take Offset and Limit in the request. We found no helper that walks the pages for you.client.go. API keys don't expire on a timer, so a key-based client has nothing to refresh. A BearerToken you set is sent as is.We also spot-checked one design choice against the raw API. The playlist reorder struct, MoveItemRequest, has the same CurrentId, NextId and PreviousId fields as the REST endpoint in our Playlist API guide. That match tells you the generated client mirrors the neighbor-based design of the API exactly.
We keep the Go client in sync with the same REST API that the Node.js SDK and the raw docs use, at https://api.aiozstream.network/api. Both SDKs send your keys in the stream-public-key and stream-secret-key headers. Encoding starts after the complete call, and you can wait for it two ways. Poll client.Media.GetDetail until the status is done, or subscribe to the encoding_finished event with AIOZ Stream webhooks.
What the docs don't cover yet: the docs page for Go and the README both show the older client.Video calls. Use the compiled example above until both pages are updated for v3. Next step: read the Go SDK page in the AIOZ Stream docs for the full list of endpoints the client wraps.
How do I install the AIOZ Stream Go client?
Run go get github.com/AIOZNetwork/aioz-stream-go-client/v3, then build a client with aiozstreamsdk.ClientBuilder(apiCreds).Build().
Why does the README example fail to compile?
It calls client.Video.Create with a CreateVideoRequest, and neither exists in v3.0.4, so use client.Media.Create with a CreateMediaRequest instead.
Does the Go client handle chunked uploads automatically?
Yes. UploadVideo sends 50 MB parts and calls the complete endpoint, and Media.UploadPart is there if you want manual control.
Why does UploadVideo take a context.Context?
Context is how Go passes cancellation and deadlines, so you can stop an upload or give it a timeout.
Is playlist reordering the same in the Go client as in the raw API?
Yes. MoveItemRequest uses the same CurrentId, NextId and PreviousId fields as the REST endpoint.
Should I always use context.Background()?
Not in production, so pass a context with a deadline so a stalled upload fails instead of hanging.
SourceUrl field to CreateMediaRequest for thisUploadVideoMoveItemRequest matchesUploadVideo and the complete callCurrentId, NextId and PreviousId fields
Video streaming protocols move video from encoder to viewer. See how RTMP, SRT, HLS, DASH and WebRTC differ in latency, transport and where each one fits.

Decentralized live streaming sends a real-time broadcast through independently run nodes instead of one company's servers. Here's how each stage of it works.

A video streaming glossary of 114 terms, from AAC and ABR to WebRTC and Widevine, each defined in plain English with sources and links to the deep posts.

Read the AIOZ Stream Statistics panel: bitrate in and out, FPS in and out and current viewers, plus the documented rules for each and what the docs leave out.

Embed an AIOZ Stream livestream with the Share button's iframe or send the Public Playback URL as a link. Covers API fields, public access limits and doc gaps.

Learn how a stream key differs from a streaming session on AIOZ Stream, what each one stores, and what to preconfigure before you go live. Docs-based guide.