Open source · MIT

Drive MistServer
from Go.

A small, typed client for the MistServer controller API. Create streams, wire up pushes and restreams, and let the SDK handle the challenge-response login.

$ go get github.com/Allan-Nava/MistServer-go-sdk
streams.go
// Add a stream and restream it whenever it goes live
_, err := client.PostStream(mist.PostStreamRequest{
    AddStream: map[string]mist.AddStream{
        "live": {Name: "live", Source: "push://"},
    },
})

_, err = client.PostAutoPush(mist.PostAutoPushRequest{
    PushAutoAdd: mist.PushAutoAdd{
        Stream: "live",
        Target: "rtmp://ingest.example.com/app/KEY",
    },
})

Why

The controller API, without the plumbing

MistServer exposes everything through one JSON endpoint and a login handshake. This SDK turns that into Go methods with request and response types.

Auth handled

The challenge round-trip and hashed password are done for you, and reused for a minute so calls don't pay for a second request.

Typed payloads

Structs for streams, auto-pushes, push lists and server config, so the compiler catches a misspelt field before MistServer does.

Bring your own client

Pass in your own resty client and zap logger, so timeouts, TLS, retries and log format stay under your control.

Quickstart

From zero to a live restream

The controller API usually listens on :4242/api. Point the client at it with the admin credentials you set in MistServer.

  1. Installgo get the module. Go 1.25 or newer.
  2. ConfigurePass a resty client, a sugared zap logger, and the With… options.
  3. CallEvery method logs in on its own; you just send the request.
main.go
package main

import (
    "fmt"
    "log"

    mist "github.com/Allan-Nava/MistServer-go-sdk/mist"
    "github.com/go-resty/resty/v2"
    "go.uber.org/zap"
)

func main() {
    logger, _ := zap.NewProduction()
    defer logger.Sync()

    client := mist.NewService(
        resty.New(),
        logger.Sugar(),
        mist.WithBaseURL("http://localhost:4242/api"),
        mist.WithUsername("admin"),
        mist.WithPassword("secret"),
    )

    pushes, err := client.PostPushList(mist.PostPushListRequest{PushList: true})
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(len(pushes.PushList), "active pushes")
}

API

Every documented API call

56 methods, one per MistServer API command, checked against the controller source where the docs disagree. PostRaw covers anything else. Field-level docs and a runnable example for every method are on pkg.go.dev; command semantics are in the MistServer API reference.

MethodCommandWhat it does
Streams
Health()authorizeLogs in; returns server config, configured streams and the recent log.
PostStream(req)addstreamCreates or updates streams; an update replaces the stream's whole config.
PostStreams(req)streamsReplaces the whole stream list; an empty map deletes every stream.
PostStreamRemove(req)deletestreamDeletes a stream.
PostDeleteStreamSource(req)deletestreamsourceDeletes streams and their source files.
PostNukeStream(req)nuke_streamForce-stops a stream and cleans up its memory.
PostNoUnconfiguredStreams()no_unconfigured_streamsNukes active streams that are not configured.
PostTagStream(req)tag_streamAdds stream tags.
PostUntagStream(req)untag_streamRemoves stream tags.
PostStreamTags(req)stream_tagsReturns stream tags; no names means all active streams.
Pushes
PostPushStart(req)push_startStarts a push now.
PostPushList(req)push_listLists running pushes.
PostPushStop(req)push_stopStops running pushes by ID.
PostAutoPush(req)push_auto_addAdds an auto-push rule.
PostAutoPushRemove(req)push_auto_removeRemoves auto-push rules.
PostPushAutoList()push_auto_listLists auto-push rules by ID.
PostPushSettings(req)push_settingsReads or changes auto-push restart settings.
Statistics & server info
PostActiveStreams(req)active_streamsActive streams with the fields you ask for.
PostStatsStreams(req)stats_streamsStreams with statistics in the last ~10 minutes.
PostClients(req)clientsConnected clients at a point in time.
PostTotals(req)totalsAggregated statistics over a period.
PostProcList(req)proc_listRunning stream processes.
PostCapabilities()capabilitiesInstalled inputs/outputs, CPU, load and memory.
PostAPIEndpoint()api_endpointThe local TCP API URL.
PostBrowse(req)browseLists a directory on the server.
Sessions
PostStopSessions(req)stop_sessionsDisconnects sessions by stream and protocol.
PostStopSessID(req)stop_sessidDisconnects sessions by ID.
PostStopTag(req)stop_tagDisconnects sessions by session tag.
PostTagSessID(req)tag_sessidTags sessions.
PostInvalidateSessions(req)invalidate_sessionsRe-runs USER_NEW for a stream's sessions.
Configuration & control
PostConfig(req)configChanges core server settings.
PostAddProtocol(req)addprotocolEnables outputs.
PostDeleteProtocol(req)deleteprotocolRemoves outputs that match exactly.
PostUpdateProtocol(req)updateprotocolReplaces an output configuration.
PostConfigBackup()config_backupReturns the full configuration.
PostConfigRestore(req)config_restoreReplaces the full configuration.
PostSave()saveWrites the configuration to disk now.
PostUISettings(req)ui_settingsStores or reads interface settings.
PostClearStatLogs()clearstatlogsTruncates the server log.
PostUpdate()updateCached update information.
PostAutoUpdate()autoupdateStarts a rolling update, if available.
PostLogout()logoutDrops the login on the connection.
PostShutdown(req)shutdownShuts the controller down (local connections only).
Access keys
PostStreamKeys(req)streamkeysReads or replaces all stream keys.
PostStreamKeyAdd(req)streamkey_addAdds or re-points stream keys.
PostStreamKeyDel(req)streamkey_delDeletes stream keys.
PostJWKS(req)jwksReads or replaces all JSON Web Keys.
PostAddJWKS(req)addjwksAdds JSON Web Keys.
PostDeleteJWKS(req)deletejwksRemoves JSON Web Keys by kid or exact match.
Variables & external writers
PostVariableList()variable_listLists custom variables.
PostVariableAdd(req)variable_addAdds or updates a custom variable.
PostVariableRemove(req)variable_removeRemoves custom variables.
PostExternalWriterList()external_writer_listLists external writers.
PostExternalWriterAdd(req)external_writer_addAdds an external writer.
PostExternalWriterRemove(req)external_writer_removeRemoves an external writer.
Anything else
PostRaw(command)anySends arbitrary members, e.g. several commands at once; returns the reply undecoded.

Auth

Challenge-response, done once a minute

MistServer never receives the plain password. The first request fetches a challenge; the SDK answers with md5(md5(password) + challenge) and reuses that answer for the next 60 seconds, behind a mutex, so concurrent calls share it.

MistServer replies HTTP 200 even to a rejected login, so the SDK checks authorize.status on every reply. A stale challenge (it rolls over daily) is retried once; wrong credentials, or a server with no accounts, return mist.ErrUnauthorized.

MD5 is what the MistServer protocol specifies. Put the API behind TLS or a private network if it leaves the host.

Sequence: the SDK requests a challenge, MistServer returns it, the SDK sends the hashed answer with the command, MistServer replies. Go SDK MistServer :4242 POST {} authorize.challenge hash · cache 60s {authorize, addstream…} result JSON