> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bonya.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Installation

> Install and configure the Go SDK

The Go SDK's module path is `github.com/bonyai/bonya-sdk-go`, package name
`bonya`. It talks to the Bonya REST API over HTTPS, and to the sandbox edge over a WebSocket for streaming exec and terminal sessions.

## Requirements

* Go 1.24 or newer
* Depends on `github.com/gorilla/websocket`
* A Bonya API key (`byk_...`)

## Install

```bash theme={null}
go get github.com/bonyai/bonya-sdk-go
```

## Configure

Every option has an environment-variable fallback, so the common case
needs no options at all:

```bash Environment variable theme={null}
export BONYA_API_KEY=byk_...
```

```go Explicit theme={null}
client, err := bonya.NewClient(
	bonya.WithAPIKey("byk_..."),
	bonya.WithOrganizationID("org_123"),
	bonya.WithTimeout(30*time.Second),
)
```

| Option | Environment variable | Default |
| - | - | - |
| `WithAPIKey` | `BONYA_API_KEY` | *required* |
| `WithOrganizationID` | `BONYA_ORGANIZATION_ID` | your personal organization |
| `WithCABundle` | `BONYA_CA_BUNDLE` | system trust store |
| `WithTimeout` | — | `30 * time.Second` |
| `WithMaxRetries` | — | `2` |
| `WithFilesystemReadLimit` | — | 64 MiB |

`WithAPIKey` (or `BONYA_API_KEY`) is required.

`WithCABundle` (or `BONYA_CA_BUNDLE`) points to a PEM bundle for private
development CAs; if the file can't be read, `NewClient` returns an
`*InvalidRequestError`.

`WithTimeout` is the default per-operation deadline; buffered and
streaming exec calls can override it per call with `ExecOptions.Timeout`.
`WithMaxRetries` controls SDK retries for retryable control-plane
operations (create, get, list, delete, snapshot create, snapshot
delete) — it retries transient failures while preserving the same request
and idempotency key where one exists. `WithFilesystemReadLimit` caps bytes
buffered by `sandbox.ReadFile`.

> [!NOTE]
>
> An empty `WithOrganizationID("")` (or `BONYA_ORGANIZATION_ID=""`) makes
> `NewClient` return an `*InvalidRequestError` rather than silently falling
> back to your personal organization — this avoids CI jobs quietly running
> against the wrong tenant when a variable expansion is empty. See
> [Organizations](https://docs.bonya.ai/sdks/go/usage.md#organizations) for the full precedence and
> a CI example.

Close the client when done:

```go theme={null}
client, err := bonya.NewClient()
if err != nil {
	log.Fatal(err)
}
defer client.Close()
```

## Quickstart

```go theme={null}
package main

import (
	"context"
	"fmt"
	"log"

	bonya "github.com/bonyai/bonya-sdk-go"
)

func main() {
	client, err := bonya.NewClient() // reads BONYA_API_KEY
	if err != nil {
		log.Fatal(err)
	}
	defer client.Close()

	ctx := context.Background()
	sandbox, err := client.CreateSandbox(ctx, "bonya-dev")
	if err != nil {
		log.Fatal(err)
	}
	defer sandbox.Delete(ctx)

	result, err := sandbox.Exec(ctx, []string{"echo", "hello"}, bonya.ExecOptions{Check: true})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Print(result.Stdout()) // hello
}
```

That is a real VM: it boots in about a second, runs anything Linux runs,
and is gone when `Delete` runs.

See [Usage](https://docs.bonya.ai/sdks/go/usage.md) for the full surface — sessions, files,
previews, snapshots, and error handling.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.