Go SDK

github.com/runnev/runnev-go is the official Go SDK. Standard library only, no external modules, Go 1.21+. Context-aware throughout; subscriptions deliver batches on a channel.

Install

bash
go get github.com/runnev/runnev-go@v1.4.2

Configure

go
import "github.com/runnev/runnev-go"

client := runnev.New(runnev.Options{
    APIKey:     os.Getenv("RUNNEV_API_KEY"), // required
    BaseURL:    "https://runnev.dev/v1",      // default
    Timeout:    30 * time.Second,             // per unary request; not the subscribe stream
    MaxRetries: 4,                            // retries on 429 / 5xx
})

Publish

go
ctx := context.Background()

stream, err := client.CreateStream(ctx, runnev.CreateStreamParams{
    Name: "orders-eu", RetentionSeconds: 86400,
})

// explicit sequence - idempotent, safe to retry
res, err := client.Publish(ctx, stream.ID, 41823, []runnev.Event{
    {"type": "order.paid", "id": "o_5521", "amount": 1999},
})
_ = res.Cursor // 41823

// server-assigned sequence
_, err = client.PublishAuto(ctx, stream.ID, []runnev.Event{{"type": "tick"}})

// raw bytes for a raw-mode stream
_, err = client.PublishRaw(ctx, stream.ID, 9001, protobufBytes, "application/octet-stream")

Subscribe

Subscribe returns a *Subscription exposing a receive-only channel, an error accessor, and Close. It reconnects automatically, resuming from the last sequence.

go
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

sub, err := client.Subscribe(ctx, stream.ID, runnev.SubscribeOptions{Cursor: "0"})
if err != nil {
    log.Fatal(err)
}
defer sub.Close()

for batch := range sub.C {
    fmt.Println(batch.Seq, batch.Events)
}
if err := sub.Err(); err != nil {
    log.Println("subscription ended:", err)
}

Error handling

go
res, err := client.Publish(ctx, id, seq, events)
if err != nil {
    var rerr *runnev.Error
    if errors.As(err, &rerr) {
        log.Printf("code=%s status=%d request_id=%s", rerr.Code, rerr.Status, rerr.RequestID)
    }
    if errors.Is(err, runnev.ErrRateLimited) {
        time.Sleep(rerr.RetryAfter)
    }
}

*runnev.Error carries Type, Code, Message, RequestID, Status, and DocURL. Sentinels for common codes (ErrRateLimited, ErrStreamNotFound, ErrInvalidAPIKey, and more) work with errors.Is.

API surface

MethodReturns
CreateStream(ctx, CreateStreamParams)(*Stream, error)
ListStreams(ctx, ListParams)(*StreamPage, error)
GetStream(ctx, id)(*Stream, error)
DeleteStream(ctx, id)error
Publish(ctx, id, seq, events)(*PublishResult, error)
PublishRaw(ctx, id, seq, data, contentType)(*PublishResult, error)
PublishAuto(ctx, id, events)(*PublishResult, error)
Cursor(ctx, id)(*CursorInfo, error)
Batch(ctx, id, seq)(*Batch, error)
Subscribe(ctx, id, SubscribeOptions)(*Subscription, error)

Runnable examples: examples/publish and examples/subscribe.