KKlarora

One workspace for your entire team. Tasks, docs, chat, and AI — all connected.

Product

  • Features
  • Pricing
  • API
  • Docs
  • Compare
  • Changelog

Solutions

  • Engineering Teams
  • Enterprise
  • Startups
  • Agencies
  • All Use Cases

Company

  • About Us
  • Careers
  • Blog
  • FAQ
  • Support
  • Contact
  • Status ↗

Legal

  • Privacy Policy
  • Google User Data
  • Terms of Service
  • Security
  • Trust ↗
  • Subprocessors
  • DPA
  • Cookie policy
© 2026 Kairos Connect B.V. All rights reserved.
KKlarora
Products
Core features
FoFeatures overviewSee every module at a glancePrTasks and projectsBoard, calendar, Gantt, sprintsGoGoals and OKRsKey results, check-ins, stakeholdersChTeam chat and mailEnd-to-end encrypted, with a connected mailboxDoDocs and databasesBlock editor, 17 property types, six viewsWbWhiteboardsPrompt-to-diagram, real-time canvasFmFormsBuilder, templates, records that trigger flowsCrCRMPeople, companies, pipeline, outreach inbox
AI and add-ons
AiAssistantSkills, memory, bounds, undoAgAgents and automationsDescribe a flow, approve the work · UltimateDrDeep ResearchPlan → Research → Write → Polish · add-onFiFinanceInvoicing, ledger, bank reconciliation · add-onReRecruitmentSourcing, screening, shortlists, ATS · add-on
View all products
Platform
iOMobile appsiOS and AndroidDkDesktop appsmacOS, Windows, Linux
Solutions
StFor startupsScale fast without the tool taxSbFor small businessGrow without chaosEnFor enterpriseSecurity meets simplicityRtFor remote teamsStay aligned across time zonesEgFor engineering teamsSpecs, sprints and an autofix loopAgFor agenciesA workspace per client, hours into invoicesRaRecruitment agenciesAI that screens candidates for youView all solutions
Pricing
Compare
vs ClickUpvs Linearvs Asanavs monday.comvs Jiravs Slackvs Notion
Blog
Book a demoLog in
Start free
Getting Started
Quick StartAuthentication
API Reference
TasksGoalsCommentsTeamDocuments
SDKs
JavaScript/TypeScriptPythonGo
SDKs/Go

Go SDK

The official Klarora SDK for Go. Idiomatic Go client with context support and strongly-typed interfaces. It covers tasks, goals, team, documents, whiteboards, and forms, and authenticates with an API key.

Requirements

  • Go 1.21 or higher
  • No external dependencies (standard library only)

Installation

go get github.com/moemollaei-org/kairos-connect-sdks/go

The module path ends in /go, but the package name is kairos. Import it with an explicit alias, as shown below.

Quick Start

package main

import (
    "context"
    "fmt"
    "log"

    kairos "github.com/moemollaei-org/kairos-connect-sdks/go"
)

func main() {
    // Initialize the client
    client, err := kairos.New("kairos_sk_...")
    if err != nil {
        log.Fatal(err)
    }

    // Create a context
    ctx := context.Background()

    // List tasks
    tasks, pagination, err := client.Tasks.List(ctx, &kairos.ListTasksOptions{
        ListOptions: kairos.ListOptions{Limit: 10},
        Status:      "in_progress",
    })
    if err != nil {
        log.Fatal(err)
    }

    fmt.Printf("Found %d tasks\n", pagination.Total)
    for _, task := range tasks {
        fmt.Printf("- %s (%s)\n", task.Title, task.Status)
    }
}

Authentication

The SDK authenticates with an API key (kairos_sk_...). kairos.New(apiKey, opts...) returns (*Client, error). When apiKey is an empty string, it reads the KAIROS_API_KEY environment variable, and it returns an error if neither is set. Use client.Me(ctx) to validate the key and see its team, scopes, and rate limits.

// Reads KAIROS_API_KEY from the environment
client, err := kairos.New("")
if err != nil {
    log.Fatal(err)
}

me, err := client.Me(ctx)
if err != nil {
    log.Fatal(err)
}
fmt.Println(me.TeamID, me.Scopes)
fmt.Println(me.RateLimitPerMinute, me.RateLimitPerHour)

Configuration

package main

import (
    "log"
    "net/http"
    "time"

    kairos "github.com/moemollaei-org/kairos-connect-sdks/go"
)

func main() {
    // Basic configuration
    client, err := kairos.New("kairos_sk_...")
    if err != nil {
        log.Fatal(err)
    }

    // With options
    client, err = kairos.New(
        "kairos_sk_...",
        kairos.WithBaseURL("https://gateway.thekairos.app/v1"),
        kairos.WithHTTPClient(&http.Client{}),
        kairos.WithTimeout(60*time.Second),
        kairos.WithMaxRetries(3),
    )
    if err != nil {
        log.Fatal(err)
    }
    _ = client
}

The defaults are a 30 second timeout and 3 retries. Rate-limited (HTTP 429) responses are retried after the Retry-After delay. Options are applied in order, so pass WithHTTPClient before WithTimeout if you use both.

Context Support

All methods accept a context for cancellation and timeout control:

import (
    "context"
    "errors"
    "log"
    "time"
)

// With timeout
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()

task, err := client.Tasks.Get(ctx, "task-id")
if err != nil {
    if errors.Is(err, context.DeadlineExceeded) {
        log.Println("Request timed out")
    }
    return
}
log.Println(task.Title)

// With cancellation
ctx, cancel = context.WithCancel(context.Background())

go func() {
    // Cancel after some condition
    time.Sleep(5 * time.Second)
    cancel()
}()

tasks, _, err := client.Tasks.List(ctx, nil)

Tasks

Optional input fields are pointers. The examples use a small generic helper: func ptr[T any](v T) *T { return &v }.

ctx := context.Background()

// List tasks with filters
tasks, pagination, err := client.Tasks.List(ctx, &kairos.ListTasksOptions{
    ListOptions: kairos.ListOptions{Limit: 50, Offset: 0},
    Status:      "in_progress",
    Priority:    "high",
    AssignedTo:  "user-id",
    GoalID:      "goal-id",
    Search:      "authentication",
})

// Get a single task
task, err := client.Tasks.Get(ctx, "task-id")
fmt.Println(task.Title, task.Status)

// Create a task
newTask, err := client.Tasks.Create(ctx, kairos.CreateTaskInput{
    Title:          "Implement new feature",
    Description:    ptr("Add user authentication"),
    GoalID:         ptr("goal-id"),
    Priority:       ptr("high"),
    DueDate:        ptr("2026-12-15"),
    EstimatedHours: ptr(8.0),
})

// Update a task
updatedTask, err := client.Tasks.Update(ctx, "task-id", kairos.UpdateTaskInput{
    Status:   ptr("completed"),
    Priority: ptr("low"),
})

// Delete a task
err = client.Tasks.Delete(ctx, "task-id")

// Labels
labels, err := client.Tasks.ListLabels(ctx, "task-id")
_, err = client.Tasks.AddLabel(ctx, "task-id", "label-id")
err = client.Tasks.RemoveLabel(ctx, "task-id", "label-id")

// Comments
comments, _, err := client.Tasks.ListComments(ctx, "task-id", &kairos.ListOptions{Limit: 10})
comment, err := client.Tasks.AddComment(ctx, "task-id", kairos.CreateCommentInput{
    Content: "Ready for review",
})
_, err = client.Tasks.UpdateComment(ctx, comment.ID, kairos.UpdateCommentInput{
    Content: "Ready for review, tests added",
})
err = client.Tasks.DeleteComment(ctx, comment.ID)

Goals

ctx := context.Background()

// List goals
goals, pagination, err := client.Goals.List(ctx, &kairos.ListOptions{Limit: 20})

// Create, get, update, delete
created, err := client.Goals.Create(ctx, kairos.CreateGoalInput{
    Title:   "Q2 Product Launch",
    DueDate: ptr("2026-06-30"),
})
goal, err := client.Goals.Get(ctx, created.ID)
_, err = client.Goals.Update(ctx, goal.ID, kairos.UpdateGoalInput{
    Status: ptr("completed"),
})
err = client.Goals.Delete(ctx, goal.ID)

fmt.Printf("Goal: %s\n", goal.Title)
fmt.Printf("Progress: %.0f\n", goal.Progress)

// Tasks that belong to a goal
goalTasks, _, err := client.Goals.ListTasks(ctx, "goal-id", nil)
for _, task := range goalTasks {
    fmt.Printf("  - %s\n", task.Title)
}

// Comments on a goal
goalComments, _, err := client.Goals.ListComments(ctx, "goal-id", nil)
_, err = client.Goals.AddComment(ctx, "goal-id", kairos.CreateCommentInput{
    Content: "On track",
})

Team

ctx := context.Background()

// Get team info
team, err := client.Team.Get(ctx)
fmt.Printf("Team: %s\n", team.Name)

// List team members (teamID required)
members, err := client.Team.ListMembers(ctx, team.ID, nil)

for _, member := range members {
    name := member.Email
    if member.Name != nil {
        name = *member.Name
    }
    fmt.Printf("%s (%s)\n", name, member.Role)
}

Documents

ctx := context.Background()

// List documents
docs, pagination, err := client.Documents.List(ctx, nil)

// Get a document
doc, err := client.Documents.Get(ctx, "doc-id")

fmt.Println(doc.Title)
fmt.Println(string(doc.Content)) // Raw JSON content

// Create, update, delete
created, err := client.Documents.Create(ctx, kairos.CreateDocumentInput{
    Title: "Meeting notes",
})
_, err = client.Documents.Update(ctx, created.ID, kairos.UpdateDocumentInput{
    Title: ptr("Meeting notes (final)"),
})
err = client.Documents.Delete(ctx, created.ID)

Whiteboards

ctx := context.Background()

// List whiteboards
boards, pagination, err := client.Whiteboards.List(ctx, &kairos.ListOptions{Limit: 20})

// Create, get, update, delete
board, err := client.Whiteboards.Create(ctx, kairos.CreateWhiteboardInput{
    Title:    "Sprint planning",
    IsPublic: ptr(false),
})
fetched, err := client.Whiteboards.Get(ctx, board.ID)
_, err = client.Whiteboards.Update(ctx, board.ID, kairos.UpdateWhiteboardInput{
    Title: ptr("Sprint 12 planning"),
})
err = client.Whiteboards.Delete(ctx, board.ID)

Forms

ctx := context.Background()

// List forms
forms, pagination, err := client.Forms.List(ctx, &kairos.ListOptions{Limit: 20})

// Create a form
form, err := client.Forms.Create(ctx, kairos.CreateFormInput{
    Name: "Contact request",
    Fields: []kairos.FormField{
        {ID: "email", Type: "email", Label: "Email", Required: true},
        {ID: "message", Type: "textarea", Label: "Message"},
    },
})

// Submit a response and list submissions
_, err = client.Forms.Submit(ctx, form.ID, map[string]interface{}{
    "email":   "jane@example.com",
    "message": "Hello",
})
submissions, _, err := client.Forms.ListSubmissions(ctx, form.ID, nil)

// Get, update, delete
_, err = client.Forms.Get(ctx, form.ID)
_, err = client.Forms.Update(ctx, form.ID, kairos.UpdateFormInput{
    IsActive: ptr(false),
})
err = client.Forms.Delete(ctx, form.ID)

Error Handling

API errors are returned as *kairos.KairosError, with the fields Code, Message, StatusCode, and RequestID. The helper functions IsAuthError (401), IsForbiddenError (403), IsNotFoundError (404), and IsRateLimitError (429) check the status code.

import (
    "errors"
    "fmt"

    kairos "github.com/moemollaei-org/kairos-connect-sdks/go"
)

task, err := client.Tasks.Get(ctx, "invalid-id")
if err != nil {
    var apiErr *kairos.KairosError
    switch {
    case kairos.IsNotFoundError(err):
        fmt.Println("Task not found")
    case kairos.IsRateLimitError(err):
        fmt.Println("Rate limited")
    case kairos.IsAuthError(err):
        fmt.Println("Authentication failed")
    case kairos.IsForbiddenError(err):
        fmt.Println("Missing permission")
    case errors.As(err, &apiErr):
        fmt.Printf("API error: %s - %s (status %d, request %s)\n",
            apiErr.Code, apiErr.Message, apiErr.StatusCode, apiErr.RequestID)
    default:
        // Network or other error
        fmt.Printf("Error: %v\n", err)
    }
    return
}
fmt.Println(task.Title)

Types

The SDK provides strongly-typed structs for all resources. Status, priority, and type fields are plain strings, and optional values are pointers:

import kairos "github.com/moemollaei-org/kairos-connect-sdks/go"

// Task type
type Task struct {
    ID             string     `json:"id"`
    TeamID         string     `json:"team_id"`
    GoalID         *string    `json:"goal_id"`
    ParentTaskID   *string    `json:"parent_task_id"`
    Title          string     `json:"title"`
    Description    *string    `json:"description"`
    Type           string     `json:"type"`
    Status         string     `json:"status"`
    Priority       string     `json:"priority"`
    AssignedTo     *string    `json:"assigned_to"`
    EstimatedHours *float64   `json:"estimated_hours"`
    ActualHours    *float64   `json:"actual_hours"`
    DueDate        *string    `json:"due_date"`
    StartDate      *string    `json:"start_date"`
    CompletedAt    *time.Time `json:"completed_at"`
    OrderIndex     int        `json:"order_index"`
    IsRecurring    bool       `json:"is_recurring"`
    RecurrenceRule *string    `json:"recurrence_rule"`
    CreatedBy      string     `json:"created_by"`
    CreatedAt      time.Time  `json:"created_at"`
    UpdatedAt      time.Time  `json:"updated_at"`
}

// Other exported types
// Goal, Comment, Document, Whiteboard, Form, FormField, FormSubmission,
// Team, TeamMember, Pagination, MeResponse, RateLimit
//
// Inputs
// CreateTaskInput, UpdateTaskInput, CreateGoalInput, UpdateGoalInput,
// CreateCommentInput, UpdateCommentInput, CreateDocumentInput, UpdateDocumentInput,
// CreateWhiteboardInput, UpdateWhiteboardInput, CreateFormInput, UpdateFormInput
//
// List options
// ListOptions, ListTasksOptions
Python SDKSDKs Overview