Cariosan

cariosan-go

Go SDK for consumer backends that manage Cariosan resources.

Go SDK for your backend — lets your server upsert users, issue JWTs, create channels, manage members, and register webhooks against a Cariosan server. Separate module so you don't pull in the full Cariosan codebase.

terminal
go get github.com/cariosan/cariosan-go

Zero third-party dependencies — uses net/http only. Pulls cleanly into any Go project, no transitive bloat.

Setup

server.go
import (
    "context"
    "time"
 
    cariosan "github.com/cariosan/cariosan-go"
)
 
client := cariosan.New(
    "pk_live_abc", "sk_live_xyz",
    "https://chat.example.com",
    cariosan.WithTimeout(10*time.Second),
    cariosan.WithMaxRetries(3),
)

Workspace credentials only on the backend — the API key/secret come from cariosan workspace create. They authenticate your backend, not end users. Never ship them to a browser or mobile client.

Users

users.go
ctx := context.Background()
 
// Idempotent — call on every sign-in or profile change.
alice, _ := client.UpsertUser(ctx, cariosan.UpsertUserRequest{
    ExternalID: "user_alice",
    Name:       "Alice",
    AvatarURL:  "https://cdn.example.com/alice.jpg",
})
 
// Mint a short-lived JWT the browser hands to @cariosan/client.
token, _ := client.IssueUserToken(ctx, alice.ExternalID, 24*time.Hour)
// Return token.Token to your frontend over HTTPS.
 
// Fetch or delete.
u, _ := client.GetUser(ctx, "user_alice")
_ = client.DeleteUser(ctx, "user_alice")

Channels

channels.go
ch, _ := client.CreateChannel(ctx, cariosan.CreateChannelRequest{
    Type:              cariosan.ChannelGroup,
    ExternalID:        "order_123",
    Name:              "Order #123",
    MemberExternalIDs: []string{"user_alice", "user_support"},
})
 
_, _ = client.AddChannelMembers(ctx, "order_123", []string{"user_support_2"})
_, _ = client.RemoveChannelMember(ctx, "order_123", "user_alice")
_ = client.DeleteChannel(ctx, "order_123")

Direct channels dedupe server-side:

direct.go
dm, _ := client.CreateChannel(ctx, cariosan.CreateChannelRequest{
    Type:              cariosan.ChannelDirect,
    MemberExternalIDs: []string{"user_alice", "user_bob"},
})
// Second call with the same two members returns the same channel.

Webhooks

webhooks.go
wh, _ := client.CreateWebhook(ctx, cariosan.CreateWebhookRequest{
    URL:    "https://api.example.com/cariosan/events",
    Events: []cariosan.EventType{
        cariosan.EventMessageCreated,
        cariosan.EventChannelCreated,
    },
})
// wh.SigningSecret is returned exactly once — store it.
 
enabled := false
_, _ = client.UpdateWebhook(ctx, wh.ID, cariosan.UpdateWebhookRequest{
    Enabled: &enabled,
})

Verify signatures

Always verify the X-Cariosan-Signature header before trusting webhook payloads.

Error handling

All API errors map to sentinel errors. errors.Is works against the HTTP status class:

errors.go
if _, err := client.GetUser(ctx, "missing"); errors.Is(err, cariosan.ErrNotFound) {
    // 404
}

Sentinels: ErrNotFound, ErrUnauthorized, ErrValidation, ErrConflict, ErrRateLimit, ErrServer, ErrProtocol.

For the raw status, code, and server-provided error envelope, use errors.As:

api_error.go
var apiErr *cariosan.APIError
if errors.As(err, &apiErr) {
    log.Printf("cariosan %s: %s (HTTP %d)", apiErr.Code, apiErr.Message, apiErr.Status)
}

Retries

The client auto-retries 5xx, network errors, and request timeouts with exponential backoff (1s × 2ⁿ, capped at 30s, ±20% jitter). 4xx is never retried except 429, which honours Retry-After.

  • WithMaxRetries(n) — tune the budget (default 3; 0 disables).
  • WithHTTPClient(c) — swap the transport entirely.
  • WithTimeout(d) — per-request timeout on the default client.
  • WithLogger(l) — a slog.Logger for retry-attempt logs.

Tip

Pass WithMaxRetries(0) to disable retries entirely, or raise it for long-running batch workloads where transient 5xx responses are expected.

Logs never include request bodies — retry-attempt logs include URL, status, and attempt number only. Server-side admin tokens or workspace API keys never appear in client SDK logs.

Context

Every method takes a context.Context as its first parameter. Cancelling it short-circuits in-flight HTTP and the retry loop. Pair with context.WithTimeout if you need a hard deadline across retries.

Note

Pair with context.WithTimeout in your request handlers — Cariosan respects the deadline and returns an error matching errors.Is(err, context.DeadlineExceeded) on expiry.

Was this page helpful?

On this page