Solari

Go SDK

Go clients for two Solari products. Browsers are a remote Chromium you drive with chromedp over CDP; sandboxes are headless microVMs for commands, code, files, and git. Two independent modules, both package solari. VMs (GUI desktops) are created with Kind: KindDesktop and expose a stream URL, but no GUI surface.

Installation

ModuleProductTypes
github.com/solari-sdk/solari-browser-goCloud browsersClient, Sessions, Connect()
github.com/solari-sdk/solari-sandbox-goSandboxes (headless)Client, Sandbox
github.com/solari-sdk/solari-sandbox-goVMs (GUI desktops)Create plus lifecycle, StreamURL, core namespaces. No GUI type.
go get github.com/solari-sdk/solari-browser-go   # browsers
go get github.com/solari-sdk/solari-sandbox-go       # sandboxes + VM lifecycle
Public modules — go get works
Both modules are public and go get-able as shown above (resolved through the Go module proxy). They require Go 1.23+.
Both modules are package solari
The module paths differ but the package name is solari in both. Importing them into the same file requires an alias, e.g. browser "github.com/solari-sdk/solari-browser-go".

Getting Started

Drive a browser

client, _ := solari.NewClient(solari.ClientOptions{APIKey: os.Getenv("SOLARI_API_KEY")})

sess, err := client.Sessions.Create(ctx, solari.CreateSessionOptions{
    Stealth: true,
    Proxy:   solari.ProxyCountry("us"),
})
if err != nil {
    log.Fatal(err)
}
defer client.Sessions.Release(context.Background(), sess.ID)

browserCtx, cancel, _ := solari.Connect(ctx, sess)  // chromedp over raw CDP
defer cancel()

var title string
err = chromedp.Run(browserCtx,
    chromedp.Navigate("https://example.com"),
    chromedp.Title(&title))

Create a sandbox

client, _ := solari.NewClient(solari.ClientOptions{
    APIKey:  os.Getenv("SOLARI_API_KEY"),
    BaseURL: "https://api.getsolari.com",
})

sbx, err := client.Create(ctx, solari.CreateOptions{Template: "base"})
if err != nil {
    log.Fatal(err)
}
defer sbx.Kill(ctx)

r, _ := sbx.Commands.Run(ctx, "echo", solari.CommandOptions{Args: []string{"hi"}})
fmt.Println(r.ExitCode, r.Stdout)  // 0 "hi"

Create a VM

// Same client. A VM is a session with Kind: KindDesktop.
vm, err := client.Create(ctx, solari.CreateOptions{
    Template: "office",
    Kind:     solari.KindDesktop,
})
if err != nil {
    log.Fatal(err)
}
defer vm.Kill(ctx)

fmt.Println(vm.StreamURL)  // wss://.../stream/<id>, empty for a sandbox

// Commands / Files / Code / Git work on a VM. Mouse, keyboard, and
// screenshots do NOT exist in Go. See the VMs page.
r, _ := vm.Commands.Run(ctx, "xdotool", solari.CommandOptions{
    Args: []string{"getactivewindow"},
})

Configuration

Each NewClient takes one ClientOptions struct. The two modules declare their own. The fields are not interchangeable. APIKey is always required.

FieldTypeDefaultModuleNotes
APIKeystringrequiredbothSent as Authorization: Bearer. NewClient errors if empty.
BaseURLstringsee notesbothbrowser: resolved from Region; setting it ignores Region. sandbox: required.
RegionRegionRegionUSWestbrowserOnly "us-west" today. An unknown region errors.
HTTPClient*http.ClientconstructedbothOverride for tests. browser: setting it ignores TimeoutMs.
TimeoutMsint90000browserPer attempt, not per call.
MaxAttemptsint2browserTotal attempts, counting the first. 2 means one retry.
BackoffMs*int500browserFixed sleep between attempts, not exponential. A pointer so 0 (no wait) differs from unset.
CallTimeoutMsint300000sandboxPer-RPC timeout on the control channel.
MaxRetriesint5sandboxRetries after the first try. Idempotent requests only.
RetryDelayMs*intexponentialsandboxWhen non-nil, replaces backoff with a fixed delay. 0 disables the wait.
No environment variables are read
Neither NewClient reads the environment. Pass APIKey (and BaseURL where required) explicitly. The os.Getenv calls above are your code, not the SDK’s.
The two retry policies differ
browser: every request retries up to MaxAttempts on transport errors and 502, 503, 504 only, with a fixed pause. sandbox: only idempotent requests (GET, DELETE, or one carrying an idempotency key, which Create sends) retry, on transport errors and any 5xx, with exponential backoff plus jitter. Neither retries 429.

Reference

PageModulePurpose
Browserssolari-browser-goClient, Sessions, Profiles, Proxy, Connect().
VMssolari-sandbox-goCreate via KindDesktop, plus StreamURL and the core namespaces. No GUI surface.
Sandboxessolari-sandbox-goClient, Sandbox, and the Commands / Files / Code / Git namespaces.