Basecamp SDK

March 24, 2026 · View on GitHub

Official Basecamp API clients, runtimes, and software development kits for Go, Ruby, TypeScript, Swift, Kotlin, and Python.

OpenAPI 3.1 spec included.

Languages

LanguagePathStatusPackage
Gogo/Activegithub.com/basecamp/basecamp-sdk/go
Rubyruby/Activebasecamp-sdk
TypeScripttypescript/Active@37signals/basecamp
Swiftswift/ActiveBasecamp (SPM)
Kotlinkotlin/Activecom.basecamp:basecamp-sdk (GitHub Packages)
Pythonpython/Activebasecamp-sdk (PyPI)
FeatureGoTypeScriptRubySwiftKotlinPython
OAuth 2.0 Authentication
Static Token Authentication
ETag HTTP Caching (opt-in)via Faraday†
Automatic Retry with Backoff
Pagination Handling
Observability Hooks
Structured Errors
Webhook Verification

† Ruby SDK uses Faraday - add caching via faraday-http-cache

Note: HTTP caching is disabled by default. Enable explicitly via configuration:

  • Go: cfg.CacheEnabled = true or BASECAMP_CACHE_ENABLED=true
  • TypeScript: enableCache: true in client options
  • Swift: BasecampConfig(enableCache: true)
  • Kotlin: enableCache = true in builder DSL

All SDKs are generated from a single Smithy specification, ensuring consistent behavior and API coverage across languages.

Quick Start

Go

package main

import (
    "context"
    "fmt"
    "os"

    "github.com/basecamp/basecamp-sdk/go/pkg/basecamp"
)

func main() {
    cfg := basecamp.DefaultConfig()
    token := &basecamp.StaticTokenProvider{Token: os.Getenv("BASECAMP_TOKEN")}
    client := basecamp.NewClient(cfg, token)

    account := client.ForAccount(os.Getenv("BASECAMP_ACCOUNT_ID"))
    result, err := account.Projects().List(context.Background(), nil)
    if err != nil {
        fmt.Fprintf(os.Stderr, "Error: %v\n", err)
        os.Exit(1)
    }

    for _, p := range result.Projects {
        fmt.Printf("%d: %s\n", p.ID, p.Name)
    }
}

Ruby

require "basecamp"

client = Basecamp.client(access_token: ENV["BASECAMP_TOKEN"])
account = client.for_account(ENV["BASECAMP_ACCOUNT_ID"])

account.projects.list.each do |project|
  puts "#{project['id']}: #{project['name']}"
end

TypeScript

import { createBasecampClient } from "@37signals/basecamp";

const client = createBasecampClient({
  accountId: process.env.BASECAMP_ACCOUNT_ID!,
  accessToken: process.env.BASECAMP_TOKEN!,
});

const projects = await client.projects.list();
projects.forEach(p => console.log(`${p.id}: ${p.name}`));

Swift

import Basecamp

let client = BasecampClient(
    accessToken: ProcessInfo.processInfo.environment["BASECAMP_TOKEN"]!,
    userAgent: "my-app/1.0 (you@example.com)"
)

let account = client.forAccount(ProcessInfo.processInfo.environment["BASECAMP_ACCOUNT_ID"]!)
let projects = try await account.projects.list()
for project in projects {
    print("\(project.id): \(project.name)")
}

Kotlin

val client = BasecampClient {
    accessToken(System.getenv("BASECAMP_TOKEN"))
    userAgent = "my-app/1.0 (you@example.com)"
}

val account = client.forAccount(System.getenv("BASECAMP_ACCOUNT_ID"))
val projects = account.projects.list()
projects.forEach { println("${it.id}: ${it.name}") }

Python

import os
from basecamp import Client

client = Client(access_token=os.environ["BASECAMP_TOKEN"])
account = client.for_account(os.environ["BASECAMP_ACCOUNT_ID"])

projects = account.projects.list()
for project in projects:
    print(f"{project['id']}: {project['name']}")

Features

All SDKs provide:

  • Full API coverage - 35+ services covering projects, todos, messages, schedules, campfires, card tables, and more
  • OAuth 2.0 authentication - Token refresh, PKCE support (Go, TypeScript, Ruby, Kotlin, Python), and static token options
  • Automatic retry - Exponential backoff with jitter, respects Retry-After headers
  • Pagination - Link header–based pagination support (high-level handling may vary by SDK; see language docs)
  • ETag caching - Built-in HTTP caching for efficient API usage (Go, TypeScript, Ruby†, Swift, Kotlin)
  • Structured errors - Typed errors with helpful hints and CLI-friendly exit codes
  • Observability hooks - Integration points for logging, metrics, and tracing

API Coverage

CategoryServices
ProjectsProjects, Templates, Tools, People
To-dosTodos, Todolists, Todosets, TodolistGroups
MessagesMessages, MessageBoards, MessageTypes, Comments
ChatCampfires (lines, chatbots)
SchedulingSchedules, Timeline, Lineup, Checkins
FilesVaults, Documents, Uploads, Attachments
Card TablesCardTables, Cards, CardColumns, CardSteps
Client PortalClientApprovals, ClientCorrespondences, ClientReplies
AutomationWebhooks, Subscriptions, Events
ReportingSearch, Reports, Timesheets, Recordings

Specification

The spec/ directory contains the API specification in Smithy IDL format. This specification drives:

  • OpenAPI generation for client codegen
  • Type definitions across all SDKs
  • Consistent behavior modeling (pagination, retries, idempotency)

See the spec README for details on the model structure.

Documentation

Environment Variables

All SDKs support common environment variables:

VariableDescription
BASECAMP_TOKENOAuth access token
BASECAMP_ACCOUNT_IDBasecamp account ID
BASECAMP_BASE_URLAPI base URL (default: https://3.basecampapi.com)

See individual SDK documentation for language-specific options.

License

MIT