Go SDK
The official server-side Go SDK. The API mirrors the official Mixpanel Go SDK (mixpanel-go), so migrating is mostly a matter of swapping the import. Go 1.22+, zero dependencies, context-based.
Install
bashgo get github.com/cohorly-io/cohorly-go
Initialize
gopackage mainimport ("context"cohorly "github.com/cohorly-io/cohorly-go")func main() {client := cohorly.NewClient("YOUR_PROJECT_TOKEN",cohorly.WithAPIHost("https://cohorly-service.velloalabs.com"))ctx := context.Background()err := client.Track(ctx, []*cohorly.Event{client.NewEvent("signup", "user-1", map[string]any{"plan": "premium",}),})if err != nil {// handle error}}
API
| Member | Notes |
|---|---|
NewClient(token, opts...) | Options: WithAPIHost, WithHTTPClient. |
client.NewEvent(name, distinctID, props) | Stamps time (unix ms), $insert_id, $lib, $lib_version. AddTime / AddInsertID override for backfills. |
Track(ctx, events) | Chunks transparently at the server's 500-event batch cap. Batches are atomic server-side, safe to retry as-is. |
PeopleSet / PeopleSetOnce / PeopleIncrement / PeopleUnset / PeopleDelete | Profile updates mapped to /engage ops. |
Alias(ctx, alias, distinctID) | POST /alias. |
NewBufferedClient(client, opts...) | Non-blocking Enqueue + background flush loop with the shared retry contract. Close(ctx) on shutdown. |
Buffered mode
gobuffered := cohorly.NewBufferedClient(client,cohorly.WithFlushInterval(10*time.Second),cohorly.WithFlushBatchSize(50),)buffered.Enqueue(buffered.NewEvent("page_view", "user-1", nil))// On shutdown: stop the loop and flush whatever is left.if err := buffered.Close(ctx); err != nil {// remaining events could not be delivered}
The buffered client implements the shared Cohorly retry contract: exponential backoff on 429/5xx/network honoring Retry-After, batch halving on 413, permanent drop on 400, queue capped at 1000 (oldest dropped). It embeds *Client, so the synchronous methods stay available.
Error handling
goerr := client.Track(ctx, events)if errors.Is(err, cohorly.ErrInvalidToken) {// bad project token (HTTP 401)}var httpErr *cohorly.HTTPErrorif errors.As(err, &httpErr) && httpErr.Status == 429 {time.Sleep(httpErr.RetryAfter)// safe to retry the same payload}