Documentation
¶
Overview ¶
Package basecamp provides a Go SDK for the Basecamp API.
The SDK handles authentication, HTTP caching, rate limiting, and retry logic. It supports both OAuth 2.0 authentication and static token authentication.
Installation ¶
To install the SDK, use go get:
go get github.com/basecamp/basecamp-sdk/go/pkg/basecamp
Authentication ¶
The SDK supports two authentication methods:
Static Token Authentication (simplest):
cfg := basecamp.DefaultConfig()
token := &basecamp.StaticTokenProvider{Token: os.Getenv("BASECAMP_TOKEN")}
client := basecamp.NewClient(cfg, token)
// Create an account-scoped client for API operations
account := client.ForAccount("12345")
OAuth 2.0 Authentication (for user-facing apps):
cfg := basecamp.DefaultConfig() authMgr := basecamp.NewAuthManager(cfg, http.DefaultClient) client := basecamp.NewClient(cfg, authMgr) // Discover available accounts info, _ := client.Authorization().GetInfo(ctx, nil) account := client.ForAccount(fmt.Sprint(info.Accounts[0].ID))
Configuration ¶
Configuration can be loaded from environment variables or set programmatically:
cfg := basecamp.DefaultConfig() cfg.LoadConfigFromEnv() // Loads BASECAMP_PROJECT_ID, etc.
Environment variables:
- BASECAMP_PROJECT_ID: Default project/bucket ID
- BASECAMP_TOKEN: Static API token for authentication
- BASECAMP_CACHE_ENABLED: Enable HTTP caching (default: true)
Services ¶
The SDK provides typed services for each Basecamp resource:
- AccountClient.Projects - Project management
- AccountClient.Todos - Todo items
- AccountClient.Todolists - Todo lists
- AccountClient.Todosets - Todo sets (containers for lists)
- AccountClient.Messages - Message board posts
- AccountClient.MessageBoards - Message boards
- AccountClient.Comments - Comments on any recording
- AccountClient.People - User and people management
- AccountClient.Campfires - Chat rooms
- AccountClient.Schedules - Calendar schedules
- AccountClient.Vaults - Document folders
- AccountClient.Search - Full-text search
- AccountClient.Webhooks - Webhook management
- AccountClient.Events - Activity events
- AccountClient.Cards - Card table cards
- AccountClient.Attachments - File attachments
- Client.Authorization - Account-agnostic authorization info
Working with Projects ¶
List all projects:
account := client.ForAccount("12345")
projects, err := account.Projects().List(ctx, nil)
if err != nil {
log.Fatal(err)
}
for _, p := range projects {
fmt.Println(p.Name)
}
Create a project:
project, err := account.Projects().Create(ctx, &basecamp.CreateProjectRequest{
Name: "New Project",
Description: "Project description",
})
Working with Todos ¶
List todos in a todolist:
todos, err := account.Todos().List(ctx, projectID, todolistID, nil)
Create a todo:
todo, err := account.Todos().Create(ctx, projectID, todolistID, &basecamp.CreateTodoRequest{
Content: "Ship the feature",
DueOn: "2024-12-31",
})
Complete a todo:
err := account.Todos().Complete(ctx, projectID, todoID)
Searching ¶
Search across your Basecamp account:
results, err := account.Search().Search(ctx, "quarterly report", nil)
for _, r := range results {
fmt.Printf("%s: %s\n", r.Type, r.Title)
}
Pagination ¶
The SDK handles pagination automatically via GetAll:
// GetAll fetches all pages automatically
account := client.ForAccount("12345")
results, err := account.GetAll(ctx, "/projects.json")
For fine-grained control, use Get with Link headers:
resp, err := client.Get(ctx, "/projects.json")
// Check resp.Headers.Get("Link") for pagination
Error Handling ¶
The SDK returns typed errors that can be inspected:
resp, err := client.Get(ctx, "/projects/999.json")
if err != nil {
if apiErr, ok := errors.AsType[*basecamp.Error](err); ok {
switch apiErr.Code {
case basecamp.CodeNotFound:
// Handle 404
case basecamp.CodeAuth:
// Handle authentication error
case basecamp.CodeRateLimit:
// Handle rate limiting (auto-retried by default)
}
}
}
Automatic Features ¶
The SDK automatically handles:
- ETag-based HTTP caching for GET requests
- Exponential backoff with jitter for retryable errors
- Token refresh when using OAuth
- Rate limit handling with automatic retry
- Pagination via GetAll for list endpoints
Client Options ¶
Customize the client with options:
client := basecamp.NewClient(cfg, token,
basecamp.WithHTTPClient(customHTTPClient),
basecamp.WithUserAgent("my-app/1.0"),
basecamp.WithLogger(slog.Default()),
basecamp.WithCache(customCache),
)
Thread Safety ¶
The Client is safe for concurrent use. The ForAccount method may be called concurrently from multiple goroutines to create AccountClient instances.
Each AccountClient is also safe for concurrent use. Service accessors (e.g., account.Projects()) use mutex-protected lazy initialization.
Example of concurrent multi-account usage:
acme := client.ForAccount("12345")
initech := client.ForAccount("67890")
go func() { acme.Todos().List(ctx, projectID, todolistID, nil) }()
go func() { initech.Projects().List(ctx, nil) }()
Package basecamp provides a Go SDK for the Basecamp API.
Example (ErrorHandling) ¶
package main
import (
"context"
"errors"
"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)
ctx := context.Background()
// Get a project that may not exist
project, err := client.ForAccount("12345").Projects().Get(ctx, 999999999)
if err != nil {
if apiErr, ok := errors.AsType[*basecamp.Error](err); ok {
switch apiErr.Code {
case basecamp.CodeNotFound:
fmt.Println("Project not found")
case basecamp.CodeAuth:
fmt.Println("Authentication required - please log in")
case basecamp.CodeForbidden:
fmt.Println("Access denied")
case basecamp.CodeRateLimit:
fmt.Println("Rate limited - try again later")
default:
fmt.Printf("API error: %s\n", apiErr.Message)
}
} else {
fmt.Printf("Error: %v\n", err)
}
return
}
fmt.Printf("Found project: %s\n", project.Name)
}
Output:
Index ¶
- Constants
- Variables
- func ComputeWebhookSignature(payload []byte, secret string) string
- func ExitCodeFor(code string) int
- func NormalizeBaseURL(url string) string
- func ParseEventKind(kind string) (recordingType, action string)
- func RedactHeaders(headers http.Header) http.Header
- func RequireSecureEndpoint(rawURL string) error
- func VerifyWebhookSignature(payload []byte, signature, secret string) bool
- type APIProvenance
- type AccountClient
- func (ac *AccountClient) AccountID() string
- func (ac *AccountClient) Attachments() *AttachmentsService
- func (ac *AccountClient) Boosts() *BoostsService
- func (ac *AccountClient) Campfires() *CampfiresService
- func (ac *AccountClient) CardColumns() *CardColumnsService
- func (ac *AccountClient) CardSteps() *CardStepsService
- func (ac *AccountClient) CardTables() *CardTablesService
- func (ac *AccountClient) Cards() *CardsService
- func (ac *AccountClient) Checkins() *CheckinsService
- func (ac *AccountClient) ClientApprovals() *ClientApprovalsService
- func (ac *AccountClient) ClientCorrespondences() *ClientCorrespondencesService
- func (ac *AccountClient) ClientReplies() *ClientRepliesService
- func (ac *AccountClient) Comments() *CommentsService
- func (ac *AccountClient) Delete(ctx context.Context, path string) (*Response, error)
- func (ac *AccountClient) Documents() *DocumentsService
- func (ac *AccountClient) Events() *EventsService
- func (ac *AccountClient) Forwards() *ForwardsService
- func (ac *AccountClient) Get(ctx context.Context, path string) (*Response, error)
- func (ac *AccountClient) GetAll(ctx context.Context, path string) ([]json.RawMessage, error)
- func (ac *AccountClient) GetAllWithLimit(ctx context.Context, path string, limit int) ([]json.RawMessage, error)
- func (ac *AccountClient) Lineup() *LineupService
- func (ac *AccountClient) MessageBoards() *MessageBoardsService
- func (ac *AccountClient) MessageTypes() *MessageTypesService
- func (ac *AccountClient) Messages() *MessagesService
- func (ac *AccountClient) People() *PeopleService
- func (ac *AccountClient) Post(ctx context.Context, path string, body any) (*Response, error)
- func (ac *AccountClient) Projects() *ProjectsService
- func (ac *AccountClient) Put(ctx context.Context, path string, body any) (*Response, error)
- func (ac *AccountClient) Recordings() *RecordingsService
- func (ac *AccountClient) Reports() *ReportsService
- func (ac *AccountClient) Schedules() *SchedulesService
- func (ac *AccountClient) Search() *SearchService
- func (ac *AccountClient) Subscriptions() *SubscriptionsService
- func (ac *AccountClient) Templates() *TemplatesService
- func (ac *AccountClient) Timeline() *TimelineService
- func (ac *AccountClient) Timesheet() *TimesheetService
- func (ac *AccountClient) TodolistGroups() *TodolistGroupsService
- func (ac *AccountClient) Todolists() *TodolistsService
- func (ac *AccountClient) Todos() *TodosService
- func (ac *AccountClient) Todosets() *TodosetsService
- func (ac *AccountClient) Tools() *ToolsService
- func (ac *AccountClient) Uploads() *UploadsService
- func (ac *AccountClient) Vaults() *VaultsService
- func (ac *AccountClient) Webhooks() *WebhooksService
- type AnswerListOptions
- type AnswerListResult
- type Assignable
- type AssignedTodosOptions
- type AssignedTodosResponse
- type AttachmentResponse
- type AttachmentsService
- type AuthManager
- func (m *AuthManager) AccessToken(ctx context.Context) (string, error)
- func (m *AuthManager) GetUserID() string
- func (m *AuthManager) IsAuthenticated() bool
- func (m *AuthManager) Logout() error
- func (m *AuthManager) Refresh(ctx context.Context) error
- func (m *AuthManager) SetUserID(userID string) error
- func (m *AuthManager) Store() *CredentialStore
- type AuthStrategy
- type AuthorizationInfo
- type AuthorizationService
- type AuthorizedAccount
- type BearerAuth
- type Boost
- type BoostListResult
- type BoostsService
- func (s *BoostsService) CreateEvent(ctx context.Context, recordingID, eventID int64, content string) (result *Boost, err error)
- func (s *BoostsService) CreateRecording(ctx context.Context, recordingID int64, content string) (result *Boost, err error)
- func (s *BoostsService) Delete(ctx context.Context, boostID int64) (err error)
- func (s *BoostsService) Get(ctx context.Context, boostID int64) (result *Boost, err error)
- func (s *BoostsService) ListEvent(ctx context.Context, recordingID, eventID int64) (result *BoostListResult, err error)
- func (s *BoostsService) ListRecording(ctx context.Context, recordingID int64) (result *BoostListResult, err error)
- type Bucket
- type BulkheadConfig
- type Cache
- type Campfire
- type CampfireLine
- type CampfireLineAttachment
- type CampfireLineListResult
- type CampfireListResult
- type CampfiresService
- func (s *CampfiresService) CreateChatbot(ctx context.Context, campfireID int64, req *CreateChatbotRequest) (result *Chatbot, err error)
- func (s *CampfiresService) CreateLine(ctx context.Context, campfireID int64, content string, ...) (result *CampfireLine, err error)
- func (s *CampfiresService) CreateUpload(ctx context.Context, campfireID int64, filename, contentType string, ...) (result *CampfireLine, err error)
- func (s *CampfiresService) DeleteChatbot(ctx context.Context, campfireID, chatbotID int64) (err error)
- func (s *CampfiresService) DeleteLine(ctx context.Context, campfireID, lineID int64) (err error)
- func (s *CampfiresService) Get(ctx context.Context, campfireID int64) (result *Campfire, err error)
- func (s *CampfiresService) GetChatbot(ctx context.Context, campfireID, chatbotID int64) (result *Chatbot, err error)
- func (s *CampfiresService) GetLine(ctx context.Context, campfireID, lineID int64) (result *CampfireLine, err error)
- func (s *CampfiresService) List(ctx context.Context) (result *CampfireListResult, err error)
- func (s *CampfiresService) ListChatbots(ctx context.Context, campfireID int64) (result []Chatbot, err error)
- func (s *CampfiresService) ListLines(ctx context.Context, campfireID int64) (result *CampfireLineListResult, err error)
- func (s *CampfiresService) ListUploads(ctx context.Context, campfireID int64) (result *CampfireLineListResult, err error)
- func (s *CampfiresService) UpdateChatbot(ctx context.Context, campfireID, chatbotID int64, req *UpdateChatbotRequest) (result *Chatbot, err error)
- type Card
- type CardColumn
- type CardColumnsService
- func (s *CardColumnsService) Create(ctx context.Context, cardTableID int64, req *CreateColumnRequest) (result *CardColumn, err error)
- func (s *CardColumnsService) DisableOnHold(ctx context.Context, columnID int64) (result *CardColumn, err error)
- func (s *CardColumnsService) EnableOnHold(ctx context.Context, columnID int64) (result *CardColumn, err error)
- func (s *CardColumnsService) Get(ctx context.Context, columnID int64) (result *CardColumn, err error)
- func (s *CardColumnsService) Move(ctx context.Context, cardTableID int64, req *MoveColumnRequest) (err error)
- func (s *CardColumnsService) SetColor(ctx context.Context, columnID int64, color string) (result *CardColumn, err error)
- func (s *CardColumnsService) Unwatch(ctx context.Context, columnID int64) (err error)
- func (s *CardColumnsService) Update(ctx context.Context, columnID int64, req *UpdateColumnRequest) (result *CardColumn, err error)
- func (s *CardColumnsService) Watch(ctx context.Context, columnID int64) (result *Subscription, err error)
- type CardListOptions
- type CardListResult
- type CardStep
- type CardStepsService
- func (s *CardStepsService) Complete(ctx context.Context, stepID int64) (result *CardStep, err error)
- func (s *CardStepsService) Create(ctx context.Context, cardID int64, req *CreateStepRequest) (result *CardStep, err error)
- func (s *CardStepsService) Delete(ctx context.Context, stepID int64) (err error)
- func (s *CardStepsService) Reposition(ctx context.Context, cardID, stepID int64, position int) (err error)
- func (s *CardStepsService) Uncomplete(ctx context.Context, stepID int64) (result *CardStep, err error)
- func (s *CardStepsService) Update(ctx context.Context, stepID int64, req *UpdateStepRequest) (result *CardStep, err error)
- type CardTable
- type CardTablesService
- type CardsService
- func (s *CardsService) Create(ctx context.Context, columnID int64, req *CreateCardRequest) (result *Card, err error)
- func (s *CardsService) Get(ctx context.Context, cardID int64) (result *Card, err error)
- func (s *CardsService) List(ctx context.Context, columnID int64, opts *CardListOptions) (result *CardListResult, err error)
- func (s *CardsService) Move(ctx context.Context, cardID, columnID int64) (err error)
- func (s *CardsService) Trash(ctx context.Context, cardID int64) (err error)
- func (s *CardsService) Update(ctx context.Context, cardID int64, req *UpdateCardRequest) (result *Card, err error)
- type ChainHooks
- func (c *ChainHooks) OnOperationEnd(ctx context.Context, op OperationInfo, err error, duration time.Duration)
- func (c *ChainHooks) OnOperationGate(ctx context.Context, op OperationInfo) (context.Context, error)
- func (c *ChainHooks) OnOperationStart(ctx context.Context, op OperationInfo) context.Context
- func (c *ChainHooks) OnRequestEnd(ctx context.Context, info RequestInfo, result RequestResult)
- func (c *ChainHooks) OnRequestStart(ctx context.Context, info RequestInfo) context.Context
- func (c *ChainHooks) OnRetry(ctx context.Context, info RequestInfo, attempt int, err error)
- type Chatbot
- type CheckinsService
- func (s *CheckinsService) CreateAnswer(ctx context.Context, questionID int64, req *CreateAnswerRequest) (result *QuestionAnswer, err error)
- func (s *CheckinsService) CreateQuestion(ctx context.Context, questionnaireID int64, req *CreateQuestionRequest) (result *Question, err error)
- func (s *CheckinsService) GetAnswer(ctx context.Context, answerID int64) (result *QuestionAnswer, err error)
- func (s *CheckinsService) GetQuestion(ctx context.Context, questionID int64) (result *Question, err error)
- func (s *CheckinsService) GetQuestionnaire(ctx context.Context, questionnaireID int64) (result *Questionnaire, err error)
- func (s *CheckinsService) ListAnswers(ctx context.Context, questionID int64, opts *AnswerListOptions) (result *AnswerListResult, err error)
- func (s *CheckinsService) ListQuestions(ctx context.Context, questionnaireID int64, opts *QuestionListOptions) (result *QuestionListResult, err error)
- func (s *CheckinsService) UpdateAnswer(ctx context.Context, answerID int64, req *UpdateAnswerRequest) (err error)
- func (s *CheckinsService) UpdateQuestion(ctx context.Context, questionID int64, req *UpdateQuestionRequest) (result *Question, err error)
- type CircuitBreakerConfig
- type Client
- func (c *Client) Authorization() *AuthorizationService
- func (c *Client) Config() Config
- func (c *Client) Delete(ctx context.Context, path string) (*Response, error)
- func (c *Client) FollowPagination(ctx context.Context, httpResp *http.Response, firstPageCount, limit int) ([]json.RawMessage, error)
- func (c *Client) ForAccount(accountID string) *AccountClient
- func (c *Client) Get(ctx context.Context, path string) (*Response, error)
- func (c *Client) GetAll(ctx context.Context, path string) ([]json.RawMessage, error)
- func (c *Client) GetAllWithLimit(ctx context.Context, path string, limit int) ([]json.RawMessage, error)
- func (c *Client) Post(ctx context.Context, path string, body any) (*Response, error)
- func (c *Client) Put(ctx context.Context, path string, body any) (*Response, error)
- type ClientApproval
- type ClientApprovalListResult
- type ClientApprovalResponse
- type ClientApprovalsService
- type ClientCompany
- type ClientCorrespondence
- type ClientCorrespondenceListResult
- type ClientCorrespondencesService
- type ClientOption
- func WithAuthStrategy(strategy AuthStrategy) ClientOption
- func WithBaseDelay(d time.Duration) ClientOption
- func WithBulkhead(cfg *BulkheadConfig) ClientOption
- func WithCache(cache *Cache) ClientOption
- func WithCircuitBreaker(cfg *CircuitBreakerConfig) ClientOption
- func WithHTTPClient(c *http.Client) ClientOption
- func WithHooks(hooks Hooks) ClientOption
- func WithLogger(l *slog.Logger) ClientOption
- func WithMaxJitter(d time.Duration) ClientOption
- func WithMaxPages(n int) ClientOption
- func WithMaxRetries(n int) ClientOption
- func WithRateLimit(cfg *RateLimitConfig) ClientOption
- func WithResilience(cfg *ResilienceConfig) ClientOption
- func WithTimeout(d time.Duration) ClientOption
- func WithTransport(t http.RoundTripper) ClientOption
- func WithUserAgent(ua string) ClientOption
- type ClientRepliesService
- type ClientReply
- type ClientReplyListResult
- type Clientside
- type Comment
- type CommentListOptions
- type CommentListResult
- type CommentsService
- func (s *CommentsService) Create(ctx context.Context, recordingID int64, req *CreateCommentRequest) (result *Comment, err error)
- func (s *CommentsService) Get(ctx context.Context, commentID int64) (result *Comment, err error)
- func (s *CommentsService) List(ctx context.Context, recordingID int64, opts *CommentListOptions) (result *CommentListResult, err error)
- func (s *CommentsService) Trash(ctx context.Context, commentID int64) (err error)
- func (s *CommentsService) Update(ctx context.Context, commentID int64, req *UpdateCommentRequest) (result *Comment, err error)
- type Config
- type CreateAnswerRequest
- type CreateCampfireLineRequest
- type CreateCardRequest
- type CreateChatbotRequest
- type CreateColumnRequest
- type CreateCommentRequest
- type CreateDocumentRequest
- type CreateForwardReplyRequest
- type CreateLineOptions
- type CreateMarkerRequest
- type CreateMessageRequest
- type CreateMessageTypeRequest
- type CreatePersonRequest
- type CreateProjectFromTemplateRequest
- type CreateProjectRequest
- type CreateQuestionRequest
- type CreateScheduleEntryRequest
- type CreateStepRequest
- type CreateTemplateRequest
- type CreateTimesheetEntryRequest
- type CreateTodoRequest
- type CreateTodolistGroupRequest
- type CreateTodolistRequest
- type CreateUploadRequest
- type CreateVaultRequest
- type CreateWebhookRequest
- type CredentialStore
- type Credentials
- type Date
- type DockItem
- type Document
- type DocumentListOptions
- type DocumentListResult
- type DocumentsService
- func (s *DocumentsService) Create(ctx context.Context, vaultID int64, req *CreateDocumentRequest) (result *Document, err error)
- func (s *DocumentsService) Get(ctx context.Context, documentID int64) (result *Document, err error)
- func (s *DocumentsService) List(ctx context.Context, vaultID int64, opts *DocumentListOptions) (result *DocumentListResult, err error)
- func (s *DocumentsService) Trash(ctx context.Context, documentID int64) (err error)
- func (s *DocumentsService) Update(ctx context.Context, documentID int64, req *UpdateDocumentRequest) (result *Document, err error)
- type DownloadResult
- type Error
- func AsError(err error) *Error
- func ErrAPI(status int, msg string) *Error
- func ErrAmbiguous(resource string, matches []string) *Error
- func ErrAuth(msg string) *Error
- func ErrForbidden(msg string) *Error
- func ErrForbiddenScope() *Error
- func ErrNetwork(cause error) *Error
- func ErrNotFound(resource, identifier string) *Error
- func ErrNotFoundHint(resource, identifier, hint string) *Error
- func ErrRateLimit(retryAfter int) *Error
- func ErrUsage(msg string) *Error
- func ErrUsageHint(msg, hint string) *Error
- type Event
- type EventDetails
- type EventListOptions
- type EventListResult
- type EventsService
- type FlexTime
- type Forward
- type ForwardListOptions
- type ForwardListResult
- type ForwardReply
- type ForwardReplyListOptions
- type ForwardReplyListResult
- type ForwardsService
- func (s *ForwardsService) CreateReply(ctx context.Context, forwardID int64, req *CreateForwardReplyRequest) (result *ForwardReply, err error)
- func (s *ForwardsService) Get(ctx context.Context, forwardID int64) (result *Forward, err error)
- func (s *ForwardsService) GetInbox(ctx context.Context, inboxID int64) (result *Inbox, err error)
- func (s *ForwardsService) GetReply(ctx context.Context, forwardID, replyID int64) (result *ForwardReply, err error)
- func (s *ForwardsService) List(ctx context.Context, inboxID int64, opts *ForwardListOptions) (result *ForwardListResult, err error)
- func (s *ForwardsService) ListReplies(ctx context.Context, forwardID int64, opts *ForwardReplyListOptions) (result *ForwardReplyListResult, err error)
- type GatingHooks
- type GetInfoOptions
- type HTTPOptions
- type Hooks
- type Identity
- type Inbox
- type LineupMarker
- type LineupService
- type ListMeta
- type Match
- type MatchSource
- type Message
- type MessageBoard
- type MessageBoardsService
- type MessageListOptions
- type MessageListResult
- type MessageType
- type MessageTypeListResult
- type MessageTypesService
- func (s *MessageTypesService) Create(ctx context.Context, req *CreateMessageTypeRequest) (result *MessageType, err error)
- func (s *MessageTypesService) Delete(ctx context.Context, typeID int64) (err error)
- func (s *MessageTypesService) Get(ctx context.Context, typeID int64) (result *MessageType, err error)
- func (s *MessageTypesService) List(ctx context.Context) (result *MessageTypeListResult, err error)
- func (s *MessageTypesService) Update(ctx context.Context, typeID int64, req *UpdateMessageTypeRequest) (result *MessageType, err error)
- type MessagesService
- func (s *MessagesService) Archive(ctx context.Context, messageID int64) (err error)
- func (s *MessagesService) Create(ctx context.Context, boardID int64, req *CreateMessageRequest) (result *Message, err error)
- func (s *MessagesService) Get(ctx context.Context, messageID int64) (result *Message, err error)
- func (s *MessagesService) List(ctx context.Context, boardID int64, opts *MessageListOptions) (result *MessageListResult, err error)
- func (s *MessagesService) Pin(ctx context.Context, messageID int64) (err error)
- func (s *MessagesService) Trash(ctx context.Context, messageID int64) (err error)
- func (s *MessagesService) Unarchive(ctx context.Context, messageID int64) (err error)
- func (s *MessagesService) Unpin(ctx context.Context, messageID int64) (err error)
- func (s *MessagesService) Update(ctx context.Context, messageID int64, req *UpdateMessageRequest) (result *Message, err error)
- type MoveCardRequest
- type MoveColumnRequest
- type NoopHooks
- func (NoopHooks) OnOperationEnd(context.Context, OperationInfo, error, time.Duration)
- func (NoopHooks) OnOperationStart(ctx context.Context, _ OperationInfo) context.Context
- func (NoopHooks) OnRequestEnd(context.Context, RequestInfo, RequestResult)
- func (NoopHooks) OnRequestStart(ctx context.Context, _ RequestInfo) context.Context
- func (NoopHooks) OnRetry(context.Context, RequestInfo, int, error)
- type OperationInfo
- type OverdueTodosResponse
- type Parent
- type PeopleListOptions
- type PeopleListResult
- type PeopleService
- func (s *PeopleService) Get(ctx context.Context, personID int64) (result *Person, err error)
- func (s *PeopleService) List(ctx context.Context, opts *PeopleListOptions) (result *PeopleListResult, err error)
- func (s *PeopleService) ListProjectPeople(ctx context.Context, projectID int64, opts *PeopleListOptions) (result *PeopleListResult, err error)
- func (s *PeopleService) Me(ctx context.Context) (result *Person, err error)
- func (s *PeopleService) Pingable(ctx context.Context) (result []Person, err error)
- func (s *PeopleService) UpdateProjectAccess(ctx context.Context, projectID int64, req *UpdateProjectAccessRequest) (result *UpdateProjectAccessResponse, err error)
- type Person
- type PersonCompany
- type PersonProgressResponse
- type Project
- type ProjectConstruction
- type ProjectListOptions
- type ProjectListResult
- type ProjectStatus
- type ProjectsService
- func (s *ProjectsService) Create(ctx context.Context, req *CreateProjectRequest) (result *Project, err error)
- func (s *ProjectsService) Get(ctx context.Context, id int64) (result *Project, err error)
- func (s *ProjectsService) List(ctx context.Context, opts *ProjectListOptions) (result *ProjectListResult, err error)
- func (s *ProjectsService) Trash(ctx context.Context, id int64) (err error)
- func (s *ProjectsService) Update(ctx context.Context, id int64, req *UpdateProjectRequest) (result *Project, err error)
- type Question
- type QuestionAnswer
- type QuestionListOptions
- type QuestionListResult
- type QuestionSchedule
- type Questionnaire
- type RateLimitConfig
- type Recording
- type RecordingListResult
- type RecordingType
- type RecordingsListOptions
- type RecordingsService
- func (s *RecordingsService) Archive(ctx context.Context, recordingID int64) (err error)
- func (s *RecordingsService) Get(ctx context.Context, recordingID int64) (result *Recording, err error)
- func (s *RecordingsService) List(ctx context.Context, recordingType RecordingType, opts *RecordingsListOptions) (result *RecordingListResult, err error)
- func (s *RecordingsService) SetClientVisibility(ctx context.Context, recordingID int64, visible bool) (result *Recording, err error)
- func (s *RecordingsService) Trash(ctx context.Context, recordingID int64) (err error)
- func (s *RecordingsService) Unarchive(ctx context.Context, recordingID int64) (err error)
- type ReportsService
- func (s *ReportsService) AssignablePeople(ctx context.Context) (result []Person, err error)
- func (s *ReportsService) AssignedTodos(ctx context.Context, personID int64, opts *AssignedTodosOptions) (result *AssignedTodosResponse, err error)
- func (s *ReportsService) OverdueTodos(ctx context.Context) (result *OverdueTodosResponse, err error)
- func (s *ReportsService) UpcomingSchedule(ctx context.Context, startDate, endDate string) (result *UpcomingScheduleResponse, err error)
- type RequestInfo
- type RequestResult
- type ResilienceConfig
- type Response
- type Router
- type Schedule
- type ScheduleAttributes
- type ScheduleEntry
- type ScheduleEntryListOptions
- type ScheduleEntryListResult
- type SchedulesService
- func (s *SchedulesService) CreateEntry(ctx context.Context, scheduleID int64, req *CreateScheduleEntryRequest) (result *ScheduleEntry, err error)
- func (s *SchedulesService) Get(ctx context.Context, scheduleID int64) (result *Schedule, err error)
- func (s *SchedulesService) GetEntry(ctx context.Context, entryID int64) (result *ScheduleEntry, err error)
- func (s *SchedulesService) GetEntryOccurrence(ctx context.Context, entryID int64, date string) (result *ScheduleEntry, err error)
- func (s *SchedulesService) ListEntries(ctx context.Context, scheduleID int64, opts *ScheduleEntryListOptions) (result *ScheduleEntryListResult, err error)
- func (s *SchedulesService) TrashEntry(ctx context.Context, entryID int64) (err error)
- func (s *SchedulesService) UpdateEntry(ctx context.Context, entryID int64, req *UpdateScheduleEntryRequest) (result *ScheduleEntry, err error)
- func (s *SchedulesService) UpdateSettings(ctx context.Context, scheduleID int64, req *UpdateScheduleSettingsRequest) (result *Schedule, err error)
- type SearchMetadata
- type SearchOptions
- type SearchProject
- type SearchResult
- type SearchService
- type SetClientVisibilityRequest
- type SetColumnColorRequest
- type SlogHooks
- func (h *SlogHooks) OnOperationEnd(ctx context.Context, op OperationInfo, err error, duration time.Duration)
- func (h *SlogHooks) OnOperationStart(ctx context.Context, op OperationInfo) context.Context
- func (h *SlogHooks) OnRequestEnd(ctx context.Context, info RequestInfo, result RequestResult)
- func (h *SlogHooks) OnRequestStart(ctx context.Context, info RequestInfo) context.Context
- func (h *SlogHooks) OnRetry(ctx context.Context, info RequestInfo, attempt int, err error)
- type SlogHooksOption
- type StaticTokenProvider
- type Subscription
- type SubscriptionsService
- func (s *SubscriptionsService) Get(ctx context.Context, recordingID int64) (result *Subscription, err error)
- func (s *SubscriptionsService) Subscribe(ctx context.Context, recordingID int64) (result *Subscription, err error)
- func (s *SubscriptionsService) Unsubscribe(ctx context.Context, recordingID int64) (err error)
- func (s *SubscriptionsService) Update(ctx context.Context, recordingID int64, req *UpdateSubscriptionRequest) (result *Subscription, err error)
- type Template
- type TemplateListResult
- type TemplatesService
- func (s *TemplatesService) Create(ctx context.Context, req *CreateTemplateRequest) (result *Template, err error)
- func (s *TemplatesService) CreateProject(ctx context.Context, templateID int64, name, description string) (result *ProjectConstruction, err error)
- func (s *TemplatesService) Delete(ctx context.Context, templateID int64) (err error)
- func (s *TemplatesService) Get(ctx context.Context, templateID int64) (result *Template, err error)
- func (s *TemplatesService) GetConstruction(ctx context.Context, templateID, constructionID int64) (result *ProjectConstruction, err error)
- func (s *TemplatesService) List(ctx context.Context) (result *TemplateListResult, err error)
- func (s *TemplatesService) Update(ctx context.Context, templateID int64, req *UpdateTemplateRequest) (result *Template, err error)
- type TimelineEvent
- type TimelineService
- func (s *TimelineService) PersonProgress(ctx context.Context, personID int64) (result *PersonProgressResponse, err error)
- func (s *TimelineService) Progress(ctx context.Context) (result []TimelineEvent, err error)
- func (s *TimelineService) ProjectTimeline(ctx context.Context, projectID int64) (result []TimelineEvent, err error)
- type TimesheetEntry
- type TimesheetReportOptions
- type TimesheetService
- func (s *TimesheetService) Create(ctx context.Context, recordingID int64, req *CreateTimesheetEntryRequest) (result *TimesheetEntry, err error)
- func (s *TimesheetService) Get(ctx context.Context, entryID int64) (result *TimesheetEntry, err error)
- func (s *TimesheetService) ProjectReport(ctx context.Context, projectID int64, opts *TimesheetReportOptions) (result []TimesheetEntry, err error)
- func (s *TimesheetService) RecordingReport(ctx context.Context, recordingID int64, opts *TimesheetReportOptions) (result []TimesheetEntry, err error)
- func (s *TimesheetService) Report(ctx context.Context, opts *TimesheetReportOptions) (result []TimesheetEntry, err error)
- func (s *TimesheetService) Trash(ctx context.Context, entryID int64) (err error)
- func (s *TimesheetService) Update(ctx context.Context, entryID int64, req *UpdateTimesheetEntryRequest) (result *TimesheetEntry, err error)
- type Todo
- type TodoListOptions
- type TodoListResult
- type Todolist
- type TodolistGroup
- type TodolistGroupListResult
- type TodolistGroupsService
- func (s *TodolistGroupsService) Create(ctx context.Context, todolistID int64, req *CreateTodolistGroupRequest) (result *TodolistGroup, err error)
- func (s *TodolistGroupsService) Get(ctx context.Context, groupID int64) (result *TodolistGroup, err error)
- func (s *TodolistGroupsService) List(ctx context.Context, todolistID int64) (result *TodolistGroupListResult, err error)
- func (s *TodolistGroupsService) Reposition(ctx context.Context, groupID int64, position int) (err error)
- func (s *TodolistGroupsService) Trash(ctx context.Context, groupID int64) (err error)
- func (s *TodolistGroupsService) Update(ctx context.Context, groupID int64, req *UpdateTodolistGroupRequest) (result *TodolistGroup, err error)
- type TodolistListOptions
- type TodolistListResult
- type TodolistsService
- func (s *TodolistsService) Create(ctx context.Context, todosetID int64, req *CreateTodolistRequest) (result *Todolist, err error)
- func (s *TodolistsService) Get(ctx context.Context, todolistID int64) (result *Todolist, err error)
- func (s *TodolistsService) List(ctx context.Context, todosetID int64, opts *TodolistListOptions) (result *TodolistListResult, err error)
- func (s *TodolistsService) Trash(ctx context.Context, todolistID int64) (err error)
- func (s *TodolistsService) Update(ctx context.Context, todolistID int64, req *UpdateTodolistRequest) (result *Todolist, err error)
- type TodosService
- func (s *TodosService) Complete(ctx context.Context, todoID int64) (err error)
- func (s *TodosService) Create(ctx context.Context, todolistID int64, req *CreateTodoRequest) (result *Todo, err error)
- func (s *TodosService) Get(ctx context.Context, todoID int64) (result *Todo, err error)
- func (s *TodosService) List(ctx context.Context, todolistID int64, opts *TodoListOptions) (result *TodoListResult, err error)
- func (s *TodosService) Reposition(ctx context.Context, todoID int64, position int) (err error)
- func (s *TodosService) Trash(ctx context.Context, todoID int64) (err error)
- func (s *TodosService) Uncomplete(ctx context.Context, todoID int64) (err error)
- func (s *TodosService) Update(ctx context.Context, todoID int64, req *UpdateTodoRequest) (result *Todo, err error)
- type Todoset
- type TodosetsService
- type TokenProvider
- type Tool
- type ToolsService
- func (s *ToolsService) Create(ctx context.Context, sourceToolID int64) (result *Tool, err error)
- func (s *ToolsService) Delete(ctx context.Context, toolID int64) (err error)
- func (s *ToolsService) Disable(ctx context.Context, toolID int64) (err error)
- func (s *ToolsService) Enable(ctx context.Context, toolID int64) (err error)
- func (s *ToolsService) Get(ctx context.Context, toolID int64) (result *Tool, err error)
- func (s *ToolsService) Reposition(ctx context.Context, toolID int64, position int) (err error)
- func (s *ToolsService) Update(ctx context.Context, toolID int64, title string) (result *Tool, err error)
- type UpcomingScheduleResponse
- type UpdateAnswerRequest
- type UpdateCardRequest
- type UpdateChatbotRequest
- type UpdateColumnRequest
- type UpdateCommentRequest
- type UpdateDocumentRequest
- type UpdateMarkerRequest
- type UpdateMessageRequest
- type UpdateMessageTypeRequest
- type UpdateProjectAccessRequest
- type UpdateProjectAccessResponse
- type UpdateProjectRequest
- type UpdateQuestionRequest
- type UpdateScheduleEntryRequest
- type UpdateScheduleSettingsRequest
- type UpdateStepRequest
- type UpdateSubscriptionRequest
- type UpdateTemplateRequest
- type UpdateTimesheetEntryRequest
- type UpdateTodoRequest
- type UpdateTodolistGroupRequest
- type UpdateTodolistRequest
- type UpdateToolRequest
- type UpdateUploadRequest
- type UpdateVaultRequest
- type UpdateWebhookRequest
- type Upload
- type UploadListOptions
- type UploadListResult
- type UploadsService
- func (s *UploadsService) Create(ctx context.Context, vaultID int64, req *CreateUploadRequest) (result *Upload, err error)
- func (s *UploadsService) Download(ctx context.Context, uploadID int64) (result *DownloadResult, err error)
- func (s *UploadsService) Get(ctx context.Context, uploadID int64) (result *Upload, err error)
- func (s *UploadsService) List(ctx context.Context, vaultID int64, opts *UploadListOptions) (result *UploadListResult, err error)
- func (s *UploadsService) ListVersions(ctx context.Context, uploadID int64) (result []Upload, err error)
- func (s *UploadsService) Trash(ctx context.Context, uploadID int64) (err error)
- func (s *UploadsService) Update(ctx context.Context, uploadID int64, req *UpdateUploadRequest) (result *Upload, err error)
- type UpstreamRef
- type Vault
- type VaultListOptions
- type VaultListResult
- type VaultsService
- func (s *VaultsService) Create(ctx context.Context, vaultID int64, req *CreateVaultRequest) (result *Vault, err error)
- func (s *VaultsService) Get(ctx context.Context, vaultID int64) (result *Vault, err error)
- func (s *VaultsService) List(ctx context.Context, vaultID int64, opts *VaultListOptions) (result *VaultListResult, err error)
- func (s *VaultsService) Update(ctx context.Context, vaultID int64, req *UpdateVaultRequest) (result *Vault, err error)
- type Webhook
- type WebhookCopy
- type WebhookCopyBucket
- type WebhookDelivery
- type WebhookDeliveryRequest
- type WebhookDeliveryResponse
- type WebhookEvent
- type WebhookEventBucket
- type WebhookEventCompany
- type WebhookEventHandler
- type WebhookEventParent
- type WebhookEventPerson
- type WebhookEventRecording
- type WebhookListResult
- type WebhookMiddleware
- type WebhookReceiver
- func (r *WebhookReceiver) HandleRequest(body []byte, getHeader func(string) string) (*WebhookEvent, error)
- func (r *WebhookReceiver) On(pattern string, handler WebhookEventHandler)
- func (r *WebhookReceiver) OnAny(handler WebhookEventHandler)
- func (r *WebhookReceiver) ServeHTTP(w http.ResponseWriter, req *http.Request)
- func (r *WebhookReceiver) Use(middleware WebhookMiddleware)
- type WebhookReceiverConfig
- type WebhookVerificationError
- type WebhooksService
- func (s *WebhooksService) Create(ctx context.Context, bucketID int64, req *CreateWebhookRequest) (result *Webhook, err error)
- func (s *WebhooksService) Delete(ctx context.Context, webhookID int64) (err error)
- func (s *WebhooksService) Get(ctx context.Context, webhookID int64) (result *Webhook, err error)
- func (s *WebhooksService) List(ctx context.Context, bucketID int64) (result *WebhookListResult, err error)
- func (s *WebhooksService) Update(ctx context.Context, webhookID int64, req *UpdateWebhookRequest) (result *Webhook, err error)
Examples ¶
- Package (ErrorHandling)
- AccountClient.GetAll
- CampfiresService.CreateLine
- CommentsService.Create
- DefaultConfig
- MessagesService.Create
- NewClient (Oauth)
- NewClient (Options)
- NewClient (StaticToken)
- PeopleService.List
- ProjectsService.Create
- ProjectsService.List
- ProjectsService.List (Archived)
- SearchService.Search
- SearchService.Search (Sorted)
- TodosService.Complete
- TodosService.Create
- TodosService.List
- WebhooksService.Create
Constants ¶
const ( // LineContentTypePlain sends the line as plain text (the default when omitted). LineContentTypePlain = "text/plain" // LineContentTypeHTML sends the line as rich HTML content. LineContentTypeHTML = "text/html" )
Line content type constants for campfire messages.
const ( CodeUsage = "usage" CodeNotFound = "not_found" CodeAuth = "auth_required" CodeForbidden = "forbidden" CodeRateLimit = "rate_limit" CodeNetwork = "network" CodeAPI = "api_error" CodeValidation = "validation" CodeAmbiguous = "ambiguous" )
Error codes for API responses.
const ( ExitOK = 0 // Success ExitUsage = 1 // Invalid arguments or flags ExitNotFound = 2 // Resource not found ExitAuth = 3 // Not authenticated ExitForbidden = 4 // Access denied (scope issue) ExitRateLimit = 5 // Rate limited (429) ExitNetwork = 6 // Connection/DNS/timeout error ExitAPI = 7 // Server returned error ExitAmbiguous = 8 // Multiple matches for name ExitValidation = 9 // Validation error (422) )
Exit codes for CLI tools.
const ( DefaultMaxRetries = 3 DefaultBaseDelay = 1 * time.Second DefaultMaxJitter = 100 * time.Millisecond DefaultTimeout = 30 * time.Second DefaultMaxPages = 10000 )
Default values for HTTP client configuration. These can be overridden using functional options.
const ( // MaxResponseBodyBytes is the maximum size for successful API response bodies (50 MB). MaxResponseBodyBytes int64 = 50 * 1024 * 1024 // MaxErrorBodyBytes is the maximum size for error response bodies (1 MB). MaxErrorBodyBytes int64 = 1 * 1024 * 1024 // MaxErrorMessageBytes is the maximum length for error messages included in errors (500 bytes). MaxErrorMessageBytes = 500 )
Response body size limits.
const ( WebhookTypeCheckinReply = "Checkin::Reply" WebhookTypeCloudFile = "CloudFile" WebhookTypeComment = "Comment" WebhookTypeDocument = "Document" WebhookTypeForwardReply = "Forward::Reply" WebhookTypeGoogleDocument = "GoogleDocument" WebhookTypeInboxForward = "Inbox::Forward" WebhookTypeMessage = "Message" WebhookTypeQuestion = "Question" WebhookTypeQuestionAnswer = "Question::Answer" WebhookTypeScheduleEntry = "Schedule::Entry" WebhookTypeTodo = "Todo" WebhookTypeTodolist = "Todolist" WebhookTypeTodolistGroup = "Todolist::Group" WebhookTypeUpload = "Upload" WebhookTypeVault = "Vault" )
Known webhook recording types (convenience constants, not exhaustive).
const APIVersion = "2026-01-26"
APIVersion is the Basecamp API version this SDK targets.
const DefaultCommentLimit = 100
DefaultCommentLimit is the default number of comments to return when no limit is specified.
const DefaultEventLimit = 100
DefaultEventLimit is the default number of events to return when no limit is specified.
const DefaultMessageLimit = 100
DefaultMessageLimit is the default number of messages to return when no limit is specified.
const DefaultRecordingLimit = 100
DefaultRecordingLimit is the default number of recordings to return when no limit is specified.
const DefaultTodoLimit = 100
DefaultTodoLimit is the default number of todos to return when no limit is specified.
const DefaultUserAgent = "basecamp-sdk-go/" + Version + " (api:" + APIVersion + ")"
DefaultUserAgent is the default User-Agent header value.
const Version = "0.3.0"
Version is the current version of the Basecamp Go SDK.
Variables ¶
var ( // ErrCircuitOpen is returned when the circuit breaker is open. ErrCircuitOpen = errors.New("circuit breaker is open") // ErrBulkheadFull is returned when the bulkhead has no available slots. ErrBulkheadFull = errors.New("bulkhead is full") // ErrRateLimited is returned when the rate limiter rejects a request. ErrRateLimited = errors.New("rate limit exceeded") )
Resilience errors for circuit breaker, bulkhead, and rate limiting.
var DateOf = types.DateOf
DateOf returns the Date portion of a time.Time.
var ParseDate = types.ParseDate
ParseDate parses a string in YYYY-MM-DD format.
var Today = types.Today
Today returns today's date in the local timezone.
Functions ¶
func ComputeWebhookSignature ¶
ComputeWebhookSignature computes the HMAC-SHA256 signature for a webhook payload.
func ExitCodeFor ¶
ExitCodeFor returns the exit code for a given error code.
func NormalizeBaseURL ¶
NormalizeBaseURL ensures consistent URL format (no trailing slash).
func ParseEventKind ¶
ParseEventKind splits a webhook event kind string into its type and action components. For example, "todo_created" returns ("todo", "created"). For compound types like "question_answer_created", it returns ("question_answer", "created").
func RedactHeaders ¶
RedactHeaders returns a copy of the headers with sensitive values replaced by "[REDACTED]". This is useful for safely logging HTTP requests and responses without exposing tokens.
The following headers are redacted:
- Authorization
- Cookie
- Set-Cookie
- X-CSRF-Token
Example:
safeHeaders := basecamp.RedactHeaders(req.Header)
logger.Debug("request", "headers", safeHeaders)
func RequireSecureEndpoint ¶
RequireSecureEndpoint validates that an endpoint URL is secure. Secure means HTTPS, or localhost (including .localhost TLD per RFC 6761) which is trusted for local development.
func VerifyWebhookSignature ¶
VerifyWebhookSignature checks that the given payload matches the HMAC-SHA256 signature. Returns false if secret or signature is empty.
Types ¶
type APIProvenance ¶
type APIProvenance struct {
BC3 UpstreamRef `json:"bc3"`
BC3API UpstreamRef `json:"bc3_api"`
}
APIProvenance describes which upstream API revisions the SDK was built against.
func Provenance ¶
func Provenance() APIProvenance
Provenance returns the upstream API revisions this SDK was built against.
type AccountClient ¶
type AccountClient struct {
// contains filtered or unexported fields
}
AccountClient is an HTTP client bound to a specific Basecamp account. Create an AccountClient using Client.ForAccount(accountID). AccountClient is safe for concurrent use.
The Basecamp API requires an account ID in the URL path (e.g., https://3.basecampapi.com/12345/projects.json). This SDK passes the account ID as a path parameter to each generated client operation, matching the OpenAPI spec's /{accountId}/... path structure.
AccountClient shares the parent Client's generated API client and HTTP resources. Creating multiple AccountClients via ForAccount is lightweight.
func (*AccountClient) AccountID ¶
func (ac *AccountClient) AccountID() string
AccountID returns the account ID this client is bound to.
func (*AccountClient) Attachments ¶
func (ac *AccountClient) Attachments() *AttachmentsService
Attachments returns the AttachmentsService for file upload operations.
func (*AccountClient) Boosts ¶
func (ac *AccountClient) Boosts() *BoostsService
Boosts returns the BoostsService for boost (emoji reaction) operations.
func (*AccountClient) Campfires ¶
func (ac *AccountClient) Campfires() *CampfiresService
Campfires returns the CampfiresService for campfire chat operations.
func (*AccountClient) CardColumns ¶
func (ac *AccountClient) CardColumns() *CardColumnsService
CardColumns returns the CardColumnsService for card column operations.
func (*AccountClient) CardSteps ¶
func (ac *AccountClient) CardSteps() *CardStepsService
CardSteps returns the CardStepsService for card step operations.
func (*AccountClient) CardTables ¶
func (ac *AccountClient) CardTables() *CardTablesService
CardTables returns the CardTablesService for card table operations.
func (*AccountClient) Cards ¶
func (ac *AccountClient) Cards() *CardsService
Cards returns the CardsService for card operations.
func (*AccountClient) Checkins ¶
func (ac *AccountClient) Checkins() *CheckinsService
Checkins returns the CheckinsService for automatic check-in operations.
func (*AccountClient) ClientApprovals ¶
func (ac *AccountClient) ClientApprovals() *ClientApprovalsService
ClientApprovals returns the ClientApprovalsService for client approval operations.
func (*AccountClient) ClientCorrespondences ¶
func (ac *AccountClient) ClientCorrespondences() *ClientCorrespondencesService
ClientCorrespondences returns the ClientCorrespondencesService for client correspondence operations.
func (*AccountClient) ClientReplies ¶
func (ac *AccountClient) ClientReplies() *ClientRepliesService
ClientReplies returns the ClientRepliesService for client reply operations.
func (*AccountClient) Comments ¶
func (ac *AccountClient) Comments() *CommentsService
Comments returns the CommentsService for comment operations.
func (*AccountClient) Documents ¶
func (ac *AccountClient) Documents() *DocumentsService
Documents returns the DocumentsService for document operations.
func (*AccountClient) Events ¶
func (ac *AccountClient) Events() *EventsService
Events returns the EventsService for event operations.
func (*AccountClient) Forwards ¶
func (ac *AccountClient) Forwards() *ForwardsService
Forwards returns the ForwardsService for email forward operations.
func (*AccountClient) GetAll ¶
func (ac *AccountClient) GetAll(ctx context.Context, path string) ([]json.RawMessage, error)
GetAll fetches all pages for an account-scoped paginated resource.
Example ¶
package main
import (
"context"
"fmt"
"log"
"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)
ctx := context.Background()
account := client.ForAccount("12345")
// GetAll automatically handles pagination for account-scoped resources
results, err := account.GetAll(ctx, "/projects.json")
if err != nil {
log.Fatal(err)
}
fmt.Printf("Fetched %d projects across all pages\n", len(results))
}
Output:
func (*AccountClient) GetAllWithLimit ¶
func (ac *AccountClient) GetAllWithLimit(ctx context.Context, path string, limit int) ([]json.RawMessage, error)
GetAllWithLimit fetches pages for an account-scoped paginated resource up to a limit. If limit is 0, it fetches all pages (same as GetAll). If limit > 0, it stops after collecting at least limit items.
func (*AccountClient) Lineup ¶
func (ac *AccountClient) Lineup() *LineupService
Lineup returns the LineupService for lineup marker operations.
func (*AccountClient) MessageBoards ¶
func (ac *AccountClient) MessageBoards() *MessageBoardsService
MessageBoards returns the MessageBoardsService for message board operations.
func (*AccountClient) MessageTypes ¶
func (ac *AccountClient) MessageTypes() *MessageTypesService
MessageTypes returns the MessageTypesService for message type operations.
func (*AccountClient) Messages ¶
func (ac *AccountClient) Messages() *MessagesService
Messages returns the MessagesService for message operations.
func (*AccountClient) People ¶
func (ac *AccountClient) People() *PeopleService
People returns the PeopleService for people operations.
func (*AccountClient) Projects ¶
func (ac *AccountClient) Projects() *ProjectsService
Projects returns the ProjectsService for project operations.
func (*AccountClient) Recordings ¶
func (ac *AccountClient) Recordings() *RecordingsService
Recordings returns the RecordingsService for recording operations.
func (*AccountClient) Reports ¶
func (ac *AccountClient) Reports() *ReportsService
Reports returns the ReportsService for reports operations.
func (*AccountClient) Schedules ¶
func (ac *AccountClient) Schedules() *SchedulesService
Schedules returns the SchedulesService for schedule operations.
func (*AccountClient) Search ¶
func (ac *AccountClient) Search() *SearchService
Search returns the SearchService for search operations.
func (*AccountClient) Subscriptions ¶
func (ac *AccountClient) Subscriptions() *SubscriptionsService
Subscriptions returns the SubscriptionsService for subscription operations.
func (*AccountClient) Templates ¶
func (ac *AccountClient) Templates() *TemplatesService
Templates returns the TemplatesService for template operations.
func (*AccountClient) Timeline ¶
func (ac *AccountClient) Timeline() *TimelineService
Timeline returns the TimelineService for timeline and progress operations.
func (*AccountClient) Timesheet ¶
func (ac *AccountClient) Timesheet() *TimesheetService
Timesheet returns the TimesheetService for timesheet report operations.
func (*AccountClient) TodolistGroups ¶
func (ac *AccountClient) TodolistGroups() *TodolistGroupsService
TodolistGroups returns the TodolistGroupsService for todolist group operations.
func (*AccountClient) Todolists ¶
func (ac *AccountClient) Todolists() *TodolistsService
Todolists returns the TodolistsService for todolist operations.
func (*AccountClient) Todos ¶
func (ac *AccountClient) Todos() *TodosService
Todos returns the TodosService for todo operations.
func (*AccountClient) Todosets ¶
func (ac *AccountClient) Todosets() *TodosetsService
Todosets returns the TodosetsService for todoset operations.
func (*AccountClient) Tools ¶
func (ac *AccountClient) Tools() *ToolsService
Tools returns the ToolsService for dock tool operations.
func (*AccountClient) Uploads ¶
func (ac *AccountClient) Uploads() *UploadsService
Uploads returns the UploadsService for upload (file) operations.
func (*AccountClient) Vaults ¶
func (ac *AccountClient) Vaults() *VaultsService
Vaults returns the VaultsService for vault (folder) operations.
func (*AccountClient) Webhooks ¶
func (ac *AccountClient) Webhooks() *WebhooksService
Webhooks returns the WebhooksService for webhook operations.
type AnswerListOptions ¶
type AnswerListOptions struct {
// Limit is the maximum number of answers to return.
// If 0 (default), returns all answers. Use a positive value to cap results.
Limit int
// Page, if non-zero, disables pagination and returns only the first page.
// NOTE: The page number itself is not yet honored due to OpenAPI client
// limitations. Use 0 to paginate through all results up to Limit.
Page int
}
AnswerListOptions specifies options for listing answers.
type AnswerListResult ¶
type AnswerListResult struct {
// Answers is the list of answers returned.
Answers []QuestionAnswer
// Meta contains pagination metadata (total count, etc.).
Meta ListMeta
}
AnswerListResult contains the results from listing answers.
type Assignable ¶
type Assignable struct {
ID int64 `json:"id"`
Title string `json:"title"`
Type string `json:"type"`
URL string `json:"url"`
AppURL string `json:"app_url"`
Bucket *Bucket `json:"bucket,omitempty"`
Parent *Parent `json:"parent,omitempty"`
DueOn string `json:"due_on,omitempty"`
StartsOn string `json:"starts_on,omitempty"`
Assignees []Person `json:"assignees,omitempty"`
}
Assignable represents an assignable item (todo or schedule entry).
type AssignedTodosOptions ¶
type AssignedTodosOptions struct {
// GroupBy groups results by "bucket" or "date".
GroupBy string
}
AssignedTodosOptions specifies options for GetAssignedTodos.
type AssignedTodosResponse ¶
type AssignedTodosResponse struct {
Person *Person `json:"person"`
GroupedBy string `json:"grouped_by"`
Todos []Todo `json:"todos"`
}
AssignedTodosResponse contains the assigned todos for a person.
type AttachmentResponse ¶
type AttachmentResponse struct {
AttachableSGID string `json:"attachable_sgid"`
}
AttachmentResponse represents the response from creating an attachment.
type AttachmentsService ¶
type AttachmentsService struct {
// contains filtered or unexported fields
}
AttachmentsService handles attachment upload operations.
func NewAttachmentsService ¶
func NewAttachmentsService(client *AccountClient) *AttachmentsService
NewAttachmentsService creates a new AttachmentsService.
func (*AttachmentsService) Create ¶
func (s *AttachmentsService) Create(ctx context.Context, filename, contentType string, data io.Reader) (result *AttachmentResponse, err error)
Create uploads a file and returns an attachable_sgid for embedding in rich text. filename is the name of the file, contentType is the MIME type (e.g., "image/png"), and data is the raw file content.
type AuthManager ¶
type AuthManager struct {
// contains filtered or unexported fields
}
AuthManager handles OAuth token management.
func NewAuthManager ¶
func NewAuthManager(cfg *Config, httpClient *http.Client) *AuthManager
NewAuthManager creates a new auth manager.
func NewAuthManagerWithStore ¶
func NewAuthManagerWithStore(cfg *Config, httpClient *http.Client, store *CredentialStore) *AuthManager
NewAuthManagerWithStore creates an auth manager with a custom credential store.
func (*AuthManager) AccessToken ¶
func (m *AuthManager) AccessToken(ctx context.Context) (string, error)
AccessToken returns a valid access token, refreshing if needed. If BASECAMP_TOKEN env var is set, it's used directly without OAuth.
func (*AuthManager) GetUserID ¶
func (m *AuthManager) GetUserID() string
GetUserID returns the stored user ID.
func (*AuthManager) IsAuthenticated ¶
func (m *AuthManager) IsAuthenticated() bool
IsAuthenticated checks if there are valid credentials.
func (*AuthManager) Logout ¶
func (m *AuthManager) Logout() error
Logout removes stored credentials.
func (*AuthManager) Refresh ¶
func (m *AuthManager) Refresh(ctx context.Context) error
Refresh forces a token refresh.
func (*AuthManager) SetUserID ¶
func (m *AuthManager) SetUserID(userID string) error
SetUserID stores the user ID.
func (*AuthManager) Store ¶
func (m *AuthManager) Store() *CredentialStore
Store returns the credential store.
type AuthStrategy ¶
type AuthStrategy interface {
// Authenticate applies authentication to the given HTTP request.
Authenticate(ctx context.Context, req *http.Request) error
}
AuthStrategy controls how authentication is applied to HTTP requests. The default strategy is BearerAuth, which uses a TokenProvider to set the Authorization header with a Bearer token.
Custom strategies can implement alternative auth schemes such as cookie-based auth, API keys, or mutual TLS.
type AuthorizationInfo ¶
type AuthorizationInfo struct {
ExpiresAt FlexTime `json:"expires_at"`
Identity Identity `json:"identity"`
Accounts []AuthorizedAccount `json:"accounts"`
}
AuthorizationInfo contains the complete authorization response.
type AuthorizationService ¶
type AuthorizationService struct {
// contains filtered or unexported fields
}
AuthorizationService handles authorization operations.
func NewAuthorizationService ¶
func NewAuthorizationService(client *Client) *AuthorizationService
NewAuthorizationService creates a new AuthorizationService.
func (*AuthorizationService) GetInfo ¶
func (s *AuthorizationService) GetInfo(ctx context.Context, opts *GetInfoOptions) (result *AuthorizationInfo, err error)
GetInfo fetches authorization information for the current access token. This includes the user's identity and list of authorized accounts.
type AuthorizedAccount ¶
type AuthorizedAccount struct {
ID int64 `json:"id"`
Name string `json:"name"`
Product string `json:"product"`
HREF string `json:"href"`
AppHREF string `json:"app_href"`
Hidden bool `json:"hidden,omitempty"`
Expired bool `json:"expired,omitempty"`
Featured bool `json:"featured,omitempty"`
}
AuthorizedAccount represents a Basecamp account the user has access to.
type BearerAuth ¶
type BearerAuth struct {
TokenProvider TokenProvider
}
BearerAuth implements AuthStrategy using OAuth Bearer tokens. This is the default authentication strategy.
func (*BearerAuth) Authenticate ¶
Authenticate sets the Authorization header with a Bearer token.
type Boost ¶
type Boost struct {
ID int64 `json:"id"`
Content string `json:"content"`
CreatedAt time.Time `json:"created_at"`
Booster *Person `json:"booster,omitempty"`
Recording *Parent `json:"recording,omitempty"`
}
Boost represents a Basecamp boost (emoji reaction) on a recording.
type BoostListResult ¶
type BoostListResult struct {
// Boosts is the list of boosts returned.
Boosts []Boost
// Meta contains pagination metadata (total count, etc.).
Meta ListMeta
}
BoostListResult contains the results from listing boosts.
type BoostsService ¶
type BoostsService struct {
// contains filtered or unexported fields
}
BoostsService handles boost operations.
func NewBoostsService ¶
func NewBoostsService(client *AccountClient) *BoostsService
NewBoostsService creates a new BoostsService.
func (*BoostsService) CreateEvent ¶
func (s *BoostsService) CreateEvent(ctx context.Context, recordingID, eventID int64, content string) (result *Boost, err error)
CreateEvent creates a boost on a specific event within a recording. content is the emoji content for the boost. Returns the created boost.
func (*BoostsService) CreateRecording ¶
func (s *BoostsService) CreateRecording(ctx context.Context, recordingID int64, content string) (result *Boost, err error)
CreateRecording creates a boost on a recording. content is the emoji content for the boost. Returns the created boost.
func (*BoostsService) Delete ¶
func (s *BoostsService) Delete(ctx context.Context, boostID int64) (err error)
Delete deletes a boost.
func (*BoostsService) ListEvent ¶
func (s *BoostsService) ListEvent(ctx context.Context, recordingID, eventID int64) (result *BoostListResult, err error)
ListEvent returns all boosts on a specific event within a recording.
The returned BoostListResult includes pagination metadata (TotalCount from X-Total-Count header) when available.
func (*BoostsService) ListRecording ¶
func (s *BoostsService) ListRecording(ctx context.Context, recordingID int64) (result *BoostListResult, err error)
ListRecording returns all boosts on a recording.
The returned BoostListResult includes pagination metadata (TotalCount from X-Total-Count header) when available.
type BulkheadConfig ¶
type BulkheadConfig struct {
// MaxConcurrent is the maximum number of parallel requests.
// Default: 10
MaxConcurrent int
// MaxWait is the maximum time to wait for a slot.
// If zero, requests are rejected immediately when the bulkhead is full.
// Default: 5s
MaxWait time.Duration
}
BulkheadConfig configures concurrency limiting.
func DefaultBulkheadConfig ¶
func DefaultBulkheadConfig() *BulkheadConfig
DefaultBulkheadConfig returns production-ready defaults.
type Cache ¶
type Cache struct {
// contains filtered or unexported fields
}
Cache provides ETag-based HTTP caching.
func (*Cache) Invalidate ¶
Invalidate removes cached data for a specific key.
type Campfire ¶
type Campfire struct {
ID int64 `json:"id"`
Status string `json:"status"`
VisibleToClients bool `json:"visible_to_clients"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Title string `json:"title"`
InheritsStatus bool `json:"inherits_status"`
Type string `json:"type"`
URL string `json:"url"`
AppURL string `json:"app_url"`
LinesURL string `json:"lines_url"`
FilesURL string `json:"files_url,omitempty"`
Bucket *Bucket `json:"bucket,omitempty"`
Creator *Person `json:"creator,omitempty"`
BoostsCount int `json:"boosts_count,omitempty"`
}
Campfire represents a Basecamp Campfire (real-time chat room).
type CampfireLine ¶
type CampfireLine struct {
ID int64 `json:"id"`
Status string `json:"status"`
VisibleToClients bool `json:"visible_to_clients"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Title string `json:"title"`
InheritsStatus bool `json:"inherits_status"`
Type string `json:"type"`
URL string `json:"url"`
AppURL string `json:"app_url"`
Content string `json:"content,omitempty"`
Attachments []CampfireLineAttachment `json:"attachments,omitempty"`
Parent *Parent `json:"parent,omitempty"`
Bucket *Bucket `json:"bucket,omitempty"`
Creator *Person `json:"creator,omitempty"`
BoostsCount int `json:"boosts_count,omitempty"`
}
CampfireLine represents a message in a Campfire chat.
type CampfireLineAttachment ¶ added in v0.2.3
type CampfireLineAttachment struct {
Title string `json:"title,omitempty"`
URL string `json:"url,omitempty"`
Filename string `json:"filename,omitempty"`
ContentType string `json:"content_type,omitempty"`
ByteSize int64 `json:"byte_size,omitempty"`
DownloadURL string `json:"download_url,omitempty"`
}
CampfireLineAttachment represents a file attached to an upload line.
type CampfireLineListResult ¶
type CampfireLineListResult struct {
// Lines is the list of campfire lines returned.
Lines []CampfireLine
// Meta contains pagination metadata (total count, etc.).
Meta ListMeta
}
CampfireLineListResult contains the results from listing campfire lines.
type CampfireListResult ¶
type CampfireListResult struct {
// Campfires is the list of campfires returned.
Campfires []Campfire
// Meta contains pagination metadata (total count, etc.).
Meta ListMeta
}
CampfireListResult contains the results from listing campfires.
type CampfiresService ¶
type CampfiresService struct {
// contains filtered or unexported fields
}
CampfiresService handles campfire operations.
func NewCampfiresService ¶
func NewCampfiresService(client *AccountClient) *CampfiresService
NewCampfiresService creates a new CampfiresService.
func (*CampfiresService) CreateChatbot ¶
func (s *CampfiresService) CreateChatbot(ctx context.Context, campfireID int64, req *CreateChatbotRequest) (result *Chatbot, err error)
CreateChatbot creates a new chatbot for a campfire. Note: Chatbots are account-wide and can only be managed by administrators. Returns the created chatbot with its lines_url for posting.
func (*CampfiresService) CreateLine ¶
func (s *CampfiresService) CreateLine(ctx context.Context, campfireID int64, content string, opts ...*CreateLineOptions) (result *CampfireLine, err error)
CreateLine creates a new line (message) in a campfire. opts is optional; pass a CreateLineOptions to set content_type (text/html or text/plain). Returns the created line.
Example ¶
package main
import (
"context"
"fmt"
"log"
"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)
ctx := context.Background()
campfireID := int64(789012)
// Post a message to a campfire (chat)
line, err := client.ForAccount("12345").Campfires().CreateLine(ctx, campfireID, "Hello team!")
if err != nil {
log.Fatal(err)
}
fmt.Printf("Message posted: %s\n", line.Content)
}
Output:
func (*CampfiresService) CreateUpload ¶ added in v0.2.3
func (s *CampfiresService) CreateUpload(ctx context.Context, campfireID int64, filename, contentType string, data io.Reader) (result *CampfireLine, err error)
CreateUpload uploads a file to a campfire. filename is the name of the file, contentType is the MIME type (e.g., "image/png"), and data is the raw file content. Returns the created upload line.
func (*CampfiresService) DeleteChatbot ¶
func (s *CampfiresService) DeleteChatbot(ctx context.Context, campfireID, chatbotID int64) (err error)
DeleteChatbot deletes a chatbot. Note: Deleting a chatbot removes it from the entire account.
func (*CampfiresService) DeleteLine ¶
func (s *CampfiresService) DeleteLine(ctx context.Context, campfireID, lineID int64) (err error)
DeleteLine deletes a line (message) from a campfire.
func (*CampfiresService) GetChatbot ¶
func (s *CampfiresService) GetChatbot(ctx context.Context, campfireID, chatbotID int64) (result *Chatbot, err error)
GetChatbot returns a chatbot by ID.
func (*CampfiresService) GetLine ¶
func (s *CampfiresService) GetLine(ctx context.Context, campfireID, lineID int64) (result *CampfireLine, err error)
GetLine returns a single line (message) from a campfire.
func (*CampfiresService) List ¶
func (s *CampfiresService) List(ctx context.Context) (result *CampfireListResult, err error)
List returns all campfires across the account.
The returned CampfireListResult includes pagination metadata (TotalCount from X-Total-Count header) when available.
func (*CampfiresService) ListChatbots ¶
func (s *CampfiresService) ListChatbots(ctx context.Context, campfireID int64) (result []Chatbot, err error)
ListChatbots returns all chatbots for a campfire. Note: Chatbots are account-wide but with basecamp-specific callback URLs.
func (*CampfiresService) ListLines ¶
func (s *CampfiresService) ListLines(ctx context.Context, campfireID int64) (result *CampfireLineListResult, err error)
ListLines returns all lines (messages) in a campfire.
The returned CampfireLineListResult includes pagination metadata (TotalCount from X-Total-Count header) when available.
func (*CampfiresService) ListUploads ¶ added in v0.2.3
func (s *CampfiresService) ListUploads(ctx context.Context, campfireID int64) (result *CampfireLineListResult, err error)
ListUploads returns all uploaded files in a campfire.
The returned CampfireLineListResult includes pagination metadata (TotalCount from X-Total-Count header) when available.
func (*CampfiresService) UpdateChatbot ¶
func (s *CampfiresService) UpdateChatbot(ctx context.Context, campfireID, chatbotID int64, req *UpdateChatbotRequest) (result *Chatbot, err error)
UpdateChatbot updates an existing chatbot. Note: Updates to chatbots are account-wide. Returns the updated chatbot.
type Card ¶
type Card struct {
ID int64 `json:"id"`
Status string `json:"status"`
VisibleToClients bool `json:"visible_to_clients"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Title string `json:"title"`
InheritsStatus bool `json:"inherits_status"`
Type string `json:"type"`
URL string `json:"url"`
AppURL string `json:"app_url"`
BookmarkURL string `json:"bookmark_url"`
SubscriptionURL string `json:"subscription_url,omitempty"`
Position int `json:"position"`
Content string `json:"content,omitempty"`
Description string `json:"description,omitempty"`
DueOn string `json:"due_on,omitempty"`
Completed bool `json:"completed"`
CompletedAt *time.Time `json:"completed_at,omitempty"`
CommentsCount int `json:"comments_count"`
BoostsCount int `json:"boosts_count"`
CommentsURL string `json:"comments_url,omitempty"`
CommentCount int `json:"comment_count"`
CompletionURL string `json:"completion_url,omitempty"`
Parent *Parent `json:"parent,omitempty"`
Bucket *Bucket `json:"bucket,omitempty"`
Creator *Person `json:"creator,omitempty"`
Completer *Person `json:"completer,omitempty"`
Assignees []Person `json:"assignees,omitempty"`
CompletionSubscribers []Person `json:"completion_subscribers,omitempty"`
Steps []CardStep `json:"steps,omitempty"`
}
Card represents a card in a card table column.
type CardColumn ¶
type CardColumn struct {
ID int64 `json:"id"`
Status string `json:"status"`
VisibleToClients bool `json:"visible_to_clients"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Title string `json:"title"`
InheritsStatus bool `json:"inherits_status"`
Type string `json:"type"`
URL string `json:"url"`
AppURL string `json:"app_url"`
BookmarkURL string `json:"bookmark_url"`
Position int `json:"position,omitempty"`
Color string `json:"color,omitempty"`
Description string `json:"description,omitempty"`
CardsCount int `json:"cards_count"`
CommentCount int `json:"comment_count"`
CardsURL string `json:"cards_url,omitempty"`
Parent *Parent `json:"parent,omitempty"`
Bucket *Bucket `json:"bucket,omitempty"`
Creator *Person `json:"creator,omitempty"`
Subscribers []Person `json:"subscribers,omitempty"`
}
CardColumn represents a column in a card table.
type CardColumnsService ¶
type CardColumnsService struct {
// contains filtered or unexported fields
}
CardColumnsService handles card column operations.
func NewCardColumnsService ¶
func NewCardColumnsService(client *AccountClient) *CardColumnsService
NewCardColumnsService creates a new CardColumnsService.
func (*CardColumnsService) Create ¶
func (s *CardColumnsService) Create(ctx context.Context, cardTableID int64, req *CreateColumnRequest) (result *CardColumn, err error)
Create creates a new column in a card table. Returns the created column.
func (*CardColumnsService) DisableOnHold ¶
func (s *CardColumnsService) DisableOnHold(ctx context.Context, columnID int64) (result *CardColumn, err error)
DisableOnHold removes the on-hold section from a column. Returns the updated column.
func (*CardColumnsService) EnableOnHold ¶
func (s *CardColumnsService) EnableOnHold(ctx context.Context, columnID int64) (result *CardColumn, err error)
EnableOnHold adds an on-hold section to a column. Returns the updated column.
func (*CardColumnsService) Get ¶
func (s *CardColumnsService) Get(ctx context.Context, columnID int64) (result *CardColumn, err error)
Get returns a column by ID.
func (*CardColumnsService) Move ¶
func (s *CardColumnsService) Move(ctx context.Context, cardTableID int64, req *MoveColumnRequest) (err error)
Move moves a column within a card table.
func (*CardColumnsService) SetColor ¶
func (s *CardColumnsService) SetColor(ctx context.Context, columnID int64, color string) (result *CardColumn, err error)
SetColor sets the color of a column. Valid colors: white, red, orange, yellow, green, blue, aqua, purple, gray, pink, brown. Returns the updated column.
func (*CardColumnsService) Unwatch ¶
func (s *CardColumnsService) Unwatch(ctx context.Context, columnID int64) (err error)
Unwatch unsubscribes the current user from the column. Returns nil on success (204 No Content).
func (*CardColumnsService) Update ¶
func (s *CardColumnsService) Update(ctx context.Context, columnID int64, req *UpdateColumnRequest) (result *CardColumn, err error)
Update updates an existing column. Returns the updated column.
func (*CardColumnsService) Watch ¶
func (s *CardColumnsService) Watch(ctx context.Context, columnID int64) (result *Subscription, err error)
Watch subscribes the current user to the column. Returns the updated subscription information.
type CardListOptions ¶
type CardListOptions struct {
// Limit is the maximum number of cards to return.
// If 0 (default), returns all cards. Use a positive value to cap results.
Limit int
// Page, if non-zero, disables pagination and returns only the first page.
// NOTE: The page number itself is not yet honored due to OpenAPI client
// limitations. Use 0 to paginate through all results up to Limit.
Page int
}
CardListOptions specifies options for listing cards.
type CardListResult ¶
type CardListResult struct {
// Cards is the list of cards returned.
Cards []Card
// Meta contains pagination metadata (total count, etc.).
Meta ListMeta
}
CardListResult contains the results from listing cards.
type CardStep ¶
type CardStep struct {
ID int64 `json:"id"`
Status string `json:"status"`
VisibleToClients bool `json:"visible_to_clients"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Title string `json:"title"`
InheritsStatus bool `json:"inherits_status"`
Type string `json:"type"`
URL string `json:"url"`
AppURL string `json:"app_url"`
BookmarkURL string `json:"bookmark_url"`
Position int `json:"position"`
DueOn string `json:"due_on,omitempty"`
Completed bool `json:"completed"`
CompletedAt *time.Time `json:"completed_at,omitempty"`
Parent *Parent `json:"parent,omitempty"`
Bucket *Bucket `json:"bucket,omitempty"`
Creator *Person `json:"creator,omitempty"`
Completer *Person `json:"completer,omitempty"`
Assignees []Person `json:"assignees,omitempty"`
}
CardStep represents a step (checklist item) on a card.
type CardStepsService ¶
type CardStepsService struct {
// contains filtered or unexported fields
}
CardStepsService handles card step operations.
func NewCardStepsService ¶
func NewCardStepsService(client *AccountClient) *CardStepsService
NewCardStepsService creates a new CardStepsService.
func (*CardStepsService) Complete ¶
func (s *CardStepsService) Complete(ctx context.Context, stepID int64) (result *CardStep, err error)
Complete marks a step as completed. Returns the updated step.
func (*CardStepsService) Create ¶
func (s *CardStepsService) Create(ctx context.Context, cardID int64, req *CreateStepRequest) (result *CardStep, err error)
Create creates a new step on a card. Returns the created step.
func (*CardStepsService) Delete ¶
func (s *CardStepsService) Delete(ctx context.Context, stepID int64) (err error)
Delete deletes a step (moves it to trash).
func (*CardStepsService) Reposition ¶
func (s *CardStepsService) Reposition(ctx context.Context, cardID, stepID int64, position int) (err error)
Reposition changes the position of a step within a card. position is 0-indexed.
func (*CardStepsService) Uncomplete ¶
func (s *CardStepsService) Uncomplete(ctx context.Context, stepID int64) (result *CardStep, err error)
Uncomplete marks a step as incomplete. Returns the updated step.
func (*CardStepsService) Update ¶
func (s *CardStepsService) Update(ctx context.Context, stepID int64, req *UpdateStepRequest) (result *CardStep, err error)
Update updates an existing step. Returns the updated step.
type CardTable ¶
type CardTable struct {
ID int64 `json:"id"`
Status string `json:"status"`
VisibleToClients bool `json:"visible_to_clients"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Title string `json:"title"`
InheritsStatus bool `json:"inherits_status"`
Type string `json:"type"`
URL string `json:"url"`
AppURL string `json:"app_url"`
BookmarkURL string `json:"bookmark_url"`
SubscriptionURL string `json:"subscription_url"`
Bucket *Bucket `json:"bucket,omitempty"`
Creator *Person `json:"creator,omitempty"`
Subscribers []Person `json:"subscribers,omitempty"`
Lists []CardColumn `json:"lists,omitempty"`
}
CardTable represents a Basecamp card table (kanban board).
type CardTablesService ¶
type CardTablesService struct {
// contains filtered or unexported fields
}
CardTablesService handles card table operations.
func NewCardTablesService ¶
func NewCardTablesService(client *AccountClient) *CardTablesService
NewCardTablesService creates a new CardTablesService.
type CardsService ¶
type CardsService struct {
// contains filtered or unexported fields
}
CardsService handles card operations.
func NewCardsService ¶
func NewCardsService(client *AccountClient) *CardsService
NewCardsService creates a new CardsService.
func (*CardsService) Create ¶
func (s *CardsService) Create(ctx context.Context, columnID int64, req *CreateCardRequest) (result *Card, err error)
Create creates a new card in a column. Returns the created card.
func (*CardsService) List ¶
func (s *CardsService) List(ctx context.Context, columnID int64, opts *CardListOptions) (result *CardListResult, err error)
List returns all cards in a column.
By default, returns all cards (no limit). Use Limit to cap results.
Pagination options:
- Limit: maximum number of cards to return (0 = all)
- Page: if non-zero, disables pagination and returns first page only
The returned CardListResult includes pagination metadata (TotalCount from X-Total-Count header) when available.
func (*CardsService) Move ¶
func (s *CardsService) Move(ctx context.Context, cardID, columnID int64) (err error)
Move moves a card to a different column.
func (*CardsService) Trash ¶
func (s *CardsService) Trash(ctx context.Context, cardID int64) (err error)
Trash moves a card to the trash. Trashed cards can be recovered from the trash.
func (*CardsService) Update ¶
func (s *CardsService) Update(ctx context.Context, cardID int64, req *UpdateCardRequest) (result *Card, err error)
Update updates an existing card. Returns the updated card.
type ChainHooks ¶
type ChainHooks struct {
// contains filtered or unexported fields
}
ChainHooks combines multiple Hooks implementations. Start events are called in order, end events are called in reverse order. This allows proper nesting of spans/traces.
func (*ChainHooks) OnOperationEnd ¶
func (c *ChainHooks) OnOperationEnd(ctx context.Context, op OperationInfo, err error, duration time.Duration)
OnOperationEnd calls all hooks in reverse order.
func (*ChainHooks) OnOperationGate ¶
func (c *ChainHooks) OnOperationGate(ctx context.Context, op OperationInfo) (context.Context, error)
OnOperationGate calls the first GatingHooks implementation in the chain. Only ONE gater should exist in a chain (typically resilienceHooks which internally manages circuit breaker, bulkhead, and rate limiter). Returns the context from the gater (which may contain cleanup functions) and any error.
func (*ChainHooks) OnOperationStart ¶
func (c *ChainHooks) OnOperationStart(ctx context.Context, op OperationInfo) context.Context
OnOperationStart calls all hooks in order.
func (*ChainHooks) OnRequestEnd ¶
func (c *ChainHooks) OnRequestEnd(ctx context.Context, info RequestInfo, result RequestResult)
OnRequestEnd calls all hooks in reverse order.
func (*ChainHooks) OnRequestStart ¶
func (c *ChainHooks) OnRequestStart(ctx context.Context, info RequestInfo) context.Context
OnRequestStart calls all hooks in order.
func (*ChainHooks) OnRetry ¶
func (c *ChainHooks) OnRetry(ctx context.Context, info RequestInfo, attempt int, err error)
OnRetry calls all hooks in order.
type Chatbot ¶
type Chatbot struct {
ID int64 `json:"id"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
ServiceName string `json:"service_name"`
CommandURL string `json:"command_url,omitempty"`
URL string `json:"url"`
AppURL string `json:"app_url"`
LinesURL string `json:"lines_url"`
}
Chatbot represents a Basecamp chatbot integration.
type CheckinsService ¶
type CheckinsService struct {
// contains filtered or unexported fields
}
CheckinsService handles automatic check-in operations.
func NewCheckinsService ¶
func NewCheckinsService(client *AccountClient) *CheckinsService
NewCheckinsService creates a new CheckinsService.
func (*CheckinsService) CreateAnswer ¶
func (s *CheckinsService) CreateAnswer(ctx context.Context, questionID int64, req *CreateAnswerRequest) (result *QuestionAnswer, err error)
CreateAnswer creates a new answer for a question. Returns the created answer.
func (*CheckinsService) CreateQuestion ¶
func (s *CheckinsService) CreateQuestion(ctx context.Context, questionnaireID int64, req *CreateQuestionRequest) (result *Question, err error)
CreateQuestion creates a new question in a questionnaire. Returns the created question.
func (*CheckinsService) GetAnswer ¶
func (s *CheckinsService) GetAnswer(ctx context.Context, answerID int64) (result *QuestionAnswer, err error)
GetAnswer returns a question answer by ID.
func (*CheckinsService) GetQuestion ¶
func (s *CheckinsService) GetQuestion(ctx context.Context, questionID int64) (result *Question, err error)
GetQuestion returns a question by ID.
func (*CheckinsService) GetQuestionnaire ¶
func (s *CheckinsService) GetQuestionnaire(ctx context.Context, questionnaireID int64) (result *Questionnaire, err error)
GetQuestionnaire returns a questionnaire by ID.
func (*CheckinsService) ListAnswers ¶
func (s *CheckinsService) ListAnswers(ctx context.Context, questionID int64, opts *AnswerListOptions) (result *AnswerListResult, err error)
ListAnswers returns all answers for a question.
By default, returns all answers (no limit). Use Limit to cap results.
Pagination options:
- Limit: maximum number of answers to return (0 = all)
- Page: if non-zero, disables pagination and returns first page only
The returned AnswerListResult includes pagination metadata (TotalCount from X-Total-Count header) when available.
func (*CheckinsService) ListQuestions ¶
func (s *CheckinsService) ListQuestions(ctx context.Context, questionnaireID int64, opts *QuestionListOptions) (result *QuestionListResult, err error)
ListQuestions returns all questions in a questionnaire.
By default, returns all questions (no limit). Use Limit to cap results.
Pagination options:
- Limit: maximum number of questions to return (0 = all)
- Page: if non-zero, disables pagination and returns first page only
The returned QuestionListResult includes pagination metadata (TotalCount from X-Total-Count header) when available.
func (*CheckinsService) UpdateAnswer ¶
func (s *CheckinsService) UpdateAnswer(ctx context.Context, answerID int64, req *UpdateAnswerRequest) (err error)
UpdateAnswer updates an existing question answer. Returns nil on success (204 No Content).
func (*CheckinsService) UpdateQuestion ¶
func (s *CheckinsService) UpdateQuestion(ctx context.Context, questionID int64, req *UpdateQuestionRequest) (result *Question, err error)
UpdateQuestion updates an existing question. Returns the updated question.
type CircuitBreakerConfig ¶
type CircuitBreakerConfig struct {
// FailureThreshold is the number of failures before the circuit opens.
// Default: 5
FailureThreshold int
// SuccessThreshold is the number of successes to close from half-open.
// Default: 2
SuccessThreshold int
// OpenTimeout is the time before transitioning from open to half-open.
// Default: 30s
OpenTimeout time.Duration
// FailureRateThreshold is the percentage failure rate to trigger opening.
// Only evaluated when SlidingWindowSize requests have been made.
// Default: 50 (meaning 50%)
FailureRateThreshold float64
// SlidingWindowSize is the number of requests to consider for rate calculation.
// Default: 10
SlidingWindowSize int
// Now is a function that returns the current time. Used for testing.
// If nil, time.Now is used.
Now func() time.Time
}
CircuitBreakerConfig configures the circuit breaker.
func DefaultCircuitBreakerConfig ¶
func DefaultCircuitBreakerConfig() *CircuitBreakerConfig
DefaultCircuitBreakerConfig returns production-ready defaults.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is an HTTP client for the Basecamp API. Client holds shared resources and is used to create AccountClient instances for specific Basecamp accounts via the ForAccount method.
Client is safe for concurrent use after construction. Do not modify the Config after the client is in use by multiple goroutines.
func NewClient ¶
func NewClient(cfg *Config, tokenProvider TokenProvider, opts ...ClientOption) *Client
NewClient creates a new API client with spec-driven defaults.
The client automatically:
- Retries failed GET requests with exponential backoff
- Does NOT retry POST/PUT/DELETE on 429/5xx (to avoid duplicating data)
- Retries mutations once after successful 401 token refresh
- Respects Retry-After headers on 429 responses
- Follows pagination via Link headers
Configuration options:
- WithTimeout(d) - Request timeout (default: 30s)
- WithMaxRetries(n) - Max retry attempts for GET (default: 3)
- WithCache(c) - Enable ETag-based caching
- WithTransport(t) - Custom http.RoundTripper
- WithLogger(l) - slog.Logger for debug output
Example (Oauth) ¶
package main
import (
"fmt"
"net/http"
"github.com/basecamp/basecamp-sdk/go/pkg/basecamp"
)
func main() {
// Create a client with OAuth authentication
cfg := basecamp.DefaultConfig()
authMgr := basecamp.NewAuthManager(cfg, http.DefaultClient)
client := basecamp.NewClient(cfg, authMgr)
// Use the client to make API calls
_ = client
fmt.Println("Client created with OAuth")
}
Output: Client created with OAuth
Example (Options) ¶
package main
import (
"fmt"
"log/slog"
"os"
"github.com/basecamp/basecamp-sdk/go/pkg/basecamp"
)
func main() {
// Create a client with custom options
cfg := basecamp.DefaultConfig()
token := &basecamp.StaticTokenProvider{Token: os.Getenv("BASECAMP_TOKEN")}
client := basecamp.NewClient(cfg, token,
basecamp.WithUserAgent("my-app/1.0"),
basecamp.WithLogger(slog.Default()),
)
_ = client
fmt.Println("Client created with options")
}
Output: Client created with options
Example (StaticToken) ¶
package main
import (
"fmt"
"os"
"github.com/basecamp/basecamp-sdk/go/pkg/basecamp"
)
func main() {
// Create a client with a static token (simplest authentication method)
cfg := basecamp.DefaultConfig()
token := &basecamp.StaticTokenProvider{Token: os.Getenv("BASECAMP_TOKEN")}
client := basecamp.NewClient(cfg, token)
// Use the client to make API calls
_ = client
fmt.Println("Client created with static token")
}
Output: Client created with static token
func (*Client) Authorization ¶
func (c *Client) Authorization() *AuthorizationService
Authorization returns the AuthorizationService for authorization operations. This is the only service available directly on Client, as it doesn't require an account context. All other services require an AccountClient via ForAccount.
func (*Client) Config ¶
Config returns a copy of the client configuration.
Modifying the returned Config has no effect on the client. This prevents race conditions from post-construction modification.
func (*Client) FollowPagination ¶
func (c *Client) FollowPagination(ctx context.Context, httpResp *http.Response, firstPageCount, limit int) ([]json.RawMessage, error)
FollowPagination fetches additional pages following Link headers from an HTTP response. This is used after calling the generated client for the first page. The httpResp should be from the generated client's *WithResponse method. firstPageCount is the number of items already collected from the first page. limit is the maximum total items to return (0 = unlimited). Returns raw JSON items from subsequent pages only (first page items are handled by caller).
Request URL requirement: httpResp.Request.URL is required for same-origin validation. If the response has no Request (e.g., manually constructed), pagination returns an error even for absolute Link headers. This fail-closed behavior prevents SSRF and token leakage when the original request origin cannot be verified.
Security: Link headers are resolved against the current page URL and validated for same-origin against the original request to prevent SSRF and token leakage. FollowPagination is the public API — returns items and error only.
func (*Client) ForAccount ¶
func (c *Client) ForAccount(accountID string) *AccountClient
ForAccount returns an AccountClient bound to the specified Basecamp account. The AccountClient shares the parent Client's HTTP transport, token provider, and other resources, but is configured to make API calls for the given account.
The accountID must be a numeric string (e.g., "12345"). ForAccount panics if the accountID is empty or contains non-digit characters.
Example:
client := basecamp.NewClient(cfg, tokenProvider)
account := client.ForAccount("12345")
projects, err := account.Projects().List(ctx, nil)
func (*Client) GetAllWithLimit ¶
func (c *Client) GetAllWithLimit(ctx context.Context, path string, limit int) ([]json.RawMessage, error)
GetAllWithLimit fetches pages for a paginated resource up to a limit. If limit is 0, it fetches all pages (same as GetAll). If limit > 0, it stops after collecting at least limit items.
type ClientApproval ¶
type ClientApproval struct {
ID int64 `json:"id"`
Status string `json:"status"`
VisibleToClients bool `json:"visible_to_clients"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Title string `json:"title"`
InheritsStatus bool `json:"inherits_status"`
Type string `json:"type"`
URL string `json:"url"`
AppURL string `json:"app_url"`
BookmarkURL string `json:"bookmark_url"`
SubscriptionURL string `json:"subscription_url"`
Parent *Parent `json:"parent,omitempty"`
Bucket *Bucket `json:"bucket,omitempty"`
Creator *Person `json:"creator,omitempty"`
Content string `json:"content"`
Subject string `json:"subject"`
DueOn *string `json:"due_on,omitempty"`
RepliesCount int `json:"replies_count"`
RepliesURL string `json:"replies_url"`
ApprovalStatus string `json:"approval_status"`
Approver *Person `json:"approver,omitempty"`
Responses []ClientApprovalResponse `json:"responses,omitempty"`
}
ClientApproval represents a Basecamp client approval request.
type ClientApprovalListResult ¶
type ClientApprovalListResult struct {
// Approvals is the list of client approvals returned.
Approvals []ClientApproval
// Meta contains pagination metadata (total count, etc.).
Meta ListMeta
}
ClientApprovalListResult contains the results from listing client approvals.
type ClientApprovalResponse ¶
type ClientApprovalResponse struct {
ID int64 `json:"id"`
Status string `json:"status"`
VisibleToClients bool `json:"visible_to_clients"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Title string `json:"title"`
InheritsStatus bool `json:"inherits_status"`
Type string `json:"type"`
AppURL string `json:"app_url"`
BookmarkURL string `json:"bookmark_url"`
Parent *Parent `json:"parent,omitempty"`
Bucket *Bucket `json:"bucket,omitempty"`
Creator *Person `json:"creator,omitempty"`
Content string `json:"content"`
Approved bool `json:"approved"`
}
ClientApprovalResponse represents a response to a client approval.
type ClientApprovalsService ¶
type ClientApprovalsService struct {
// contains filtered or unexported fields
}
ClientApprovalsService handles client approval operations.
func NewClientApprovalsService ¶
func NewClientApprovalsService(client *AccountClient) *ClientApprovalsService
NewClientApprovalsService creates a new ClientApprovalsService.
func (*ClientApprovalsService) Get ¶
func (s *ClientApprovalsService) Get(ctx context.Context, approvalID int64) (result *ClientApproval, err error)
Get returns a client approval by ID.
func (*ClientApprovalsService) List ¶
func (s *ClientApprovalsService) List(ctx context.Context) (result *ClientApprovalListResult, err error)
List returns all client approvals in a project.
The returned ClientApprovalListResult includes pagination metadata (TotalCount from X-Total-Count header) when available.
type ClientCompany ¶
ClientCompany represents a client company associated with a project.
type ClientCorrespondence ¶
type ClientCorrespondence struct {
ID int64 `json:"id"`
Status string `json:"status"`
VisibleToClients bool `json:"visible_to_clients"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Title string `json:"title"`
InheritsStatus bool `json:"inherits_status"`
Type string `json:"type"`
URL string `json:"url"`
AppURL string `json:"app_url"`
BookmarkURL string `json:"bookmark_url"`
SubscriptionURL string `json:"subscription_url"`
Parent *Parent `json:"parent,omitempty"`
Bucket *Bucket `json:"bucket,omitempty"`
Creator *Person `json:"creator,omitempty"`
Content string `json:"content"`
Subject string `json:"subject"`
RepliesCount int `json:"replies_count"`
RepliesURL string `json:"replies_url"`
}
ClientCorrespondence represents a Basecamp client correspondence (message to clients).
type ClientCorrespondenceListResult ¶
type ClientCorrespondenceListResult struct {
// Correspondences is the list of client correspondences returned.
Correspondences []ClientCorrespondence
// Meta contains pagination metadata (total count, etc.).
Meta ListMeta
}
ClientCorrespondenceListResult contains the results from listing client correspondences.
type ClientCorrespondencesService ¶
type ClientCorrespondencesService struct {
// contains filtered or unexported fields
}
ClientCorrespondencesService handles client correspondence operations.
func NewClientCorrespondencesService ¶
func NewClientCorrespondencesService(client *AccountClient) *ClientCorrespondencesService
NewClientCorrespondencesService creates a new ClientCorrespondencesService.
func (*ClientCorrespondencesService) Get ¶
func (s *ClientCorrespondencesService) Get(ctx context.Context, correspondenceID int64) (result *ClientCorrespondence, err error)
Get returns a client correspondence by ID.
func (*ClientCorrespondencesService) List ¶
func (s *ClientCorrespondencesService) List(ctx context.Context) (result *ClientCorrespondenceListResult, err error)
List returns all client correspondences in a project.
The returned ClientCorrespondenceListResult includes pagination metadata (TotalCount from X-Total-Count header) when available.
type ClientOption ¶
type ClientOption func(*Client)
ClientOption configures a Client.
func WithAuthStrategy ¶
func WithAuthStrategy(strategy AuthStrategy) ClientOption
WithAuthStrategy sets a custom authentication strategy. The default strategy is BearerAuth, which sets the Authorization header with a Bearer token from the token provider.
Use this to implement alternative auth schemes such as cookie-based auth, API keys, or mutual TLS.
func WithBaseDelay ¶
func WithBaseDelay(d time.Duration) ClientOption
WithBaseDelay sets the initial backoff delay.
func WithBulkhead ¶
func WithBulkhead(cfg *BulkheadConfig) ClientOption
WithBulkhead enables only the bulkhead (concurrency limiter).
Example:
client := basecamp.NewClient(cfg, tokenProvider,
basecamp.WithBulkhead(&basecamp.BulkheadConfig{
MaxConcurrent: 5,
MaxWait: 10 * time.Second,
}),
)
func WithCircuitBreaker ¶
func WithCircuitBreaker(cfg *CircuitBreakerConfig) ClientOption
WithCircuitBreaker enables only the circuit breaker.
Example:
client := basecamp.NewClient(cfg, tokenProvider,
basecamp.WithCircuitBreaker(&basecamp.CircuitBreakerConfig{
FailureThreshold: 10,
}),
)
func WithHTTPClient ¶
func WithHTTPClient(c *http.Client) ClientOption
WithHTTPClient sets a custom HTTP client.
func WithHooks ¶
func WithHooks(hooks Hooks) ClientOption
WithHooks sets the observability hooks for the client. Pass nil to disable hooks (uses NoopHooks).
func WithLogger ¶
func WithLogger(l *slog.Logger) ClientOption
WithLogger sets a custom slog logger for debug output. By default, the client uses a no-op logger (silent). Passing nil is safe and will use the default no-op logger.
func WithMaxJitter ¶
func WithMaxJitter(d time.Duration) ClientOption
WithMaxJitter sets the maximum random jitter to add to delays.
func WithMaxPages ¶
func WithMaxPages(n int) ClientOption
WithMaxPages sets the maximum pages to fetch in GetAll.
func WithMaxRetries ¶
func WithMaxRetries(n int) ClientOption
WithMaxRetries sets the maximum number of retry attempts for GET requests.
func WithRateLimit ¶
func WithRateLimit(cfg *RateLimitConfig) ClientOption
WithRateLimit enables only client-side rate limiting.
Example:
client := basecamp.NewClient(cfg, tokenProvider,
basecamp.WithRateLimit(&basecamp.RateLimitConfig{
RequestsPerSecond: 10,
BurstSize: 5,
}),
)
func WithResilience ¶
func WithResilience(cfg *ResilienceConfig) ClientOption
WithResilience enables circuit breaker, bulkhead, and rate limiting. Pass nil to use DefaultResilienceConfig().
Example:
client := basecamp.NewClient(cfg, tokenProvider,
basecamp.WithResilience(nil), // Uses defaults
)
Or with custom config:
client := basecamp.NewClient(cfg, tokenProvider,
basecamp.WithResilience(&basecamp.ResilienceConfig{
CircuitBreaker: &basecamp.CircuitBreakerConfig{
FailureThreshold: 3,
OpenTimeout: 10 * time.Second,
},
Bulkhead: &basecamp.BulkheadConfig{
MaxConcurrent: 5,
},
RateLimit: &basecamp.RateLimitConfig{
RequestsPerSecond: 10,
},
}),
)
func WithTimeout ¶
func WithTimeout(d time.Duration) ClientOption
WithTimeout sets the HTTP request timeout.
func WithTransport ¶
func WithTransport(t http.RoundTripper) ClientOption
WithTransport sets a custom HTTP transport.
func WithUserAgent ¶
func WithUserAgent(ua string) ClientOption
WithUserAgent sets the User-Agent header.
type ClientRepliesService ¶
type ClientRepliesService struct {
// contains filtered or unexported fields
}
ClientRepliesService handles client reply operations.
func NewClientRepliesService ¶
func NewClientRepliesService(client *AccountClient) *ClientRepliesService
NewClientRepliesService creates a new ClientRepliesService.
func (*ClientRepliesService) Get ¶
func (s *ClientRepliesService) Get(ctx context.Context, recordingID, replyID int64) (result *ClientReply, err error)
Get returns a specific client reply.
func (*ClientRepliesService) List ¶
func (s *ClientRepliesService) List(ctx context.Context, recordingID int64) (result *ClientReplyListResult, err error)
List returns all replies for a client recording (correspondence or approval).
The returned ClientReplyListResult includes pagination metadata (TotalCount from X-Total-Count header) when available.
type ClientReply ¶
type ClientReply struct {
ID int64 `json:"id"`
Status string `json:"status"`
VisibleToClients bool `json:"visible_to_clients"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Title string `json:"title"`
InheritsStatus bool `json:"inherits_status"`
Type string `json:"type"`
URL string `json:"url"`
AppURL string `json:"app_url"`
BookmarkURL string `json:"bookmark_url"`
Parent *Parent `json:"parent,omitempty"`
Bucket *Bucket `json:"bucket,omitempty"`
Creator *Person `json:"creator,omitempty"`
Content string `json:"content"`
}
ClientReply represents a reply to a client correspondence or approval.
type ClientReplyListResult ¶
type ClientReplyListResult struct {
// Replies is the list of client replies returned.
Replies []ClientReply
// Meta contains pagination metadata (total count, etc.).
Meta ListMeta
}
ClientReplyListResult contains the results from listing client replies.
type Clientside ¶
Clientside represents the client-facing portion of a project.
type Comment ¶
type Comment struct {
ID int64 `json:"id"`
Status string `json:"status"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Content string `json:"content"`
Type string `json:"type"`
URL string `json:"url"`
AppURL string `json:"app_url"`
Parent *Parent `json:"parent,omitempty"`
Bucket *Bucket `json:"bucket,omitempty"`
Creator *Person `json:"creator,omitempty"`
}
Comment represents a Basecamp comment on a recording.
type CommentListOptions ¶
type CommentListOptions struct {
// Limit is the maximum number of comments to return.
// If 0, uses DefaultCommentLimit (100). Use -1 for unlimited.
Limit int
// Page, if non-zero, disables pagination and returns only the first page.
// NOTE: The page number itself is not yet honored due to OpenAPI client
// limitations. Use 0 to paginate through all results up to Limit.
Page int
}
CommentListOptions specifies options for listing comments.
type CommentListResult ¶
type CommentListResult struct {
// Comments is the list of comments returned.
Comments []Comment
// Meta contains pagination metadata (total count, etc.).
Meta ListMeta
}
CommentListResult contains the results from listing comments.
type CommentsService ¶
type CommentsService struct {
// contains filtered or unexported fields
}
CommentsService handles comment operations.
func NewCommentsService ¶
func NewCommentsService(client *AccountClient) *CommentsService
NewCommentsService creates a new CommentsService.
func (*CommentsService) Create ¶
func (s *CommentsService) Create(ctx context.Context, recordingID int64, req *CreateCommentRequest) (result *Comment, err error)
Create creates a new comment on a recording. Returns the created comment.
Example ¶
package main
import (
"context"
"fmt"
"log"
"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)
ctx := context.Background()
recordingID := int64(789012) // Can be a todo, message, etc.
// Add a comment to any recording
comment, err := client.ForAccount("12345").Comments().Create(ctx, recordingID, &basecamp.CreateCommentRequest{
Content: "<p>Looks good to me!</p>",
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("Comment added by %s\n", comment.Creator.Name)
}
Output:
func (*CommentsService) List ¶
func (s *CommentsService) List(ctx context.Context, recordingID int64, opts *CommentListOptions) (result *CommentListResult, err error)
List returns comments on a recording.
By default, returns up to 100 comments. Use Limit: -1 for unlimited.
Pagination options:
- Limit: maximum number of comments to return (0 = 100, -1 = unlimited)
- Page: if non-zero, disables pagination and returns first page only
The returned CommentListResult includes pagination metadata (TotalCount from X-Total-Count header) when available.
func (*CommentsService) Trash ¶
func (s *CommentsService) Trash(ctx context.Context, commentID int64) (err error)
Trash moves a comment to the trash. Trashed comments can be recovered from the trash.
func (*CommentsService) Update ¶
func (s *CommentsService) Update(ctx context.Context, commentID int64, req *UpdateCommentRequest) (result *Comment, err error)
Update updates an existing comment. Returns the updated comment.
type Config ¶
type Config struct {
// BaseURL is the API base URL (e.g., "https://3.basecampapi.com").
BaseURL string `json:"base_url"`
// ProjectID is the default project/bucket ID.
ProjectID string `json:"project_id"`
// TodolistID is the default todolist ID.
TodolistID string `json:"todolist_id"`
// CacheDir is the directory for HTTP cache storage.
CacheDir string `json:"cache_dir"`
// CacheEnabled controls whether HTTP caching is enabled.
CacheEnabled bool `json:"cache_enabled"`
}
Config holds the resolved configuration for API access.
func DefaultConfig ¶
func DefaultConfig() *Config
DefaultConfig returns a Config with sensible defaults.
Example ¶
package main
import (
"fmt"
"github.com/basecamp/basecamp-sdk/go/pkg/basecamp"
)
func main() {
// Create a default configuration
cfg := basecamp.DefaultConfig()
// Override with environment variables
cfg.LoadConfigFromEnv()
// Or set values programmatically
cfg.ProjectID = "67890"
cfg.CacheEnabled = true
fmt.Println("Configuration ready")
}
Output: Configuration ready
func LoadConfig ¶
LoadConfig loads configuration from a JSON file.
func (*Config) LoadConfigFromEnv ¶
func (c *Config) LoadConfigFromEnv()
LoadConfigFromEnv loads configuration from environment variables. Environment variables override any values already set in the config.
type CreateAnswerRequest ¶
type CreateAnswerRequest struct {
// Content is the answer content in HTML (required).
Content string `json:"content"`
// GroupOn is the date to group the answer with (optional, ISO 8601 format).
GroupOn string `json:"group_on,omitempty"`
}
CreateAnswerRequest specifies the parameters for creating an answer.
type CreateCampfireLineRequest ¶
type CreateCampfireLineRequest struct {
// Content is the message body (required).
Content string `json:"content"`
// ContentType is "text/plain" or "text/html". If empty, the API defaults to plain text.
ContentType string `json:"content_type,omitempty"`
}
CreateCampfireLineRequest specifies the parameters for creating a campfire line.
type CreateCardRequest ¶
type CreateCardRequest struct {
// Title is the card title (required).
Title string `json:"title"`
// Content is the card body in HTML (optional).
Content string `json:"content,omitempty"`
// DueOn is the due date in ISO 8601 format (optional).
DueOn string `json:"due_on,omitempty"`
// Notify when true, will notify assignees (optional).
Notify bool `json:"notify,omitempty"`
}
CreateCardRequest specifies the parameters for creating a card.
type CreateChatbotRequest ¶
type CreateChatbotRequest struct {
// ServiceName is the chatbot name used to invoke queries and commands (required).
// No spaces, emoji or non-word characters are allowed.
ServiceName string `json:"service_name"`
// CommandURL is the HTTPS URL that Basecamp should call when the bot is addressed (optional).
CommandURL string `json:"command_url,omitempty"`
}
CreateChatbotRequest specifies the parameters for creating a chatbot.
type CreateColumnRequest ¶
type CreateColumnRequest struct {
// Title is the column title (required).
Title string `json:"title"`
// Description is the column description (optional).
Description string `json:"description,omitempty"`
}
CreateColumnRequest specifies the parameters for creating a column.
type CreateCommentRequest ¶
type CreateCommentRequest struct {
// Content is the comment text in HTML (required).
Content string `json:"content"`
}
CreateCommentRequest specifies the parameters for creating a comment.
type CreateDocumentRequest ¶
type CreateDocumentRequest struct {
// Title is the document title (required).
Title string `json:"title"`
// Content is the document body in HTML (optional).
Content string `json:"content,omitempty"`
// Status is either "drafted" or "active" (optional, defaults to active).
Status string `json:"status,omitempty"`
// Subscriptions controls who gets notified and subscribed.
// nil: field omitted (server default). &[]int64{}: subscribe nobody. &[]int64{1,2}: those people.
Subscriptions *[]int64 `json:"subscriptions,omitempty"`
}
CreateDocumentRequest specifies the parameters for creating a document.
type CreateForwardReplyRequest ¶
type CreateForwardReplyRequest struct {
// Content is the reply body in HTML (required).
Content string `json:"content"`
}
CreateForwardReplyRequest specifies the parameters for creating a reply to a forward.
type CreateLineOptions ¶
type CreateLineOptions struct {
// ContentType is "text/plain" or "text/html". If empty, the API defaults to plain text.
ContentType string
}
CreateLineOptions specifies optional parameters for creating a campfire line.
type CreateMarkerRequest ¶
type CreateMarkerRequest struct {
// Name is the marker name (required).
Name string `json:"name"`
// Date is the marker date in YYYY-MM-DD format (required).
Date string `json:"date"`
}
CreateMarkerRequest specifies the parameters for creating a lineup marker.
type CreateMessageRequest ¶
type CreateMessageRequest struct {
// Subject is the message title (required).
Subject string `json:"subject"`
// Content is the message body in HTML (optional).
Content string `json:"content,omitempty"`
// Status is either "drafted" or "active" (optional, defaults to active).
Status string `json:"status,omitempty"`
// CategoryID is the message type ID (optional).
CategoryID int64 `json:"category_id,omitempty"`
// Subscriptions controls who gets notified and subscribed.
// nil: field omitted (server default). &[]int64{}: subscribe nobody. &[]int64{1,2}: those people.
Subscriptions *[]int64 `json:"subscriptions,omitempty"`
}
CreateMessageRequest specifies the parameters for creating a message.
type CreateMessageTypeRequest ¶
type CreateMessageTypeRequest struct {
// Name is the message type name (required).
Name string `json:"name"`
// Icon is the message type icon (required).
Icon string `json:"icon"`
}
CreateMessageTypeRequest specifies the parameters for creating a message type.
type CreatePersonRequest ¶
type CreatePersonRequest struct {
// Name is the person's full name (required).
Name string `json:"name"`
// EmailAddress is the person's email address (required).
EmailAddress string `json:"email_address"`
// Title is the person's job title (optional).
Title string `json:"title,omitempty"`
// CompanyName is the person's company name (optional).
CompanyName string `json:"company_name,omitempty"`
}
CreatePersonRequest specifies the parameters for creating a new person.
type CreateProjectFromTemplateRequest ¶
type CreateProjectFromTemplateRequest struct {
// Name is the project name (required).
Name string `json:"name"`
// Description is an optional project description.
Description string `json:"description,omitempty"`
}
CreateProjectFromTemplateRequest specifies the parameters for creating a project from a template.
type CreateProjectRequest ¶
type CreateProjectRequest struct {
// Name is the project name (required).
Name string `json:"name"`
// Description is an optional project description.
Description string `json:"description,omitempty"`
}
CreateProjectRequest specifies the parameters for creating a project.
type CreateQuestionRequest ¶
type CreateQuestionRequest struct {
// Title is the question text (required).
Title string `json:"title"`
// Schedule is the question schedule configuration (required).
Schedule *QuestionSchedule `json:"schedule"`
}
CreateQuestionRequest specifies the parameters for creating a question.
type CreateScheduleEntryRequest ¶
type CreateScheduleEntryRequest struct {
// Summary is the event title (required).
Summary string `json:"summary"`
// StartsAt is the event start time (required, ISO 8601 format).
StartsAt string `json:"starts_at"`
// EndsAt is the event end time (required, ISO 8601 format).
EndsAt string `json:"ends_at"`
// Description is the event details in HTML (optional).
Description string `json:"description,omitempty"`
// ParticipantIDs is a list of people IDs to assign (optional).
ParticipantIDs []int64 `json:"participant_ids,omitempty"`
// AllDay indicates if this is an all-day event (optional).
AllDay bool `json:"all_day,omitempty"`
// Notify triggers participant notifications when true (optional).
Notify bool `json:"notify,omitempty"`
// Subscriptions controls who gets notified and subscribed.
// nil: field omitted (server default). &[]int64{}: subscribe nobody. &[]int64{1,2}: those people.
Subscriptions *[]int64 `json:"subscriptions,omitempty"`
}
CreateScheduleEntryRequest specifies the parameters for creating a schedule entry.
type CreateStepRequest ¶
type CreateStepRequest struct {
// Title is the step title (required).
Title string `json:"title"`
// DueOn is the due date in ISO 8601 format (optional).
DueOn string `json:"due_on,omitempty"`
// Assignees is a list of person IDs to assign this step to (optional).
Assignees []int64 `json:"assignees,omitempty"`
}
CreateStepRequest specifies the parameters for creating a step.
type CreateTemplateRequest ¶
type CreateTemplateRequest struct {
// Name is the template name (required).
Name string `json:"name"`
// Description is an optional template description.
Description string `json:"description,omitempty"`
}
CreateTemplateRequest specifies the parameters for creating a template.
type CreateTimesheetEntryRequest ¶
type CreateTimesheetEntryRequest struct {
Date string `json:"date"`
Hours string `json:"hours"`
Description string `json:"description,omitempty"`
PersonID int64 `json:"person_id,omitempty"`
}
CreateTimesheetEntryRequest specifies the parameters for creating a timesheet entry.
type CreateTodoRequest ¶
type CreateTodoRequest struct {
// Content is the todo text (required).
Content string `json:"content"`
// Description is an optional extended description (can include HTML).
Description string `json:"description,omitempty"`
// AssigneeIDs is a list of person IDs to assign this todo to.
AssigneeIDs []int64 `json:"assignee_ids,omitempty"`
// CompletionSubscriberIDs is a list of person IDs to notify on completion.
CompletionSubscriberIDs []int64 `json:"completion_subscriber_ids,omitempty"`
// Notify when true, will notify assignees.
Notify bool `json:"notify,omitempty"`
// DueOn is the due date in ISO 8601 format (YYYY-MM-DD).
DueOn string `json:"due_on,omitempty"`
// StartsOn is the start date in ISO 8601 format (YYYY-MM-DD).
StartsOn string `json:"starts_on,omitempty"`
}
CreateTodoRequest specifies the parameters for creating a todo.
type CreateTodolistGroupRequest ¶
type CreateTodolistGroupRequest struct {
// Name is the group name (required).
Name string `json:"name"`
}
CreateTodolistGroupRequest specifies the parameters for creating a todolist group.
type CreateTodolistRequest ¶
type CreateTodolistRequest struct {
// Name is the todolist name (required).
Name string `json:"name"`
// Description is an optional description (can include HTML).
Description string `json:"description,omitempty"`
}
CreateTodolistRequest specifies the parameters for creating a todolist.
type CreateUploadRequest ¶
type CreateUploadRequest struct {
// AttachableSGID is the signed global ID for an uploaded attachment (required).
// See the Create Attachment endpoint for how to upload files.
AttachableSGID string `json:"attachable_sgid"`
// Description is the upload description in HTML (optional).
Description string `json:"description,omitempty"`
// BaseName is the filename without extension (optional).
BaseName string `json:"base_name,omitempty"`
// Subscriptions controls who gets notified and subscribed.
// nil: field omitted (server default). &[]int64{}: subscribe nobody. &[]int64{1,2}: those people.
Subscriptions *[]int64 `json:"subscriptions,omitempty"`
}
CreateUploadRequest specifies the parameters for creating an upload.
type CreateVaultRequest ¶
type CreateVaultRequest struct {
// Title is the vault name (required).
Title string `json:"title"`
}
CreateVaultRequest specifies the parameters for creating a vault (folder).
type CreateWebhookRequest ¶
type CreateWebhookRequest struct {
// PayloadURL is the URL to receive webhook payloads (required).
PayloadURL string `json:"payload_url"`
// Types is a list of event types to subscribe to (required).
// Example: ["Todo", "Todolist", "Comment"]
Types []string `json:"types"`
// Active indicates whether the webhook is active (default: true).
Active *bool `json:"active,omitempty"`
}
CreateWebhookRequest specifies the parameters for creating a webhook.
type CredentialStore ¶
type CredentialStore struct {
// contains filtered or unexported fields
}
CredentialStore handles secure credential storage.
func NewCredentialStore ¶
func NewCredentialStore(fallbackDir string) *CredentialStore
NewCredentialStore creates a credential store. It prefers the system keyring if available, falling back to file storage.
func (*CredentialStore) Delete ¶
func (s *CredentialStore) Delete(origin string) error
Delete removes credentials for the given origin.
func (*CredentialStore) Load ¶
func (s *CredentialStore) Load(origin string) (*Credentials, error)
Load retrieves credentials for the given origin.
func (*CredentialStore) Save ¶
func (s *CredentialStore) Save(origin string, creds *Credentials) error
Save stores credentials for the given origin.
func (*CredentialStore) UsingKeyring ¶
func (s *CredentialStore) UsingKeyring() bool
UsingKeyring returns true if the store is using the system keyring.
type Credentials ¶
type Credentials struct {
AccessToken string `json:"access_token"`
RefreshToken string `json:"refresh_token"`
ExpiresAt int64 `json:"expires_at"`
Scope string `json:"scope"`
TokenEndpoint string `json:"token_endpoint"`
UserID string `json:"user_id,omitempty"`
}
Credentials holds OAuth tokens and metadata.
type Date ¶
Date is an alias for types.Date, representing a calendar date without time. Re-exported here for convenience so users can use basecamp.Date.
type DockItem ¶
type DockItem struct {
ID int64 `json:"id"`
Title string `json:"title"`
Name string `json:"name"`
Enabled bool `json:"enabled"`
Position *int `json:"position"`
URL string `json:"url"`
AppURL string `json:"app_url"`
}
DockItem represents a tool in a project's dock.
type Document ¶
type Document struct {
ID int64 `json:"id"`
Status string `json:"status"`
VisibleToClients bool `json:"visible_to_clients"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Title string `json:"title"`
InheritsStatus bool `json:"inherits_status"`
Type string `json:"type"`
URL string `json:"url"`
AppURL string `json:"app_url"`
BookmarkURL string `json:"bookmark_url"`
SubscriptionURL string `json:"subscription_url"`
CommentsCount int `json:"comments_count"`
BoostsCount int `json:"boosts_count,omitempty"`
CommentsURL string `json:"comments_url"`
Position int `json:"position,omitempty"`
Parent *Parent `json:"parent,omitempty"`
Bucket *Bucket `json:"bucket,omitempty"`
Creator *Person `json:"creator,omitempty"`
Content string `json:"content"`
}
Document represents a Basecamp document in a vault.
type DocumentListOptions ¶
type DocumentListOptions struct {
// Limit is the maximum number of documents to return.
// If 0 (default), returns all documents. Use a positive value to cap results.
Limit int
// Page, if non-zero, disables pagination and returns only the first page.
// NOTE: The page number itself is not yet honored due to OpenAPI client
// limitations. Use 0 to paginate through all results up to Limit.
Page int
}
DocumentListOptions specifies options for listing documents.
type DocumentListResult ¶
type DocumentListResult struct {
// Documents is the list of documents returned.
Documents []Document
// Meta contains pagination metadata (total count, etc.).
Meta ListMeta
}
DocumentListResult contains the results from listing documents.
type DocumentsService ¶
type DocumentsService struct {
// contains filtered or unexported fields
}
DocumentsService handles document operations.
func NewDocumentsService ¶
func NewDocumentsService(client *AccountClient) *DocumentsService
NewDocumentsService creates a new DocumentsService.
func (*DocumentsService) Create ¶
func (s *DocumentsService) Create(ctx context.Context, vaultID int64, req *CreateDocumentRequest) (result *Document, err error)
Create creates a new document in a vault. Returns the created document.
func (*DocumentsService) List ¶
func (s *DocumentsService) List(ctx context.Context, vaultID int64, opts *DocumentListOptions) (result *DocumentListResult, err error)
List returns all documents in a vault.
By default, returns all documents (no limit). Use Limit to cap results.
Pagination options:
- Limit: maximum number of documents to return (0 = all)
- Page: if non-zero, disables pagination and returns first page only
The returned DocumentListResult includes pagination metadata (TotalCount from X-Total-Count header) when available.
func (*DocumentsService) Trash ¶
func (s *DocumentsService) Trash(ctx context.Context, documentID int64) (err error)
Trash moves a document to the trash. Trashed documents can be recovered from the trash.
func (*DocumentsService) Update ¶
func (s *DocumentsService) Update(ctx context.Context, documentID int64, req *UpdateDocumentRequest) (result *Document, err error)
Update updates an existing document. Returns the updated document.
type DownloadResult ¶
type DownloadResult struct {
// Body is the file content. Caller must close this.
Body io.ReadCloser
// ContentType is the MIME type of the file.
ContentType string
// ContentLength is the size of the file in bytes (-1 if unknown).
ContentLength int64
// Filename is the name of the file.
Filename string
}
DownloadResult contains the result from downloading an upload.
type Error ¶
type Error struct {
Code string
Message string
Hint string
HTTPStatus int
Retryable bool
RequestID string
Cause error
}
Error is a structured error with code, message, and optional hint.
func AsError ¶
AsError attempts to convert an error to an *Error. If the error is not an *Error, it wraps it in one.
func ErrAmbiguous ¶
ErrAmbiguous creates an ambiguous match error.
func ErrForbiddenScope ¶
func ErrForbiddenScope() *Error
ErrForbiddenScope creates a forbidden error due to insufficient scope.
func ErrNotFound ¶
ErrNotFound creates a not-found error.
func ErrNotFoundHint ¶
ErrNotFoundHint creates a not-found error with a hint.
func ErrRateLimit ¶
ErrRateLimit creates a rate-limit error.
func ErrUsageHint ¶
ErrUsageHint creates a usage error with a hint.
type Event ¶
type Event struct {
ID int64 `json:"id"`
RecordingID int64 `json:"recording_id"`
Action string `json:"action"`
Details *EventDetails `json:"details,omitempty"`
CreatedAt time.Time `json:"created_at"`
Creator *Person `json:"creator,omitempty"`
}
Event represents a recording change event in Basecamp. An event is created any time a recording changes.
type EventDetails ¶
type EventDetails struct {
// AddedPersonIDs is populated for assignment_changed actions.
AddedPersonIDs []int64 `json:"added_person_ids,omitempty"`
// RemovedPersonIDs is populated for assignment_changed actions.
RemovedPersonIDs []int64 `json:"removed_person_ids,omitempty"`
// NotifiedRecipientIDs is populated for completion events.
NotifiedRecipientIDs []int64 `json:"notified_recipient_ids,omitempty"`
}
EventDetails contains action-specific information for an event.
type EventListOptions ¶
type EventListOptions struct {
// Limit is the maximum number of events to return.
// If 0, uses DefaultEventLimit (100). Use -1 for unlimited.
Limit int
// Page, if non-zero, disables pagination and returns only the first page.
// NOTE: The page number itself is not yet honored due to OpenAPI client
// limitations. Use 0 to paginate through all results up to Limit.
Page int
}
EventListOptions specifies options for listing events.
type EventListResult ¶
type EventListResult struct {
// Events is the list of events returned.
Events []Event
// Meta contains pagination metadata (total count, etc.).
Meta ListMeta
}
EventListResult contains the results from listing events.
type EventsService ¶
type EventsService struct {
// contains filtered or unexported fields
}
EventsService handles event operations.
func NewEventsService ¶
func NewEventsService(client *AccountClient) *EventsService
NewEventsService creates a new EventsService.
func (*EventsService) List ¶
func (s *EventsService) List(ctx context.Context, recordingID int64, opts *EventListOptions) (result *EventListResult, err error)
List returns all events for a recording.
By default, returns up to 100 events. Use Limit: -1 for unlimited.
Pagination options:
- Limit: maximum number of events to return (0 = 100, -1 = unlimited)
- Page: if non-zero, disables pagination and returns first page only
The returned EventListResult includes pagination metadata (TotalCount from X-Total-Count header) when available.
type FlexTime ¶
FlexTime is a time.Time that can unmarshal from either a Unix timestamp (integer) or an RFC 3339 string. This supports both BC3 OAuth 2.1 (integer) and Launchpad (string).
func (*FlexTime) UnmarshalJSON ¶
UnmarshalJSON implements json.Unmarshaler for FlexTime.
type Forward ¶
type Forward struct {
ID int64 `json:"id"`
Status string `json:"status"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Subject string `json:"subject"`
Content string `json:"content"`
From string `json:"from"`
Type string `json:"type"`
URL string `json:"url"`
AppURL string `json:"app_url"`
Parent *Parent `json:"parent,omitempty"`
Bucket *Bucket `json:"bucket,omitempty"`
Creator *Person `json:"creator,omitempty"`
}
Forward represents a forwarded email in Basecamp.
type ForwardListOptions ¶
type ForwardListOptions struct {
// Limit is the maximum number of forwards to return.
// If 0 (default), returns all forwards. Use a positive value to cap results.
Limit int
// Page, if non-zero, disables pagination and returns only the first page.
// NOTE: The page number itself is not yet honored due to OpenAPI client
// limitations. Use 0 to paginate through all results up to Limit.
Page int
}
ForwardListOptions specifies options for listing forwards.
type ForwardListResult ¶
type ForwardListResult struct {
// Forwards is the list of forwards returned.
Forwards []Forward
// Meta contains pagination metadata (total count, etc.).
Meta ListMeta
}
ForwardListResult contains the results from listing forwards.
type ForwardReply ¶
type ForwardReply struct {
ID int64 `json:"id"`
Status string `json:"status"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Content string `json:"content"`
Type string `json:"type"`
URL string `json:"url"`
AppURL string `json:"app_url"`
Parent *Parent `json:"parent,omitempty"`
Bucket *Bucket `json:"bucket,omitempty"`
Creator *Person `json:"creator,omitempty"`
}
ForwardReply represents a reply to a forwarded email.
type ForwardReplyListOptions ¶
type ForwardReplyListOptions struct {
// Limit is the maximum number of replies to return.
// If 0 (default), returns all replies. Use a positive value to cap results.
Limit int
// Page, if non-zero, disables pagination and returns only the first page.
// NOTE: The page number itself is not yet honored due to OpenAPI client
// limitations. Use 0 to paginate through all results up to Limit.
Page int
}
ForwardReplyListOptions specifies options for listing forward replies.
type ForwardReplyListResult ¶
type ForwardReplyListResult struct {
// Replies is the list of forward replies returned.
Replies []ForwardReply
// Meta contains pagination metadata (total count, etc.).
Meta ListMeta
}
ForwardReplyListResult contains the results from listing forward replies.
type ForwardsService ¶
type ForwardsService struct {
// contains filtered or unexported fields
}
ForwardsService handles email forward operations.
func NewForwardsService ¶
func NewForwardsService(client *AccountClient) *ForwardsService
NewForwardsService creates a new ForwardsService.
func (*ForwardsService) CreateReply ¶
func (s *ForwardsService) CreateReply(ctx context.Context, forwardID int64, req *CreateForwardReplyRequest) (result *ForwardReply, err error)
CreateReply creates a new reply to a forwarded email. Returns the created reply.
func (*ForwardsService) GetReply ¶
func (s *ForwardsService) GetReply(ctx context.Context, forwardID, replyID int64) (result *ForwardReply, err error)
GetReply returns a forward reply by ID.
func (*ForwardsService) List ¶
func (s *ForwardsService) List(ctx context.Context, inboxID int64, opts *ForwardListOptions) (result *ForwardListResult, err error)
List returns all forwards in an inbox.
By default, returns all forwards (no limit). Use Limit to cap results.
Pagination options:
- Limit: maximum number of forwards to return (0 = all)
- Page: if non-zero, disables pagination and returns first page only
The returned ForwardListResult includes pagination metadata (TotalCount from X-Total-Count header) when available.
func (*ForwardsService) ListReplies ¶
func (s *ForwardsService) ListReplies(ctx context.Context, forwardID int64, opts *ForwardReplyListOptions) (result *ForwardReplyListResult, err error)
ListReplies returns all replies to a forward.
By default, returns all replies (no limit). Use Limit to cap results.
Pagination options:
- Limit: maximum number of replies to return (0 = all)
- Page: if non-zero, disables pagination and returns first page only
The returned ForwardReplyListResult includes pagination metadata (TotalCount from X-Total-Count header) when available.
type GatingHooks ¶
type GatingHooks interface {
Hooks
// OnOperationGate is called before OnOperationStart.
// Returns a new context (which may contain cleanup functions like bulkhead
// release) and an error. Return non-nil error to reject the operation.
// The returned context should be used for the operation and passed to
// OnOperationEnd for proper cleanup.
OnOperationGate(ctx context.Context, op OperationInfo) (context.Context, error)
}
GatingHooks extends Hooks with request gating capability. Implementations can reject operations before they execute, enabling patterns like circuit breakers, bulkheads, and rate limiters.
type GetInfoOptions ¶
type GetInfoOptions struct {
// Endpoint overrides the default authorization endpoint URL.
// If empty, defaults to "https://launchpad.37signals.com/authorization.json".
Endpoint string
// FilterProduct filters accounts to only those matching this product.
// Common values: "bc3" (Basecamp), "bcx" (Basecamp 2), "hey" (HEY).
// If empty, all accounts are returned.
FilterProduct string
}
GetInfoOptions specifies options for fetching authorization info.
type HTTPOptions ¶
type HTTPOptions struct {
// Timeout is the request timeout (default: 30s).
Timeout time.Duration
// MaxRetries is the maximum retry attempts for GET requests (default: 3).
// POST/PUT/DELETE requests only get 1 retry after successful token refresh.
MaxRetries int
// BaseDelay is the initial backoff delay (default: 1s).
BaseDelay time.Duration
// MaxJitter is the maximum random jitter to add to delays (default: 100ms).
MaxJitter time.Duration
// MaxPages is the maximum pages to fetch in GetAll (default: 10000).
MaxPages int
// Transport is the HTTP transport to use. If nil, a default transport
// with sensible connection pooling is created.
Transport http.RoundTripper
}
HTTPOptions configures the HTTP client behavior.
func DefaultHTTPOptions ¶
func DefaultHTTPOptions() HTTPOptions
DefaultHTTPOptions returns HTTPOptions with sensible defaults.
type Hooks ¶
type Hooks interface {
// OnOperationStart is called when a semantic SDK operation begins.
// Returns a context that will be passed to OnOperationEnd.
OnOperationStart(ctx context.Context, op OperationInfo) context.Context
// OnOperationEnd is called when a semantic SDK operation completes.
// The ctx is the one returned from OnOperationStart.
OnOperationEnd(ctx context.Context, op OperationInfo, err error, duration time.Duration)
// OnRequestStart is called before an HTTP request is sent.
// The returned context is used for the request and passed to OnRequestEnd.
OnRequestStart(ctx context.Context, info RequestInfo) context.Context
// OnRequestEnd is called after an HTTP request completes.
// It receives the same context returned by OnRequestStart.
OnRequestEnd(ctx context.Context, info RequestInfo, result RequestResult)
// OnRetry is called before a retry attempt.
OnRetry(ctx context.Context, info RequestInfo, attempt int, err error)
}
Hooks provides observability callbacks for SDK operations. Implementations can use these hooks for logging, metrics, tracing, etc.
There are two levels of hooks:
- Operation-level: OnOperationStart/OnOperationEnd for semantic SDK operations
- Request-level: OnRequestStart/OnRequestEnd for HTTP requests
Operation hooks provide business-meaningful spans (e.g., "Todos.Complete"), while request hooks capture transport-level details (retries, cache, timing).
The context passed to hooks allows correlation of nested operations and requests.
func NewChainHooks ¶
NewChainHooks creates a ChainHooks from the given hooks. Nil hooks are filtered out. If all hooks are nil, returns NoopHooks.
type Identity ¶
type Identity struct {
ID int64 `json:"id"`
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
EmailAddress string `json:"email_address"`
}
Identity represents the authenticated user's identity from the authorization endpoint.
type Inbox ¶
type Inbox struct {
ID int64 `json:"id"`
Status string `json:"status"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Title string `json:"title"`
Type string `json:"type"`
URL string `json:"url"`
AppURL string `json:"app_url"`
Bucket *Bucket `json:"bucket,omitempty"`
Creator *Person `json:"creator,omitempty"`
}
Inbox represents a Basecamp email inbox (forwards tool).
type LineupMarker ¶
type LineupMarker struct {
ID int64 `json:"id"`
Status string `json:"status"`
Color string `json:"color"`
Title string `json:"title"`
StartsOn string `json:"starts_on"`
EndsOn string `json:"ends_on"`
Description string `json:"description,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Type string `json:"type"`
URL string `json:"url"`
AppURL string `json:"app_url"`
Creator *Person `json:"creator,omitempty"`
Parent *Parent `json:"parent,omitempty"`
Bucket *Bucket `json:"bucket,omitempty"`
}
LineupMarker represents a marker on the Basecamp Lineup.
type LineupService ¶
type LineupService struct {
// contains filtered or unexported fields
}
LineupService handles lineup marker operations.
func NewLineupService ¶
func NewLineupService(client *AccountClient) *LineupService
NewLineupService creates a new LineupService.
func (*LineupService) CreateMarker ¶
func (s *LineupService) CreateMarker(ctx context.Context, req *CreateMarkerRequest) (err error)
CreateMarker creates a new marker on the lineup.
func (*LineupService) DeleteMarker ¶
func (s *LineupService) DeleteMarker(ctx context.Context, markerID int64) (err error)
DeleteMarker deletes a marker. markerID is the marker ID.
func (*LineupService) UpdateMarker ¶
func (s *LineupService) UpdateMarker(ctx context.Context, markerID int64, req *UpdateMarkerRequest) (err error)
UpdateMarker updates an existing marker. markerID is the marker ID.
type ListMeta ¶
type ListMeta struct {
// TotalCount is the total number of items available (from X-Total-Count header).
// Zero if the header was not present or could not be parsed.
TotalCount int
// Truncated is true when results were capped by MaxPages or Limit, either
// because more pages are available on the server or because items were
// dropped within a page due to the limit.
Truncated bool
}
ListMeta contains pagination metadata from list operations.
type Match ¶
type Match struct {
// Source indicates how the URL was matched: API route table or structural convention.
Source MatchSource
// Operation is the matched API operation name (e.g., "GetTodo", "CreateMessage").
// Empty for structural matches.
Operation string
// Operations lists all API operations for the matched pattern, keyed by HTTP method.
// Nil for structural matches.
Operations map[string]string
// Resource is the API resource group (e.g., "Todos", "Messages").
// Empty for structural matches.
Resource string
// PathType is the resource type segment from the URL path (e.g., "todos",
// "messages", "cards", "columns"). Always populated when a bucket resource
// is matched, whether by API route or structural fallback.
PathType string
// AccountID is the Basecamp account ID from the URL path.
AccountID string
// ProjectID is the bucket/project ID. Present for most resource URLs.
ProjectID string
// Params contains all named path parameters extracted from the URL.
// Keys match the route table parameter names (e.g., "todoId", "messageId").
// Nil for structural matches.
Params map[string]string
// CommentID is the comment ID extracted from a #__recording_{id} fragment.
CommentID string
// contains filtered or unexported fields
}
Match holds the components extracted from a Basecamp URL.
func (*Match) ResourceID ¶
ResourceID returns the "primary" resource ID from the match — the last path parameter that isn't accountId or projectId. Returns empty string if no such parameter exists (e.g., for project or list URLs).
type MatchSource ¶
type MatchSource int
MatchSource indicates how a URL was recognized.
const ( // MatchedAPI means the URL matched a route in the OpenAPI-derived route table. // Operation, Resource, and Params are populated. MatchedAPI MatchSource = iota + 1 // MatchedStructural means the URL matched Basecamp's web URL conventions // but has no corresponding API route. Only IDs and PathType are populated. MatchedStructural )
type Message ¶
type Message struct {
ID int64 `json:"id"`
Status string `json:"status"`
Subject string `json:"subject"`
Content string `json:"content"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Type string `json:"type"`
URL string `json:"url"`
AppURL string `json:"app_url"`
Parent *Parent `json:"parent,omitempty"`
Bucket *Bucket `json:"bucket,omitempty"`
Creator *Person `json:"creator,omitempty"`
Category *MessageType `json:"category,omitempty"`
BoostsCount int `json:"boosts_count,omitempty"`
}
Message represents a Basecamp message on a message board.
type MessageBoard ¶
type MessageBoard struct {
ID int64 `json:"id"`
Status string `json:"status"`
Title string `json:"title"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Type string `json:"type"`
URL string `json:"url"`
AppURL string `json:"app_url"`
MessagesCount int `json:"messages_count"`
MessagesURL string `json:"messages_url"`
Bucket *Bucket `json:"bucket,omitempty"`
Creator *Person `json:"creator,omitempty"`
}
MessageBoard represents a Basecamp message board in a project.
type MessageBoardsService ¶
type MessageBoardsService struct {
// contains filtered or unexported fields
}
MessageBoardsService handles message board operations.
func NewMessageBoardsService ¶
func NewMessageBoardsService(client *AccountClient) *MessageBoardsService
NewMessageBoardsService creates a new MessageBoardsService.
func (*MessageBoardsService) Get ¶
func (s *MessageBoardsService) Get(ctx context.Context, boardID int64) (result *MessageBoard, err error)
Get returns a message board by ID.
type MessageListOptions ¶
type MessageListOptions struct {
// Limit is the maximum number of messages to return.
// If 0, uses DefaultMessageLimit (100). Use -1 for unlimited.
Limit int
// Page, if non-zero, disables pagination and returns only the first page.
// NOTE: The page number itself is not yet honored due to OpenAPI client
// limitations. Use 0 to paginate through all results up to Limit.
Page int
}
MessageListOptions specifies options for listing messages.
type MessageListResult ¶
type MessageListResult struct {
// Messages is the list of messages returned.
Messages []Message
// Meta contains pagination metadata (total count, etc.).
Meta ListMeta
}
MessageListResult contains the results from listing messages.
type MessageType ¶
type MessageType struct {
ID int64 `json:"id"`
Name string `json:"name"`
Icon string `json:"icon"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
MessageType represents a Basecamp message type (category) in a project.
type MessageTypeListResult ¶
type MessageTypeListResult struct {
// MessageTypes is the list of message types returned.
MessageTypes []MessageType
// Meta contains pagination metadata (total count, etc.).
Meta ListMeta
}
MessageTypeListResult contains the results from listing message types.
type MessageTypesService ¶
type MessageTypesService struct {
// contains filtered or unexported fields
}
MessageTypesService handles message type operations.
func NewMessageTypesService ¶
func NewMessageTypesService(client *AccountClient) *MessageTypesService
NewMessageTypesService creates a new MessageTypesService.
func (*MessageTypesService) Create ¶
func (s *MessageTypesService) Create(ctx context.Context, req *CreateMessageTypeRequest) (result *MessageType, err error)
Create creates a new message type in a project. Returns the created message type.
func (*MessageTypesService) Delete ¶
func (s *MessageTypesService) Delete(ctx context.Context, typeID int64) (err error)
Delete deletes a message type from a project.
func (*MessageTypesService) Get ¶
func (s *MessageTypesService) Get(ctx context.Context, typeID int64) (result *MessageType, err error)
Get returns a message type by ID.
func (*MessageTypesService) List ¶
func (s *MessageTypesService) List(ctx context.Context) (result *MessageTypeListResult, err error)
List returns all message types for the account.
The returned MessageTypeListResult includes pagination metadata (TotalCount from X-Total-Count header) when available.
func (*MessageTypesService) Update ¶
func (s *MessageTypesService) Update(ctx context.Context, typeID int64, req *UpdateMessageTypeRequest) (result *MessageType, err error)
Update updates an existing message type. Returns the updated message type.
type MessagesService ¶
type MessagesService struct {
// contains filtered or unexported fields
}
MessagesService handles message operations.
func NewMessagesService ¶
func NewMessagesService(client *AccountClient) *MessagesService
NewMessagesService creates a new MessagesService.
func (*MessagesService) Archive ¶
func (s *MessagesService) Archive(ctx context.Context, messageID int64) (err error)
Archive moves a message to the archive. Archived messages can be unarchived.
func (*MessagesService) Create ¶
func (s *MessagesService) Create(ctx context.Context, boardID int64, req *CreateMessageRequest) (result *Message, err error)
Create creates a new message on a message board. Returns the created message.
Example ¶
package main
import (
"context"
"fmt"
"log"
"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)
ctx := context.Background()
boardID := int64(789012)
// Create a message on a message board
message, err := client.ForAccount("12345").Messages().Create(ctx, boardID, &basecamp.CreateMessageRequest{
Subject: "Weekly Update",
Content: "<p>Here's what we accomplished this week...</p>",
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("Posted: %s\n", message.Subject)
}
Output:
func (*MessagesService) List ¶
func (s *MessagesService) List(ctx context.Context, boardID int64, opts *MessageListOptions) (result *MessageListResult, err error)
List returns messages on a message board.
By default, returns up to 100 messages. Use Limit: -1 for unlimited.
Pagination options:
- Limit: maximum number of messages to return (0 = 100, -1 = unlimited)
- Page: if non-zero, disables pagination and returns first page only
The returned MessageListResult includes pagination metadata (TotalCount from X-Total-Count header) when available.
func (*MessagesService) Pin ¶
func (s *MessagesService) Pin(ctx context.Context, messageID int64) (err error)
Pin pins a message to the top of the message board.
func (*MessagesService) Trash ¶
func (s *MessagesService) Trash(ctx context.Context, messageID int64) (err error)
Trash moves a message to the trash. Trashed messages can be recovered from the trash.
func (*MessagesService) Unarchive ¶
func (s *MessagesService) Unarchive(ctx context.Context, messageID int64) (err error)
Unarchive restores an archived message to active status.
func (*MessagesService) Unpin ¶
func (s *MessagesService) Unpin(ctx context.Context, messageID int64) (err error)
Unpin unpins a message from the top of the message board.
func (*MessagesService) Update ¶
func (s *MessagesService) Update(ctx context.Context, messageID int64, req *UpdateMessageRequest) (result *Message, err error)
Update updates an existing message. Returns the updated message.
type MoveCardRequest ¶
type MoveCardRequest struct {
// ColumnID is the destination column ID (required).
ColumnID int64 `json:"column_id"`
}
MoveCardRequest specifies the parameters for moving a card.
type MoveColumnRequest ¶
type MoveColumnRequest struct {
// SourceID is the column ID to move (required).
SourceID int64 `json:"source_id"`
// TargetID is the column ID to move relative to (required).
TargetID int64 `json:"target_id"`
// Position is the position relative to target (optional).
Position int `json:"position,omitempty"`
}
MoveColumnRequest specifies the parameters for moving a column.
type NoopHooks ¶
type NoopHooks struct{}
NoopHooks is a no-op implementation of Hooks. All methods are empty and designed to be inlined by the compiler, resulting in zero overhead when no observability is needed.
func (NoopHooks) OnOperationEnd ¶
OnOperationEnd does nothing.
func (NoopHooks) OnOperationStart ¶
OnOperationStart does nothing and returns the context unchanged.
func (NoopHooks) OnRequestEnd ¶
func (NoopHooks) OnRequestEnd(context.Context, RequestInfo, RequestResult)
OnRequestEnd does nothing.
func (NoopHooks) OnRequestStart ¶
OnRequestStart does nothing and returns the context unchanged.
type OperationInfo ¶
type OperationInfo struct {
// Service is the logical service (e.g., "Projects", "Todos").
Service string
// Operation is the specific method (e.g., "List", "Create", "Complete").
Operation string
// ResourceType is the Basecamp resource type (e.g., "project", "todo").
ResourceType string
// IsMutation indicates if this operation modifies state.
IsMutation bool
// ResourceID is the specific resource ID if applicable.
ResourceID int64
}
OperationInfo describes a semantic SDK operation. This carries more meaning than raw HTTP requests, enabling business-level tracing and metrics (e.g., "Todos.Complete" not "POST /url").
type OverdueTodosResponse ¶
type OverdueTodosResponse struct {
UnderAWeekLate []Todo `json:"under_a_week_late"`
OverAWeekLate []Todo `json:"over_a_week_late"`
OverAMonthLate []Todo `json:"over_a_month_late"`
OverThreeMonthsLate []Todo `json:"over_three_months_late"`
}
OverdueTodosResponse contains overdue todos grouped by lateness.
type Parent ¶
type Parent struct {
ID int64 `json:"id"`
Title string `json:"title"`
Type string `json:"type"`
URL string `json:"url"`
AppURL string `json:"app_url"`
}
Parent represents the parent object of a todo.
type PeopleListOptions ¶
type PeopleListOptions struct {
// Limit is the maximum number of people to return.
// If 0 (default), returns all people.
Limit int
// Page, if non-zero, disables pagination and returns only the first page.
// NOTE: The page number itself is not yet honored due to OpenAPI client
// limitations. Use 0 to paginate through all results up to Limit.
Page int
}
PeopleListOptions specifies options for listing people.
type PeopleListResult ¶
type PeopleListResult struct {
// People is the list of people returned.
People []Person
// Meta contains pagination metadata (total count, etc.).
Meta ListMeta
}
PeopleListResult contains the results from listing people.
type PeopleService ¶
type PeopleService struct {
// contains filtered or unexported fields
}
PeopleService handles people operations.
func NewPeopleService ¶
func NewPeopleService(client *AccountClient) *PeopleService
NewPeopleService creates a new PeopleService.
func (*PeopleService) List ¶
func (s *PeopleService) List(ctx context.Context, opts *PeopleListOptions) (result *PeopleListResult, err error)
List returns all people visible to the current user in the account.
Pagination options:
- Limit: maximum number of people to return (0 = all)
- Page: if non-zero, disables pagination and returns first page only
The returned PeopleListResult includes pagination metadata (TotalCount from X-Total-Count header) when available.
Example ¶
package main
import (
"context"
"fmt"
"log"
"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)
ctx := context.Background()
// List all people in the account
peopleResult, err := client.ForAccount("12345").People().List(ctx, nil)
if err != nil {
log.Fatal(err)
}
for _, p := range peopleResult.People {
fmt.Printf("%s <%s>\n", p.Name, p.EmailAddress)
}
}
Output:
func (*PeopleService) ListProjectPeople ¶
func (s *PeopleService) ListProjectPeople(ctx context.Context, projectID int64, opts *PeopleListOptions) (result *PeopleListResult, err error)
ListProjectPeople returns all active people on a project.
Pagination options:
- Limit: maximum number of people to return (0 = all)
- Page: if non-zero, disables pagination and returns first page only
The returned PeopleListResult includes pagination metadata (TotalCount from X-Total-Count header) when available.
func (*PeopleService) Me ¶
func (s *PeopleService) Me(ctx context.Context) (result *Person, err error)
Me returns the current authenticated user's profile.
func (*PeopleService) Pingable ¶
func (s *PeopleService) Pingable(ctx context.Context) (result []Person, err error)
Pingable returns all account users who can be pinged. Note: This endpoint is not paginated in the Basecamp API.
func (*PeopleService) UpdateProjectAccess ¶
func (s *PeopleService) UpdateProjectAccess(ctx context.Context, projectID int64, req *UpdateProjectAccessRequest) (result *UpdateProjectAccessResponse, err error)
UpdateProjectAccess grants or revokes project access for people. Returns the list of people who were granted and revoked access.
type Person ¶
type Person struct {
ID int64 `json:"id"`
AttachableSGID string `json:"attachable_sgid,omitempty"`
Name string `json:"name"`
EmailAddress string `json:"email_address,omitempty"`
PersonableType string `json:"personable_type,omitempty"`
Title string `json:"title,omitempty"`
Bio string `json:"bio,omitempty"`
Location string `json:"location,omitempty"`
CreatedAt string `json:"created_at,omitempty"`
UpdatedAt string `json:"updated_at,omitempty"`
Admin bool `json:"admin,omitempty"`
Owner bool `json:"owner,omitempty"`
Client bool `json:"client,omitempty"`
Employee bool `json:"employee,omitempty"`
TimeZone string `json:"time_zone,omitempty"`
AvatarURL string `json:"avatar_url,omitempty"`
CanPing bool `json:"can_ping,omitempty"`
Company *PersonCompany `json:"company,omitempty"`
CanManageProjects bool `json:"can_manage_projects,omitempty"`
CanManagePeople bool `json:"can_manage_people,omitempty"`
}
Person represents a Basecamp user.
type PersonCompany ¶
PersonCompany represents a company associated with a person.
type PersonProgressResponse ¶
type PersonProgressResponse struct {
Person *Person `json:"person"`
Events []TimelineEvent `json:"events"`
}
PersonProgressResponse contains a person's activity timeline.
type Project ¶
type Project struct {
ID int64 `json:"id"`
Status string `json:"status"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Name string `json:"name"`
Description string `json:"description"`
Purpose string `json:"purpose"`
ClientsEnabled bool `json:"clients_enabled"`
BookmarkURL string `json:"bookmark_url"`
URL string `json:"url"`
AppURL string `json:"app_url"`
Dock []DockItem `json:"dock,omitempty"`
Bookmarked bool `json:"bookmarked"`
ClientCompany *ClientCompany `json:"client_company,omitempty"`
Clientside *Clientside `json:"clientside,omitempty"`
}
Project represents a Basecamp project.
type ProjectConstruction ¶
type ProjectConstruction struct {
ID int64 `json:"id"`
Status string `json:"status"`
URL string `json:"url"`
Project *Project `json:"project,omitempty"`
}
ProjectConstruction represents the status of a project being created from a template.
type ProjectListOptions ¶
type ProjectListOptions struct {
// Status filters by project status (active, archived, trashed).
// If empty, defaults to active projects.
Status ProjectStatus
// Limit is the maximum number of projects to return.
// If 0 (default), returns all projects.
Limit int
// Page, if non-zero, disables pagination and returns only the first page.
// NOTE: The page number itself is not yet honored due to OpenAPI client
// limitations. Use 0 to paginate through all results up to Limit.
Page int
}
ProjectListOptions specifies options for listing projects.
type ProjectListResult ¶
type ProjectListResult struct {
// Projects is the list of projects returned.
Projects []Project
// Meta contains pagination metadata (total count, etc.).
Meta ListMeta
}
ProjectListResult contains the results from listing projects.
type ProjectStatus ¶
type ProjectStatus string
ProjectStatus represents valid project statuses.
const ( ProjectStatusActive ProjectStatus = "active" ProjectStatusArchived ProjectStatus = "archived" ProjectStatusTrashed ProjectStatus = "trashed" )
type ProjectsService ¶
type ProjectsService struct {
// contains filtered or unexported fields
}
ProjectsService handles project operations.
func NewProjectsService ¶
func NewProjectsService(client *AccountClient) *ProjectsService
NewProjectsService creates a new ProjectsService.
func (*ProjectsService) Create ¶
func (s *ProjectsService) Create(ctx context.Context, req *CreateProjectRequest) (result *Project, err error)
Create creates a new project. Returns the created project.
Example ¶
package main
import (
"context"
"fmt"
"log"
"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)
ctx := context.Background()
// Create a new project
project, err := client.ForAccount("12345").Projects().Create(ctx, &basecamp.CreateProjectRequest{
Name: "Q1 Planning",
Description: "Planning for the first quarter",
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("Created project: %s (ID: %d)\n", project.Name, project.ID)
}
Output:
func (*ProjectsService) List ¶
func (s *ProjectsService) List(ctx context.Context, opts *ProjectListOptions) (result *ProjectListResult, err error)
List returns all projects visible to the current user. By default, returns active projects sorted by most recently created first.
Pagination options:
- Limit: maximum number of projects to return (0 = all)
- Page: if non-zero, disables pagination and returns first page only
The returned ProjectListResult includes pagination metadata (TotalCount from X-Total-Count header) when available.
Example ¶
package main
import (
"context"
"fmt"
"log"
"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)
ctx := context.Background()
// List all active projects
result, err := client.ForAccount("12345").Projects().List(ctx, nil)
if err != nil {
log.Fatal(err)
}
for _, p := range result.Projects {
fmt.Printf("Project: %s (ID: %d)\n", p.Name, p.ID)
}
}
Output:
Example (Archived) ¶
package main
import (
"context"
"fmt"
"log"
"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)
ctx := context.Background()
// List archived projects
result, err := client.ForAccount("12345").Projects().List(ctx, &basecamp.ProjectListOptions{
Status: basecamp.ProjectStatusArchived,
})
if err != nil {
log.Fatal(err)
}
for _, p := range result.Projects {
fmt.Printf("Archived: %s\n", p.Name)
}
}
Output:
func (*ProjectsService) Trash ¶
func (s *ProjectsService) Trash(ctx context.Context, id int64) (err error)
Trash moves a project to the trash. Trashed projects are deleted after 30 days.
func (*ProjectsService) Update ¶
func (s *ProjectsService) Update(ctx context.Context, id int64, req *UpdateProjectRequest) (result *Project, err error)
Update updates an existing project. Returns the updated project.
type Question ¶
type Question struct {
ID int64 `json:"id"`
Status string `json:"status"`
VisibleToClients bool `json:"visible_to_clients"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Title string `json:"title"`
InheritsStatus bool `json:"inherits_status"`
Type string `json:"type"`
URL string `json:"url"`
AppURL string `json:"app_url"`
BookmarkURL string `json:"bookmark_url"`
SubscriptionURL string `json:"subscription_url"`
Parent *Parent `json:"parent,omitempty"`
Bucket *Bucket `json:"bucket,omitempty"`
Creator *Person `json:"creator,omitempty"`
Paused bool `json:"paused"`
Schedule *QuestionSchedule `json:"schedule,omitempty"`
AnswersCount int `json:"answers_count"`
AnswersURL string `json:"answers_url"`
}
Question represents a Basecamp automatic check-in question.
type QuestionAnswer ¶
type QuestionAnswer struct {
ID int64 `json:"id"`
Status string `json:"status"`
VisibleToClients bool `json:"visible_to_clients"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Title string `json:"title"`
InheritsStatus bool `json:"inherits_status"`
Type string `json:"type"`
URL string `json:"url"`
AppURL string `json:"app_url"`
BookmarkURL string `json:"bookmark_url"`
SubscriptionURL string `json:"subscription_url"`
CommentsCount int `json:"comments_count"`
CommentsURL string `json:"comments_url"`
Content string `json:"content"`
GroupOn string `json:"group_on"`
Parent *Parent `json:"parent,omitempty"`
Bucket *Bucket `json:"bucket,omitempty"`
Creator *Person `json:"creator,omitempty"`
}
QuestionAnswer represents an answer to a Basecamp check-in question.
type QuestionListOptions ¶
type QuestionListOptions struct {
// Limit is the maximum number of questions to return.
// If 0 (default), returns all questions. Use a positive value to cap results.
Limit int
// Page, if non-zero, disables pagination and returns only the first page.
// NOTE: The page number itself is not yet honored due to OpenAPI client
// limitations. Use 0 to paginate through all results up to Limit.
Page int
}
QuestionListOptions specifies options for listing questions.
type QuestionListResult ¶
type QuestionListResult struct {
// Questions is the list of questions returned.
Questions []Question
// Meta contains pagination metadata (total count, etc.).
Meta ListMeta
}
QuestionListResult contains the results from listing questions.
type QuestionSchedule ¶
type QuestionSchedule struct {
Frequency string `json:"frequency"`
Days []int `json:"days"`
Hour int `json:"hour"`
Minute int `json:"minute"`
WeekInstance *int `json:"week_instance,omitempty"`
WeekInterval *int `json:"week_interval,omitempty"`
MonthInterval *int `json:"month_interval,omitempty"`
StartDate string `json:"start_date,omitempty"`
EndDate string `json:"end_date,omitempty"`
}
QuestionSchedule represents the schedule configuration for a question.
type Questionnaire ¶
type Questionnaire struct {
ID int64 `json:"id"`
Status string `json:"status"`
VisibleToClients bool `json:"visible_to_clients"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Title string `json:"title"`
InheritsStatus bool `json:"inherits_status"`
Type string `json:"type"`
URL string `json:"url"`
AppURL string `json:"app_url"`
BookmarkURL string `json:"bookmark_url"`
QuestionsURL string `json:"questions_url"`
QuestionsCount int `json:"questions_count"`
Name string `json:"name"`
Bucket *Bucket `json:"bucket,omitempty"`
Creator *Person `json:"creator,omitempty"`
}
Questionnaire represents a Basecamp automatic check-in questionnaire.
type RateLimitConfig ¶
type RateLimitConfig struct {
// RequestsPerSecond is the sustained rate of requests allowed.
// Default: 50
RequestsPerSecond float64
// BurstSize is the maximum number of requests allowed in a burst.
// Default: 10
BurstSize int
// RespectRetryAfter honors 429 Retry-After headers by blocking requests
// until the server-specified time has passed.
// Default: true
RespectRetryAfter bool
// Now is a function that returns the current time. Used for testing.
// If nil, time.Now is used.
Now func() time.Time
}
RateLimitConfig configures client-side rate limiting.
func DefaultRateLimitConfig ¶
func DefaultRateLimitConfig() *RateLimitConfig
DefaultRateLimitConfig returns production-ready defaults.
type Recording ¶
type Recording struct {
ID int64 `json:"id"`
Status string `json:"status"`
VisibleToClients bool `json:"visible_to_clients"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Title string `json:"title"`
InheritsStatus bool `json:"inherits_status"`
Type string `json:"type"`
URL string `json:"url"`
AppURL string `json:"app_url"`
BookmarkURL string `json:"bookmark_url"`
Parent *Parent `json:"parent,omitempty"`
Bucket *Bucket `json:"bucket,omitempty"`
Creator *Person `json:"creator,omitempty"`
}
Recording represents a generic Basecamp recording. Recordings are the base type for most content in Basecamp including messages, todos, comments, documents, and more.
type RecordingListResult ¶
type RecordingListResult struct {
// Recordings is the list of recordings returned.
Recordings []Recording
// Meta contains pagination metadata (total count, etc.).
Meta ListMeta
}
RecordingListResult contains the results from listing recordings.
type RecordingType ¶
type RecordingType string
RecordingType represents a type of recording in Basecamp.
const ( RecordingTypeComment RecordingType = "Comment" RecordingTypeDocument RecordingType = "Document" RecordingTypeKanbanCard RecordingType = "Kanban::Card" RecordingTypeKanbanStep RecordingType = "Kanban::Step" RecordingTypeMessage RecordingType = "Message" RecordingTypeQuestionAnswer RecordingType = "Question::Answer" RecordingTypeScheduleEntry RecordingType = "Schedule::Entry" RecordingTypeTodo RecordingType = "Todo" RecordingTypeTodolist RecordingType = "Todolist" RecordingTypeUpload RecordingType = "Upload" RecordingTypeVault RecordingType = "Vault" )
Recording types supported by the Basecamp API.
type RecordingsListOptions ¶
type RecordingsListOptions struct {
// Bucket filters by project IDs (comma-separated or slice).
// Defaults to all active projects visible to the user.
Bucket []int64
// Status filters by recording status: "active", "archived", or "trashed".
// Defaults to "active".
Status string
// Sort specifies the sort field: "created_at" or "updated_at".
// Defaults to "created_at".
Sort string
// Direction specifies the sort direction: "desc" or "asc".
// Defaults to "desc".
Direction string
// Limit is the maximum number of recordings to return.
// If 0, uses DefaultRecordingLimit (100). Use -1 for unlimited.
Limit int
// Page, if non-zero, disables pagination and returns only the first page.
// NOTE: The page number itself is not yet honored due to OpenAPI client
// limitations. Use 0 to paginate through all results up to Limit.
Page int
}
RecordingsListOptions specifies options for listing recordings.
type RecordingsService ¶
type RecordingsService struct {
// contains filtered or unexported fields
}
RecordingsService handles recording operations. Recordings are the base type for most content in Basecamp.
func NewRecordingsService ¶
func NewRecordingsService(client *AccountClient) *RecordingsService
NewRecordingsService creates a new RecordingsService.
func (*RecordingsService) Archive ¶
func (s *RecordingsService) Archive(ctx context.Context, recordingID int64) (err error)
Archive archives a recording. Archived recordings are hidden but not deleted.
func (*RecordingsService) Get ¶
func (s *RecordingsService) Get(ctx context.Context, recordingID int64) (result *Recording, err error)
Get returns a recording by ID.
func (*RecordingsService) List ¶
func (s *RecordingsService) List(ctx context.Context, recordingType RecordingType, opts *RecordingsListOptions) (result *RecordingListResult, err error)
List returns all recordings of a given type across projects. recordingType is required and specifies what type of recordings to list. Use the RecordingType constants (e.g., RecordingTypeTodo, RecordingTypeMessage).
By default, returns up to 100 recordings. Use Limit: -1 for unlimited.
Pagination options:
- Limit: maximum number of recordings to return (0 = 100, -1 = unlimited)
- Page: if non-zero, disables pagination and returns first page only
The returned RecordingListResult includes pagination metadata (TotalCount from X-Total-Count header) when available.
func (*RecordingsService) SetClientVisibility ¶
func (s *RecordingsService) SetClientVisibility(ctx context.Context, recordingID int64, visible bool) (result *Recording, err error)
SetClientVisibility sets whether a recording is visible to clients. visible specifies whether the recording should be visible to clients. Returns the updated recording. Note: Not all recordings support client visibility. Some inherit visibility from their parent.
type ReportsService ¶
type ReportsService struct {
// contains filtered or unexported fields
}
ReportsService handles reports operations.
func NewReportsService ¶
func NewReportsService(client *AccountClient) *ReportsService
NewReportsService creates a new ReportsService.
func (*ReportsService) AssignablePeople ¶
func (s *ReportsService) AssignablePeople(ctx context.Context) (result []Person, err error)
AssignablePeople returns people who can be assigned todos.
func (*ReportsService) AssignedTodos ¶
func (s *ReportsService) AssignedTodos(ctx context.Context, personID int64, opts *AssignedTodosOptions) (result *AssignedTodosResponse, err error)
AssignedTodos returns todos assigned to a specific person.
func (*ReportsService) OverdueTodos ¶
func (s *ReportsService) OverdueTodos(ctx context.Context) (result *OverdueTodosResponse, err error)
OverdueTodos returns all overdue todos grouped by lateness.
func (*ReportsService) UpcomingSchedule ¶
func (s *ReportsService) UpcomingSchedule(ctx context.Context, startDate, endDate string) (result *UpcomingScheduleResponse, err error)
UpcomingSchedule returns schedule entries within a date window. startDate and endDate should be in YYYY-MM-DD format.
type RequestInfo ¶
type RequestInfo struct {
Method string
URL string
// Attempt is the current attempt number (1-indexed).
Attempt int
}
RequestInfo contains information about an HTTP request.
type RequestResult ¶
type RequestResult struct {
// StatusCode is the HTTP status code (0 if request failed before response).
StatusCode int
// Duration is the time taken for the request.
Duration time.Duration
// Error is non-nil if the request failed.
Error error
// FromCache indicates the response was served from cache.
FromCache bool
// Retryable indicates whether this error will be retried.
Retryable bool
// RetryAfter is the Retry-After header value in seconds (0 if not present).
// Used by resilience hooks to respect server-requested backoff on 429/503.
RetryAfter int
}
RequestResult contains the result of an HTTP request.
type ResilienceConfig ¶
type ResilienceConfig struct {
// CircuitBreaker configuration. If nil, circuit breaker is disabled.
CircuitBreaker *CircuitBreakerConfig
// Bulkhead configuration. If nil, bulkhead is disabled.
Bulkhead *BulkheadConfig
// RateLimit configuration. If nil, rate limiting is disabled.
RateLimit *RateLimitConfig
}
ResilienceConfig combines all resilience settings. Use DefaultResilienceConfig() for production-ready defaults.
func DefaultResilienceConfig ¶
func DefaultResilienceConfig() *ResilienceConfig
DefaultResilienceConfig returns production-ready defaults for all resilience features.
type Response ¶
Response wraps an API response.
func (*Response) UnmarshalData ¶
UnmarshalData unmarshals the response data into the given value.
type Router ¶
type Router struct {
// contains filtered or unexported fields
}
Router matches Basecamp URLs against the OpenAPI-derived route table, with structural fallbacks for web-only URLs.
func DefaultRouter ¶
func DefaultRouter() *Router
DefaultRouter returns a shared Router instance using the embedded route table.
func (*Router) Match ¶
Match parses a Basecamp URL and returns the matched route and extracted parameters. Returns nil if the URL does not look like a Basecamp URL.
First tries the spec-derived API route table for a rich match (Source=MatchedAPI). Falls back to structural pattern matching for web-only URLs (Source=MatchedStructural).
func (*Router) MatchAPI ¶
MatchAPI matches only against the spec-derived API route table. Returns nil if the URL doesn't correspond to a known API route. Use this when you need to resolve a URL to a specific API operation.
func (*Router) MatchStructural ¶
MatchStructural matches only against Basecamp's web URL conventions. Returns nil if the URL doesn't look like a Basecamp URL. Use this when you know you have a web URL and only need ID extraction.
type Schedule ¶
type Schedule struct {
ID int64 `json:"id"`
Status string `json:"status"`
VisibleToClients bool `json:"visible_to_clients"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Title string `json:"title"`
InheritsStatus bool `json:"inherits_status"`
Type string `json:"type"`
URL string `json:"url"`
AppURL string `json:"app_url"`
BookmarkURL string `json:"bookmark_url"`
Position int `json:"position"`
Bucket *Bucket `json:"bucket,omitempty"`
Creator *Person `json:"creator,omitempty"`
IncludeDueAssignments bool `json:"include_due_assignments"`
EntriesCount int `json:"entries_count"`
EntriesURL string `json:"entries_url"`
}
Schedule represents a Basecamp schedule (calendar) within a project.
type ScheduleAttributes ¶
type ScheduleAttributes struct {
// StartDate is the project start date (ISO 8601 format, e.g., "2022-01-01").
StartDate string `json:"start_date"`
// EndDate is the project end date (ISO 8601 format).
EndDate string `json:"end_date"`
}
ScheduleAttributes specifies project schedule dates.
type ScheduleEntry ¶
type ScheduleEntry struct {
ID int64 `json:"id"`
Status string `json:"status"`
VisibleToClients bool `json:"visible_to_clients"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Title string `json:"title"`
Summary string `json:"summary"`
InheritsStatus bool `json:"inherits_status"`
Type string `json:"type"`
URL string `json:"url"`
AppURL string `json:"app_url"`
BookmarkURL string `json:"bookmark_url"`
SubscriptionURL string `json:"subscription_url"`
CommentsURL string `json:"comments_url"`
CommentsCount int `json:"comments_count"`
StartsAt time.Time `json:"starts_at"`
EndsAt time.Time `json:"ends_at"`
AllDay bool `json:"all_day"`
Description string `json:"description"`
Parent *Parent `json:"parent,omitempty"`
Bucket *Bucket `json:"bucket,omitempty"`
Creator *Person `json:"creator,omitempty"`
Participants []Person `json:"participants,omitempty"`
}
ScheduleEntry represents an event on a Basecamp schedule.
type ScheduleEntryListOptions ¶
type ScheduleEntryListOptions struct {
// Limit is the maximum number of entries to return.
// If 0 (default), returns all entries. Use a positive value to cap results.
Limit int
// Page, if non-zero, disables pagination and returns only the first page.
// NOTE: The page number itself is not yet honored due to OpenAPI client
// limitations. Use 0 to paginate through all results up to Limit.
Page int
// Status filters entries by status: "active", "archived", or "trashed".
// If empty, returns active entries (API default).
Status string
}
ScheduleEntryListOptions specifies options for listing schedule entries.
type ScheduleEntryListResult ¶
type ScheduleEntryListResult struct {
// Entries is the list of schedule entries returned.
Entries []ScheduleEntry
// Meta contains pagination metadata (total count, etc.).
Meta ListMeta
}
ScheduleEntryListResult contains the results from listing schedule entries.
type SchedulesService ¶
type SchedulesService struct {
// contains filtered or unexported fields
}
SchedulesService handles schedule operations.
func NewSchedulesService ¶
func NewSchedulesService(client *AccountClient) *SchedulesService
NewSchedulesService creates a new SchedulesService.
func (*SchedulesService) CreateEntry ¶
func (s *SchedulesService) CreateEntry(ctx context.Context, scheduleID int64, req *CreateScheduleEntryRequest) (result *ScheduleEntry, err error)
CreateEntry creates a new entry on a schedule. Returns the created schedule entry.
func (*SchedulesService) GetEntry ¶
func (s *SchedulesService) GetEntry(ctx context.Context, entryID int64) (result *ScheduleEntry, err error)
GetEntry returns a schedule entry by ID.
func (*SchedulesService) GetEntryOccurrence ¶
func (s *SchedulesService) GetEntryOccurrence(ctx context.Context, entryID int64, date string) (result *ScheduleEntry, err error)
GetEntryOccurrence returns a specific occurrence of a recurring schedule entry.
func (*SchedulesService) ListEntries ¶
func (s *SchedulesService) ListEntries(ctx context.Context, scheduleID int64, opts *ScheduleEntryListOptions) (result *ScheduleEntryListResult, err error)
ListEntries returns all entries on a schedule.
By default, returns all entries (no limit). Use Limit to cap results.
Pagination options:
- Limit: maximum number of entries to return (0 = all)
- Page: if non-zero, disables pagination and returns first page only
The returned ScheduleEntryListResult includes pagination metadata (TotalCount from X-Total-Count header) when available.
func (*SchedulesService) TrashEntry ¶
func (s *SchedulesService) TrashEntry(ctx context.Context, entryID int64) (err error)
TrashEntry moves a schedule entry to the trash. Trashed entries can be recovered from the trash.
func (*SchedulesService) UpdateEntry ¶
func (s *SchedulesService) UpdateEntry(ctx context.Context, entryID int64, req *UpdateScheduleEntryRequest) (result *ScheduleEntry, err error)
UpdateEntry updates an existing schedule entry. Returns the updated schedule entry.
func (*SchedulesService) UpdateSettings ¶
func (s *SchedulesService) UpdateSettings(ctx context.Context, scheduleID int64, req *UpdateScheduleSettingsRequest) (result *Schedule, err error)
UpdateSettings updates the settings for a schedule. Returns the updated schedule.
type SearchMetadata ¶
type SearchMetadata struct {
Projects []SearchProject `json:"projects"`
}
SearchMetadata represents metadata about available search scopes.
type SearchOptions ¶
type SearchOptions struct {
// Sort specifies the sort order: "created_at" or "updated_at" (default: relevance).
Sort string
}
SearchOptions specifies optional parameters for search.
type SearchProject ¶
SearchProject represents a project available for search scope filtering.
type SearchResult ¶
type SearchResult struct {
ID int64 `json:"id"`
Status string `json:"status"`
VisibleToClients bool `json:"visible_to_clients"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Title string `json:"title"`
InheritsStatus bool `json:"inherits_status"`
Type string `json:"type"`
URL string `json:"url"`
AppURL string `json:"app_url"`
BookmarkURL string `json:"bookmark_url"`
Parent *Parent `json:"parent,omitempty"`
Bucket *Bucket `json:"bucket,omitempty"`
Creator *Person `json:"creator,omitempty"`
Content string `json:"content,omitempty"`
Description string `json:"description,omitempty"`
Subject string `json:"subject,omitempty"`
}
SearchResult represents a single search result from the Basecamp API.
type SearchService ¶
type SearchService struct {
// contains filtered or unexported fields
}
SearchService handles search operations.
func NewSearchService ¶
func NewSearchService(client *AccountClient) *SearchService
NewSearchService creates a new SearchService.
func (*SearchService) Metadata ¶
func (s *SearchService) Metadata(ctx context.Context) (result *SearchMetadata, err error)
Metadata returns metadata about available search scopes. This includes the list of projects available for filtering.
func (*SearchService) Search ¶
func (s *SearchService) Search(ctx context.Context, query string, opts *SearchOptions) (result []SearchResult, err error)
Search searches for content across the account. The query parameter is the search string. Returns a list of matching results.
Example ¶
package main
import (
"context"
"fmt"
"log"
"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)
ctx := context.Background()
// Search across the account
results, err := client.ForAccount("12345").Search().Search(ctx, "quarterly report", nil)
if err != nil {
log.Fatal(err)
}
for _, r := range results {
fmt.Printf("[%s] %s\n", r.Type, r.Title)
}
}
Output:
Example (Sorted) ¶
package main
import (
"context"
"fmt"
"log"
"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)
ctx := context.Background()
// Search with results sorted by creation date
results, err := client.ForAccount("12345").Search().Search(ctx, "meeting notes", &basecamp.SearchOptions{
Sort: "created_at",
})
if err != nil {
log.Fatal(err)
}
for _, r := range results {
fmt.Printf("%s: %s\n", r.CreatedAt.Format("2006-01-02"), r.Title)
}
}
Output:
type SetClientVisibilityRequest ¶
type SetClientVisibilityRequest struct {
VisibleToClients bool `json:"visible_to_clients"`
}
SetClientVisibilityRequest specifies the parameters for setting client visibility.
type SetColumnColorRequest ¶
type SetColumnColorRequest struct {
// Color is the column color. Valid values: white, red, orange, yellow,
// green, blue, aqua, purple, gray, pink, brown (required).
Color string `json:"color"`
}
SetColumnColorRequest specifies the parameters for changing a column color.
type SlogHooks ¶
type SlogHooks struct {
// contains filtered or unexported fields
}
SlogHooks is a Hooks implementation that logs to a *slog.Logger. It provides structured logging for all SDK operations (both semantic and HTTP).
func NewSlogHooks ¶
func NewSlogHooks(logger *slog.Logger, opts ...SlogHooksOption) *SlogHooks
NewSlogHooks creates a new SlogHooks that logs to the given logger. If logger is nil, uses slog.Default().
func (*SlogHooks) OnOperationEnd ¶
func (h *SlogHooks) OnOperationEnd(ctx context.Context, op OperationInfo, err error, duration time.Duration)
OnOperationEnd logs the completion of a semantic SDK operation.
func (*SlogHooks) OnOperationStart ¶
OnOperationStart logs the start of a semantic SDK operation.
func (*SlogHooks) OnRequestEnd ¶
func (h *SlogHooks) OnRequestEnd(ctx context.Context, info RequestInfo, result RequestResult)
OnRequestEnd logs the completion of an HTTP request.
func (*SlogHooks) OnRequestStart ¶
OnRequestStart logs the start of an HTTP request.
type SlogHooksOption ¶
type SlogHooksOption func(*SlogHooks)
SlogHooksOption configures a SlogHooks instance.
func WithLevel ¶
func WithLevel(level slog.Level) SlogHooksOption
WithLevel sets the log level for SlogHooks. Default is slog.LevelDebug.
type StaticTokenProvider ¶
type StaticTokenProvider struct {
Token string
}
StaticTokenProvider provides a fixed token (e.g., from BASECAMP_TOKEN env var).
func (*StaticTokenProvider) AccessToken ¶
func (p *StaticTokenProvider) AccessToken(ctx context.Context) (string, error)
AccessToken returns the static token.
type Subscription ¶
type Subscription struct {
Subscribed bool `json:"subscribed"`
Count int `json:"count"`
URL string `json:"url"`
Subscribers []Person `json:"subscribers"`
}
Subscription represents the subscription state for a recording.
type SubscriptionsService ¶
type SubscriptionsService struct {
// contains filtered or unexported fields
}
SubscriptionsService handles subscription operations on recordings.
func NewSubscriptionsService ¶
func NewSubscriptionsService(client *AccountClient) *SubscriptionsService
NewSubscriptionsService creates a new SubscriptionsService.
func (*SubscriptionsService) Get ¶
func (s *SubscriptionsService) Get(ctx context.Context, recordingID int64) (result *Subscription, err error)
Get returns the subscription information for a recording.
func (*SubscriptionsService) Subscribe ¶
func (s *SubscriptionsService) Subscribe(ctx context.Context, recordingID int64) (result *Subscription, err error)
Subscribe subscribes the current user to the recording. Returns the updated subscription information.
func (*SubscriptionsService) Unsubscribe ¶
func (s *SubscriptionsService) Unsubscribe(ctx context.Context, recordingID int64) (err error)
Unsubscribe unsubscribes the current user from the recording. Returns nil on success (204 No Content).
func (*SubscriptionsService) Update ¶
func (s *SubscriptionsService) Update(ctx context.Context, recordingID int64, req *UpdateSubscriptionRequest) (result *Subscription, err error)
Update batch modifies subscriptions by adding or removing specific users. Returns the updated subscription information.
type Template ¶
type Template struct {
ID int64 `json:"id"`
Status string `json:"status"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Name string `json:"name"`
Description string `json:"description"`
}
Template represents a Basecamp project template.
type TemplateListResult ¶
type TemplateListResult struct {
// Templates is the list of templates returned.
Templates []Template
// Meta contains pagination metadata (total count, etc.).
Meta ListMeta
}
TemplateListResult contains the results from listing templates.
type TemplatesService ¶
type TemplatesService struct {
// contains filtered or unexported fields
}
TemplatesService handles template operations.
func NewTemplatesService ¶
func NewTemplatesService(client *AccountClient) *TemplatesService
NewTemplatesService creates a new TemplatesService.
func (*TemplatesService) Create ¶
func (s *TemplatesService) Create(ctx context.Context, req *CreateTemplateRequest) (result *Template, err error)
Create creates a new template. Returns the created template.
func (*TemplatesService) CreateProject ¶
func (s *TemplatesService) CreateProject(ctx context.Context, templateID int64, name, description string) (result *ProjectConstruction, err error)
CreateProject creates a new project from a template. This operation is asynchronous; use GetConstruction to check the status.
func (*TemplatesService) Delete ¶
func (s *TemplatesService) Delete(ctx context.Context, templateID int64) (err error)
Delete deletes a template.
func (*TemplatesService) GetConstruction ¶
func (s *TemplatesService) GetConstruction(ctx context.Context, templateID, constructionID int64) (result *ProjectConstruction, err error)
GetConstruction returns the status of a project construction.
func (*TemplatesService) List ¶
func (s *TemplatesService) List(ctx context.Context) (result *TemplateListResult, err error)
List returns all templates visible to the current user.
The returned TemplateListResult includes pagination metadata (TotalCount from X-Total-Count header) when available.
func (*TemplatesService) Update ¶
func (s *TemplatesService) Update(ctx context.Context, templateID int64, req *UpdateTemplateRequest) (result *Template, err error)
Update updates an existing template. Returns the updated template.
type TimelineEvent ¶
type TimelineEvent struct {
ID int64 `json:"id"`
CreatedAt time.Time `json:"created_at"`
Kind string `json:"kind"`
ParentRecordingID int64 `json:"parent_recording_id"`
URL string `json:"url"`
AppURL string `json:"app_url"`
Creator *Person `json:"creator,omitempty"`
Action string `json:"action"`
Target string `json:"target"`
Title string `json:"title"`
SummaryExcerpt string `json:"summary_excerpt"`
Bucket *Bucket `json:"bucket,omitempty"`
}
TimelineEvent represents an activity event in the timeline.
type TimelineService ¶
type TimelineService struct {
// contains filtered or unexported fields
}
TimelineService handles timeline and progress operations.
func NewTimelineService ¶
func NewTimelineService(client *AccountClient) *TimelineService
NewTimelineService creates a new TimelineService.
func (*TimelineService) PersonProgress ¶
func (s *TimelineService) PersonProgress(ctx context.Context, personID int64) (result *PersonProgressResponse, err error)
PersonProgress returns the activity timeline for a specific person.
func (*TimelineService) Progress ¶
func (s *TimelineService) Progress(ctx context.Context) (result []TimelineEvent, err error)
Progress returns the account-wide activity feed. This shows recent activity across all projects.
func (*TimelineService) ProjectTimeline ¶
func (s *TimelineService) ProjectTimeline(ctx context.Context, projectID int64) (result []TimelineEvent, err error)
ProjectTimeline returns the activity timeline for a specific project.
type TimesheetEntry ¶
type TimesheetEntry struct {
ID int64 `json:"id"`
Date string `json:"date"`
Hours string `json:"hours"`
Description string `json:"description,omitempty"`
Creator *Person `json:"creator,omitempty"`
Person *Person `json:"person,omitempty"`
Parent *Parent `json:"parent,omitempty"`
Bucket *Bucket `json:"bucket,omitempty"`
BillableStatus string `json:"billable_status,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
TimesheetEntry represents a single time entry in a Basecamp timesheet report.
type TimesheetReportOptions ¶
type TimesheetReportOptions struct {
// From filters entries on or after this date (ISO 8601 format, e.g., "2024-01-01").
From string
// To filters entries on or before this date (ISO 8601 format, e.g., "2024-01-31").
To string
// PersonID filters entries by a specific person.
PersonID int64
}
TimesheetReportOptions specifies options for timesheet reports.
type TimesheetService ¶
type TimesheetService struct {
// contains filtered or unexported fields
}
TimesheetService handles timesheet report operations.
func NewTimesheetService ¶
func NewTimesheetService(client *AccountClient) *TimesheetService
NewTimesheetService creates a new TimesheetService.
func (*TimesheetService) Create ¶
func (s *TimesheetService) Create(ctx context.Context, recordingID int64, req *CreateTimesheetEntryRequest) (result *TimesheetEntry, err error)
Create creates a timesheet entry on a recording.
func (*TimesheetService) Get ¶
func (s *TimesheetService) Get(ctx context.Context, entryID int64) (result *TimesheetEntry, err error)
Get returns a single timesheet entry.
func (*TimesheetService) ProjectReport ¶
func (s *TimesheetService) ProjectReport(ctx context.Context, projectID int64, opts *TimesheetReportOptions) (result []TimesheetEntry, err error)
ProjectReport returns the timesheet report for a specific project. projectID is the project (bucket) ID.
func (*TimesheetService) RecordingReport ¶
func (s *TimesheetService) RecordingReport(ctx context.Context, recordingID int64, opts *TimesheetReportOptions) (result []TimesheetEntry, err error)
RecordingReport returns the timesheet report for a specific recording. recordingID is the recording ID (e.g., a todo).
func (*TimesheetService) Report ¶
func (s *TimesheetService) Report(ctx context.Context, opts *TimesheetReportOptions) (result []TimesheetEntry, err error)
Report returns the account-wide timesheet report. This includes time entries across all projects in the account.
func (*TimesheetService) Trash ¶
func (s *TimesheetService) Trash(ctx context.Context, entryID int64) (err error)
Trash moves a timesheet entry to the trash.
func (*TimesheetService) Update ¶
func (s *TimesheetService) Update(ctx context.Context, entryID int64, req *UpdateTimesheetEntryRequest) (result *TimesheetEntry, err error)
Update updates an existing timesheet entry.
type Todo ¶
type Todo struct {
ID int64 `json:"id"`
Status string `json:"status"`
VisibleTo []int64 `json:"visible_to"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Title string `json:"title"`
InheritsVis bool `json:"inherits_status"`
Type string `json:"type"`
URL string `json:"url"`
AppURL string `json:"app_url"`
BookmarkURL string `json:"bookmark_url"`
Parent *Parent `json:"parent,omitempty"`
Bucket *Bucket `json:"bucket,omitempty"`
Creator *Person `json:"creator,omitempty"`
Content string `json:"content"`
Description string `json:"description"`
StartsOn string `json:"starts_on,omitempty"`
DueOn string `json:"due_on,omitempty"`
Completed bool `json:"completed"`
BoostsCount int `json:"boosts_count,omitempty"`
CompletedAt *time.Time `json:"completed_at,omitempty"`
Completer *Person `json:"completer,omitempty"`
Assignees []Person `json:"assignees,omitempty"`
Position int `json:"position"`
}
Todo represents a Basecamp todo item.
type TodoListOptions ¶
type TodoListOptions struct {
// Status filters by completion status.
// "completed" returns completed todos, "pending" returns pending todos.
// Empty returns all todos.
Status string
// Limit is the maximum number of todos to return.
// If 0, uses DefaultTodoLimit (100). Use -1 for unlimited.
Limit int
// Page, if non-zero, disables pagination and returns only the first page.
// NOTE: The page number itself is not yet honored due to OpenAPI client
// limitations. Use 0 to paginate through all results up to Limit.
Page int
}
TodoListOptions specifies options for listing todos.
type TodoListResult ¶
type TodoListResult struct {
// Todos is the list of todos returned.
Todos []Todo
// Meta contains pagination metadata (total count, etc.).
Meta ListMeta
}
TodoListResult contains the results from listing todos.
type Todolist ¶
type Todolist struct {
ID int64 `json:"id"`
Status string `json:"status"`
VisibleToClients bool `json:"visible_to_clients"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Title string `json:"title"`
InheritsStatus bool `json:"inherits_status"`
Type string `json:"type"`
URL string `json:"url"`
AppURL string `json:"app_url"`
BookmarkURL string `json:"bookmark_url"`
SubscriptionURL string `json:"subscription_url"`
CommentsCount int `json:"comments_count"`
CommentsURL string `json:"comments_url"`
Position int `json:"position"`
Parent *Parent `json:"parent,omitempty"`
Bucket *Bucket `json:"bucket,omitempty"`
Creator *Person `json:"creator,omitempty"`
Description string `json:"description"`
Completed bool `json:"completed"`
CompletedRatio string `json:"completed_ratio"`
Name string `json:"name"`
TodosURL string `json:"todos_url"`
GroupsURL string `json:"groups_url"`
AppTodosURL string `json:"app_todos_url"`
}
Todolist represents a Basecamp todolist.
type TodolistGroup ¶
type TodolistGroup struct {
ID int64 `json:"id"`
Status string `json:"status"`
VisibleToClients bool `json:"visible_to_clients"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Title string `json:"title"`
InheritsStatus bool `json:"inherits_status"`
Type string `json:"type"`
URL string `json:"url"`
AppURL string `json:"app_url"`
BookmarkURL string `json:"bookmark_url"`
SubscriptionURL string `json:"subscription_url"`
CommentsCount int `json:"comments_count"`
CommentsURL string `json:"comments_url"`
Position int `json:"position"`
Parent *Parent `json:"parent,omitempty"`
Bucket *Bucket `json:"bucket,omitempty"`
Creator *Person `json:"creator,omitempty"`
Name string `json:"name"`
Completed bool `json:"completed"`
CompletedRatio string `json:"completed_ratio"`
TodosURL string `json:"todos_url"`
AppTodosURL string `json:"app_todos_url"`
}
TodolistGroup represents a Basecamp todolist group (organizational folder within a todolist).
type TodolistGroupListResult ¶
type TodolistGroupListResult struct {
// Groups is the list of todolist groups returned.
Groups []TodolistGroup
// Meta contains pagination metadata (total count, etc.).
Meta ListMeta
}
TodolistGroupListResult contains the results from listing todolist groups.
type TodolistGroupsService ¶
type TodolistGroupsService struct {
// contains filtered or unexported fields
}
TodolistGroupsService handles todolist group operations.
func NewTodolistGroupsService ¶
func NewTodolistGroupsService(client *AccountClient) *TodolistGroupsService
NewTodolistGroupsService creates a new TodolistGroupsService.
func (*TodolistGroupsService) Create ¶
func (s *TodolistGroupsService) Create(ctx context.Context, todolistID int64, req *CreateTodolistGroupRequest) (result *TodolistGroup, err error)
Create creates a new group in a todolist. Returns the created group.
func (*TodolistGroupsService) Get ¶
func (s *TodolistGroupsService) Get(ctx context.Context, groupID int64) (result *TodolistGroup, err error)
Get returns a todolist group by ID.
func (*TodolistGroupsService) List ¶
func (s *TodolistGroupsService) List(ctx context.Context, todolistID int64) (result *TodolistGroupListResult, err error)
List returns all groups in a todolist.
The returned TodolistGroupListResult includes pagination metadata (TotalCount from X-Total-Count header) when available.
func (*TodolistGroupsService) Reposition ¶
func (s *TodolistGroupsService) Reposition(ctx context.Context, groupID int64, position int) (err error)
Reposition changes the position of a group within its todolist. position is 1-based (1 = first position).
func (*TodolistGroupsService) Trash ¶
func (s *TodolistGroupsService) Trash(ctx context.Context, groupID int64) (err error)
Trash moves a todolist group to the trash. Trashed groups can be recovered from the trash.
func (*TodolistGroupsService) Update ¶
func (s *TodolistGroupsService) Update(ctx context.Context, groupID int64, req *UpdateTodolistGroupRequest) (result *TodolistGroup, err error)
Update updates an existing todolist group. Returns the updated group.
type TodolistListOptions ¶
type TodolistListOptions struct {
// Status filters by status: "archived" or "trashed".
// Empty returns active todolists.
Status string
// Limit is the maximum number of todolists to return.
// If 0 (default), returns all todolists. Use a positive value to cap results.
Limit int
// Page, if non-zero, disables pagination and returns only the first page.
// NOTE: The page number itself is not yet honored due to OpenAPI client
// limitations. Use 0 to paginate through all results up to Limit.
Page int
}
TodolistListOptions specifies options for listing todolists.
type TodolistListResult ¶
type TodolistListResult struct {
// Todolists is the list of todolists returned.
Todolists []Todolist
// Meta contains pagination metadata (total count, etc.).
Meta ListMeta
}
TodolistListResult contains the results from listing todolists.
type TodolistsService ¶
type TodolistsService struct {
// contains filtered or unexported fields
}
TodolistsService handles todolist operations.
func NewTodolistsService ¶
func NewTodolistsService(client *AccountClient) *TodolistsService
NewTodolistsService creates a new TodolistsService.
func (*TodolistsService) Create ¶
func (s *TodolistsService) Create(ctx context.Context, todosetID int64, req *CreateTodolistRequest) (result *Todolist, err error)
Create creates a new todolist in a todoset. Returns the created todolist.
func (*TodolistsService) List ¶
func (s *TodolistsService) List(ctx context.Context, todosetID int64, opts *TodolistListOptions) (result *TodolistListResult, err error)
List returns todolists in a todoset.
By default, returns all todolists (no limit). Use Limit to cap results.
Pagination options:
- Limit: maximum number of todolists to return (0 = all)
- Page: if non-zero, disables pagination and returns first page only
The returned TodolistListResult includes pagination metadata (TotalCount from X-Total-Count header) when available.
func (*TodolistsService) Trash ¶
func (s *TodolistsService) Trash(ctx context.Context, todolistID int64) (err error)
Trash moves a todolist to the trash. Trashed todolists can be recovered from the trash.
func (*TodolistsService) Update ¶
func (s *TodolistsService) Update(ctx context.Context, todolistID int64, req *UpdateTodolistRequest) (result *Todolist, err error)
Update updates an existing todolist. Returns the updated todolist.
type TodosService ¶
type TodosService struct {
// contains filtered or unexported fields
}
TodosService handles todo operations.
func NewTodosService ¶
func NewTodosService(client *AccountClient) *TodosService
NewTodosService creates a new TodosService.
func (*TodosService) Complete ¶
func (s *TodosService) Complete(ctx context.Context, todoID int64) (err error)
Complete marks a todo as completed.
Example ¶
package main
import (
"context"
"fmt"
"log"
"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)
ctx := context.Background()
todoID := int64(789012)
// Mark a todo as complete
err := client.ForAccount("12345").Todos().Complete(ctx, todoID)
if err != nil {
log.Fatal(err)
}
fmt.Println("Todo completed")
}
Output:
func (*TodosService) Create ¶
func (s *TodosService) Create(ctx context.Context, todolistID int64, req *CreateTodoRequest) (result *Todo, err error)
Create creates a new todo in a todolist. Returns the created todo.
Example ¶
package main
import (
"context"
"fmt"
"log"
"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)
ctx := context.Background()
todolistID := int64(789012)
// Create a new todo with assignees and due date
todo, err := client.ForAccount("12345").Todos().Create(ctx, todolistID, &basecamp.CreateTodoRequest{
Content: "Review pull request",
Description: "<strong>Priority:</strong> High",
DueOn: "2024-12-31",
AssigneeIDs: []int64{111, 222},
Notify: true,
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("Created todo: %s (ID: %d)\n", todo.Content, todo.ID)
}
Output:
func (*TodosService) List ¶
func (s *TodosService) List(ctx context.Context, todolistID int64, opts *TodoListOptions) (result *TodoListResult, err error)
List returns todos in a todolist.
By default, returns up to 100 todos. Use Limit: -1 for unlimited.
Pagination options:
- Limit: maximum number of todos to return (0 = 100, -1 = unlimited)
- Page: if non-zero, disables pagination and returns first page only
The returned TodoListResult includes pagination metadata (TotalCount from X-Total-Count header) when available.
Example ¶
package main
import (
"context"
"fmt"
"log"
"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)
ctx := context.Background()
todolistID := int64(789012)
// List all todos in a todolist
todosResult, err := client.ForAccount("12345").Todos().List(ctx, todolistID, nil)
if err != nil {
log.Fatal(err)
}
for _, t := range todosResult.Todos {
status := "[ ]"
if t.Completed {
status = "[x]"
}
fmt.Printf("%s %s\n", status, t.Content)
}
}
Output:
func (*TodosService) Reposition ¶
Reposition changes the position of a todo within its todolist. position is 1-based (1 = first position).
func (*TodosService) Trash ¶
func (s *TodosService) Trash(ctx context.Context, todoID int64) (err error)
Trash moves a todo to the trash. Trashed todos can be recovered from the trash.
func (*TodosService) Uncomplete ¶
func (s *TodosService) Uncomplete(ctx context.Context, todoID int64) (err error)
Uncomplete marks a completed todo as incomplete (reopens it).
func (*TodosService) Update ¶
func (s *TodosService) Update(ctx context.Context, todoID int64, req *UpdateTodoRequest) (result *Todo, err error)
Update updates an existing todo. Returns the updated todo.
type Todoset ¶
type Todoset struct {
ID int64 `json:"id"`
Status string `json:"status"`
VisibleToClients bool `json:"visible_to_clients"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Title string `json:"title"`
InheritsStatus bool `json:"inherits_status"`
Type string `json:"type"`
URL string `json:"url"`
AppURL string `json:"app_url"`
BookmarkURL string `json:"bookmark_url"`
Position *int `json:"position,omitempty"`
Bucket *Bucket `json:"bucket,omitempty"`
Creator *Person `json:"creator,omitempty"`
Name string `json:"name"`
TodolistsCount int `json:"todolists_count"`
TodolistsURL string `json:"todolists_url"`
CompletedRatio string `json:"completed_ratio"`
Completed bool `json:"completed"`
CompletedCount int `json:"completed_count"`
OnScheduleCount int `json:"on_schedule_count"`
OverScheduleCount int `json:"over_schedule_count"`
AppTodolistsURL string `json:"app_todolists_url"`
}
Todoset represents a Basecamp todoset (container for todolists in a project). Each project has exactly one todoset in its dock.
type TodosetsService ¶
type TodosetsService struct {
// contains filtered or unexported fields
}
TodosetsService handles todoset operations.
func NewTodosetsService ¶
func NewTodosetsService(client *AccountClient) *TodosetsService
NewTodosetsService creates a new TodosetsService.
type TokenProvider ¶
type TokenProvider interface {
// AccessToken returns a valid access token, refreshing if needed.
AccessToken(ctx context.Context) (string, error)
}
TokenProvider is the interface for obtaining access tokens.
type Tool ¶
type Tool struct {
ID int64 `json:"id"`
Status string `json:"status"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Title string `json:"title"`
Name string `json:"name"`
Enabled bool `json:"enabled"`
Position *int `json:"position"`
URL string `json:"url"`
AppURL string `json:"app_url"`
Bucket *Bucket `json:"bucket,omitempty"`
}
Tool represents a dock tool in a Basecamp project.
type ToolsService ¶
type ToolsService struct {
// contains filtered or unexported fields
}
ToolsService handles dock tool operations.
func NewToolsService ¶
func NewToolsService(client *AccountClient) *ToolsService
NewToolsService creates a new ToolsService.
func (*ToolsService) Create ¶
Create clones an existing tool to create a new one. Returns the newly created tool.
func (*ToolsService) Delete ¶
func (s *ToolsService) Delete(ctx context.Context, toolID int64) (err error)
Delete moves a tool to the trash. Trashed tools can be recovered from the trash.
func (*ToolsService) Disable ¶
func (s *ToolsService) Disable(ctx context.Context, toolID int64) (err error)
Disable disables (hides) a tool from the project dock. The tool is not deleted, just hidden from the dock.
func (*ToolsService) Enable ¶
func (s *ToolsService) Enable(ctx context.Context, toolID int64) (err error)
Enable enables (shows) a tool on the project dock. The tool will be placed at the end of the dock.
func (*ToolsService) Reposition ¶
Reposition changes the position of a tool on the project dock. position is 1-based (1 = first position on dock).
type UpcomingScheduleResponse ¶
type UpcomingScheduleResponse struct {
ScheduleEntries []ScheduleEntry `json:"schedule_entries"`
RecurringOccurrences []ScheduleEntry `json:"recurring_schedule_entry_occurrences"`
Assignables []Assignable `json:"assignables"`
}
UpcomingScheduleResponse contains upcoming schedule entries.
type UpdateAnswerRequest ¶
type UpdateAnswerRequest struct {
// Content is the updated answer content in HTML (required).
Content string `json:"content"`
}
UpdateAnswerRequest specifies the parameters for updating an answer.
type UpdateCardRequest ¶
type UpdateCardRequest struct {
// Title is the card title (optional).
Title string `json:"title,omitempty"`
// Content is the card body in HTML (optional).
Content string `json:"content,omitempty"`
// DueOn is the due date in ISO 8601 format (optional).
DueOn string `json:"due_on,omitempty"`
// AssigneeIDs is a list of person IDs to assign this card to (optional).
AssigneeIDs []int64 `json:"assignee_ids,omitempty"`
}
UpdateCardRequest specifies the parameters for updating a card.
type UpdateChatbotRequest ¶
type UpdateChatbotRequest struct {
// ServiceName is the chatbot name used to invoke queries and commands (required).
// No spaces, emoji or non-word characters are allowed.
ServiceName string `json:"service_name"`
// CommandURL is the HTTPS URL that Basecamp should call when the bot is addressed (optional).
CommandURL string `json:"command_url,omitempty"`
}
UpdateChatbotRequest specifies the parameters for updating a chatbot.
type UpdateColumnRequest ¶
type UpdateColumnRequest struct {
// Title is the column title (optional).
Title string `json:"title,omitempty"`
// Description is the column description (optional).
Description string `json:"description,omitempty"`
}
UpdateColumnRequest specifies the parameters for updating a column.
type UpdateCommentRequest ¶
type UpdateCommentRequest struct {
// Content is the comment text in HTML (required).
Content string `json:"content"`
}
UpdateCommentRequest specifies the parameters for updating a comment.
type UpdateDocumentRequest ¶
type UpdateDocumentRequest struct {
// Title is the document title.
Title string `json:"title,omitempty"`
// Content is the document body in HTML.
Content string `json:"content,omitempty"`
}
UpdateDocumentRequest specifies the parameters for updating a document.
type UpdateMarkerRequest ¶
type UpdateMarkerRequest struct {
// Name is the marker name (optional).
Name string `json:"name,omitempty"`
// Date is the marker date in YYYY-MM-DD format (optional).
Date string `json:"date,omitempty"`
}
UpdateMarkerRequest specifies the parameters for updating a lineup marker.
type UpdateMessageRequest ¶
type UpdateMessageRequest struct {
// Subject is the message title (optional).
Subject string `json:"subject,omitempty"`
// Content is the message body in HTML (optional).
Content string `json:"content,omitempty"`
// Status is either "drafted" or "active" (optional).
Status string `json:"status,omitempty"`
// CategoryID is the message type ID (optional).
CategoryID int64 `json:"category_id,omitempty"`
}
UpdateMessageRequest specifies the parameters for updating a message.
type UpdateMessageTypeRequest ¶
type UpdateMessageTypeRequest struct {
// Name is the message type name (optional).
Name string `json:"name,omitempty"`
// Icon is the message type icon (optional).
Icon string `json:"icon,omitempty"`
}
UpdateMessageTypeRequest specifies the parameters for updating a message type.
type UpdateProjectAccessRequest ¶
type UpdateProjectAccessRequest struct {
// Grant is a list of person IDs to grant access to the project.
Grant []int64 `json:"grant,omitempty"`
// Revoke is a list of person IDs to revoke access from the project.
Revoke []int64 `json:"revoke,omitempty"`
// Create is a list of new people to create and grant access.
Create []CreatePersonRequest `json:"create,omitempty"`
}
UpdateProjectAccessRequest specifies the parameters for updating project access.
type UpdateProjectAccessResponse ¶
type UpdateProjectAccessResponse struct {
// Granted is the list of people who were granted access.
Granted []Person `json:"granted"`
// Revoked is the list of people whose access was revoked.
Revoked []Person `json:"revoked"`
}
UpdateProjectAccessResponse is the response from updating project access.
type UpdateProjectRequest ¶
type UpdateProjectRequest struct {
// Name is the project name (required for update).
Name string `json:"name"`
// Description is an optional project description.
Description string `json:"description,omitempty"`
// Admissions specifies access policy (invite, employee, team).
Admissions string `json:"admissions,omitempty"`
// ScheduleAttributes sets project start and end dates.
ScheduleAttributes *ScheduleAttributes `json:"schedule_attributes,omitempty"`
}
UpdateProjectRequest specifies the parameters for updating a project.
type UpdateQuestionRequest ¶
type UpdateQuestionRequest struct {
// Title is the question text.
Title string `json:"title,omitempty"`
// Schedule is the question schedule configuration.
Schedule *QuestionSchedule `json:"schedule,omitempty"`
// Paused indicates whether the question is paused.
Paused *bool `json:"paused,omitempty"`
}
UpdateQuestionRequest specifies the parameters for updating a question.
type UpdateScheduleEntryRequest ¶
type UpdateScheduleEntryRequest struct {
// Summary is the event title (optional).
Summary string `json:"summary,omitempty"`
// StartsAt is the event start time (optional, ISO 8601 format).
StartsAt string `json:"starts_at,omitempty"`
// EndsAt is the event end time (optional, ISO 8601 format).
EndsAt string `json:"ends_at,omitempty"`
// Description is the event details in HTML (optional).
Description string `json:"description,omitempty"`
// ParticipantIDs is a list of people IDs to assign (optional).
ParticipantIDs []int64 `json:"participant_ids,omitempty"`
// AllDay indicates if this is an all-day event (optional).
AllDay bool `json:"all_day,omitempty"`
// Notify triggers participant notifications when true (optional).
Notify bool `json:"notify,omitempty"`
}
UpdateScheduleEntryRequest specifies the parameters for updating a schedule entry.
type UpdateScheduleSettingsRequest ¶
type UpdateScheduleSettingsRequest struct {
// IncludeDueAssignments controls whether to-do due dates appear on the schedule.
IncludeDueAssignments bool `json:"include_due_assignments"`
}
UpdateScheduleSettingsRequest specifies the parameters for updating schedule settings.
type UpdateStepRequest ¶
type UpdateStepRequest struct {
// Title is the step title (optional).
Title string `json:"title,omitempty"`
// DueOn is the due date in ISO 8601 format (optional).
DueOn string `json:"due_on,omitempty"`
// Assignees is a list of person IDs to assign this step to (optional).
Assignees []int64 `json:"assignees,omitempty"`
}
UpdateStepRequest specifies the parameters for updating a step.
type UpdateSubscriptionRequest ¶
type UpdateSubscriptionRequest struct {
// Subscriptions is a list of person IDs to subscribe to the recording.
Subscriptions []int64 `json:"subscriptions,omitempty"`
// Unsubscriptions is a list of person IDs to unsubscribe from the recording.
Unsubscriptions []int64 `json:"unsubscriptions,omitempty"`
}
UpdateSubscriptionRequest specifies the parameters for updating subscriptions.
type UpdateTemplateRequest ¶
type UpdateTemplateRequest struct {
// Name is the template name (required for update).
Name string `json:"name"`
// Description is an optional template description.
Description string `json:"description,omitempty"`
}
UpdateTemplateRequest specifies the parameters for updating a template.
type UpdateTimesheetEntryRequest ¶
type UpdateTimesheetEntryRequest struct {
Date string `json:"date,omitempty"`
Hours string `json:"hours,omitempty"`
Description string `json:"description,omitempty"`
PersonID int64 `json:"person_id,omitempty"`
}
UpdateTimesheetEntryRequest specifies the parameters for updating a timesheet entry.
type UpdateTodoRequest ¶
type UpdateTodoRequest struct {
// Content is the todo text.
Content string `json:"content,omitempty"`
// Description is an optional extended description (can include HTML).
Description string `json:"description,omitempty"`
// AssigneeIDs is a list of person IDs to assign this todo to.
AssigneeIDs []int64 `json:"assignee_ids,omitempty"`
// CompletionSubscriberIDs is a list of person IDs to notify on completion.
CompletionSubscriberIDs []int64 `json:"completion_subscriber_ids,omitempty"`
// Notify when true, will notify assignees.
Notify bool `json:"notify,omitempty"`
// DueOn is the due date in ISO 8601 format (YYYY-MM-DD).
DueOn string `json:"due_on,omitempty"`
// StartsOn is the start date in ISO 8601 format (YYYY-MM-DD).
StartsOn string `json:"starts_on,omitempty"`
}
UpdateTodoRequest specifies the parameters for updating a todo.
type UpdateTodolistGroupRequest ¶
type UpdateTodolistGroupRequest struct {
// Name is the group name.
Name string `json:"name,omitempty"`
}
UpdateTodolistGroupRequest specifies the parameters for updating a todolist group.
type UpdateTodolistRequest ¶
type UpdateTodolistRequest struct {
// Name is the todolist name.
Name string `json:"name,omitempty"`
// Description is an optional description (can include HTML).
Description string `json:"description,omitempty"`
}
UpdateTodolistRequest specifies the parameters for updating a todolist.
type UpdateToolRequest ¶
type UpdateToolRequest struct {
// Title is the new title for the tool (required).
Title string `json:"title"`
}
UpdateToolRequest specifies the parameters for updating (renaming) a tool.
type UpdateUploadRequest ¶
type UpdateUploadRequest struct {
// Description is the upload description.
Description string `json:"description,omitempty"`
// BaseName is the filename without extension.
BaseName string `json:"base_name,omitempty"`
}
UpdateUploadRequest specifies the parameters for updating an upload.
type UpdateVaultRequest ¶
type UpdateVaultRequest struct {
// Title is the vault name.
Title string `json:"title,omitempty"`
}
UpdateVaultRequest specifies the parameters for updating a vault.
type UpdateWebhookRequest ¶
type UpdateWebhookRequest struct {
// PayloadURL is the URL to receive webhook payloads.
PayloadURL string `json:"payload_url,omitempty"`
// Types is a list of event types to subscribe to.
Types []string `json:"types,omitempty"`
// Active indicates whether the webhook is active.
Active *bool `json:"active,omitempty"`
}
UpdateWebhookRequest specifies the parameters for updating a webhook.
type Upload ¶
type Upload struct {
ID int64 `json:"id"`
Status string `json:"status"`
VisibleToClients bool `json:"visible_to_clients"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Title string `json:"title"`
InheritsStatus bool `json:"inherits_status"`
Type string `json:"type"`
URL string `json:"url"`
AppURL string `json:"app_url"`
BookmarkURL string `json:"bookmark_url"`
SubscriptionURL string `json:"subscription_url"`
CommentsCount int `json:"comments_count"`
BoostsCount int `json:"boosts_count,omitempty"`
CommentsURL string `json:"comments_url"`
Position int `json:"position,omitempty"`
Parent *Parent `json:"parent,omitempty"`
Bucket *Bucket `json:"bucket,omitempty"`
Creator *Person `json:"creator,omitempty"`
Description string `json:"description"`
ContentType string `json:"content_type"`
ByteSize int64 `json:"byte_size"`
Width int `json:"width,omitempty"`
Height int `json:"height,omitempty"`
DownloadURL string `json:"download_url"`
Filename string `json:"filename"`
}
Upload represents a Basecamp uploaded file in a vault.
type UploadListOptions ¶
type UploadListOptions struct {
// Limit is the maximum number of uploads to return.
// If 0 (default), returns all uploads. Use a positive value to cap results.
Limit int
// Page, if non-zero, disables pagination and returns only the first page.
// NOTE: The page number itself is not yet honored due to OpenAPI client
// limitations. Use 0 to paginate through all results up to Limit.
Page int
}
UploadListOptions specifies options for listing uploads.
type UploadListResult ¶
type UploadListResult struct {
// Uploads is the list of uploads returned.
Uploads []Upload
// Meta contains pagination metadata (total count, etc.).
Meta ListMeta
}
UploadListResult contains the results from listing uploads.
type UploadsService ¶
type UploadsService struct {
// contains filtered or unexported fields
}
UploadsService handles upload (file) operations.
func NewUploadsService ¶
func NewUploadsService(client *AccountClient) *UploadsService
NewUploadsService creates a new UploadsService.
func (*UploadsService) Create ¶
func (s *UploadsService) Create(ctx context.Context, vaultID int64, req *CreateUploadRequest) (result *Upload, err error)
Create creates a new upload in a vault. The attachable_sgid must be obtained from the Create Attachment endpoint. Returns the created upload.
func (*UploadsService) Download ¶
func (s *UploadsService) Download(ctx context.Context, uploadID int64) (result *DownloadResult, err error)
Download fetches the file content from an upload's download URL. The caller is responsible for closing the returned Body.
This method first fetches the upload metadata to get the download URL, then fetches the file content from that URL. The download URL is a signed S3 URL that doesn't require authentication headers.
func (*UploadsService) List ¶
func (s *UploadsService) List(ctx context.Context, vaultID int64, opts *UploadListOptions) (result *UploadListResult, err error)
List returns all uploads in a vault.
By default, returns all uploads (no limit). Use Limit to cap results.
Pagination options:
- Limit: maximum number of uploads to return (0 = all)
- Page: if non-zero, disables pagination and returns first page only
The returned UploadListResult includes pagination metadata (TotalCount from X-Total-Count header) when available.
func (*UploadsService) ListVersions ¶
func (s *UploadsService) ListVersions(ctx context.Context, uploadID int64) (result []Upload, err error)
ListVersions returns all versions of an upload.
func (*UploadsService) Trash ¶
func (s *UploadsService) Trash(ctx context.Context, uploadID int64) (err error)
Trash moves an upload to the trash. Trashed uploads can be recovered from the trash.
func (*UploadsService) Update ¶
func (s *UploadsService) Update(ctx context.Context, uploadID int64, req *UpdateUploadRequest) (result *Upload, err error)
Update updates an existing upload. Returns the updated upload.
type UpstreamRef ¶
UpstreamRef is a git revision and the date it was synced.
type Vault ¶
type Vault struct {
ID int64 `json:"id"`
Status string `json:"status"`
VisibleToClients bool `json:"visible_to_clients"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Title string `json:"title"`
InheritsStatus bool `json:"inherits_status"`
Type string `json:"type"`
URL string `json:"url"`
AppURL string `json:"app_url"`
BookmarkURL string `json:"bookmark_url"`
Position int `json:"position,omitempty"`
Parent *Parent `json:"parent,omitempty"`
Bucket *Bucket `json:"bucket,omitempty"`
Creator *Person `json:"creator,omitempty"`
DocumentsCount int `json:"documents_count"`
DocumentsURL string `json:"documents_url"`
UploadsCount int `json:"uploads_count"`
UploadsURL string `json:"uploads_url"`
VaultsCount int `json:"vaults_count"`
VaultsURL string `json:"vaults_url"`
}
Vault represents a Basecamp vault (folder) in the Files tool.
type VaultListOptions ¶
type VaultListOptions struct {
// Limit is the maximum number of vaults to return.
// If 0 (default), returns all vaults. Use a positive value to cap results.
Limit int
// Page, if non-zero, disables pagination and returns only the first page.
// NOTE: The page number itself is not yet honored due to OpenAPI client
// limitations. Use 0 to paginate through all results up to Limit.
Page int
}
VaultListOptions specifies options for listing vaults.
type VaultListResult ¶
type VaultListResult struct {
// Vaults is the list of vaults returned.
Vaults []Vault
// Meta contains pagination metadata (total count, etc.).
Meta ListMeta
}
VaultListResult contains the results from listing vaults.
type VaultsService ¶
type VaultsService struct {
// contains filtered or unexported fields
}
VaultsService handles vault (folder) operations.
func NewVaultsService ¶
func NewVaultsService(client *AccountClient) *VaultsService
NewVaultsService creates a new VaultsService.
func (*VaultsService) Create ¶
func (s *VaultsService) Create(ctx context.Context, vaultID int64, req *CreateVaultRequest) (result *Vault, err error)
Create creates a new subfolder (child vault) in a vault. Returns the created vault.
func (*VaultsService) List ¶
func (s *VaultsService) List(ctx context.Context, vaultID int64, opts *VaultListOptions) (result *VaultListResult, err error)
List returns all subfolders (child vaults) in a vault.
By default, returns all vaults (no limit). Use Limit to cap results.
Pagination options:
- Limit: maximum number of vaults to return (0 = all)
- Page: if non-zero, disables pagination and returns first page only
The returned VaultListResult includes pagination metadata (TotalCount from X-Total-Count header) when available.
func (*VaultsService) Update ¶
func (s *VaultsService) Update(ctx context.Context, vaultID int64, req *UpdateVaultRequest) (result *Vault, err error)
Update updates an existing vault. Returns the updated vault.
type Webhook ¶
type Webhook struct {
ID int64 `json:"id"`
Active bool `json:"active"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
PayloadURL string `json:"payload_url"`
Types []string `json:"types"`
AppURL string `json:"app_url,omitempty"`
URL string `json:"url,omitempty"`
RecentDeliveries []WebhookDelivery `json:"recent_deliveries,omitempty"`
}
Webhook represents a Basecamp webhook subscription.
type WebhookCopy ¶
type WebhookCopy struct {
ID int64 `json:"id"`
URL string `json:"url"`
AppURL string `json:"app_url"`
Bucket WebhookCopyBucket `json:"bucket"`
}
WebhookCopy contains copy/move reference data.
type WebhookCopyBucket ¶
type WebhookCopyBucket struct {
ID int64 `json:"id"`
}
WebhookCopyBucket is the bucket reference in a webhook copy.
type WebhookDelivery ¶
type WebhookDelivery struct {
ID int64 `json:"id"`
CreatedAt time.Time `json:"created_at"`
Request WebhookDeliveryRequest `json:"request"`
Response WebhookDeliveryResponse `json:"response"`
}
WebhookDelivery represents a recent delivery attempt for a webhook.
type WebhookDeliveryRequest ¶
type WebhookDeliveryRequest struct {
Headers map[string]string `json:"headers"`
Body WebhookEvent `json:"body"`
}
WebhookDeliveryRequest contains the outbound request details.
type WebhookDeliveryResponse ¶
type WebhookDeliveryResponse struct {
Headers map[string]string `json:"headers"`
Code int `json:"code"`
Message string `json:"message"`
}
WebhookDeliveryResponse contains the response from the webhook endpoint.
type WebhookEvent ¶
type WebhookEvent struct {
ID int64 `json:"id"`
Kind string `json:"kind"`
Details any `json:"details"`
CreatedAt string `json:"created_at"`
Recording WebhookEventRecording `json:"recording"`
Creator WebhookEventPerson `json:"creator"`
Copy *WebhookCopy `json:"copy,omitempty"`
}
WebhookEvent is the payload delivered by Basecamp webhooks.
type WebhookEventBucket ¶
type WebhookEventBucket struct {
ID int64 `json:"id"`
Name string `json:"name"`
Type string `json:"type"`
}
WebhookEventBucket is the bucket (project) in webhook event payloads.
type WebhookEventCompany ¶
WebhookEventCompany is a company embedded in a webhook event person.
type WebhookEventHandler ¶
type WebhookEventHandler func(event *WebhookEvent) error
WebhookEventHandler handles a parsed webhook event.
type WebhookEventParent ¶
type WebhookEventParent struct {
ID int64 `json:"id"`
Title string `json:"title"`
Type string `json:"type"`
URL string `json:"url"`
AppURL string `json:"app_url"`
}
WebhookEventParent is the parent recording in webhook event payloads.
type WebhookEventPerson ¶
type WebhookEventPerson struct {
ID int64 `json:"id"`
AttachableSGID string `json:"attachable_sgid"`
Name string `json:"name"`
EmailAddress string `json:"email_address"`
PersonableType string `json:"personable_type"`
Title string `json:"title"`
Bio *string `json:"bio"`
Location *string `json:"location"`
CreatedAt string `json:"created_at"`
UpdatedAt string `json:"updated_at"`
Admin bool `json:"admin"`
Owner bool `json:"owner"`
Client bool `json:"client"`
Employee bool `json:"employee"`
TimeZone string `json:"time_zone"`
AvatarURL string `json:"avatar_url"`
Company *WebhookEventCompany `json:"company,omitempty"`
CanManageProjects bool `json:"can_manage_projects"`
CanManagePeople bool `json:"can_manage_people"`
CanPing bool `json:"can_ping"`
CanAccessTimesheet bool `json:"can_access_timesheet"`
CanAccessHillCharts bool `json:"can_access_hill_charts"`
}
WebhookEventPerson is a person in webhook event payloads.
type WebhookEventRecording ¶
type WebhookEventRecording struct {
ID int64 `json:"id"`
Status string `json:"status"`
VisibleToClients bool `json:"visible_to_clients"`
CreatedAt string `json:"created_at"`
UpdatedAt string `json:"updated_at"`
Title string `json:"title"`
InheritsStatus bool `json:"inherits_status"`
Type string `json:"type"`
URL string `json:"url"`
AppURL string `json:"app_url"`
BookmarkURL string `json:"bookmark_url"`
Content string `json:"content"`
CommentsCount int `json:"comments_count"`
CommentsURL string `json:"comments_url"`
SubscriptionURL string `json:"subscription_url"`
Parent *WebhookEventParent `json:"parent,omitempty"`
Bucket *WebhookEventBucket `json:"bucket,omitempty"`
Creator *WebhookEventPerson `json:"creator,omitempty"`
}
WebhookEventRecording is the recording included in webhook event payloads. It has additional fields beyond what the API returns for recordings.
type WebhookListResult ¶
type WebhookListResult struct {
// Webhooks is the list of webhooks returned.
Webhooks []Webhook
// Meta contains pagination metadata (total count, etc.).
Meta ListMeta
}
WebhookListResult contains the results from listing webhooks.
type WebhookMiddleware ¶
type WebhookMiddleware func(event *WebhookEvent, next func() error) error
WebhookMiddleware wraps webhook event processing.
type WebhookReceiver ¶
type WebhookReceiver struct {
// contains filtered or unexported fields
}
WebhookReceiver receives and routes webhook events from Basecamp. It implements http.Handler for direct use as an HTTP endpoint.
func NewWebhookReceiver ¶
func NewWebhookReceiver(config WebhookReceiverConfig) *WebhookReceiver
NewWebhookReceiver creates a new WebhookReceiver with the given config.
func (*WebhookReceiver) HandleRequest ¶
func (r *WebhookReceiver) HandleRequest(body []byte, getHeader func(string) string) (*WebhookEvent, error)
HandleRequest processes a raw webhook request body and headers. Returns the parsed WebhookEvent, or an error if verification/parsing fails. Duplicate events (by ID) return the parsed event but do not trigger handlers.
func (*WebhookReceiver) On ¶
func (r *WebhookReceiver) On(pattern string, handler WebhookEventHandler)
On registers a handler for a specific event kind pattern. Patterns support simple glob matching: "todo_*" matches "todo_created", "todo_completed", etc. "*_created" matches "todo_created", "message_created", etc.
func (*WebhookReceiver) OnAny ¶
func (r *WebhookReceiver) OnAny(handler WebhookEventHandler)
OnAny registers a handler for all webhook events.
func (*WebhookReceiver) ServeHTTP ¶
func (r *WebhookReceiver) ServeHTTP(w http.ResponseWriter, req *http.Request)
ServeHTTP implements http.Handler.
func (*WebhookReceiver) Use ¶
func (r *WebhookReceiver) Use(middleware WebhookMiddleware)
Use adds a middleware to the processing chain.
type WebhookReceiverConfig ¶
type WebhookReceiverConfig struct {
// Secret is the HMAC secret for signature verification. If empty, verification is skipped.
Secret string
// SignatureHeader is the HTTP header containing the signature (default: "X-Basecamp-Signature").
SignatureHeader string
// MaxBodyBytes limits the request body size (default: 1MB).
MaxBodyBytes int64
// DedupWindowSize is the number of recent event IDs to track for deduplication (default: 1000, -1 to disable).
DedupWindowSize int
}
WebhookReceiverConfig configures a WebhookReceiver.
type WebhookVerificationError ¶
type WebhookVerificationError struct {
Message string
}
WebhookVerificationError indicates a signature verification failure.
func (*WebhookVerificationError) Error ¶
func (e *WebhookVerificationError) Error() string
type WebhooksService ¶
type WebhooksService struct {
// contains filtered or unexported fields
}
WebhooksService handles webhook operations.
func NewWebhooksService ¶
func NewWebhooksService(client *AccountClient) *WebhooksService
NewWebhooksService creates a new WebhooksService.
func (*WebhooksService) Create ¶
func (s *WebhooksService) Create(ctx context.Context, bucketID int64, req *CreateWebhookRequest) (result *Webhook, err error)
Create creates a new webhook for a project (bucket). Returns the created webhook.
Example ¶
package main
import (
"context"
"fmt"
"log"
"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)
ctx := context.Background()
// Create a webhook to receive notifications
var bucketID int64 = 67890
webhook, err := client.ForAccount("12345").Webhooks().Create(ctx, bucketID, &basecamp.CreateWebhookRequest{
PayloadURL: "https://example.com/webhooks/basecamp",
Types: []string{"Todo", "Comment"},
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("Webhook created: %s\n", webhook.PayloadURL)
}
Output:
func (*WebhooksService) Delete ¶
func (s *WebhooksService) Delete(ctx context.Context, webhookID int64) (err error)
Delete removes a webhook.
func (*WebhooksService) List ¶
func (s *WebhooksService) List(ctx context.Context, bucketID int64) (result *WebhookListResult, err error)
List returns all webhooks for a project (bucket).
The returned WebhookListResult includes pagination metadata (TotalCount from X-Total-Count header) when available.
func (*WebhooksService) Update ¶
func (s *WebhooksService) Update(ctx context.Context, webhookID int64, req *UpdateWebhookRequest) (result *Webhook, err error)
Update updates an existing webhook. Returns the updated webhook.
Source Files
¶
- attachments.go
- auth.go
- auth_strategy.go
- authorization.go
- boosts.go
- bulkhead.go
- cache.go
- campfires.go
- cards.go
- checkins.go
- circuit_breaker.go
- client.go
- client_approvals.go
- client_correspondences.go
- client_replies.go
- comments.go
- config.go
- date.go
- doc.go
- errors.go
- events.go
- forwards.go
- helpers.go
- http.go
- lineup.go
- message_boards.go
- message_types.go
- messages.go
- observability.go
- people.go
- projects.go
- provenance.go
- rate_limit.go
- recordings.go
- reports.go
- resilience.go
- schedules.go
- search.go
- security.go
- slog_hooks.go
- subscriptions.go
- templates.go
- timeline.go
- timesheet.go
- todolist_groups.go
- todolists.go
- todos.go
- todosets.go
- tools.go
- url.go
- vaults.go
- version.go
- webhook_event.go
- webhook_handler.go
- webhook_verify.go
- webhooks.go
Directories
¶
| Path | Synopsis |
|---|---|
|
Package oauth provides OAuth 2.0 discovery, token exchange, and refresh functionality.
|
Package oauth provides OAuth 2.0 discovery, token exchange, and refresh functionality. |
|
Package otel provides OpenTelemetry integration for the Basecamp SDK.
|
Package otel provides OpenTelemetry integration for the Basecamp SDK. |
|
Package prometheus provides Prometheus metrics integration for the Basecamp SDK.
|
Package prometheus provides Prometheus metrics integration for the Basecamp SDK. |