Documentation

Everything you need to get Kollaber running and capturing your infrastructure events.

Getting Started

Kollaber captures deploys, alerts, and manual notes in a shared timeline your entire team can see. Getting started takes about five minutes.

1. Create an account

Visit /register and sign up with your email address. You can also sign in with GitHub if your organization uses it.

On first login you will be prompted to create an organization — this is the shared workspace for your team.

2. Create an environment

Go to Dashboard → New Environment and give it a name like production or staging. You can add an optional cluster name for Kubernetes setups.

3. Send your first event

Install the CLI (see CLI Reference) and run:

kollaber login --api https://kollaber.io --email you@example.com --password yourpassword
kollaber deploy --env production --service api --version v1.0.0

Head back to the dashboard — your deploy event will appear in the timeline immediately.

Dashboard

The dashboard is the primary UI for browsing your infrastructure history and collaborating with your team.

Timeline view

Each environment has its own timeline. Events are sorted newest-first and show the event type, service name, timestamp, and any attached metadata (version, author, etc.).

The timeline polls for new events every 10 seconds — no refresh needed. A coloured badge indicates the event type:

  • DEPLOY — a service release recorded via the CLI, CI, or webhook
  • ALERT — an alert ingested via webhook
  • NOTE — a manual note added by a team member

Commenting on events

Click any event to expand it. Use the comment box to leave context — root cause, rollback decision, follow-up ticket, anything. Comments are timestamped and attributed to the author.

Team management

Go to Settings → Members to invite teammates via email. Each member can be assigned one of four roles:

  • Owner — full control including billing and org deletion
  • Admin — manage members, environments, and all events
  • Member — create events and comments
  • Viewer — read-only access to the timeline

Notifications

Kollaber notifies you when events are recorded on your timeline — via email, Slack, or Microsoft Teams. Email notifications are opt-in and per-user; Slack and Teams are configured once per organization.

Email preferences

Go to Settings → Notifications. Check the event types you want to be notified about and optionally enter a notification email address:

  • Deployments — emailed when a deploy event is recorded
  • Alerts — emailed when an alert event is recorded
  • Notes — emailed when a note is added to the timeline

The Notification email field lets you receive alerts at a different address than your account email — useful for shared inboxes or on-call aliases. Leave it blank to use your account email.

Preferences are saved per organization. Members who have not configured preferences receive no emails by default.

How it works

When any event is created (via the CLI, webhook, or UI), Kollaber fires all configured channels asynchronously — email recipients, the Slack webhook, and the Teams webhook all receive a notification without blocking the API response.

Integrations

In addition to email, Kollaber can post to a Slack channel or Microsoft Teams channel when events are recorded. These are org-level settings — one webhook URL covers all team members.

Slack

Go to Settings → Slack and paste an Incoming Webhook URL. To get one:

  1. Open your Slack workspace's App Directory and install Incoming Webhooks
  2. Choose a channel and click Add Incoming Webhooks integration
  3. Copy the generated webhook URL and paste it into Kollaber

Use the Send test message button to verify delivery. Slack messages include the event type (with an emoji), the service name, and the environment.

Microsoft Teams

Go to Settings → Teams and paste an Incoming Webhook URL. To get one:

  1. Open the target Teams channel and click ···Connectors
  2. Search for Incoming Webhook and click Configure
  3. Give it a name, click Create, then copy the webhook URL

Teams messages are sent as colour-coded MessageCard payloads — blue for deploys, red for alerts, purple for notes.

Permissions

Only owners and admins can save or clear the Slack and Teams webhook URLs. Members and viewers can see whether a webhook is configured but cannot change it.

CLI Reference

The kollaber CLI lets you send events, view the timeline, and manage environments directly from your terminal or CI pipeline.

Installation

Install with Go:

go install github.com/urbangeeks/kollaber/cmd/kollaber@latest

Or download a pre-built binary from the downloads page.

Set the KOLLABER_API environment variable to point at your self-hosted instance. Defaults to http://localhost:8080.

kollaber login

Authenticate and save a token to ~/.kollaber/config.json.

# Email + password
kollaber login --api https://kollaber.io --email you@example.com --password yourpassword

# CLI token from Settings → API Tokens (for GitHub OAuth users)
kollaber login --api https://kollaber.io --token <your-token>

kollaber envs

List all environments in your organization.

kollaber envs

kollaber deploy

Record a deploy event.

kollaber deploy \
  --env production \
  --service api \
  --version v1.2.3
--envEnvironment name or UUID (required)
--serviceService name (required)
--versionVersion string, e.g. v1.2.3 (required)

kollaber note

Drop a manual note into the timeline — useful for maintenance windows or on-call observations.

kollaber note --env production "Rolling back v1.2.3 due to 5xx spike"
--envEnvironment name or UUID (required)

kollaber timeline

View recent events for an environment.

kollaber timeline --env production --limit 20
--envEnvironment name or UUID (required)
--limitNumber of events to fetch (default 20)

Kubernetes

The kube-watcher is a lightweight agent that watches your Kubernetes cluster and automatically fires events to your Kollaber timeline — no manual CLI calls or CI steps needed.

  • DEPLOY — fired when a Deployment completes a rollout, capturing the image tag and replica count
  • ALERT — fired when a pod enters CrashLoopBackOff, capturing the pod and container name

Deploy with Helm

The watcher runs as a Deployment inside your cluster using a ServiceAccount with read-only access to Deployments and Pods. Install one release per cluster:

helm install kollaber-watcher ./charts/kube-watcher \
  --set kollaber.env=prod \
  --set kollaber.api=https://kollaber.io \
  --set kollaber.token=<cli-token>

Get your CLI token from the dashboard under Settings → CLI Token.

Helm values

kollaber.envKollaber environment name to map events to (required)
kollaber.apiKollaber API base URL (required)
kollaber.tokenCLI token — from Settings → CLI Token
kollaber.existingSecretUse an existing Secret with key token instead of creating one
watchNamespaceLimit to a single namespace; empty = all namespaces

Multiple clusters

Install a separate Helm release for each cluster, pointing each one at the matching Kollaber environment:

helm install kollaber-watcher-prod    ./charts/kube-watcher --set kollaber.env=prod    ...
helm install kollaber-watcher-staging ./charts/kube-watcher --set kollaber.env=staging ...

Events from each cluster will appear in their respective environment timelines in the dashboard.

Using an existing secret

If you manage secrets externally (Vault, Sealed Secrets, External Secrets Operator), skip secret creation by pointing at your own:

# Your secret must have a key named "token"
kubectl create secret generic my-kollaber-token --from-literal=token=<cli-token>

helm install kollaber-watcher ./charts/kube-watcher \
  --set kollaber.env=prod \
  --set kollaber.api=https://kollaber.io \
  --set kollaber.existingSecret=my-kollaber-token

Running locally (out-of-cluster)

The watcher binary also works outside the cluster using your local kubeconfig — useful for testing:

go install github.com/urbangeeks/kollaber/cmd/kube-watcher@latest

kube-watcher \
  --kubeconfig ~/.kube/config \
  --env prod \
  --api https://kollaber.io \
  --token <cli-token>

The binary tries in-cluster config first. If it is not running inside a pod it falls back to --kubeconfig (or ~/.kube/config by default).

Webhooks

Send events directly from your CI/CD pipeline or any HTTP-capable tool by posting to the webhook endpoint — no CLI install required.

Endpoint

POST https://kollaber.io/webhooks/events

No authentication required on the webhook endpoint. Payloads are normalized into the events table.

GitHub Actions

Add a step at the end of your deploy job:

- name: Notify Kollaber
  run: |
    curl -sS -X POST https://kollaber.io/webhooks/events \
      -H "Content-Type: application/json" \
      -d '{
        "type": "deploy",
        "service": "${{ github.repository }}",
        "environment_id": "${{ secrets.KOLLABER_ENV_ID }}",
        "metadata": {
          "version": "${{ github.sha }}",
          "author": "${{ github.actor }}",
          "ref": "${{ github.ref }}"
        }
      }'

Store your environment UUID as a GitHub secret named KOLLABER_ENV_ID. Find it on the Dashboard under your environment settings.

Generic JSON

Any JSON body with the following shape is accepted:

{
  "type":           "deploy" | "alert" | "note",
  "service":        "your-service-name",
  "environment_id": "uuid-of-environment",
  "metadata":       { /* any key-value pairs */ }
}

Self-hosting

Kollaber ships as a single binary that embeds the frontend. The official Helm chart is the recommended way to deploy a self-hosted instance on Kubernetes.

Prerequisites

  • Kubernetes cluster with Helm 3
  • PostgreSQL 14+ (or use the in-cluster option below)

Minimal install

helm install kollaber oci://ghcr.io/urbangeeks/charts/kollaber \
  --namespace kollaber \
  --create-namespace \
  --set secret.jwtSecret=$(openssl rand -hex 32) \
  --set externalDatabaseUrl=postgres://user:pass@your-postgres:5432/kollaber \
  --set ingress.enabled=true \
  --set ingress.host=kollaber.mycompany.com

Save the generated jwtSecret — it must stay the same across upgrades or existing sessions will be invalidated.

In-cluster PostgreSQL

If you don't have an external database, deploy one with Bitnami's chart:

helm install postgres oci://registry-1.docker.io/bitnamicharts/postgresql \
  --namespace kollaber \
  --set auth.username=kollaber \
  --set auth.password=changeme \
  --set auth.database=kollaber

Then use the service name as the hostname:

--set externalDatabaseUrl=postgres://kollaber:changeme@postgres-postgresql:5432/kollaber

All Helm values

Core

secret.jwtSecretJWT signing secret — openssl rand -hex 32 (required)
externalDatabaseUrlPostgres connection string (required)
replicaCountNumber of API replicas (default: 1)
migrate.enabledRun DB migrations on install/upgrade (default: true)

Image

image.repositoryImage repository (default: ghcr.io/urbangeeks/kollaber-api)
image.tagImage tag (default: latest)
image.pullPolicyImage pull policy (default: IfNotPresent)
imagePullSecretsPull secrets for private registries

Ingress

ingress.enabledCreate a standard Kubernetes Ingress resource (default: false)
ingress.hostHostname for the Ingress
ingress.classNameIngress class, e.g. nginx
ingress.annotationsAnnotations to add to the Ingress resource
ingress.tlsTLS configuration block

Istio

istio.enabledCreate Istio Gateway + VirtualService instead of Ingress (default: false)
istio.hostHostname for the Gateway and VirtualService
istio.gatewaySelectorLabel selector for the Istio ingress gateway pod (default: istio: ingressgateway)
istio.tls.modeTLS mode, e.g. SIMPLE
istio.tls.credentialNameName of the TLS credential in istio-system

Optional integrations

secret.githubClientIdGitHub OAuth client ID — disables GitHub login if unset
secret.githubClientSecretGitHub OAuth client secret
secret.smtpHostSMTP host — disables email if unset
secret.smtpPortSMTP port (default: 587)
secret.smtpUserSMTP username
secret.smtpPasswordSMTP password
secret.webhookSecretHMAC secret for webhook verification — skips verification if unset

Optional: GitHub OAuth

Create a GitHub OAuth App at github.com/settings/developers. Set the callback URL to https://kollaber.mycompany.com/auth/github/callback, then pass the credentials:

--set secret.githubClientId=your_client_id \
--set secret.githubClientSecret=your_client_secret

If not set, GitHub OAuth is disabled and users log in with email/password only.

Email delivery

Kollaber uses email OTP for login — users receive a 6-digit code to sign in. Delivery is resolved in this order:

1Resend API — if RESEND_API_KEY is set (SaaS default)
2SMTP — if SMTP_HOST is set (recommended for self-hosted)
3Pod logs — fallback if neither is configured; retrieve with kubectl logs -n kollaber deployment/kollaber-api

For production installs, configure SMTP:

--set secret.smtpHost=smtp.yourprovider.com \
--set secret.smtpPort=587 \
--set secret.smtpUser=notifications@mycompany.com \
--set secret.smtpPassword=your_password

SMTP uses STARTTLS on port 587. Port 465 (implicit TLS) is not supported. Most providers — Gmail, SendGrid, Mailgun, Exchange — support port 587.

Optional: Webhook HMAC verification

--set secret.webhookSecret=your_hmac_secret

If not set, webhook payloads are accepted without signature verification.

Istio (Gateway + VirtualService)

If your cluster uses Istio instead of a standard ingress controller, disable the Ingress resource and enable Istio routing:

helm install kollaber oci://ghcr.io/urbangeeks/charts/kollaber \
  --namespace kollaber \
  --create-namespace \
  --set secret.jwtSecret=$(openssl rand -hex 32) \
  --set externalDatabaseUrl=postgres://user:pass@your-postgres:5432/kollaber \
  --set ingress.enabled=false \
  --set istio.enabled=true \
  --set istio.host=kollaber.mycompany.com

With TLS:

--set istio.tls.mode=SIMPLE \
--set istio.tls.credentialName=kollaber-tls

The gateway selector defaults to istio: ingressgateway. Override with --set istio.gatewaySelector.istio=my-gateway if your gateway pod uses a different label.

Upgrading

helm upgrade kollaber oci://ghcr.io/urbangeeks/charts/kollaber \
  --namespace kollaber \
  --reuse-values

Use --reuse-values to keep your existing secrets and config. Migrations run automatically on every upgrade.

API Reference

All endpoints accept and return JSON. Authenticated endpoints require an Authorization: Bearer <token> header.

Auth

POST/auth/registerCreate a new account
POST/auth/loginLog in and receive a JWT
POST/auth/tokenGenerate a long-lived CLI token (authenticated)
GET/auth/orgsList organizations for the current user (authenticated)
POST/auth/switchSwitch active organization (authenticated)

Environments

GET/environmentsList all environments (authenticated)
POST/environmentsCreate an environment (authenticated)
PUT/environments/:idUpdate an environment (authenticated)
DELETE/environments/:idDelete an environment (authenticated)

Events

GET/eventsList events, filter by environment_id and limit (authenticated)
POST/eventsCreate an event (authenticated)
POST/webhooks/eventsIngest an event via webhook (unauthenticated)

Query parameters for GET /events: environment_id (required) and limit (default 50).

Comments

GET/events/:id/commentsList comments on an event (authenticated)
POST/events/:id/commentsAdd a comment to an event (authenticated)

Settings

GET/settings/notificationsGet email notification preferences (authenticated)
PUT/settings/notificationsUpdate email notification preferences (authenticated)
GET/settings/slackGet org Slack webhook URL (authenticated)
PUT/settings/slackSet org Slack webhook URL (admin)
POST/settings/slack/testSend a test Slack message (admin)
GET/settings/teamsGet org Teams webhook URL (authenticated)
PUT/settings/teamsSet org Teams webhook URL (admin)
POST/settings/teams/testSend a test Teams message (admin)

Members & Invites

GET/membersList org members (authenticated)
PATCH/members/:userIDUpdate a member's role (authenticated)
DELETE/members/:userIDRemove a member (authenticated)
POST/invitesCreate an invite (authenticated)
GET/invites/:tokenLook up an invite by token
POST/invites/:token/acceptAccept an invite and create account
GET/members/invitesList pending invites (authenticated)
DELETE/members/invites/:tokenRevoke a pending invite (authenticated)