Go SDK Reference
Module: github.com/cpod-ai/cpod-go
pkg.go.dev: pkg.go.dev/github.com/cpod-ai/cpod-go
Source: github.com/cpod-ai/cpod-sdk/tree/main/sdks/go
Go: ≥ 1.21
Installation
go get github.com/cpod-ai/cpod-go@latestClient Initialization
package main
import (
"context"
"os"
"time"
"github.com/cpod-ai/cpod-go"
)
func main() {
// Reads CPOD_API_KEY from environment
client := cpod.NewClient()
// With options
client := cpod.NewClient(
cpod.WithAPIKey(os.Getenv("CPOD_API_KEY")),
cpod.WithBaseURL("https://api.cyberpod.app/v1"),
cpod.WithTimeout(30 * time.Second),
cpod.WithMaxRetries(3),
cpod.WithHTTPClient(customHTTPClient),
)
ctx := context.Background()
_ = ctx // pass ctx to all service methods
}The Client struct is safe for concurrent use. Create one instance and share it across goroutines.
PodService — client.Pods
List pods
result, err := client.Pods.List(ctx, &cpod.PodListParams{
TenantID: "acme-corp",
Status: cpod.PodStatusRunning,
Region: cpod.String("us-east-1"),
Limit: cpod.Int(50),
})
if err != nil {
return err
}
for _, pod := range result.Data {
fmt.Printf("%s: %s [%s]\n", pod.ID, pod.Name, pod.Status)
}
// result.NextCursor — pass to next call for paginationGet a pod
pod, err := client.Pods.Get(ctx, "pod_01jm8xk2y3z")Create a pod
pod, err := client.Pods.Create(ctx, &cpod.PodCreateParams{
TenantID: "acme-corp",
Name: "my-worker",
Image: "cpod/worker:latest",
CPU: 2.0,
MemoryMB: 4096,
Region: "us-east-1",
Env: map[string]string{"NODE_ENV": "production"},
Labels: map[string]string{"team": "platform"},
})Update a pod
pod, err := client.Pods.Update(ctx, "pod_01jm8xk2y3z", &cpod.PodUpdateParams{
Name: cpod.String("renamed-worker"),
Labels: map[string]string{"app": "worker-v2"},
})Delete a pod
err := client.Pods.Delete(ctx, "pod_01jm8xk2y3z")Lifecycle operations
err = client.Pods.Start(ctx, "pod_01jm8xk2y3z")
err = client.Pods.Stop(ctx, "pod_01jm8xk2y3z", &cpod.PodStopParams{
GracePeriodSeconds: cpod.Int(30),
})
err = client.Pods.Restart(ctx, "pod_01jm8xk2y3z")Stream logs
stream, err := client.Pods.Logs(ctx, "pod_01jm8xk2y3z", &cpod.PodLogsParams{
Follow: true,
Tail: 100,
})
if err != nil {
return err
}
defer stream.Close()
scanner := bufio.NewScanner(stream)
for scanner.Scan() {
fmt.Println(scanner.Text())
}Auto-paginated iterator
iter := client.Pods.ListAll(ctx, &cpod.PodListParams{TenantID: "acme-corp"})
for iter.Next() {
pod := iter.Current()
fmt.Println(pod.ID)
}
if err := iter.Err(); err != nil {
return err
}TenantService — client.Tenants
// List
result, err := client.Tenants.List(ctx, &cpod.TenantListParams{Limit: cpod.Int(50)})
// Get
tenant, err := client.Tenants.Get(ctx, "acme-corp")
// Create
tenant, err := client.Tenants.Create(ctx, &cpod.TenantCreateParams{
ID: "acme-corp",
Name: "Acme Corporation",
Plan: cpod.PlanEnterprise,
Region: "us-east-1",
Metadata: map[string]string{"salesforce_id": "SF-001234"},
})
// Update
tenant, err := client.Tenants.Update(ctx, "acme-corp", &cpod.TenantUpdateParams{
Name: cpod.String("Acme Corp (Updated)"),
})
// Members
err = client.Tenants.AddMember(ctx, "acme-corp", &cpod.AddMemberParams{
UserID: "user_123",
Role: cpod.RoleAdmin,
})
err = client.Tenants.RemoveMember(ctx, "acme-corp", "user_123")
// Policy
err = client.Tenants.SetPolicy(ctx, "acme-corp", &cpod.TenantPolicy{
MaxPods: 100,
AllowedRegions: []string{"us-east-1", "eu-west-1"},
RequireLabels: []string{"team", "env"},
IPAllowlist: []string{"10.0.0.0/8"},
})EventService — client.Events
Query events
result, err := client.Events.List(ctx, &cpod.EventListParams{
TenantID: "acme-corp",
Type: cpod.String("pod.started"),
Since: cpod.Time(time.Now().Add(-24 * time.Hour)),
Limit: cpod.Int(100),
})SSE subscription
sub, err := client.Events.Subscribe(ctx, &cpod.EventSubscribeParams{
TenantID: "acme-corp",
Types: []string{"pod.started", "pod.stopped", "pod.error"},
})
if err != nil {
return err
}
defer sub.Close()
for {
select {
case event, ok := <-sub.Events():
if !ok {
return nil // stream closed
}
fmt.Printf("[%s] %s on %s\n", event.Timestamp, event.Type, event.ResourceID)
case err := <-sub.Errors():
log.Printf("SSE error: %v", err)
case <-ctx.Done():
return ctx.Err()
}
}WebSocket subscription
ws, err := client.Events.SubscribeWebSocket(ctx, &cpod.EventSubscribeParams{
TenantID: "acme-corp",
Types: []string{"pod.*"},
})
if err != nil {
return err
}
defer ws.Close()
for event := range ws.Events() {
fmt.Println(event.Type, event.ResourceID)
}Types
type Pod struct {
ID string `json:"id"`
TenantID string `json:"tenantId"`
Name string `json:"name"`
Status PodStatus `json:"status"`
Image string `json:"image"`
CPU float64 `json:"cpu"`
MemoryMB int `json:"memoryMb"`
Region string `json:"region"`
Env map[string]string `json:"env"`
Labels map[string]string `json:"labels"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
StartedAt *time.Time `json:"startedAt,omitempty"`
StoppedAt *time.Time `json:"stoppedAt,omitempty"`
}
type PodStatus string
const (
PodStatusPending PodStatus = "pending"
PodStatusRunning PodStatus = "running"
PodStatusStopped PodStatus = "stopped"
PodStatusError PodStatus = "error"
PodStatusTerminating PodStatus = "terminating"
)Helper Functions
The SDK provides pointer helpers for optional fields:
cpod.String("value") // *string
cpod.Int(42) // *int
cpod.Bool(true) // *bool
cpod.Float64(1.5) // *float64
cpod.Time(time.Now()) // *time.TimeError Handling
import "github.com/cpod-ai/cpod-go/errors"
pod, err := client.Pods.Get(ctx, "pod_nonexistent")
if err != nil {
var notFound *errors.NotFoundError
var validation *errors.ValidationError
var auth *errors.AuthError
var rateLimit *errors.RateLimitError
var apiErr *errors.APIError
switch {
case errors.As(err, ¬Found):
fmt.Println("Not found:", notFound.Message)
case errors.As(err, &validation):
for field, msg := range validation.Fields {
fmt.Printf(" %s: %s\n", field, msg)
}
case errors.As(err, &auth):
fmt.Println("Auth error:", auth.Status, auth.Message)
case errors.As(err, &rateLimit):
fmt.Printf("Rate limited. Retry after %ds\n", rateLimit.RetryAfter)
case errors.As(err, &apiErr):
fmt.Printf("API error %d [%s]: %s\n", apiErr.Status, apiErr.Code, apiErr.Message)
default:
return fmt.Errorf("unexpected error: %w", err)
}
}All SDK functions accept a context.Context as the first argument.
Use it for cancellation, deadlines, and request-scoped values (e.g., trace IDs).