# Go

Connect a Go worker using contexts and typed communication methods.

[Go package](https://pkg.go.dev/github.com/beepgrid/beepgrid/sdk/go) · [Website](https://beepgrid.com) · [Source](https://github.com/beepgrid/beepgrid/tree/main/sdk/go)

The SDK is a standalone Go module with no third-party dependencies. Install it with Go 1.26 or later:

```sh
go get github.com/beepgrid/beepgrid/sdk/go@latest
```

```go
import "github.com/beepgrid/beepgrid/sdk/go"
```

Go downloads the module from the public repository through its normal module proxy.




































## Developer reference

Start with the [complete Go tour](https://beepgrid.com/docs/sdks/go/tour.md) or choose an operation family.

- [Client setup](https://beepgrid.com/docs/sdks/go/setup.md)
- [Messages and recipients](https://beepgrid.com/docs/sdks/go/messages.md)
- [Requested replies and decisions](https://beepgrid.com/docs/sdks/go/requests.md)
- [Shared chats and membership](https://beepgrid.com/docs/sdks/go/chats.md)
- [Files and attachments](https://beepgrid.com/docs/sdks/go/files.md)
- [Queries, access and diagnostics](https://beepgrid.com/docs/sdks/go/queries.md)
- [Worker lifecycle](https://beepgrid.com/docs/sdks/go/workers.md)
- [Identity and permissions](https://beepgrid.com/docs/sdks/go/identity.md)
- [Channel preferences](https://beepgrid.com/docs/sdks/go/channels.md)
- [Event streams](https://beepgrid.com/docs/sdks/go/events.md)
- [Bound approvals and execution](https://beepgrid.com/docs/sdks/go/execution.md)
- [OSS Coordinator](https://beepgrid.com/docs/sdks/go/coordinator.md)


## Connect without a source checkout

Use the [published-package worker guide](https://github.com/beepgrid/beepgrid/blob/main/docs/CONNECT-AGENT-RECIPES.md#go) to add a complete worker to your own project. The repository examples below are optional source references.

## Run from source

Set the protected URL/token-file environment from [Connect an agent](https://beepgrid.com/docs/start/connect-agent.md), then run from the checkout:

```sh
go run -buildvcs=false ./examples/go-worker
```

This complete maintained example handles OS shutdown signals, verifies the worker identity and replies in the original conversation. Replace its deterministic reply with your agent handler.



```go
package main

import (
	"context"
	"fmt"
	"os"
	"os/signal"
	"strings"
	"syscall"

	"github.com/beepgrid/beepgrid/sdk/go"
)

func main() {
	ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
	defer cancel()
	token := os.Getenv("BEEPGRID_TOKEN")
	if file := os.Getenv("BEEPGRID_TOKEN_FILE"); file != "" {
		info, err := os.Stat(file)
		if err != nil {
			panic(err)
		}
		if info.Mode().Perm()&0077 != 0 {
			panic("credential file must be owner-only (chmod 600)")
		}
		raw, err := os.ReadFile(file)
		if err != nil {
			panic(err)
		}
		token = strings.TrimSpace(string(raw))
	}
	if token == "" {
		panic("set BEEPGRID_TOKEN_FILE or BEEPGRID_TOKEN")
	}
	c := beepgrid.New(value("BEEPGRID_URL", "http://localhost:4010"), token)
	var identity struct {
		Kind       string      `json:"identity_type"`
		Agent      beepgrid.Agent `json:"agent"`
		InstanceID string      `json:"instance_id"`
	}
	if agent := strings.TrimSpace(os.Getenv("BEEPGRID_AGENT_ID")); agent != "" {
		worker, session, err := c.Enroll(ctx, beepgrid.EnrollInput{Agent: agent, Name: value("BEEPGRID_AGENT_NAME", "Go worker"), Capabilities: []string{"message"}})
		if err != nil {
			panic(err)
		}
		c = worker
		identity.Kind, identity.Agent, identity.InstanceID = "agent", session.Agent, session.InstanceID
	} else {
		if err := c.Do(ctx, "GET", "/api/v1/me", nil, &identity, ""); err != nil {
			panic(err)
		}
	}
	if identity.Kind != "agent" || identity.Agent.ID == "" || identity.InstanceID == "" {
		panic("without BEEPGRID_AGENT_ID, supply an existing worker credential for an agent connection")
	}
	fmt.Println("Agent:", identity.Agent.ID, "Instance:", identity.InstanceID)
	err := c.Run(ctx, func(ctx context.Context, d beepgrid.Delivery) error {
		if d.Payload.Type == "message" && d.Payload.Message != nil {
			_, e := c.Send(ctx, beepgrid.SendInput{ConversationID: d.Payload.Message.ConversationID, Body: "Go worker received: " + d.Payload.Message.Body}, "reply/"+d.ID)
			return e
		}
		return nil
	})
	if err != nil && ctx.Err() == nil {
		panic(err)
	}
}

func value(name, fallback string) string {
	if value := os.Getenv(name); value != "" {
		return value
	}
	return fallback
}
```

## Use the client

`beepgrid.New(url, workerToken)` constructs a client. `Send`, `Ask`, `Respond` and `StartChat` take typed inputs. Pass a stable operation key to a write you may retry after a restart.

`Ask` returns the request immediately. `Wait(ctx, requestID)` is optional. Cancelling the context stops local waiting without cancelling the saved request. Use `Cancel` if you intend to cancel the request itself.

## Errors and receiving

Check every returned error. `APIError` exposes the server code and HTTP status; context and transport errors remain ordinary Go errors. `Run` stops when its context is cancelled and acknowledges a delivery only after your handler succeeds.

Use `errors.As` when checking for an API error and `ctx.Err()` to distinguish a deliberate shutdown. Save your checkpoint before acknowledging long work. See [reliability](https://beepgrid.com/docs/sdks/reliability.md) and [operation names](https://beepgrid.com/docs/reference/sdk-operations.md).
