diff --git a/behavior-model.json b/behavior-model.json index 52a8e8f1..2013f921 100644 --- a/behavior-model.json +++ b/behavior-model.json @@ -806,6 +806,38 @@ ] } }, + "GetEverythingCompletedCards": { + "readonly": true, + "pagination": { + "style": "link", + "maxPageSize": 50 + }, + "retry": { + "max": 3, + "base_delay_ms": 1000, + "backoff": "exponential", + "retry_on": [ + 429, + 503 + ] + } + }, + "GetEverythingCompletedTodos": { + "readonly": true, + "pagination": { + "style": "link", + "maxPageSize": 50 + }, + "retry": { + "max": 3, + "base_delay_ms": 1000, + "backoff": "exponential", + "retry_on": [ + 429, + 503 + ] + } + }, "GetEverythingFiles": { "readonly": true, "pagination": { @@ -854,6 +886,86 @@ ] } }, + "GetEverythingNoDueDateCards": { + "readonly": true, + "pagination": { + "style": "link", + "maxPageSize": 50 + }, + "retry": { + "max": 3, + "base_delay_ms": 1000, + "backoff": "exponential", + "retry_on": [ + 429, + 503 + ] + } + }, + "GetEverythingNoDueDateTodos": { + "readonly": true, + "pagination": { + "style": "link", + "maxPageSize": 50 + }, + "retry": { + "max": 3, + "base_delay_ms": 1000, + "backoff": "exponential", + "retry_on": [ + 429, + 503 + ] + } + }, + "GetEverythingNotNowCards": { + "readonly": true, + "pagination": { + "style": "link", + "maxPageSize": 50 + }, + "retry": { + "max": 3, + "base_delay_ms": 1000, + "backoff": "exponential", + "retry_on": [ + 429, + 503 + ] + } + }, + "GetEverythingOpenCards": { + "readonly": true, + "pagination": { + "style": "link", + "maxPageSize": 50 + }, + "retry": { + "max": 3, + "base_delay_ms": 1000, + "backoff": "exponential", + "retry_on": [ + 429, + 503 + ] + } + }, + "GetEverythingOpenTodos": { + "readonly": true, + "pagination": { + "style": "link", + "maxPageSize": 50 + }, + "retry": { + "max": 3, + "base_delay_ms": 1000, + "backoff": "exponential", + "retry_on": [ + 429, + 503 + ] + } + }, "GetEverythingOverdueCards": { "readonly": true, "retry": { @@ -878,6 +990,38 @@ ] } }, + "GetEverythingUnassignedCards": { + "readonly": true, + "pagination": { + "style": "link", + "maxPageSize": 50 + }, + "retry": { + "max": 3, + "base_delay_ms": 1000, + "backoff": "exponential", + "retry_on": [ + 429, + 503 + ] + } + }, + "GetEverythingUnassignedTodos": { + "readonly": true, + "pagination": { + "style": "link", + "maxPageSize": 50 + }, + "retry": { + "max": 3, + "base_delay_ms": 1000, + "backoff": "exponential", + "retry_on": [ + 429, + 503 + ] + } + }, "GetForward": { "readonly": true, "retry": { diff --git a/go/pkg/basecamp/everything.go b/go/pkg/basecamp/everything.go index 3038d9dd..64237fb6 100644 --- a/go/pkg/basecamp/everything.go +++ b/go/pkg/basecamp/everything.go @@ -416,6 +416,240 @@ func (s *EverythingService) OverdueCards(ctx context.Context) (result []Card, er return cards, nil } +// ---- bucket-grouped todo/card filter family ---- + +// BucketTodosGroup is one project's slice of a filtered to-do listing: the +// parent project and the matching to-dos (each carrying its steps). +type BucketTodosGroup struct { + Bucket *Bucket `json:"bucket,omitempty"` + Todos []Todo `json:"todos,omitempty"` +} + +// BucketCardsGroup is one project's slice of a filtered card listing. +type BucketCardsGroup struct { + Bucket *Bucket `json:"bucket,omitempty"` + Cards []Card `json:"cards,omitempty"` +} + +// BucketTodosGroupsPage is a page-followed list of to-do bucket groups. +type BucketTodosGroupsPage struct { + Groups []BucketTodosGroup + Meta ListMeta +} + +// BucketCardsGroupsPage is a page-followed list of card bucket groups. +type BucketCardsGroupsPage struct { + Groups []BucketCardsGroup + Meta ListMeta +} + +func bucketTodosGroupFromGenerated(g generated.BucketTodosGroup) BucketTodosGroup { + grp := BucketTodosGroup{} + if g.Bucket.Id != 0 || g.Bucket.Name != "" { + grp.Bucket = &Bucket{ID: g.Bucket.Id, Name: g.Bucket.Name, Type: g.Bucket.Type} + } + for _, gt := range g.Todos { + grp.Todos = append(grp.Todos, todoFromGenerated(gt)) + } + return grp +} + +func bucketCardsGroupFromGenerated(g generated.BucketCardsGroup) BucketCardsGroup { + grp := BucketCardsGroup{} + if g.Bucket.Id != 0 || g.Bucket.Name != "" { + grp.Bucket = &Bucket{ID: g.Bucket.Id, Name: g.Bucket.Name, Type: g.Bucket.Type} + } + for _, gc := range g.Cards { + grp.Cards = append(grp.Cards, cardFromGenerated(gc)) + } + return grp +} + +// OpenTodos returns active, incomplete to-dos across all accessible projects, +// grouped by project (paginated). Pass a positive page to return only that page; +// page 0 follows the Link header across all pages. +func (s *EverythingService) OpenTodos(ctx context.Context, page int32) (result *BucketTodosGroupsPage, err error) { + ctx, done, err := s.begin(ctx, OperationInfo{Service: "Everything", Operation: "OpenTodos", ResourceType: "todo"}) + if err != nil { + return nil, err + } + defer done(&err) + r, err := s.client.parent.gen.GetEverythingOpenTodosWithResponse(ctx, s.client.accountID) + if err != nil { + return nil, err + } + return s.finishTodoGroupsPage(ctx, r.HTTPResponse, r.Body, r.JSON200, page) +} + +// CompletedTodos returns completed to-dos, grouped by project (paginated). +func (s *EverythingService) CompletedTodos(ctx context.Context, page int32) (result *BucketTodosGroupsPage, err error) { + ctx, done, err := s.begin(ctx, OperationInfo{Service: "Everything", Operation: "CompletedTodos", ResourceType: "todo"}) + if err != nil { + return nil, err + } + defer done(&err) + r, err := s.client.parent.gen.GetEverythingCompletedTodosWithResponse(ctx, s.client.accountID) + if err != nil { + return nil, err + } + return s.finishTodoGroupsPage(ctx, r.HTTPResponse, r.Body, r.JSON200, page) +} + +// UnassignedTodos returns open, unassigned to-dos, grouped by project (paginated). +func (s *EverythingService) UnassignedTodos(ctx context.Context, page int32) (result *BucketTodosGroupsPage, err error) { + ctx, done, err := s.begin(ctx, OperationInfo{Service: "Everything", Operation: "UnassignedTodos", ResourceType: "todo"}) + if err != nil { + return nil, err + } + defer done(&err) + r, err := s.client.parent.gen.GetEverythingUnassignedTodosWithResponse(ctx, s.client.accountID) + if err != nil { + return nil, err + } + return s.finishTodoGroupsPage(ctx, r.HTTPResponse, r.Body, r.JSON200, page) +} + +// NoDueDateTodos returns open to-dos with no due date, grouped by project (paginated). +func (s *EverythingService) NoDueDateTodos(ctx context.Context, page int32) (result *BucketTodosGroupsPage, err error) { + ctx, done, err := s.begin(ctx, OperationInfo{Service: "Everything", Operation: "NoDueDateTodos", ResourceType: "todo"}) + if err != nil { + return nil, err + } + defer done(&err) + r, err := s.client.parent.gen.GetEverythingNoDueDateTodosWithResponse(ctx, s.client.accountID) + if err != nil { + return nil, err + } + return s.finishTodoGroupsPage(ctx, r.HTTPResponse, r.Body, r.JSON200, page) +} + +// OpenCards returns incomplete cards in active columns, grouped by project (paginated). +func (s *EverythingService) OpenCards(ctx context.Context, page int32) (result *BucketCardsGroupsPage, err error) { + ctx, done, err := s.begin(ctx, OperationInfo{Service: "Everything", Operation: "OpenCards", ResourceType: "card"}) + if err != nil { + return nil, err + } + defer done(&err) + r, err := s.client.parent.gen.GetEverythingOpenCardsWithResponse(ctx, s.client.accountID) + if err != nil { + return nil, err + } + return s.finishCardGroupsPage(ctx, r.HTTPResponse, r.Body, r.JSON200, page) +} + +// CompletedCards returns completed cards, grouped by project (paginated). +func (s *EverythingService) CompletedCards(ctx context.Context, page int32) (result *BucketCardsGroupsPage, err error) { + ctx, done, err := s.begin(ctx, OperationInfo{Service: "Everything", Operation: "CompletedCards", ResourceType: "card"}) + if err != nil { + return nil, err + } + defer done(&err) + r, err := s.client.parent.gen.GetEverythingCompletedCardsWithResponse(ctx, s.client.accountID) + if err != nil { + return nil, err + } + return s.finishCardGroupsPage(ctx, r.HTTPResponse, r.Body, r.JSON200, page) +} + +// UnassignedCards returns open, unassigned cards, grouped by project (paginated). +func (s *EverythingService) UnassignedCards(ctx context.Context, page int32) (result *BucketCardsGroupsPage, err error) { + ctx, done, err := s.begin(ctx, OperationInfo{Service: "Everything", Operation: "UnassignedCards", ResourceType: "card"}) + if err != nil { + return nil, err + } + defer done(&err) + r, err := s.client.parent.gen.GetEverythingUnassignedCardsWithResponse(ctx, s.client.accountID) + if err != nil { + return nil, err + } + return s.finishCardGroupsPage(ctx, r.HTTPResponse, r.Body, r.JSON200, page) +} + +// NoDueDateCards returns open cards with no due date, grouped by project (paginated). +func (s *EverythingService) NoDueDateCards(ctx context.Context, page int32) (result *BucketCardsGroupsPage, err error) { + ctx, done, err := s.begin(ctx, OperationInfo{Service: "Everything", Operation: "NoDueDateCards", ResourceType: "card"}) + if err != nil { + return nil, err + } + defer done(&err) + r, err := s.client.parent.gen.GetEverythingNoDueDateCardsWithResponse(ctx, s.client.accountID) + if err != nil { + return nil, err + } + return s.finishCardGroupsPage(ctx, r.HTTPResponse, r.Body, r.JSON200, page) +} + +// NotNowCards returns cards parked in a project's "Not now" column, grouped by +// project (paginated). +func (s *EverythingService) NotNowCards(ctx context.Context, page int32) (result *BucketCardsGroupsPage, err error) { + ctx, done, err := s.begin(ctx, OperationInfo{Service: "Everything", Operation: "NotNowCards", ResourceType: "card"}) + if err != nil { + return nil, err + } + defer done(&err) + r, err := s.client.parent.gen.GetEverythingNotNowCardsWithResponse(ctx, s.client.accountID) + if err != nil { + return nil, err + } + return s.finishCardGroupsPage(ctx, r.HTTPResponse, r.Body, r.JSON200, page) +} + +func (s *EverythingService) finishTodoGroupsPage(ctx context.Context, httpResp *http.Response, body []byte, json200 *[]generated.BucketTodosGroup, page int32) (*BucketTodosGroupsPage, error) { + if err := checkResponse(httpResp, body); err != nil { + return nil, err + } + var groups []BucketTodosGroup + if json200 != nil { + for _, g := range *json200 { + groups = append(groups, bucketTodosGroupFromGenerated(g)) + } + } + totalCount := parseTotalCount(httpResp) + if page > 0 { + return &BucketTodosGroupsPage{Groups: groups, Meta: ListMeta{TotalCount: totalCount}}, nil + } + rawMore, truncated, err := s.client.parent.followPagination(ctx, httpResp, len(groups), 0) + if err != nil { + return nil, err + } + for _, raw := range rawMore { + var g generated.BucketTodosGroup + if err := json.Unmarshal(raw, &g); err != nil { + return nil, fmt.Errorf("failed to parse bucket todo group: %w", err) + } + groups = append(groups, bucketTodosGroupFromGenerated(g)) + } + return &BucketTodosGroupsPage{Groups: groups, Meta: ListMeta{TotalCount: totalCount, Truncated: truncated}}, nil +} + +func (s *EverythingService) finishCardGroupsPage(ctx context.Context, httpResp *http.Response, body []byte, json200 *[]generated.BucketCardsGroup, page int32) (*BucketCardsGroupsPage, error) { + if err := checkResponse(httpResp, body); err != nil { + return nil, err + } + var groups []BucketCardsGroup + if json200 != nil { + for _, g := range *json200 { + groups = append(groups, bucketCardsGroupFromGenerated(g)) + } + } + totalCount := parseTotalCount(httpResp) + if page > 0 { + return &BucketCardsGroupsPage{Groups: groups, Meta: ListMeta{TotalCount: totalCount}}, nil + } + rawMore, truncated, err := s.client.parent.followPagination(ctx, httpResp, len(groups), 0) + if err != nil { + return nil, err + } + for _, raw := range rawMore { + var g generated.BucketCardsGroup + if err := json.Unmarshal(raw, &g); err != nil { + return nil, fmt.Errorf("failed to parse bucket card group: %w", err) + } + groups = append(groups, bucketCardsGroupFromGenerated(g)) + } + return &BucketCardsGroupsPage{Groups: groups, Meta: ListMeta{TotalCount: totalCount, Truncated: truncated}}, nil +} + // begin runs the gating + start/end hook lifecycle shared by the everything // methods and returns the (possibly gated) context plus a deferred finisher. func (s *EverythingService) begin(ctx context.Context, op OperationInfo) (context.Context, func(*error), error) { diff --git a/go/pkg/basecamp/everything_test.go b/go/pkg/basecamp/everything_test.go index 44314610..9e3c80f2 100644 --- a/go/pkg/basecamp/everything_test.go +++ b/go/pkg/basecamp/everything_test.go @@ -168,3 +168,87 @@ func TestEverythingService_Files_Filters(t *testing.T) { t.Errorf("expected people_ids[]=101,202, got %v (query %q)", ids, captured) } } + +// TestEverythingService_OpenTodos_BucketGrouped_MultiPage exercises the +// bucket-grouped todo filter family: Link-header following across two pages, the +// {bucket, todos} grouping, and embedded steps on a todo. +func TestEverythingService_OpenTodos_BucketGrouped_MultiPage(t *testing.T) { + var serverURL string + var page1, page2 int + svc, url := everythingTestClient(t, func(w http.ResponseWriter, r *http.Request) { + if r.URL.Path != "/99999/todos/open.json" { + t.Errorf("unexpected path: %s", r.URL.Path) + } + w.Header().Set("Content-Type", "application/json") + w.Header().Set("X-Total-Count", "2") + if r.URL.Query().Get("page") == "2" { + page2++ + w.WriteHeader(200) + _, _ = w.Write([]byte(`[{"bucket":{"id":20,"name":"Project B","type":"Project"},"todos":[{"id":5,"content":"Second bucket todo","completed":false}]}]`)) + return + } + page1++ + w.Header().Set("Link", fmt.Sprintf(`<%s/99999/todos/open.json?page=2>; rel="next"`, serverURL)) + w.WriteHeader(200) + _, _ = w.Write([]byte(`[{"bucket":{"id":10,"name":"Project A","type":"Project"},"todos":[{"id":1,"content":"First","completed":false,"steps":[{"id":100,"title":"Step 1","completed":false}]}]}]`)) + }) + serverURL = url + + result, err := svc.OpenTodos(context.Background(), 0) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if page1 != 1 || page2 != 1 { + t.Fatalf("expected one hit per page, got page1=%d page2=%d", page1, page2) + } + if len(result.Groups) != 2 { + t.Fatalf("expected 2 bucket groups across pages, got %d", len(result.Groups)) + } + g0 := result.Groups[0] + if g0.Bucket == nil || g0.Bucket.Name != "Project A" { + t.Errorf("expected group 0 bucket 'Project A', got %+v", g0.Bucket) + } + if len(g0.Todos) != 1 || g0.Todos[0].ID != 1 { + t.Fatalf("expected 1 todo in group 0, got %+v", g0.Todos) + } + if len(g0.Todos[0].Steps) != 1 || g0.Todos[0].Steps[0].Title != "Step 1" { + t.Errorf("expected embedded step on todo, got %+v", g0.Todos[0].Steps) + } + if result.Groups[1].Bucket == nil || result.Groups[1].Bucket.Name != "Project B" { + t.Errorf("expected group 1 bucket 'Project B', got %+v", result.Groups[1].Bucket) + } + if result.Meta.TotalCount != 2 { + t.Errorf("expected TotalCount 2, got %d", result.Meta.TotalCount) + } +} + +// TestEverythingService_NotNowCards_BucketGrouped verifies the card filter +// family decodes the {bucket, cards} grouping with embedded steps. +func TestEverythingService_NotNowCards_BucketGrouped(t *testing.T) { + svc, _ := everythingTestClient(t, func(w http.ResponseWriter, r *http.Request) { + if r.URL.Path != "/99999/cards/not_now.json" { + t.Errorf("unexpected path: %s", r.URL.Path) + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, _ = w.Write([]byte(`[{"bucket":{"id":30,"name":"Kanban Project","type":"Project"},"cards":[{"id":7,"title":"Parked card","completed":false,"steps":[{"id":200,"title":"Do later","completed":false}]}]}]`)) + }) + + result, err := svc.NotNowCards(context.Background(), 1) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if len(result.Groups) != 1 { + t.Fatalf("expected 1 bucket group, got %d", len(result.Groups)) + } + g := result.Groups[0] + if g.Bucket == nil || g.Bucket.Name != "Kanban Project" { + t.Errorf("expected bucket 'Kanban Project', got %+v", g.Bucket) + } + if len(g.Cards) != 1 || g.Cards[0].ID != 7 { + t.Fatalf("expected 1 card, got %+v", g.Cards) + } + if len(g.Cards[0].Steps) != 1 || g.Cards[0].Steps[0].Title != "Do later" { + t.Errorf("expected embedded step on card, got %+v", g.Cards[0].Steps) + } +} diff --git a/go/pkg/basecamp/url-routes.json b/go/pkg/basecamp/url-routes.json index a6c7b471..bcf49ae1 100644 --- a/go/pkg/basecamp/url-routes.json +++ b/go/pkg/basecamp/url-routes.json @@ -374,6 +374,58 @@ } } }, + { + "pattern": "/{accountId}/cards/completed", + "resource": "Everything", + "operations": { + "GET": "GetEverythingCompletedCards" + }, + "params": { + "accountId": { + "role": "account", + "type": "string" + } + } + }, + { + "pattern": "/{accountId}/cards/no_due_date", + "resource": "Everything", + "operations": { + "GET": "GetEverythingNoDueDateCards" + }, + "params": { + "accountId": { + "role": "account", + "type": "string" + } + } + }, + { + "pattern": "/{accountId}/cards/not_now", + "resource": "Everything", + "operations": { + "GET": "GetEverythingNotNowCards" + }, + "params": { + "accountId": { + "role": "account", + "type": "string" + } + } + }, + { + "pattern": "/{accountId}/cards/open", + "resource": "Everything", + "operations": { + "GET": "GetEverythingOpenCards" + }, + "params": { + "accountId": { + "role": "account", + "type": "string" + } + } + }, { "pattern": "/{accountId}/cards/overdue", "resource": "Everything", @@ -387,6 +439,19 @@ } } }, + { + "pattern": "/{accountId}/cards/unassigned", + "resource": "Everything", + "operations": { + "GET": "GetEverythingUnassignedCards" + }, + "params": { + "accountId": { + "role": "account", + "type": "string" + } + } + }, { "pattern": "/{accountId}/categories", "resource": "Messages", @@ -2078,6 +2143,45 @@ } } }, + { + "pattern": "/{accountId}/todos/completed", + "resource": "Everything", + "operations": { + "GET": "GetEverythingCompletedTodos" + }, + "params": { + "accountId": { + "role": "account", + "type": "string" + } + } + }, + { + "pattern": "/{accountId}/todos/no_due_date", + "resource": "Everything", + "operations": { + "GET": "GetEverythingNoDueDateTodos" + }, + "params": { + "accountId": { + "role": "account", + "type": "string" + } + } + }, + { + "pattern": "/{accountId}/todos/open", + "resource": "Everything", + "operations": { + "GET": "GetEverythingOpenTodos" + }, + "params": { + "accountId": { + "role": "account", + "type": "string" + } + } + }, { "pattern": "/{accountId}/todos/overdue", "resource": "Everything", @@ -2091,6 +2195,19 @@ } } }, + { + "pattern": "/{accountId}/todos/unassigned", + "resource": "Everything", + "operations": { + "GET": "GetEverythingUnassignedTodos" + }, + "params": { + "accountId": { + "role": "account", + "type": "string" + } + } + }, { "pattern": "/{accountId}/todos/{todoId}", "resource": "Todos", diff --git a/go/pkg/generated/client.gen.go b/go/pkg/generated/client.gen.go index a000a619..5b998754 100644 --- a/go/pkg/generated/client.gen.go +++ b/go/pkg/generated/client.gen.go @@ -137,6 +137,20 @@ type Boost struct { Recording RecordingParent `json:"recording,omitempty"` } +// BucketCardsGroup One project's slice of a filtered card listing: the parent project and the +// matching cards (each carrying its steps). +type BucketCardsGroup struct { + Bucket RecordingBucket `json:"bucket,omitempty"` + Cards []Card `json:"cards,omitempty"` +} + +// BucketTodosGroup One project's slice of a filtered to-do listing: the parent project and the +// matching to-dos (each carrying its steps). +type BucketTodosGroup struct { + Bucket RecordingBucket `json:"bucket,omitempty"` + Todos []Todo `json:"todos,omitempty"` +} + // Campfire defines model for Campfire. type Campfire struct { AppUrl string `json:"app_url"` @@ -1089,6 +1103,12 @@ type GetEverythingCheckinsResponseContent = []Recording // GetEverythingCommentsResponseContent defines model for GetEverythingCommentsResponseContent. type GetEverythingCommentsResponseContent = []Recording +// GetEverythingCompletedCardsResponseContent defines model for GetEverythingCompletedCardsResponseContent. +type GetEverythingCompletedCardsResponseContent = []BucketCardsGroup + +// GetEverythingCompletedTodosResponseContent defines model for GetEverythingCompletedTodosResponseContent. +type GetEverythingCompletedTodosResponseContent = []BucketTodosGroup + // GetEverythingFilesResponseContent defines model for GetEverythingFilesResponseContent. type GetEverythingFilesResponseContent = []EverythingFile @@ -1098,12 +1118,33 @@ type GetEverythingForwardsResponseContent = []Recording // GetEverythingMessagesResponseContent defines model for GetEverythingMessagesResponseContent. type GetEverythingMessagesResponseContent = []Recording +// GetEverythingNoDueDateCardsResponseContent defines model for GetEverythingNoDueDateCardsResponseContent. +type GetEverythingNoDueDateCardsResponseContent = []BucketCardsGroup + +// GetEverythingNoDueDateTodosResponseContent defines model for GetEverythingNoDueDateTodosResponseContent. +type GetEverythingNoDueDateTodosResponseContent = []BucketTodosGroup + +// GetEverythingNotNowCardsResponseContent defines model for GetEverythingNotNowCardsResponseContent. +type GetEverythingNotNowCardsResponseContent = []BucketCardsGroup + +// GetEverythingOpenCardsResponseContent defines model for GetEverythingOpenCardsResponseContent. +type GetEverythingOpenCardsResponseContent = []BucketCardsGroup + +// GetEverythingOpenTodosResponseContent defines model for GetEverythingOpenTodosResponseContent. +type GetEverythingOpenTodosResponseContent = []BucketTodosGroup + // GetEverythingOverdueCardsResponseContent defines model for GetEverythingOverdueCardsResponseContent. type GetEverythingOverdueCardsResponseContent = []Card // GetEverythingOverdueTodosResponseContent defines model for GetEverythingOverdueTodosResponseContent. type GetEverythingOverdueTodosResponseContent = []Todo +// GetEverythingUnassignedCardsResponseContent defines model for GetEverythingUnassignedCardsResponseContent. +type GetEverythingUnassignedCardsResponseContent = []BucketCardsGroup + +// GetEverythingUnassignedTodosResponseContent defines model for GetEverythingUnassignedTodosResponseContent. +type GetEverythingUnassignedTodosResponseContent = []BucketTodosGroup + // GetForwardReplyResponseContent defines model for GetForwardReplyResponseContent. type GetForwardReplyResponseContent = ForwardReply @@ -3853,9 +3894,24 @@ type ClientInterface interface { MoveCardColumn(ctx context.Context, accountId string, cardTableId int64, body MoveCardColumnJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + // GetEverythingCompletedCards request + GetEverythingCompletedCards(ctx context.Context, accountId string, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetEverythingNoDueDateCards request + GetEverythingNoDueDateCards(ctx context.Context, accountId string, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetEverythingNotNowCards request + GetEverythingNotNowCards(ctx context.Context, accountId string, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetEverythingOpenCards request + GetEverythingOpenCards(ctx context.Context, accountId string, reqEditors ...RequestEditorFn) (*http.Response, error) + // GetEverythingOverdueCards request GetEverythingOverdueCards(ctx context.Context, accountId string, reqEditors ...RequestEditorFn) (*http.Response, error) + // GetEverythingUnassignedCards request + GetEverythingUnassignedCards(ctx context.Context, accountId string, reqEditors ...RequestEditorFn) (*http.Response, error) + // ListMessageTypes request ListMessageTypes(ctx context.Context, accountId string, reqEditors ...RequestEditorFn) (*http.Response, error) @@ -4415,9 +4471,21 @@ type ClientInterface interface { CreateTodo(ctx context.Context, accountId string, todolistId int64, body CreateTodoJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + // GetEverythingCompletedTodos request + GetEverythingCompletedTodos(ctx context.Context, accountId string, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetEverythingNoDueDateTodos request + GetEverythingNoDueDateTodos(ctx context.Context, accountId string, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetEverythingOpenTodos request + GetEverythingOpenTodos(ctx context.Context, accountId string, reqEditors ...RequestEditorFn) (*http.Response, error) + // GetEverythingOverdueTodos request GetEverythingOverdueTodos(ctx context.Context, accountId string, reqEditors ...RequestEditorFn) (*http.Response, error) + // GetEverythingUnassignedTodos request + GetEverythingUnassignedTodos(ctx context.Context, accountId string, reqEditors ...RequestEditorFn) (*http.Response, error) + // TrashTodo request TrashTodo(ctx context.Context, accountId string, todoId int64, reqEditors ...RequestEditorFn) (*http.Response, error) @@ -5049,6 +5117,46 @@ func (c *Client) MoveCardColumn(ctx context.Context, accountId string, cardTable } +// GetEverythingCompletedCards is marked as idempotent and will be retried on transient failures. + +func (c *Client) GetEverythingCompletedCards(ctx context.Context, accountId string, reqEditors ...RequestEditorFn) (*http.Response, error) { + + return c.doWithRetry(ctx, func() (*http.Request, error) { + return NewGetEverythingCompletedCardsRequest(c.Server, accountId) + }, true, "GetEverythingCompletedCards", reqEditors...) + +} + +// GetEverythingNoDueDateCards is marked as idempotent and will be retried on transient failures. + +func (c *Client) GetEverythingNoDueDateCards(ctx context.Context, accountId string, reqEditors ...RequestEditorFn) (*http.Response, error) { + + return c.doWithRetry(ctx, func() (*http.Request, error) { + return NewGetEverythingNoDueDateCardsRequest(c.Server, accountId) + }, true, "GetEverythingNoDueDateCards", reqEditors...) + +} + +// GetEverythingNotNowCards is marked as idempotent and will be retried on transient failures. + +func (c *Client) GetEverythingNotNowCards(ctx context.Context, accountId string, reqEditors ...RequestEditorFn) (*http.Response, error) { + + return c.doWithRetry(ctx, func() (*http.Request, error) { + return NewGetEverythingNotNowCardsRequest(c.Server, accountId) + }, true, "GetEverythingNotNowCards", reqEditors...) + +} + +// GetEverythingOpenCards is marked as idempotent and will be retried on transient failures. + +func (c *Client) GetEverythingOpenCards(ctx context.Context, accountId string, reqEditors ...RequestEditorFn) (*http.Response, error) { + + return c.doWithRetry(ctx, func() (*http.Request, error) { + return NewGetEverythingOpenCardsRequest(c.Server, accountId) + }, true, "GetEverythingOpenCards", reqEditors...) + +} + // GetEverythingOverdueCards is marked as idempotent and will be retried on transient failures. func (c *Client) GetEverythingOverdueCards(ctx context.Context, accountId string, reqEditors ...RequestEditorFn) (*http.Response, error) { @@ -5059,6 +5167,16 @@ func (c *Client) GetEverythingOverdueCards(ctx context.Context, accountId string } +// GetEverythingUnassignedCards is marked as idempotent and will be retried on transient failures. + +func (c *Client) GetEverythingUnassignedCards(ctx context.Context, accountId string, reqEditors ...RequestEditorFn) (*http.Response, error) { + + return c.doWithRetry(ctx, func() (*http.Request, error) { + return NewGetEverythingUnassignedCardsRequest(c.Server, accountId) + }, true, "GetEverythingUnassignedCards", reqEditors...) + +} + // ListMessageTypes is marked as idempotent and will be retried on transient failures. func (c *Client) ListMessageTypes(ctx context.Context, accountId string, reqEditors ...RequestEditorFn) (*http.Response, error) { @@ -7249,6 +7367,36 @@ func (c *Client) CreateTodo(ctx context.Context, accountId string, todolistId in } +// GetEverythingCompletedTodos is marked as idempotent and will be retried on transient failures. + +func (c *Client) GetEverythingCompletedTodos(ctx context.Context, accountId string, reqEditors ...RequestEditorFn) (*http.Response, error) { + + return c.doWithRetry(ctx, func() (*http.Request, error) { + return NewGetEverythingCompletedTodosRequest(c.Server, accountId) + }, true, "GetEverythingCompletedTodos", reqEditors...) + +} + +// GetEverythingNoDueDateTodos is marked as idempotent and will be retried on transient failures. + +func (c *Client) GetEverythingNoDueDateTodos(ctx context.Context, accountId string, reqEditors ...RequestEditorFn) (*http.Response, error) { + + return c.doWithRetry(ctx, func() (*http.Request, error) { + return NewGetEverythingNoDueDateTodosRequest(c.Server, accountId) + }, true, "GetEverythingNoDueDateTodos", reqEditors...) + +} + +// GetEverythingOpenTodos is marked as idempotent and will be retried on transient failures. + +func (c *Client) GetEverythingOpenTodos(ctx context.Context, accountId string, reqEditors ...RequestEditorFn) (*http.Response, error) { + + return c.doWithRetry(ctx, func() (*http.Request, error) { + return NewGetEverythingOpenTodosRequest(c.Server, accountId) + }, true, "GetEverythingOpenTodos", reqEditors...) + +} + // GetEverythingOverdueTodos is marked as idempotent and will be retried on transient failures. func (c *Client) GetEverythingOverdueTodos(ctx context.Context, accountId string, reqEditors ...RequestEditorFn) (*http.Response, error) { @@ -7259,6 +7407,16 @@ func (c *Client) GetEverythingOverdueTodos(ctx context.Context, accountId string } +// GetEverythingUnassignedTodos is marked as idempotent and will be retried on transient failures. + +func (c *Client) GetEverythingUnassignedTodos(ctx context.Context, accountId string, reqEditors ...RequestEditorFn) (*http.Response, error) { + + return c.doWithRetry(ctx, func() (*http.Request, error) { + return NewGetEverythingUnassignedTodosRequest(c.Server, accountId) + }, true, "GetEverythingUnassignedTodos", reqEditors...) + +} + // TrashTodo is marked as idempotent and will be retried on transient failures. func (c *Client) TrashTodo(ctx context.Context, accountId string, todoId int64, reqEditors ...RequestEditorFn) (*http.Response, error) { @@ -9109,8 +9267,8 @@ func NewMoveCardColumnRequestWithBody(server string, accountId string, cardTable return req, nil } -// NewGetEverythingOverdueCardsRequest generates requests for GetEverythingOverdueCards -func NewGetEverythingOverdueCardsRequest(server string, accountId string) (*http.Request, error) { +// NewGetEverythingCompletedCardsRequest generates requests for GetEverythingCompletedCards +func NewGetEverythingCompletedCardsRequest(server string, accountId string) (*http.Request, error) { var err error var pathParam0 string @@ -9125,7 +9283,7 @@ func NewGetEverythingOverdueCardsRequest(server string, accountId string) (*http return nil, err } - operationPath := fmt.Sprintf("/%s/cards/overdue.json", pathParam0) + operationPath := fmt.Sprintf("/%s/cards/completed.json", pathParam0) if operationPath[0] == '/' { operationPath = "." + operationPath } @@ -9143,8 +9301,8 @@ func NewGetEverythingOverdueCardsRequest(server string, accountId string) (*http return req, nil } -// NewListMessageTypesRequest generates requests for ListMessageTypes -func NewListMessageTypesRequest(server string, accountId string) (*http.Request, error) { +// NewGetEverythingNoDueDateCardsRequest generates requests for GetEverythingNoDueDateCards +func NewGetEverythingNoDueDateCardsRequest(server string, accountId string) (*http.Request, error) { var err error var pathParam0 string @@ -9159,7 +9317,7 @@ func NewListMessageTypesRequest(server string, accountId string) (*http.Request, return nil, err } - operationPath := fmt.Sprintf("/%s/categories.json", pathParam0) + operationPath := fmt.Sprintf("/%s/cards/no_due_date.json", pathParam0) if operationPath[0] == '/' { operationPath = "." + operationPath } @@ -9177,19 +9335,8 @@ func NewListMessageTypesRequest(server string, accountId string) (*http.Request, return req, nil } -// NewCreateMessageTypeRequest calls the generic CreateMessageType builder with application/json body -func NewCreateMessageTypeRequest(server string, accountId string, body CreateMessageTypeJSONRequestBody) (*http.Request, error) { - var bodyReader io.Reader - buf, err := json.Marshal(body) - if err != nil { - return nil, err - } - bodyReader = bytes.NewReader(buf) - return NewCreateMessageTypeRequestWithBody(server, accountId, "application/json", bodyReader) -} - -// NewCreateMessageTypeRequestWithBody generates requests for CreateMessageType with any type of body -func NewCreateMessageTypeRequestWithBody(server string, accountId string, contentType string, body io.Reader) (*http.Request, error) { +// NewGetEverythingNotNowCardsRequest generates requests for GetEverythingNotNowCards +func NewGetEverythingNotNowCardsRequest(server string, accountId string) (*http.Request, error) { var err error var pathParam0 string @@ -9204,7 +9351,7 @@ func NewCreateMessageTypeRequestWithBody(server string, accountId string, conten return nil, err } - operationPath := fmt.Sprintf("/%s/categories.json", pathParam0) + operationPath := fmt.Sprintf("/%s/cards/not_now.json", pathParam0) if operationPath[0] == '/' { operationPath = "." + operationPath } @@ -9214,18 +9361,16 @@ func NewCreateMessageTypeRequestWithBody(server string, accountId string, conten return nil, err } - req, err := http.NewRequest("POST", queryURL.String(), body) + req, err := http.NewRequest("GET", queryURL.String(), nil) if err != nil { return nil, err } - req.Header.Add("Content-Type", contentType) - return req, nil } -// NewDeleteMessageTypeRequest generates requests for DeleteMessageType -func NewDeleteMessageTypeRequest(server string, accountId string, typeId int64) (*http.Request, error) { +// NewGetEverythingOpenCardsRequest generates requests for GetEverythingOpenCards +func NewGetEverythingOpenCardsRequest(server string, accountId string) (*http.Request, error) { var err error var pathParam0 string @@ -9235,9 +9380,36 @@ func NewDeleteMessageTypeRequest(server string, accountId string, typeId int64) return nil, err } - var pathParam1 string + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } - pathParam1, err = runtime.StyleParamWithLocation("simple", false, "typeId", runtime.ParamLocationPath, typeId) + operationPath := fmt.Sprintf("/%s/cards/open.json", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("GET", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewGetEverythingOverdueCardsRequest generates requests for GetEverythingOverdueCards +func NewGetEverythingOverdueCardsRequest(server string, accountId string) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "accountId", runtime.ParamLocationPath, accountId) if err != nil { return nil, err } @@ -9247,7 +9419,7 @@ func NewDeleteMessageTypeRequest(server string, accountId string, typeId int64) return nil, err } - operationPath := fmt.Sprintf("/%s/categories/%s", pathParam0, pathParam1) + operationPath := fmt.Sprintf("/%s/cards/overdue.json", pathParam0) if operationPath[0] == '/' { operationPath = "." + operationPath } @@ -9257,7 +9429,7 @@ func NewDeleteMessageTypeRequest(server string, accountId string, typeId int64) return nil, err } - req, err := http.NewRequest("DELETE", queryURL.String(), nil) + req, err := http.NewRequest("GET", queryURL.String(), nil) if err != nil { return nil, err } @@ -9265,8 +9437,8 @@ func NewDeleteMessageTypeRequest(server string, accountId string, typeId int64) return req, nil } -// NewGetMessageTypeRequest generates requests for GetMessageType -func NewGetMessageTypeRequest(server string, accountId string, typeId int64) (*http.Request, error) { +// NewGetEverythingUnassignedCardsRequest generates requests for GetEverythingUnassignedCards +func NewGetEverythingUnassignedCardsRequest(server string, accountId string) (*http.Request, error) { var err error var pathParam0 string @@ -9276,9 +9448,36 @@ func NewGetMessageTypeRequest(server string, accountId string, typeId int64) (*h return nil, err } - var pathParam1 string + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } - pathParam1, err = runtime.StyleParamWithLocation("simple", false, "typeId", runtime.ParamLocationPath, typeId) + operationPath := fmt.Sprintf("/%s/cards/unassigned.json", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("GET", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewListMessageTypesRequest generates requests for ListMessageTypes +func NewListMessageTypesRequest(server string, accountId string) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "accountId", runtime.ParamLocationPath, accountId) if err != nil { return nil, err } @@ -9288,7 +9487,7 @@ func NewGetMessageTypeRequest(server string, accountId string, typeId int64) (*h return nil, err } - operationPath := fmt.Sprintf("/%s/categories/%s", pathParam0, pathParam1) + operationPath := fmt.Sprintf("/%s/categories.json", pathParam0) if operationPath[0] == '/' { operationPath = "." + operationPath } @@ -9306,19 +9505,19 @@ func NewGetMessageTypeRequest(server string, accountId string, typeId int64) (*h return req, nil } -// NewUpdateMessageTypeRequest calls the generic UpdateMessageType builder with application/json body -func NewUpdateMessageTypeRequest(server string, accountId string, typeId int64, body UpdateMessageTypeJSONRequestBody) (*http.Request, error) { +// NewCreateMessageTypeRequest calls the generic CreateMessageType builder with application/json body +func NewCreateMessageTypeRequest(server string, accountId string, body CreateMessageTypeJSONRequestBody) (*http.Request, error) { var bodyReader io.Reader buf, err := json.Marshal(body) if err != nil { return nil, err } bodyReader = bytes.NewReader(buf) - return NewUpdateMessageTypeRequestWithBody(server, accountId, typeId, "application/json", bodyReader) + return NewCreateMessageTypeRequestWithBody(server, accountId, "application/json", bodyReader) } -// NewUpdateMessageTypeRequestWithBody generates requests for UpdateMessageType with any type of body -func NewUpdateMessageTypeRequestWithBody(server string, accountId string, typeId int64, contentType string, body io.Reader) (*http.Request, error) { +// NewCreateMessageTypeRequestWithBody generates requests for CreateMessageType with any type of body +func NewCreateMessageTypeRequestWithBody(server string, accountId string, contentType string, body io.Reader) (*http.Request, error) { var err error var pathParam0 string @@ -9328,19 +9527,12 @@ func NewUpdateMessageTypeRequestWithBody(server string, accountId string, typeId return nil, err } - var pathParam1 string - - pathParam1, err = runtime.StyleParamWithLocation("simple", false, "typeId", runtime.ParamLocationPath, typeId) - if err != nil { - return nil, err - } - serverURL, err := url.Parse(server) if err != nil { return nil, err } - operationPath := fmt.Sprintf("/%s/categories/%s", pathParam0, pathParam1) + operationPath := fmt.Sprintf("/%s/categories.json", pathParam0) if operationPath[0] == '/' { operationPath = "." + operationPath } @@ -9350,7 +9542,7 @@ func NewUpdateMessageTypeRequestWithBody(server string, accountId string, typeId return nil, err } - req, err := http.NewRequest("PUT", queryURL.String(), body) + req, err := http.NewRequest("POST", queryURL.String(), body) if err != nil { return nil, err } @@ -9360,8 +9552,8 @@ func NewUpdateMessageTypeRequestWithBody(server string, accountId string, typeId return req, nil } -// NewListCampfiresRequest generates requests for ListCampfires -func NewListCampfiresRequest(server string, accountId string) (*http.Request, error) { +// NewDeleteMessageTypeRequest generates requests for DeleteMessageType +func NewDeleteMessageTypeRequest(server string, accountId string, typeId int64) (*http.Request, error) { var err error var pathParam0 string @@ -9371,12 +9563,19 @@ func NewListCampfiresRequest(server string, accountId string) (*http.Request, er return nil, err } + var pathParam1 string + + pathParam1, err = runtime.StyleParamWithLocation("simple", false, "typeId", runtime.ParamLocationPath, typeId) + if err != nil { + return nil, err + } + serverURL, err := url.Parse(server) if err != nil { return nil, err } - operationPath := fmt.Sprintf("/%s/chats.json", pathParam0) + operationPath := fmt.Sprintf("/%s/categories/%s", pathParam0, pathParam1) if operationPath[0] == '/' { operationPath = "." + operationPath } @@ -9386,7 +9585,7 @@ func NewListCampfiresRequest(server string, accountId string) (*http.Request, er return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest("DELETE", queryURL.String(), nil) if err != nil { return nil, err } @@ -9394,8 +9593,8 @@ func NewListCampfiresRequest(server string, accountId string) (*http.Request, er return req, nil } -// NewGetCampfireRequest generates requests for GetCampfire -func NewGetCampfireRequest(server string, accountId string, campfireId int64) (*http.Request, error) { +// NewGetMessageTypeRequest generates requests for GetMessageType +func NewGetMessageTypeRequest(server string, accountId string, typeId int64) (*http.Request, error) { var err error var pathParam0 string @@ -9407,7 +9606,7 @@ func NewGetCampfireRequest(server string, accountId string, campfireId int64) (* var pathParam1 string - pathParam1, err = runtime.StyleParamWithLocation("simple", false, "campfireId", runtime.ParamLocationPath, campfireId) + pathParam1, err = runtime.StyleParamWithLocation("simple", false, "typeId", runtime.ParamLocationPath, typeId) if err != nil { return nil, err } @@ -9417,7 +9616,7 @@ func NewGetCampfireRequest(server string, accountId string, campfireId int64) (* return nil, err } - operationPath := fmt.Sprintf("/%s/chats/%s", pathParam0, pathParam1) + operationPath := fmt.Sprintf("/%s/categories/%s", pathParam0, pathParam1) if operationPath[0] == '/' { operationPath = "." + operationPath } @@ -9435,8 +9634,19 @@ func NewGetCampfireRequest(server string, accountId string, campfireId int64) (* return req, nil } -// NewListChatbotsRequest generates requests for ListChatbots -func NewListChatbotsRequest(server string, accountId string, campfireId int64) (*http.Request, error) { +// NewUpdateMessageTypeRequest calls the generic UpdateMessageType builder with application/json body +func NewUpdateMessageTypeRequest(server string, accountId string, typeId int64, body UpdateMessageTypeJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewUpdateMessageTypeRequestWithBody(server, accountId, typeId, "application/json", bodyReader) +} + +// NewUpdateMessageTypeRequestWithBody generates requests for UpdateMessageType with any type of body +func NewUpdateMessageTypeRequestWithBody(server string, accountId string, typeId int64, contentType string, body io.Reader) (*http.Request, error) { var err error var pathParam0 string @@ -9448,7 +9658,7 @@ func NewListChatbotsRequest(server string, accountId string, campfireId int64) ( var pathParam1 string - pathParam1, err = runtime.StyleParamWithLocation("simple", false, "campfireId", runtime.ParamLocationPath, campfireId) + pathParam1, err = runtime.StyleParamWithLocation("simple", false, "typeId", runtime.ParamLocationPath, typeId) if err != nil { return nil, err } @@ -9458,7 +9668,7 @@ func NewListChatbotsRequest(server string, accountId string, campfireId int64) ( return nil, err } - operationPath := fmt.Sprintf("/%s/chats/%s/integrations.json", pathParam0, pathParam1) + operationPath := fmt.Sprintf("/%s/categories/%s", pathParam0, pathParam1) if operationPath[0] == '/' { operationPath = "." + operationPath } @@ -9468,27 +9678,145 @@ func NewListChatbotsRequest(server string, accountId string, campfireId int64) ( return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest("PUT", queryURL.String(), body) if err != nil { return nil, err } + req.Header.Add("Content-Type", contentType) + return req, nil } -// NewCreateChatbotRequest calls the generic CreateChatbot builder with application/json body -func NewCreateChatbotRequest(server string, accountId string, campfireId int64, body CreateChatbotJSONRequestBody) (*http.Request, error) { - var bodyReader io.Reader - buf, err := json.Marshal(body) +// NewListCampfiresRequest generates requests for ListCampfires +func NewListCampfiresRequest(server string, accountId string) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "accountId", runtime.ParamLocationPath, accountId) if err != nil { return nil, err } - bodyReader = bytes.NewReader(buf) - return NewCreateChatbotRequestWithBody(server, accountId, campfireId, "application/json", bodyReader) + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/%s/chats.json", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("GET", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil } -// NewCreateChatbotRequestWithBody generates requests for CreateChatbot with any type of body -func NewCreateChatbotRequestWithBody(server string, accountId string, campfireId int64, contentType string, body io.Reader) (*http.Request, error) { +// NewGetCampfireRequest generates requests for GetCampfire +func NewGetCampfireRequest(server string, accountId string, campfireId int64) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "accountId", runtime.ParamLocationPath, accountId) + if err != nil { + return nil, err + } + + var pathParam1 string + + pathParam1, err = runtime.StyleParamWithLocation("simple", false, "campfireId", runtime.ParamLocationPath, campfireId) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/%s/chats/%s", pathParam0, pathParam1) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("GET", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewListChatbotsRequest generates requests for ListChatbots +func NewListChatbotsRequest(server string, accountId string, campfireId int64) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "accountId", runtime.ParamLocationPath, accountId) + if err != nil { + return nil, err + } + + var pathParam1 string + + pathParam1, err = runtime.StyleParamWithLocation("simple", false, "campfireId", runtime.ParamLocationPath, campfireId) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/%s/chats/%s/integrations.json", pathParam0, pathParam1) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("GET", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewCreateChatbotRequest calls the generic CreateChatbot builder with application/json body +func NewCreateChatbotRequest(server string, accountId string, campfireId int64, body CreateChatbotJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewCreateChatbotRequestWithBody(server, accountId, campfireId, "application/json", bodyReader) +} + +// NewCreateChatbotRequestWithBody generates requests for CreateChatbot with any type of body +func NewCreateChatbotRequestWithBody(server string, accountId string, campfireId int64, contentType string, body io.Reader) (*http.Request, error) { var err error var pathParam0 string @@ -16910,8 +17238,8 @@ func NewCreateTodoRequestWithBody(server string, accountId string, todolistId in return req, nil } -// NewGetEverythingOverdueTodosRequest generates requests for GetEverythingOverdueTodos -func NewGetEverythingOverdueTodosRequest(server string, accountId string) (*http.Request, error) { +// NewGetEverythingCompletedTodosRequest generates requests for GetEverythingCompletedTodos +func NewGetEverythingCompletedTodosRequest(server string, accountId string) (*http.Request, error) { var err error var pathParam0 string @@ -16926,7 +17254,7 @@ func NewGetEverythingOverdueTodosRequest(server string, accountId string) (*http return nil, err } - operationPath := fmt.Sprintf("/%s/todos/overdue.json", pathParam0) + operationPath := fmt.Sprintf("/%s/todos/completed.json", pathParam0) if operationPath[0] == '/' { operationPath = "." + operationPath } @@ -16944,8 +17272,8 @@ func NewGetEverythingOverdueTodosRequest(server string, accountId string) (*http return req, nil } -// NewTrashTodoRequest generates requests for TrashTodo -func NewTrashTodoRequest(server string, accountId string, todoId int64) (*http.Request, error) { +// NewGetEverythingNoDueDateTodosRequest generates requests for GetEverythingNoDueDateTodos +func NewGetEverythingNoDueDateTodosRequest(server string, accountId string) (*http.Request, error) { var err error var pathParam0 string @@ -16955,19 +17283,12 @@ func NewTrashTodoRequest(server string, accountId string, todoId int64) (*http.R return nil, err } - var pathParam1 string - - pathParam1, err = runtime.StyleParamWithLocation("simple", false, "todoId", runtime.ParamLocationPath, todoId) - if err != nil { - return nil, err - } - serverURL, err := url.Parse(server) if err != nil { return nil, err } - operationPath := fmt.Sprintf("/%s/todos/%s", pathParam0, pathParam1) + operationPath := fmt.Sprintf("/%s/todos/no_due_date.json", pathParam0) if operationPath[0] == '/' { operationPath = "." + operationPath } @@ -16977,7 +17298,7 @@ func NewTrashTodoRequest(server string, accountId string, todoId int64) (*http.R return nil, err } - req, err := http.NewRequest("DELETE", queryURL.String(), nil) + req, err := http.NewRequest("GET", queryURL.String(), nil) if err != nil { return nil, err } @@ -16985,8 +17306,8 @@ func NewTrashTodoRequest(server string, accountId string, todoId int64) (*http.R return req, nil } -// NewGetTodoRequest generates requests for GetTodo -func NewGetTodoRequest(server string, accountId string, todoId int64) (*http.Request, error) { +// NewGetEverythingOpenTodosRequest generates requests for GetEverythingOpenTodos +func NewGetEverythingOpenTodosRequest(server string, accountId string) (*http.Request, error) { var err error var pathParam0 string @@ -16996,19 +17317,12 @@ func NewGetTodoRequest(server string, accountId string, todoId int64) (*http.Req return nil, err } - var pathParam1 string - - pathParam1, err = runtime.StyleParamWithLocation("simple", false, "todoId", runtime.ParamLocationPath, todoId) - if err != nil { - return nil, err - } - serverURL, err := url.Parse(server) if err != nil { return nil, err } - operationPath := fmt.Sprintf("/%s/todos/%s", pathParam0, pathParam1) + operationPath := fmt.Sprintf("/%s/todos/open.json", pathParam0) if operationPath[0] == '/' { operationPath = "." + operationPath } @@ -17026,31 +17340,47 @@ func NewGetTodoRequest(server string, accountId string, todoId int64) (*http.Req return req, nil } -// NewReplaceTodoRequest calls the generic ReplaceTodo builder with application/json body -func NewReplaceTodoRequest(server string, accountId string, todoId int64, body ReplaceTodoJSONRequestBody) (*http.Request, error) { - var bodyReader io.Reader - buf, err := json.Marshal(body) +// NewGetEverythingOverdueTodosRequest generates requests for GetEverythingOverdueTodos +func NewGetEverythingOverdueTodosRequest(server string, accountId string) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "accountId", runtime.ParamLocationPath, accountId) if err != nil { return nil, err } - bodyReader = bytes.NewReader(buf) - return NewReplaceTodoRequestWithBody(server, accountId, todoId, "application/json", bodyReader) -} -// NewReplaceTodoRequestWithBody generates requests for ReplaceTodo with any type of body -func NewReplaceTodoRequestWithBody(server string, accountId string, todoId int64, contentType string, body io.Reader) (*http.Request, error) { - var err error + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } - var pathParam0 string + operationPath := fmt.Sprintf("/%s/todos/overdue.json", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } - pathParam0, err = runtime.StyleParamWithLocation("simple", false, "accountId", runtime.ParamLocationPath, accountId) + queryURL, err := serverURL.Parse(operationPath) if err != nil { return nil, err } - var pathParam1 string + req, err := http.NewRequest("GET", queryURL.String(), nil) + if err != nil { + return nil, err + } - pathParam1, err = runtime.StyleParamWithLocation("simple", false, "todoId", runtime.ParamLocationPath, todoId) + return req, nil +} + +// NewGetEverythingUnassignedTodosRequest generates requests for GetEverythingUnassignedTodos +func NewGetEverythingUnassignedTodosRequest(server string, accountId string) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "accountId", runtime.ParamLocationPath, accountId) if err != nil { return nil, err } @@ -17060,7 +17390,7 @@ func NewReplaceTodoRequestWithBody(server string, accountId string, todoId int64 return nil, err } - operationPath := fmt.Sprintf("/%s/todos/%s", pathParam0, pathParam1) + operationPath := fmt.Sprintf("/%s/todos/unassigned.json", pathParam0) if operationPath[0] == '/' { operationPath = "." + operationPath } @@ -17070,18 +17400,16 @@ func NewReplaceTodoRequestWithBody(server string, accountId string, todoId int64 return nil, err } - req, err := http.NewRequest("PUT", queryURL.String(), body) + req, err := http.NewRequest("GET", queryURL.String(), nil) if err != nil { return nil, err } - req.Header.Add("Content-Type", contentType) - return req, nil } -// NewUncompleteTodoRequest generates requests for UncompleteTodo -func NewUncompleteTodoRequest(server string, accountId string, todoId int64) (*http.Request, error) { +// NewTrashTodoRequest generates requests for TrashTodo +func NewTrashTodoRequest(server string, accountId string, todoId int64) (*http.Request, error) { var err error var pathParam0 string @@ -17103,7 +17431,7 @@ func NewUncompleteTodoRequest(server string, accountId string, todoId int64) (*h return nil, err } - operationPath := fmt.Sprintf("/%s/todos/%s/completion.json", pathParam0, pathParam1) + operationPath := fmt.Sprintf("/%s/todos/%s", pathParam0, pathParam1) if operationPath[0] == '/' { operationPath = "." + operationPath } @@ -17121,8 +17449,8 @@ func NewUncompleteTodoRequest(server string, accountId string, todoId int64) (*h return req, nil } -// NewCompleteTodoRequest generates requests for CompleteTodo -func NewCompleteTodoRequest(server string, accountId string, todoId int64) (*http.Request, error) { +// NewGetTodoRequest generates requests for GetTodo +func NewGetTodoRequest(server string, accountId string, todoId int64) (*http.Request, error) { var err error var pathParam0 string @@ -17144,7 +17472,7 @@ func NewCompleteTodoRequest(server string, accountId string, todoId int64) (*htt return nil, err } - operationPath := fmt.Sprintf("/%s/todos/%s/completion.json", pathParam0, pathParam1) + operationPath := fmt.Sprintf("/%s/todos/%s", pathParam0, pathParam1) if operationPath[0] == '/' { operationPath = "." + operationPath } @@ -17154,7 +17482,7 @@ func NewCompleteTodoRequest(server string, accountId string, todoId int64) (*htt return nil, err } - req, err := http.NewRequest("POST", queryURL.String(), nil) + req, err := http.NewRequest("GET", queryURL.String(), nil) if err != nil { return nil, err } @@ -17162,19 +17490,19 @@ func NewCompleteTodoRequest(server string, accountId string, todoId int64) (*htt return req, nil } -// NewRepositionTodoRequest calls the generic RepositionTodo builder with application/json body -func NewRepositionTodoRequest(server string, accountId string, todoId int64, body RepositionTodoJSONRequestBody) (*http.Request, error) { +// NewReplaceTodoRequest calls the generic ReplaceTodo builder with application/json body +func NewReplaceTodoRequest(server string, accountId string, todoId int64, body ReplaceTodoJSONRequestBody) (*http.Request, error) { var bodyReader io.Reader buf, err := json.Marshal(body) if err != nil { return nil, err } bodyReader = bytes.NewReader(buf) - return NewRepositionTodoRequestWithBody(server, accountId, todoId, "application/json", bodyReader) + return NewReplaceTodoRequestWithBody(server, accountId, todoId, "application/json", bodyReader) } -// NewRepositionTodoRequestWithBody generates requests for RepositionTodo with any type of body -func NewRepositionTodoRequestWithBody(server string, accountId string, todoId int64, contentType string, body io.Reader) (*http.Request, error) { +// NewReplaceTodoRequestWithBody generates requests for ReplaceTodo with any type of body +func NewReplaceTodoRequestWithBody(server string, accountId string, todoId int64, contentType string, body io.Reader) (*http.Request, error) { var err error var pathParam0 string @@ -17196,7 +17524,7 @@ func NewRepositionTodoRequestWithBody(server string, accountId string, todoId in return nil, err } - operationPath := fmt.Sprintf("/%s/todos/%s/position.json", pathParam0, pathParam1) + operationPath := fmt.Sprintf("/%s/todos/%s", pathParam0, pathParam1) if operationPath[0] == '/' { operationPath = "." + operationPath } @@ -17216,19 +17544,8 @@ func NewRepositionTodoRequestWithBody(server string, accountId string, todoId in return req, nil } -// NewRepositionTodolistRequest calls the generic RepositionTodolist builder with application/json body -func NewRepositionTodolistRequest(server string, accountId string, todolistId int64, body RepositionTodolistJSONRequestBody) (*http.Request, error) { - var bodyReader io.Reader - buf, err := json.Marshal(body) - if err != nil { - return nil, err - } - bodyReader = bytes.NewReader(buf) - return NewRepositionTodolistRequestWithBody(server, accountId, todolistId, "application/json", bodyReader) -} - -// NewRepositionTodolistRequestWithBody generates requests for RepositionTodolist with any type of body -func NewRepositionTodolistRequestWithBody(server string, accountId string, todolistId int64, contentType string, body io.Reader) (*http.Request, error) { +// NewUncompleteTodoRequest generates requests for UncompleteTodo +func NewUncompleteTodoRequest(server string, accountId string, todoId int64) (*http.Request, error) { var err error var pathParam0 string @@ -17240,7 +17557,7 @@ func NewRepositionTodolistRequestWithBody(server string, accountId string, todol var pathParam1 string - pathParam1, err = runtime.StyleParamWithLocation("simple", false, "todolistId", runtime.ParamLocationPath, todolistId) + pathParam1, err = runtime.StyleParamWithLocation("simple", false, "todoId", runtime.ParamLocationPath, todoId) if err != nil { return nil, err } @@ -17250,7 +17567,7 @@ func NewRepositionTodolistRequestWithBody(server string, accountId string, todol return nil, err } - operationPath := fmt.Sprintf("/%s/todosets/todolists/%s/position.json", pathParam0, pathParam1) + operationPath := fmt.Sprintf("/%s/todos/%s/completion.json", pathParam0, pathParam1) if operationPath[0] == '/' { operationPath = "." + operationPath } @@ -17260,18 +17577,16 @@ func NewRepositionTodolistRequestWithBody(server string, accountId string, todol return nil, err } - req, err := http.NewRequest("PUT", queryURL.String(), body) + req, err := http.NewRequest("DELETE", queryURL.String(), nil) if err != nil { return nil, err } - req.Header.Add("Content-Type", contentType) - return req, nil } -// NewGetTodosetRequest generates requests for GetTodoset -func NewGetTodosetRequest(server string, accountId string, todosetId int64) (*http.Request, error) { +// NewCompleteTodoRequest generates requests for CompleteTodo +func NewCompleteTodoRequest(server string, accountId string, todoId int64) (*http.Request, error) { var err error var pathParam0 string @@ -17283,7 +17598,7 @@ func NewGetTodosetRequest(server string, accountId string, todosetId int64) (*ht var pathParam1 string - pathParam1, err = runtime.StyleParamWithLocation("simple", false, "todosetId", runtime.ParamLocationPath, todosetId) + pathParam1, err = runtime.StyleParamWithLocation("simple", false, "todoId", runtime.ParamLocationPath, todoId) if err != nil { return nil, err } @@ -17293,7 +17608,7 @@ func NewGetTodosetRequest(server string, accountId string, todosetId int64) (*ht return nil, err } - operationPath := fmt.Sprintf("/%s/todosets/%s", pathParam0, pathParam1) + operationPath := fmt.Sprintf("/%s/todos/%s/completion.json", pathParam0, pathParam1) if operationPath[0] == '/' { operationPath = "." + operationPath } @@ -17303,7 +17618,7 @@ func NewGetTodosetRequest(server string, accountId string, todosetId int64) (*ht return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest("POST", queryURL.String(), nil) if err != nil { return nil, err } @@ -17311,8 +17626,19 @@ func NewGetTodosetRequest(server string, accountId string, todosetId int64) (*ht return req, nil } -// NewGetHillChartRequest generates requests for GetHillChart -func NewGetHillChartRequest(server string, accountId string, todosetId int64) (*http.Request, error) { +// NewRepositionTodoRequest calls the generic RepositionTodo builder with application/json body +func NewRepositionTodoRequest(server string, accountId string, todoId int64, body RepositionTodoJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewRepositionTodoRequestWithBody(server, accountId, todoId, "application/json", bodyReader) +} + +// NewRepositionTodoRequestWithBody generates requests for RepositionTodo with any type of body +func NewRepositionTodoRequestWithBody(server string, accountId string, todoId int64, contentType string, body io.Reader) (*http.Request, error) { var err error var pathParam0 string @@ -17324,7 +17650,7 @@ func NewGetHillChartRequest(server string, accountId string, todosetId int64) (* var pathParam1 string - pathParam1, err = runtime.StyleParamWithLocation("simple", false, "todosetId", runtime.ParamLocationPath, todosetId) + pathParam1, err = runtime.StyleParamWithLocation("simple", false, "todoId", runtime.ParamLocationPath, todoId) if err != nil { return nil, err } @@ -17334,7 +17660,7 @@ func NewGetHillChartRequest(server string, accountId string, todosetId int64) (* return nil, err } - operationPath := fmt.Sprintf("/%s/todosets/%s/hill.json", pathParam0, pathParam1) + operationPath := fmt.Sprintf("/%s/todos/%s/position.json", pathParam0, pathParam1) if operationPath[0] == '/' { operationPath = "." + operationPath } @@ -17344,27 +17670,29 @@ func NewGetHillChartRequest(server string, accountId string, todosetId int64) (* return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest("PUT", queryURL.String(), body) if err != nil { return nil, err } + req.Header.Add("Content-Type", contentType) + return req, nil } -// NewUpdateHillChartSettingsRequest calls the generic UpdateHillChartSettings builder with application/json body -func NewUpdateHillChartSettingsRequest(server string, accountId string, todosetId int64, body UpdateHillChartSettingsJSONRequestBody) (*http.Request, error) { +// NewRepositionTodolistRequest calls the generic RepositionTodolist builder with application/json body +func NewRepositionTodolistRequest(server string, accountId string, todolistId int64, body RepositionTodolistJSONRequestBody) (*http.Request, error) { var bodyReader io.Reader buf, err := json.Marshal(body) if err != nil { return nil, err } bodyReader = bytes.NewReader(buf) - return NewUpdateHillChartSettingsRequestWithBody(server, accountId, todosetId, "application/json", bodyReader) + return NewRepositionTodolistRequestWithBody(server, accountId, todolistId, "application/json", bodyReader) } -// NewUpdateHillChartSettingsRequestWithBody generates requests for UpdateHillChartSettings with any type of body -func NewUpdateHillChartSettingsRequestWithBody(server string, accountId string, todosetId int64, contentType string, body io.Reader) (*http.Request, error) { +// NewRepositionTodolistRequestWithBody generates requests for RepositionTodolist with any type of body +func NewRepositionTodolistRequestWithBody(server string, accountId string, todolistId int64, contentType string, body io.Reader) (*http.Request, error) { var err error var pathParam0 string @@ -17376,7 +17704,7 @@ func NewUpdateHillChartSettingsRequestWithBody(server string, accountId string, var pathParam1 string - pathParam1, err = runtime.StyleParamWithLocation("simple", false, "todosetId", runtime.ParamLocationPath, todosetId) + pathParam1, err = runtime.StyleParamWithLocation("simple", false, "todolistId", runtime.ParamLocationPath, todolistId) if err != nil { return nil, err } @@ -17386,7 +17714,7 @@ func NewUpdateHillChartSettingsRequestWithBody(server string, accountId string, return nil, err } - operationPath := fmt.Sprintf("/%s/todosets/%s/hills/settings.json", pathParam0, pathParam1) + operationPath := fmt.Sprintf("/%s/todosets/todolists/%s/position.json", pathParam0, pathParam1) if operationPath[0] == '/' { operationPath = "." + operationPath } @@ -17406,8 +17734,144 @@ func NewUpdateHillChartSettingsRequestWithBody(server string, accountId string, return req, nil } -// NewListTodolistsRequest generates requests for ListTodolists -func NewListTodolistsRequest(server string, accountId string, todosetId int64, params *ListTodolistsParams) (*http.Request, error) { +// NewGetTodosetRequest generates requests for GetTodoset +func NewGetTodosetRequest(server string, accountId string, todosetId int64) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "accountId", runtime.ParamLocationPath, accountId) + if err != nil { + return nil, err + } + + var pathParam1 string + + pathParam1, err = runtime.StyleParamWithLocation("simple", false, "todosetId", runtime.ParamLocationPath, todosetId) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/%s/todosets/%s", pathParam0, pathParam1) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("GET", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewGetHillChartRequest generates requests for GetHillChart +func NewGetHillChartRequest(server string, accountId string, todosetId int64) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "accountId", runtime.ParamLocationPath, accountId) + if err != nil { + return nil, err + } + + var pathParam1 string + + pathParam1, err = runtime.StyleParamWithLocation("simple", false, "todosetId", runtime.ParamLocationPath, todosetId) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/%s/todosets/%s/hill.json", pathParam0, pathParam1) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("GET", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewUpdateHillChartSettingsRequest calls the generic UpdateHillChartSettings builder with application/json body +func NewUpdateHillChartSettingsRequest(server string, accountId string, todosetId int64, body UpdateHillChartSettingsJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewUpdateHillChartSettingsRequestWithBody(server, accountId, todosetId, "application/json", bodyReader) +} + +// NewUpdateHillChartSettingsRequestWithBody generates requests for UpdateHillChartSettings with any type of body +func NewUpdateHillChartSettingsRequestWithBody(server string, accountId string, todosetId int64, contentType string, body io.Reader) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "accountId", runtime.ParamLocationPath, accountId) + if err != nil { + return nil, err + } + + var pathParam1 string + + pathParam1, err = runtime.StyleParamWithLocation("simple", false, "todosetId", runtime.ParamLocationPath, todosetId) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/%s/todosets/%s/hills/settings.json", pathParam0, pathParam1) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("PUT", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + +// NewListTodolistsRequest generates requests for ListTodolists +func NewListTodolistsRequest(server string, accountId string, todosetId int64, params *ListTodolistsParams) (*http.Request, error) { var err error var pathParam0 string @@ -18232,7 +18696,12 @@ var operationMetadata = map[string]OperationMetadata{ "GetCardTable": {Idempotent: true, HasSensitiveParams: false}, "CreateCardColumn": {Idempotent: false, HasSensitiveParams: false}, "MoveCardColumn": {Idempotent: false, HasSensitiveParams: false}, + "GetEverythingCompletedCards": {Idempotent: true, HasSensitiveParams: false}, + "GetEverythingNoDueDateCards": {Idempotent: true, HasSensitiveParams: false}, + "GetEverythingNotNowCards": {Idempotent: true, HasSensitiveParams: false}, + "GetEverythingOpenCards": {Idempotent: true, HasSensitiveParams: false}, "GetEverythingOverdueCards": {Idempotent: true, HasSensitiveParams: false}, + "GetEverythingUnassignedCards": {Idempotent: true, HasSensitiveParams: false}, "ListMessageTypes": {Idempotent: true, HasSensitiveParams: false}, "CreateMessageType": {Idempotent: false, HasSensitiveParams: false}, "DeleteMessageType": {Idempotent: true, HasSensitiveParams: false}, @@ -18388,7 +18857,11 @@ var operationMetadata = map[string]OperationMetadata{ "CreateTodolistGroup": {Idempotent: false, HasSensitiveParams: false}, "ListTodos": {Idempotent: true, HasSensitiveParams: false}, "CreateTodo": {Idempotent: false, HasSensitiveParams: false}, + "GetEverythingCompletedTodos": {Idempotent: true, HasSensitiveParams: false}, + "GetEverythingNoDueDateTodos": {Idempotent: true, HasSensitiveParams: false}, + "GetEverythingOpenTodos": {Idempotent: true, HasSensitiveParams: false}, "GetEverythingOverdueTodos": {Idempotent: true, HasSensitiveParams: false}, + "GetEverythingUnassignedTodos": {Idempotent: true, HasSensitiveParams: false}, "TrashTodo": {Idempotent: true, HasSensitiveParams: false}, "GetTodo": {Idempotent: true, HasSensitiveParams: false}, "ReplaceTodo": {Idempotent: true, HasSensitiveParams: false}, @@ -19471,9 +19944,24 @@ type ClientWithResponsesInterface interface { MoveCardColumnWithResponse(ctx context.Context, accountId string, cardTableId int64, body MoveCardColumnJSONRequestBody, reqEditors ...RequestEditorFn) (*MoveCardColumnResponse, error) + // GetEverythingCompletedCardsWithResponse request + GetEverythingCompletedCardsWithResponse(ctx context.Context, accountId string, reqEditors ...RequestEditorFn) (*GetEverythingCompletedCardsResponse, error) + + // GetEverythingNoDueDateCardsWithResponse request + GetEverythingNoDueDateCardsWithResponse(ctx context.Context, accountId string, reqEditors ...RequestEditorFn) (*GetEverythingNoDueDateCardsResponse, error) + + // GetEverythingNotNowCardsWithResponse request + GetEverythingNotNowCardsWithResponse(ctx context.Context, accountId string, reqEditors ...RequestEditorFn) (*GetEverythingNotNowCardsResponse, error) + + // GetEverythingOpenCardsWithResponse request + GetEverythingOpenCardsWithResponse(ctx context.Context, accountId string, reqEditors ...RequestEditorFn) (*GetEverythingOpenCardsResponse, error) + // GetEverythingOverdueCardsWithResponse request GetEverythingOverdueCardsWithResponse(ctx context.Context, accountId string, reqEditors ...RequestEditorFn) (*GetEverythingOverdueCardsResponse, error) + // GetEverythingUnassignedCardsWithResponse request + GetEverythingUnassignedCardsWithResponse(ctx context.Context, accountId string, reqEditors ...RequestEditorFn) (*GetEverythingUnassignedCardsResponse, error) + // ListMessageTypesWithResponse request ListMessageTypesWithResponse(ctx context.Context, accountId string, reqEditors ...RequestEditorFn) (*ListMessageTypesResponse, error) @@ -20033,9 +20521,21 @@ type ClientWithResponsesInterface interface { CreateTodoWithResponse(ctx context.Context, accountId string, todolistId int64, body CreateTodoJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateTodoResponse, error) + // GetEverythingCompletedTodosWithResponse request + GetEverythingCompletedTodosWithResponse(ctx context.Context, accountId string, reqEditors ...RequestEditorFn) (*GetEverythingCompletedTodosResponse, error) + + // GetEverythingNoDueDateTodosWithResponse request + GetEverythingNoDueDateTodosWithResponse(ctx context.Context, accountId string, reqEditors ...RequestEditorFn) (*GetEverythingNoDueDateTodosResponse, error) + + // GetEverythingOpenTodosWithResponse request + GetEverythingOpenTodosWithResponse(ctx context.Context, accountId string, reqEditors ...RequestEditorFn) (*GetEverythingOpenTodosResponse, error) + // GetEverythingOverdueTodosWithResponse request GetEverythingOverdueTodosWithResponse(ctx context.Context, accountId string, reqEditors ...RequestEditorFn) (*GetEverythingOverdueTodosResponse, error) + // GetEverythingUnassignedTodosWithResponse request + GetEverythingUnassignedTodosWithResponse(ctx context.Context, accountId string, reqEditors ...RequestEditorFn) (*GetEverythingUnassignedTodosResponse, error) + // TrashTodoWithResponse request TrashTodoWithResponse(ctx context.Context, accountId string, todoId int64, reqEditors ...RequestEditorFn) (*TrashTodoResponse, error) @@ -21203,6 +21703,142 @@ func (r MoveCardColumnResponse) ContentType() string { return "" } +type GetEverythingCompletedCardsResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *GetEverythingCompletedCardsResponseContent + JSON401 *UnauthorizedErrorResponseContent + JSON403 *ForbiddenErrorResponseContent + JSON429 *RateLimitErrorResponseContent + JSON500 *InternalServerErrorResponseContent +} + +// Status returns HTTPResponse.Status +func (r GetEverythingCompletedCardsResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetEverythingCompletedCardsResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetEverythingCompletedCardsResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + +type GetEverythingNoDueDateCardsResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *GetEverythingNoDueDateCardsResponseContent + JSON401 *UnauthorizedErrorResponseContent + JSON403 *ForbiddenErrorResponseContent + JSON429 *RateLimitErrorResponseContent + JSON500 *InternalServerErrorResponseContent +} + +// Status returns HTTPResponse.Status +func (r GetEverythingNoDueDateCardsResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetEverythingNoDueDateCardsResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetEverythingNoDueDateCardsResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + +type GetEverythingNotNowCardsResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *GetEverythingNotNowCardsResponseContent + JSON401 *UnauthorizedErrorResponseContent + JSON403 *ForbiddenErrorResponseContent + JSON429 *RateLimitErrorResponseContent + JSON500 *InternalServerErrorResponseContent +} + +// Status returns HTTPResponse.Status +func (r GetEverythingNotNowCardsResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetEverythingNotNowCardsResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetEverythingNotNowCardsResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + +type GetEverythingOpenCardsResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *GetEverythingOpenCardsResponseContent + JSON401 *UnauthorizedErrorResponseContent + JSON403 *ForbiddenErrorResponseContent + JSON429 *RateLimitErrorResponseContent + JSON500 *InternalServerErrorResponseContent +} + +// Status returns HTTPResponse.Status +func (r GetEverythingOpenCardsResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetEverythingOpenCardsResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetEverythingOpenCardsResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetEverythingOverdueCardsResponse struct { Body []byte HTTPResponse *http.Response @@ -21236,6 +21872,40 @@ func (r GetEverythingOverdueCardsResponse) ContentType() string { return "" } +type GetEverythingUnassignedCardsResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *GetEverythingUnassignedCardsResponseContent + JSON401 *UnauthorizedErrorResponseContent + JSON403 *ForbiddenErrorResponseContent + JSON429 *RateLimitErrorResponseContent + JSON500 *InternalServerErrorResponseContent +} + +// Status returns HTTPResponse.Status +func (r GetEverythingUnassignedCardsResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetEverythingUnassignedCardsResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetEverythingUnassignedCardsResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type ListMessageTypesResponse struct { Body []byte HTTPResponse *http.Response @@ -26538,6 +27208,108 @@ func (r CreateTodoResponse) ContentType() string { return "" } +type GetEverythingCompletedTodosResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *GetEverythingCompletedTodosResponseContent + JSON401 *UnauthorizedErrorResponseContent + JSON403 *ForbiddenErrorResponseContent + JSON429 *RateLimitErrorResponseContent + JSON500 *InternalServerErrorResponseContent +} + +// Status returns HTTPResponse.Status +func (r GetEverythingCompletedTodosResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetEverythingCompletedTodosResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetEverythingCompletedTodosResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + +type GetEverythingNoDueDateTodosResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *GetEverythingNoDueDateTodosResponseContent + JSON401 *UnauthorizedErrorResponseContent + JSON403 *ForbiddenErrorResponseContent + JSON429 *RateLimitErrorResponseContent + JSON500 *InternalServerErrorResponseContent +} + +// Status returns HTTPResponse.Status +func (r GetEverythingNoDueDateTodosResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetEverythingNoDueDateTodosResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetEverythingNoDueDateTodosResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + +type GetEverythingOpenTodosResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *GetEverythingOpenTodosResponseContent + JSON401 *UnauthorizedErrorResponseContent + JSON403 *ForbiddenErrorResponseContent + JSON429 *RateLimitErrorResponseContent + JSON500 *InternalServerErrorResponseContent +} + +// Status returns HTTPResponse.Status +func (r GetEverythingOpenTodosResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetEverythingOpenTodosResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetEverythingOpenTodosResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetEverythingOverdueTodosResponse struct { Body []byte HTTPResponse *http.Response @@ -26571,6 +27343,40 @@ func (r GetEverythingOverdueTodosResponse) ContentType() string { return "" } +type GetEverythingUnassignedTodosResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *GetEverythingUnassignedTodosResponseContent + JSON401 *UnauthorizedErrorResponseContent + JSON403 *ForbiddenErrorResponseContent + JSON429 *RateLimitErrorResponseContent + JSON500 *InternalServerErrorResponseContent +} + +// Status returns HTTPResponse.Status +func (r GetEverythingUnassignedTodosResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetEverythingUnassignedTodosResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetEverythingUnassignedTodosResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type TrashTodoResponse struct { Body []byte HTTPResponse *http.Response @@ -27853,6 +28659,42 @@ func (c *ClientWithResponses) MoveCardColumnWithResponse(ctx context.Context, ac return ParseMoveCardColumnResponse(rsp) } +// GetEverythingCompletedCardsWithResponse request returning *GetEverythingCompletedCardsResponse +func (c *ClientWithResponses) GetEverythingCompletedCardsWithResponse(ctx context.Context, accountId string, reqEditors ...RequestEditorFn) (*GetEverythingCompletedCardsResponse, error) { + rsp, err := c.GetEverythingCompletedCards(ctx, accountId, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetEverythingCompletedCardsResponse(rsp) +} + +// GetEverythingNoDueDateCardsWithResponse request returning *GetEverythingNoDueDateCardsResponse +func (c *ClientWithResponses) GetEverythingNoDueDateCardsWithResponse(ctx context.Context, accountId string, reqEditors ...RequestEditorFn) (*GetEverythingNoDueDateCardsResponse, error) { + rsp, err := c.GetEverythingNoDueDateCards(ctx, accountId, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetEverythingNoDueDateCardsResponse(rsp) +} + +// GetEverythingNotNowCardsWithResponse request returning *GetEverythingNotNowCardsResponse +func (c *ClientWithResponses) GetEverythingNotNowCardsWithResponse(ctx context.Context, accountId string, reqEditors ...RequestEditorFn) (*GetEverythingNotNowCardsResponse, error) { + rsp, err := c.GetEverythingNotNowCards(ctx, accountId, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetEverythingNotNowCardsResponse(rsp) +} + +// GetEverythingOpenCardsWithResponse request returning *GetEverythingOpenCardsResponse +func (c *ClientWithResponses) GetEverythingOpenCardsWithResponse(ctx context.Context, accountId string, reqEditors ...RequestEditorFn) (*GetEverythingOpenCardsResponse, error) { + rsp, err := c.GetEverythingOpenCards(ctx, accountId, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetEverythingOpenCardsResponse(rsp) +} + // GetEverythingOverdueCardsWithResponse request returning *GetEverythingOverdueCardsResponse func (c *ClientWithResponses) GetEverythingOverdueCardsWithResponse(ctx context.Context, accountId string, reqEditors ...RequestEditorFn) (*GetEverythingOverdueCardsResponse, error) { rsp, err := c.GetEverythingOverdueCards(ctx, accountId, reqEditors...) @@ -27862,6 +28704,15 @@ func (c *ClientWithResponses) GetEverythingOverdueCardsWithResponse(ctx context. return ParseGetEverythingOverdueCardsResponse(rsp) } +// GetEverythingUnassignedCardsWithResponse request returning *GetEverythingUnassignedCardsResponse +func (c *ClientWithResponses) GetEverythingUnassignedCardsWithResponse(ctx context.Context, accountId string, reqEditors ...RequestEditorFn) (*GetEverythingUnassignedCardsResponse, error) { + rsp, err := c.GetEverythingUnassignedCards(ctx, accountId, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetEverythingUnassignedCardsResponse(rsp) +} + // ListMessageTypesWithResponse request returning *ListMessageTypesResponse func (c *ClientWithResponses) ListMessageTypesWithResponse(ctx context.Context, accountId string, reqEditors ...RequestEditorFn) (*ListMessageTypesResponse, error) { rsp, err := c.ListMessageTypes(ctx, accountId, reqEditors...) @@ -29633,6 +30484,33 @@ func (c *ClientWithResponses) CreateTodoWithResponse(ctx context.Context, accoun return ParseCreateTodoResponse(rsp) } +// GetEverythingCompletedTodosWithResponse request returning *GetEverythingCompletedTodosResponse +func (c *ClientWithResponses) GetEverythingCompletedTodosWithResponse(ctx context.Context, accountId string, reqEditors ...RequestEditorFn) (*GetEverythingCompletedTodosResponse, error) { + rsp, err := c.GetEverythingCompletedTodos(ctx, accountId, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetEverythingCompletedTodosResponse(rsp) +} + +// GetEverythingNoDueDateTodosWithResponse request returning *GetEverythingNoDueDateTodosResponse +func (c *ClientWithResponses) GetEverythingNoDueDateTodosWithResponse(ctx context.Context, accountId string, reqEditors ...RequestEditorFn) (*GetEverythingNoDueDateTodosResponse, error) { + rsp, err := c.GetEverythingNoDueDateTodos(ctx, accountId, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetEverythingNoDueDateTodosResponse(rsp) +} + +// GetEverythingOpenTodosWithResponse request returning *GetEverythingOpenTodosResponse +func (c *ClientWithResponses) GetEverythingOpenTodosWithResponse(ctx context.Context, accountId string, reqEditors ...RequestEditorFn) (*GetEverythingOpenTodosResponse, error) { + rsp, err := c.GetEverythingOpenTodos(ctx, accountId, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetEverythingOpenTodosResponse(rsp) +} + // GetEverythingOverdueTodosWithResponse request returning *GetEverythingOverdueTodosResponse func (c *ClientWithResponses) GetEverythingOverdueTodosWithResponse(ctx context.Context, accountId string, reqEditors ...RequestEditorFn) (*GetEverythingOverdueTodosResponse, error) { rsp, err := c.GetEverythingOverdueTodos(ctx, accountId, reqEditors...) @@ -29642,6 +30520,15 @@ func (c *ClientWithResponses) GetEverythingOverdueTodosWithResponse(ctx context. return ParseGetEverythingOverdueTodosResponse(rsp) } +// GetEverythingUnassignedTodosWithResponse request returning *GetEverythingUnassignedTodosResponse +func (c *ClientWithResponses) GetEverythingUnassignedTodosWithResponse(ctx context.Context, accountId string, reqEditors ...RequestEditorFn) (*GetEverythingUnassignedTodosResponse, error) { + rsp, err := c.GetEverythingUnassignedTodos(ctx, accountId, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetEverythingUnassignedTodosResponse(rsp) +} + // TrashTodoWithResponse request returning *TrashTodoResponse func (c *ClientWithResponses) TrashTodoWithResponse(ctx context.Context, accountId string, todoId int64, reqEditors ...RequestEditorFn) (*TrashTodoResponse, error) { rsp, err := c.TrashTodo(ctx, accountId, todoId, reqEditors...) @@ -30508,13 +31395,311 @@ func ParseDisableCardColumnOnHoldResponse(rsp *http.Response) (*DisableCardColum } response.JSON404 = &dest - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 429: - var dest RateLimitErrorResponseContent - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON429 = &dest - + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 429: + var dest RateLimitErrorResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON429 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: + var dest InternalServerErrorResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON500 = &dest + + } + + return response, nil +} + +// ParseEnableCardColumnOnHoldResponse parses an HTTP response from a EnableCardColumnOnHoldWithResponse call +func ParseEnableCardColumnOnHoldResponse(rsp *http.Response) (*EnableCardColumnOnHoldResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &EnableCardColumnOnHoldResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest EnableCardColumnOnHoldResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: + var dest UnauthorizedErrorResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON401 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 403: + var dest ForbiddenErrorResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON403 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 422: + var dest ValidationErrorResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON422 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 429: + var dest RateLimitErrorResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON429 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: + var dest InternalServerErrorResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON500 = &dest + + } + + return response, nil +} + +// ParseCreateToolResponse parses an HTTP response from a CreateToolWithResponse call +func ParseCreateToolResponse(rsp *http.Response) (*CreateToolResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &CreateToolResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 201: + var dest CreateToolResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON201 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: + var dest UnauthorizedErrorResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON401 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 403: + var dest ForbiddenErrorResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON403 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 422: + var dest ValidationErrorResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON422 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 429: + var dest RateLimitErrorResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON429 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: + var dest InternalServerErrorResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON500 = &dest + + } + + return response, nil +} + +// ParseListWebhooksResponse parses an HTTP response from a ListWebhooksWithResponse call +func ParseListWebhooksResponse(rsp *http.Response) (*ListWebhooksResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &ListWebhooksResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest ListWebhooksResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: + var dest UnauthorizedErrorResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON401 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 403: + var dest ForbiddenErrorResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON403 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 429: + var dest RateLimitErrorResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON429 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: + var dest InternalServerErrorResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON500 = &dest + + } + + return response, nil +} + +// ParseCreateWebhookResponse parses an HTTP response from a CreateWebhookWithResponse call +func ParseCreateWebhookResponse(rsp *http.Response) (*CreateWebhookResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &CreateWebhookResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 201: + var dest CreateWebhookResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON201 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: + var dest BadRequestErrorResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON400 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: + var dest UnauthorizedErrorResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON401 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 403: + var dest ForbiddenErrorResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON403 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 429: + var dest RateLimitErrorResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON429 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: + var dest InternalServerErrorResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON500 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 507: + var dest WebhookLimitErrorResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON507 = &dest + + } + + return response, nil +} + +// ParseGetCardResponse parses an HTTP response from a GetCardWithResponse call +func ParseGetCardResponse(rsp *http.Response) (*GetCardResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetCardResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest GetCardResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: + var dest UnauthorizedErrorResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON401 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 403: + var dest ForbiddenErrorResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON403 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404: + var dest NotFoundErrorResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON404 = &dest + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: var dest InternalServerErrorResponseContent if err := json.Unmarshal(bodyBytes, &dest); err != nil { @@ -30527,22 +31712,22 @@ func ParseDisableCardColumnOnHoldResponse(rsp *http.Response) (*DisableCardColum return response, nil } -// ParseEnableCardColumnOnHoldResponse parses an HTTP response from a EnableCardColumnOnHoldWithResponse call -func ParseEnableCardColumnOnHoldResponse(rsp *http.Response) (*EnableCardColumnOnHoldResponse, error) { +// ParseUpdateCardResponse parses an HTTP response from a UpdateCardWithResponse call +func ParseUpdateCardResponse(rsp *http.Response) (*UpdateCardResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } - response := &EnableCardColumnOnHoldResponse{ + response := &UpdateCardResponse{ Body: bodyBytes, HTTPResponse: rsp, } switch { case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest EnableCardColumnOnHoldResponseContent + var dest UpdateCardResponseContent if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } @@ -30562,19 +31747,19 @@ func ParseEnableCardColumnOnHoldResponse(rsp *http.Response) (*EnableCardColumnO } response.JSON403 = &dest - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 422: - var dest ValidationErrorResponseContent + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404: + var dest NotFoundErrorResponseContent if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } - response.JSON422 = &dest + response.JSON404 = &dest - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 429: - var dest RateLimitErrorResponseContent + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 422: + var dest ValidationErrorResponseContent if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } - response.JSON429 = &dest + response.JSON422 = &dest case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: var dest InternalServerErrorResponseContent @@ -30588,26 +31773,22 @@ func ParseEnableCardColumnOnHoldResponse(rsp *http.Response) (*EnableCardColumnO return response, nil } -// ParseCreateToolResponse parses an HTTP response from a CreateToolWithResponse call -func ParseCreateToolResponse(rsp *http.Response) (*CreateToolResponse, error) { +// ParseMoveCardResponse parses an HTTP response from a MoveCardWithResponse call +func ParseMoveCardResponse(rsp *http.Response) (*MoveCardResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } - response := &CreateToolResponse{ + response := &MoveCardResponse{ Body: bodyBytes, HTTPResponse: rsp, } switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 201: - var dest CreateToolResponseContent - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON201 = &dest + case rsp.StatusCode == 204: + break // No content-type case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: var dest UnauthorizedErrorResponseContent @@ -30649,26 +31830,22 @@ func ParseCreateToolResponse(rsp *http.Response) (*CreateToolResponse, error) { return response, nil } -// ParseListWebhooksResponse parses an HTTP response from a ListWebhooksWithResponse call -func ParseListWebhooksResponse(rsp *http.Response) (*ListWebhooksResponse, error) { +// ParseRepositionCardStepResponse parses an HTTP response from a RepositionCardStepWithResponse call +func ParseRepositionCardStepResponse(rsp *http.Response) (*RepositionCardStepResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } - response := &ListWebhooksResponse{ + response := &RepositionCardStepResponse{ Body: bodyBytes, HTTPResponse: rsp, } switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest ListWebhooksResponseContent - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON200 = &dest + case rsp.StatusCode == 200: + break // No content-type case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: var dest UnauthorizedErrorResponseContent @@ -30684,6 +31861,13 @@ func ParseListWebhooksResponse(rsp *http.Response) (*ListWebhooksResponse, error } response.JSON403 = &dest + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 422: + var dest ValidationErrorResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON422 = &dest + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 429: var dest RateLimitErrorResponseContent if err := json.Unmarshal(bodyBytes, &dest); err != nil { @@ -30703,34 +31887,27 @@ func ParseListWebhooksResponse(rsp *http.Response) (*ListWebhooksResponse, error return response, nil } -// ParseCreateWebhookResponse parses an HTTP response from a CreateWebhookWithResponse call -func ParseCreateWebhookResponse(rsp *http.Response) (*CreateWebhookResponse, error) { +// ParseCreateCardStepResponse parses an HTTP response from a CreateCardStepWithResponse call +func ParseCreateCardStepResponse(rsp *http.Response) (*CreateCardStepResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } - response := &CreateWebhookResponse{ + response := &CreateCardStepResponse{ Body: bodyBytes, HTTPResponse: rsp, } switch { case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 201: - var dest CreateWebhookResponseContent + var dest CreateCardStepResponseContent if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } response.JSON201 = &dest - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: - var dest BadRequestErrorResponseContent - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON400 = &dest - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: var dest UnauthorizedErrorResponseContent if err := json.Unmarshal(bodyBytes, &dest); err != nil { @@ -30745,6 +31922,13 @@ func ParseCreateWebhookResponse(rsp *http.Response) (*CreateWebhookResponse, err } response.JSON403 = &dest + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 422: + var dest ValidationErrorResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON422 = &dest + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 429: var dest RateLimitErrorResponseContent if err := json.Unmarshal(bodyBytes, &dest); err != nil { @@ -30759,34 +31943,27 @@ func ParseCreateWebhookResponse(rsp *http.Response) (*CreateWebhookResponse, err } response.JSON500 = &dest - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 507: - var dest WebhookLimitErrorResponseContent - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON507 = &dest - } return response, nil } -// ParseGetCardResponse parses an HTTP response from a GetCardWithResponse call -func ParseGetCardResponse(rsp *http.Response) (*GetCardResponse, error) { +// ParseGetCardColumnResponse parses an HTTP response from a GetCardColumnWithResponse call +func ParseGetCardColumnResponse(rsp *http.Response) (*GetCardColumnResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } - response := &GetCardResponse{ + response := &GetCardColumnResponse{ Body: bodyBytes, HTTPResponse: rsp, } switch { case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest GetCardResponseContent + var dest GetCardColumnResponseContent if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } @@ -30825,22 +32002,22 @@ func ParseGetCardResponse(rsp *http.Response) (*GetCardResponse, error) { return response, nil } -// ParseUpdateCardResponse parses an HTTP response from a UpdateCardWithResponse call -func ParseUpdateCardResponse(rsp *http.Response) (*UpdateCardResponse, error) { +// ParseUpdateCardColumnResponse parses an HTTP response from a UpdateCardColumnWithResponse call +func ParseUpdateCardColumnResponse(rsp *http.Response) (*UpdateCardColumnResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } - response := &UpdateCardResponse{ + response := &UpdateCardColumnResponse{ Body: bodyBytes, HTTPResponse: rsp, } switch { case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest UpdateCardResponseContent + var dest UpdateCardColumnResponseContent if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } @@ -30886,22 +32063,26 @@ func ParseUpdateCardResponse(rsp *http.Response) (*UpdateCardResponse, error) { return response, nil } -// ParseMoveCardResponse parses an HTTP response from a MoveCardWithResponse call -func ParseMoveCardResponse(rsp *http.Response) (*MoveCardResponse, error) { +// ParseListCardsResponse parses an HTTP response from a ListCardsWithResponse call +func ParseListCardsResponse(rsp *http.Response) (*ListCardsResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } - response := &MoveCardResponse{ + response := &ListCardsResponse{ Body: bodyBytes, HTTPResponse: rsp, } switch { - case rsp.StatusCode == 204: - break // No content-type + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest ListCardsResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: var dest UnauthorizedErrorResponseContent @@ -30917,13 +32098,6 @@ func ParseMoveCardResponse(rsp *http.Response) (*MoveCardResponse, error) { } response.JSON403 = &dest - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 422: - var dest ValidationErrorResponseContent - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON422 = &dest - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 429: var dest RateLimitErrorResponseContent if err := json.Unmarshal(bodyBytes, &dest); err != nil { @@ -30943,22 +32117,26 @@ func ParseMoveCardResponse(rsp *http.Response) (*MoveCardResponse, error) { return response, nil } -// ParseRepositionCardStepResponse parses an HTTP response from a RepositionCardStepWithResponse call -func ParseRepositionCardStepResponse(rsp *http.Response) (*RepositionCardStepResponse, error) { +// ParseCreateCardResponse parses an HTTP response from a CreateCardWithResponse call +func ParseCreateCardResponse(rsp *http.Response) (*CreateCardResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } - response := &RepositionCardStepResponse{ + response := &CreateCardResponse{ Body: bodyBytes, HTTPResponse: rsp, } switch { - case rsp.StatusCode == 200: - break // No content-type + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 201: + var dest CreateCardResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON201 = &dest case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: var dest UnauthorizedErrorResponseContent @@ -31000,26 +32178,22 @@ func ParseRepositionCardStepResponse(rsp *http.Response) (*RepositionCardStepRes return response, nil } -// ParseCreateCardStepResponse parses an HTTP response from a CreateCardStepWithResponse call -func ParseCreateCardStepResponse(rsp *http.Response) (*CreateCardStepResponse, error) { +// ParseUnsubscribeFromCardColumnResponse parses an HTTP response from a UnsubscribeFromCardColumnWithResponse call +func ParseUnsubscribeFromCardColumnResponse(rsp *http.Response) (*UnsubscribeFromCardColumnResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } - response := &CreateCardStepResponse{ + response := &UnsubscribeFromCardColumnResponse{ Body: bodyBytes, HTTPResponse: rsp, } switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 201: - var dest CreateCardStepResponseContent - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON201 = &dest + case rsp.StatusCode == 204: + break // No content-type case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: var dest UnauthorizedErrorResponseContent @@ -31035,19 +32209,12 @@ func ParseCreateCardStepResponse(rsp *http.Response) (*CreateCardStepResponse, e } response.JSON403 = &dest - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 422: - var dest ValidationErrorResponseContent - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON422 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 429: - var dest RateLimitErrorResponseContent + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404: + var dest NotFoundErrorResponseContent if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } - response.JSON429 = &dest + response.JSON404 = &dest case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: var dest InternalServerErrorResponseContent @@ -31061,26 +32228,22 @@ func ParseCreateCardStepResponse(rsp *http.Response) (*CreateCardStepResponse, e return response, nil } -// ParseGetCardColumnResponse parses an HTTP response from a GetCardColumnWithResponse call -func ParseGetCardColumnResponse(rsp *http.Response) (*GetCardColumnResponse, error) { +// ParseSubscribeToCardColumnResponse parses an HTTP response from a SubscribeToCardColumnWithResponse call +func ParseSubscribeToCardColumnResponse(rsp *http.Response) (*SubscribeToCardColumnResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } - response := &GetCardColumnResponse{ + response := &SubscribeToCardColumnResponse{ Body: bodyBytes, HTTPResponse: rsp, } switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest GetCardColumnResponseContent - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON200 = &dest + case rsp.StatusCode == 204: + break // No content-type case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: var dest UnauthorizedErrorResponseContent @@ -31103,6 +32266,13 @@ func ParseGetCardColumnResponse(rsp *http.Response) (*GetCardColumnResponse, err } response.JSON404 = &dest + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 429: + var dest RateLimitErrorResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON429 = &dest + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: var dest InternalServerErrorResponseContent if err := json.Unmarshal(bodyBytes, &dest); err != nil { @@ -31115,22 +32285,22 @@ func ParseGetCardColumnResponse(rsp *http.Response) (*GetCardColumnResponse, err return response, nil } -// ParseUpdateCardColumnResponse parses an HTTP response from a UpdateCardColumnWithResponse call -func ParseUpdateCardColumnResponse(rsp *http.Response) (*UpdateCardColumnResponse, error) { +// ParseGetCardStepResponse parses an HTTP response from a GetCardStepWithResponse call +func ParseGetCardStepResponse(rsp *http.Response) (*GetCardStepResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } - response := &UpdateCardColumnResponse{ + response := &GetCardStepResponse{ Body: bodyBytes, HTTPResponse: rsp, } switch { case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest UpdateCardColumnResponseContent + var dest GetCardStepResponseContent if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } @@ -31157,13 +32327,6 @@ func ParseUpdateCardColumnResponse(rsp *http.Response) (*UpdateCardColumnRespons } response.JSON404 = &dest - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 422: - var dest ValidationErrorResponseContent - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON422 = &dest - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: var dest InternalServerErrorResponseContent if err := json.Unmarshal(bodyBytes, &dest); err != nil { @@ -31176,22 +32339,22 @@ func ParseUpdateCardColumnResponse(rsp *http.Response) (*UpdateCardColumnRespons return response, nil } -// ParseListCardsResponse parses an HTTP response from a ListCardsWithResponse call -func ParseListCardsResponse(rsp *http.Response) (*ListCardsResponse, error) { +// ParseUpdateCardStepResponse parses an HTTP response from a UpdateCardStepWithResponse call +func ParseUpdateCardStepResponse(rsp *http.Response) (*UpdateCardStepResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } - response := &ListCardsResponse{ + response := &UpdateCardStepResponse{ Body: bodyBytes, HTTPResponse: rsp, } switch { case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest ListCardsResponseContent + var dest UpdateCardStepResponseContent if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } @@ -31211,12 +32374,19 @@ func ParseListCardsResponse(rsp *http.Response) (*ListCardsResponse, error) { } response.JSON403 = &dest - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 429: - var dest RateLimitErrorResponseContent + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404: + var dest NotFoundErrorResponseContent if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } - response.JSON429 = &dest + response.JSON404 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 422: + var dest ValidationErrorResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON422 = &dest case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: var dest InternalServerErrorResponseContent @@ -31230,26 +32400,26 @@ func ParseListCardsResponse(rsp *http.Response) (*ListCardsResponse, error) { return response, nil } -// ParseCreateCardResponse parses an HTTP response from a CreateCardWithResponse call -func ParseCreateCardResponse(rsp *http.Response) (*CreateCardResponse, error) { +// ParseSetCardStepCompletionResponse parses an HTTP response from a SetCardStepCompletionWithResponse call +func ParseSetCardStepCompletionResponse(rsp *http.Response) (*SetCardStepCompletionResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } - response := &CreateCardResponse{ + response := &SetCardStepCompletionResponse{ Body: bodyBytes, HTTPResponse: rsp, } switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 201: - var dest CreateCardResponseContent + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest SetCardStepCompletionResponseContent if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } - response.JSON201 = &dest + response.JSON200 = &dest case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: var dest UnauthorizedErrorResponseContent @@ -31265,19 +32435,19 @@ func ParseCreateCardResponse(rsp *http.Response) (*CreateCardResponse, error) { } response.JSON403 = &dest - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 422: - var dest ValidationErrorResponseContent + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404: + var dest NotFoundErrorResponseContent if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } - response.JSON422 = &dest + response.JSON404 = &dest - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 429: - var dest RateLimitErrorResponseContent + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 422: + var dest ValidationErrorResponseContent if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } - response.JSON429 = &dest + response.JSON422 = &dest case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: var dest InternalServerErrorResponseContent @@ -31291,22 +32461,26 @@ func ParseCreateCardResponse(rsp *http.Response) (*CreateCardResponse, error) { return response, nil } -// ParseUnsubscribeFromCardColumnResponse parses an HTTP response from a UnsubscribeFromCardColumnWithResponse call -func ParseUnsubscribeFromCardColumnResponse(rsp *http.Response) (*UnsubscribeFromCardColumnResponse, error) { +// ParseGetCardTableResponse parses an HTTP response from a GetCardTableWithResponse call +func ParseGetCardTableResponse(rsp *http.Response) (*GetCardTableResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } - response := &UnsubscribeFromCardColumnResponse{ + response := &GetCardTableResponse{ Body: bodyBytes, HTTPResponse: rsp, } switch { - case rsp.StatusCode == 204: - break // No content-type + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest GetCardTableResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: var dest UnauthorizedErrorResponseContent @@ -31341,22 +32515,26 @@ func ParseUnsubscribeFromCardColumnResponse(rsp *http.Response) (*UnsubscribeFro return response, nil } -// ParseSubscribeToCardColumnResponse parses an HTTP response from a SubscribeToCardColumnWithResponse call -func ParseSubscribeToCardColumnResponse(rsp *http.Response) (*SubscribeToCardColumnResponse, error) { +// ParseCreateCardColumnResponse parses an HTTP response from a CreateCardColumnWithResponse call +func ParseCreateCardColumnResponse(rsp *http.Response) (*CreateCardColumnResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } - response := &SubscribeToCardColumnResponse{ + response := &CreateCardColumnResponse{ Body: bodyBytes, HTTPResponse: rsp, } switch { - case rsp.StatusCode == 204: - break // No content-type + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 201: + var dest CreateCardColumnResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON201 = &dest case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: var dest UnauthorizedErrorResponseContent @@ -31372,12 +32550,12 @@ func ParseSubscribeToCardColumnResponse(rsp *http.Response) (*SubscribeToCardCol } response.JSON403 = &dest - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404: - var dest NotFoundErrorResponseContent + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 422: + var dest ValidationErrorResponseContent if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } - response.JSON404 = &dest + response.JSON422 = &dest case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 429: var dest RateLimitErrorResponseContent @@ -31398,26 +32576,22 @@ func ParseSubscribeToCardColumnResponse(rsp *http.Response) (*SubscribeToCardCol return response, nil } -// ParseGetCardStepResponse parses an HTTP response from a GetCardStepWithResponse call -func ParseGetCardStepResponse(rsp *http.Response) (*GetCardStepResponse, error) { +// ParseMoveCardColumnResponse parses an HTTP response from a MoveCardColumnWithResponse call +func ParseMoveCardColumnResponse(rsp *http.Response) (*MoveCardColumnResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } - response := &GetCardStepResponse{ + response := &MoveCardColumnResponse{ Body: bodyBytes, HTTPResponse: rsp, } switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest GetCardStepResponseContent - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON200 = &dest + case rsp.StatusCode == 204: + break // No content-type case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: var dest UnauthorizedErrorResponseContent @@ -31433,12 +32607,19 @@ func ParseGetCardStepResponse(rsp *http.Response) (*GetCardStepResponse, error) } response.JSON403 = &dest - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404: - var dest NotFoundErrorResponseContent + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 422: + var dest ValidationErrorResponseContent if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } - response.JSON404 = &dest + response.JSON422 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 429: + var dest RateLimitErrorResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON429 = &dest case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: var dest InternalServerErrorResponseContent @@ -31452,22 +32633,22 @@ func ParseGetCardStepResponse(rsp *http.Response) (*GetCardStepResponse, error) return response, nil } -// ParseUpdateCardStepResponse parses an HTTP response from a UpdateCardStepWithResponse call -func ParseUpdateCardStepResponse(rsp *http.Response) (*UpdateCardStepResponse, error) { +// ParseGetEverythingCompletedCardsResponse parses an HTTP response from a GetEverythingCompletedCardsWithResponse call +func ParseGetEverythingCompletedCardsResponse(rsp *http.Response) (*GetEverythingCompletedCardsResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } - response := &UpdateCardStepResponse{ + response := &GetEverythingCompletedCardsResponse{ Body: bodyBytes, HTTPResponse: rsp, } switch { case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest UpdateCardStepResponseContent + var dest GetEverythingCompletedCardsResponseContent if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } @@ -31487,19 +32668,12 @@ func ParseUpdateCardStepResponse(rsp *http.Response) (*UpdateCardStepResponse, e } response.JSON403 = &dest - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404: - var dest NotFoundErrorResponseContent - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON404 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 422: - var dest ValidationErrorResponseContent + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 429: + var dest RateLimitErrorResponseContent if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } - response.JSON422 = &dest + response.JSON429 = &dest case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: var dest InternalServerErrorResponseContent @@ -31513,22 +32687,22 @@ func ParseUpdateCardStepResponse(rsp *http.Response) (*UpdateCardStepResponse, e return response, nil } -// ParseSetCardStepCompletionResponse parses an HTTP response from a SetCardStepCompletionWithResponse call -func ParseSetCardStepCompletionResponse(rsp *http.Response) (*SetCardStepCompletionResponse, error) { +// ParseGetEverythingNoDueDateCardsResponse parses an HTTP response from a GetEverythingNoDueDateCardsWithResponse call +func ParseGetEverythingNoDueDateCardsResponse(rsp *http.Response) (*GetEverythingNoDueDateCardsResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } - response := &SetCardStepCompletionResponse{ + response := &GetEverythingNoDueDateCardsResponse{ Body: bodyBytes, HTTPResponse: rsp, } switch { case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest SetCardStepCompletionResponseContent + var dest GetEverythingNoDueDateCardsResponseContent if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } @@ -31548,19 +32722,12 @@ func ParseSetCardStepCompletionResponse(rsp *http.Response) (*SetCardStepComplet } response.JSON403 = &dest - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404: - var dest NotFoundErrorResponseContent - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON404 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 422: - var dest ValidationErrorResponseContent + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 429: + var dest RateLimitErrorResponseContent if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } - response.JSON422 = &dest + response.JSON429 = &dest case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: var dest InternalServerErrorResponseContent @@ -31574,22 +32741,22 @@ func ParseSetCardStepCompletionResponse(rsp *http.Response) (*SetCardStepComplet return response, nil } -// ParseGetCardTableResponse parses an HTTP response from a GetCardTableWithResponse call -func ParseGetCardTableResponse(rsp *http.Response) (*GetCardTableResponse, error) { +// ParseGetEverythingNotNowCardsResponse parses an HTTP response from a GetEverythingNotNowCardsWithResponse call +func ParseGetEverythingNotNowCardsResponse(rsp *http.Response) (*GetEverythingNotNowCardsResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } - response := &GetCardTableResponse{ + response := &GetEverythingNotNowCardsResponse{ Body: bodyBytes, HTTPResponse: rsp, } switch { case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest GetCardTableResponseContent + var dest GetEverythingNotNowCardsResponseContent if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } @@ -31609,12 +32776,12 @@ func ParseGetCardTableResponse(rsp *http.Response) (*GetCardTableResponse, error } response.JSON403 = &dest - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404: - var dest NotFoundErrorResponseContent + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 429: + var dest RateLimitErrorResponseContent if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } - response.JSON404 = &dest + response.JSON429 = &dest case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: var dest InternalServerErrorResponseContent @@ -31628,26 +32795,26 @@ func ParseGetCardTableResponse(rsp *http.Response) (*GetCardTableResponse, error return response, nil } -// ParseCreateCardColumnResponse parses an HTTP response from a CreateCardColumnWithResponse call -func ParseCreateCardColumnResponse(rsp *http.Response) (*CreateCardColumnResponse, error) { +// ParseGetEverythingOpenCardsResponse parses an HTTP response from a GetEverythingOpenCardsWithResponse call +func ParseGetEverythingOpenCardsResponse(rsp *http.Response) (*GetEverythingOpenCardsResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } - response := &CreateCardColumnResponse{ + response := &GetEverythingOpenCardsResponse{ Body: bodyBytes, HTTPResponse: rsp, } switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 201: - var dest CreateCardColumnResponseContent + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest GetEverythingOpenCardsResponseContent if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } - response.JSON201 = &dest + response.JSON200 = &dest case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: var dest UnauthorizedErrorResponseContent @@ -31663,13 +32830,6 @@ func ParseCreateCardColumnResponse(rsp *http.Response) (*CreateCardColumnRespons } response.JSON403 = &dest - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 422: - var dest ValidationErrorResponseContent - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON422 = &dest - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 429: var dest RateLimitErrorResponseContent if err := json.Unmarshal(bodyBytes, &dest); err != nil { @@ -31689,22 +32849,26 @@ func ParseCreateCardColumnResponse(rsp *http.Response) (*CreateCardColumnRespons return response, nil } -// ParseMoveCardColumnResponse parses an HTTP response from a MoveCardColumnWithResponse call -func ParseMoveCardColumnResponse(rsp *http.Response) (*MoveCardColumnResponse, error) { +// ParseGetEverythingOverdueCardsResponse parses an HTTP response from a GetEverythingOverdueCardsWithResponse call +func ParseGetEverythingOverdueCardsResponse(rsp *http.Response) (*GetEverythingOverdueCardsResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } - response := &MoveCardColumnResponse{ + response := &GetEverythingOverdueCardsResponse{ Body: bodyBytes, HTTPResponse: rsp, } switch { - case rsp.StatusCode == 204: - break // No content-type + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest GetEverythingOverdueCardsResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: var dest UnauthorizedErrorResponseContent @@ -31720,20 +32884,6 @@ func ParseMoveCardColumnResponse(rsp *http.Response) (*MoveCardColumnResponse, e } response.JSON403 = &dest - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 422: - var dest ValidationErrorResponseContent - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON422 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 429: - var dest RateLimitErrorResponseContent - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON429 = &dest - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: var dest InternalServerErrorResponseContent if err := json.Unmarshal(bodyBytes, &dest); err != nil { @@ -31746,22 +32896,22 @@ func ParseMoveCardColumnResponse(rsp *http.Response) (*MoveCardColumnResponse, e return response, nil } -// ParseGetEverythingOverdueCardsResponse parses an HTTP response from a GetEverythingOverdueCardsWithResponse call -func ParseGetEverythingOverdueCardsResponse(rsp *http.Response) (*GetEverythingOverdueCardsResponse, error) { +// ParseGetEverythingUnassignedCardsResponse parses an HTTP response from a GetEverythingUnassignedCardsWithResponse call +func ParseGetEverythingUnassignedCardsResponse(rsp *http.Response) (*GetEverythingUnassignedCardsResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } - response := &GetEverythingOverdueCardsResponse{ + response := &GetEverythingUnassignedCardsResponse{ Body: bodyBytes, HTTPResponse: rsp, } switch { case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest GetEverythingOverdueCardsResponseContent + var dest GetEverythingUnassignedCardsResponseContent if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } @@ -31781,6 +32931,13 @@ func ParseGetEverythingOverdueCardsResponse(rsp *http.Response) (*GetEverythingO } response.JSON403 = &dest + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 429: + var dest RateLimitErrorResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON429 = &dest + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: var dest InternalServerErrorResponseContent if err := json.Unmarshal(bodyBytes, &dest); err != nil { @@ -39814,13 +40971,128 @@ func ParseUpdateTemplateResponse(rsp *http.Response) (*UpdateTemplateResponse, e } response.JSON404 = &dest - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 422: - var dest ValidationErrorResponseContent - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON422 = &dest - + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 422: + var dest ValidationErrorResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON422 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: + var dest InternalServerErrorResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON500 = &dest + + } + + return response, nil +} + +// ParseCreateProjectFromTemplateResponse parses an HTTP response from a CreateProjectFromTemplateWithResponse call +func ParseCreateProjectFromTemplateResponse(rsp *http.Response) (*CreateProjectFromTemplateResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &CreateProjectFromTemplateResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 201: + var dest CreateProjectFromTemplateResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON201 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: + var dest UnauthorizedErrorResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON401 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 403: + var dest ForbiddenErrorResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON403 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 422: + var dest ValidationErrorResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON422 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 429: + var dest RateLimitErrorResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON429 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: + var dest InternalServerErrorResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON500 = &dest + + } + + return response, nil +} + +// ParseGetProjectConstructionResponse parses an HTTP response from a GetProjectConstructionWithResponse call +func ParseGetProjectConstructionResponse(rsp *http.Response) (*GetProjectConstructionResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetProjectConstructionResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest GetProjectConstructionResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: + var dest UnauthorizedErrorResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON401 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 403: + var dest ForbiddenErrorResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON403 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404: + var dest NotFoundErrorResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON404 = &dest + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: var dest InternalServerErrorResponseContent if err := json.Unmarshal(bodyBytes, &dest); err != nil { @@ -39833,26 +41105,26 @@ func ParseUpdateTemplateResponse(rsp *http.Response) (*UpdateTemplateResponse, e return response, nil } -// ParseCreateProjectFromTemplateResponse parses an HTTP response from a CreateProjectFromTemplateWithResponse call -func ParseCreateProjectFromTemplateResponse(rsp *http.Response) (*CreateProjectFromTemplateResponse, error) { +// ParseGetTimesheetEntryResponse parses an HTTP response from a GetTimesheetEntryWithResponse call +func ParseGetTimesheetEntryResponse(rsp *http.Response) (*GetTimesheetEntryResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } - response := &CreateProjectFromTemplateResponse{ + response := &GetTimesheetEntryResponse{ Body: bodyBytes, HTTPResponse: rsp, } switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 201: - var dest CreateProjectFromTemplateResponseContent + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest GetTimesheetEntryResponseContent if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } - response.JSON201 = &dest + response.JSON200 = &dest case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: var dest UnauthorizedErrorResponseContent @@ -39868,19 +41140,12 @@ func ParseCreateProjectFromTemplateResponse(rsp *http.Response) (*CreateProjectF } response.JSON403 = &dest - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 422: - var dest ValidationErrorResponseContent - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON422 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 429: - var dest RateLimitErrorResponseContent + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404: + var dest NotFoundErrorResponseContent if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } - response.JSON429 = &dest + response.JSON404 = &dest case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: var dest InternalServerErrorResponseContent @@ -39894,22 +41159,22 @@ func ParseCreateProjectFromTemplateResponse(rsp *http.Response) (*CreateProjectF return response, nil } -// ParseGetProjectConstructionResponse parses an HTTP response from a GetProjectConstructionWithResponse call -func ParseGetProjectConstructionResponse(rsp *http.Response) (*GetProjectConstructionResponse, error) { +// ParseUpdateTimesheetEntryResponse parses an HTTP response from a UpdateTimesheetEntryWithResponse call +func ParseUpdateTimesheetEntryResponse(rsp *http.Response) (*UpdateTimesheetEntryResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } - response := &GetProjectConstructionResponse{ + response := &UpdateTimesheetEntryResponse{ Body: bodyBytes, HTTPResponse: rsp, } switch { case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest GetProjectConstructionResponseContent + var dest UpdateTimesheetEntryResponseContent if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } @@ -39936,6 +41201,13 @@ func ParseGetProjectConstructionResponse(rsp *http.Response) (*GetProjectConstru } response.JSON404 = &dest + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 422: + var dest ValidationErrorResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON422 = &dest + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: var dest InternalServerErrorResponseContent if err := json.Unmarshal(bodyBytes, &dest); err != nil { @@ -39948,26 +41220,22 @@ func ParseGetProjectConstructionResponse(rsp *http.Response) (*GetProjectConstru return response, nil } -// ParseGetTimesheetEntryResponse parses an HTTP response from a GetTimesheetEntryWithResponse call -func ParseGetTimesheetEntryResponse(rsp *http.Response) (*GetTimesheetEntryResponse, error) { +// ParseRepositionTodolistGroupResponse parses an HTTP response from a RepositionTodolistGroupWithResponse call +func ParseRepositionTodolistGroupResponse(rsp *http.Response) (*RepositionTodolistGroupResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } - response := &GetTimesheetEntryResponse{ + response := &RepositionTodolistGroupResponse{ Body: bodyBytes, HTTPResponse: rsp, } switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest GetTimesheetEntryResponseContent - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON200 = &dest + case rsp.StatusCode == 200: + break // No content-type case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: var dest UnauthorizedErrorResponseContent @@ -39990,6 +41258,13 @@ func ParseGetTimesheetEntryResponse(rsp *http.Response) (*GetTimesheetEntryRespo } response.JSON404 = &dest + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 422: + var dest ValidationErrorResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON422 = &dest + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: var dest InternalServerErrorResponseContent if err := json.Unmarshal(bodyBytes, &dest); err != nil { @@ -40002,22 +41277,22 @@ func ParseGetTimesheetEntryResponse(rsp *http.Response) (*GetTimesheetEntryRespo return response, nil } -// ParseUpdateTimesheetEntryResponse parses an HTTP response from a UpdateTimesheetEntryWithResponse call -func ParseUpdateTimesheetEntryResponse(rsp *http.Response) (*UpdateTimesheetEntryResponse, error) { +// ParseGetTodolistOrGroupResponse parses an HTTP response from a GetTodolistOrGroupWithResponse call +func ParseGetTodolistOrGroupResponse(rsp *http.Response) (*GetTodolistOrGroupResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } - response := &UpdateTimesheetEntryResponse{ + response := &GetTodolistOrGroupResponse{ Body: bodyBytes, HTTPResponse: rsp, } switch { case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest UpdateTimesheetEntryResponseContent + var dest GetTodolistOrGroupResponseContent if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } @@ -40044,13 +41319,6 @@ func ParseUpdateTimesheetEntryResponse(rsp *http.Response) (*UpdateTimesheetEntr } response.JSON404 = &dest - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 422: - var dest ValidationErrorResponseContent - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON422 = &dest - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: var dest InternalServerErrorResponseContent if err := json.Unmarshal(bodyBytes, &dest); err != nil { @@ -40063,22 +41331,26 @@ func ParseUpdateTimesheetEntryResponse(rsp *http.Response) (*UpdateTimesheetEntr return response, nil } -// ParseRepositionTodolistGroupResponse parses an HTTP response from a RepositionTodolistGroupWithResponse call -func ParseRepositionTodolistGroupResponse(rsp *http.Response) (*RepositionTodolistGroupResponse, error) { +// ParseUpdateTodolistOrGroupResponse parses an HTTP response from a UpdateTodolistOrGroupWithResponse call +func ParseUpdateTodolistOrGroupResponse(rsp *http.Response) (*UpdateTodolistOrGroupResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } - response := &RepositionTodolistGroupResponse{ + response := &UpdateTodolistOrGroupResponse{ Body: bodyBytes, HTTPResponse: rsp, } switch { - case rsp.StatusCode == 200: - break // No content-type + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest UpdateTodolistOrGroupResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: var dest UnauthorizedErrorResponseContent @@ -40120,22 +41392,22 @@ func ParseRepositionTodolistGroupResponse(rsp *http.Response) (*RepositionTodoli return response, nil } -// ParseGetTodolistOrGroupResponse parses an HTTP response from a GetTodolistOrGroupWithResponse call -func ParseGetTodolistOrGroupResponse(rsp *http.Response) (*GetTodolistOrGroupResponse, error) { +// ParseListTodolistGroupsResponse parses an HTTP response from a ListTodolistGroupsWithResponse call +func ParseListTodolistGroupsResponse(rsp *http.Response) (*ListTodolistGroupsResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } - response := &GetTodolistOrGroupResponse{ + response := &ListTodolistGroupsResponse{ Body: bodyBytes, HTTPResponse: rsp, } switch { case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest GetTodolistOrGroupResponseContent + var dest ListTodolistGroupsResponseContent if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } @@ -40155,12 +41427,12 @@ func ParseGetTodolistOrGroupResponse(rsp *http.Response) (*GetTodolistOrGroupRes } response.JSON403 = &dest - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404: - var dest NotFoundErrorResponseContent + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 429: + var dest RateLimitErrorResponseContent if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } - response.JSON404 = &dest + response.JSON429 = &dest case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: var dest InternalServerErrorResponseContent @@ -40174,26 +41446,26 @@ func ParseGetTodolistOrGroupResponse(rsp *http.Response) (*GetTodolistOrGroupRes return response, nil } -// ParseUpdateTodolistOrGroupResponse parses an HTTP response from a UpdateTodolistOrGroupWithResponse call -func ParseUpdateTodolistOrGroupResponse(rsp *http.Response) (*UpdateTodolistOrGroupResponse, error) { +// ParseCreateTodolistGroupResponse parses an HTTP response from a CreateTodolistGroupWithResponse call +func ParseCreateTodolistGroupResponse(rsp *http.Response) (*CreateTodolistGroupResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } - response := &UpdateTodolistOrGroupResponse{ + response := &CreateTodolistGroupResponse{ Body: bodyBytes, HTTPResponse: rsp, } switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest UpdateTodolistOrGroupResponseContent + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 201: + var dest CreateTodolistGroupResponseContent if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } - response.JSON200 = &dest + response.JSON201 = &dest case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: var dest UnauthorizedErrorResponseContent @@ -40209,19 +41481,19 @@ func ParseUpdateTodolistOrGroupResponse(rsp *http.Response) (*UpdateTodolistOrGr } response.JSON403 = &dest - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404: - var dest NotFoundErrorResponseContent + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 422: + var dest ValidationErrorResponseContent if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } - response.JSON404 = &dest + response.JSON422 = &dest - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 422: - var dest ValidationErrorResponseContent + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 429: + var dest RateLimitErrorResponseContent if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } - response.JSON422 = &dest + response.JSON429 = &dest case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: var dest InternalServerErrorResponseContent @@ -40235,22 +41507,22 @@ func ParseUpdateTodolistOrGroupResponse(rsp *http.Response) (*UpdateTodolistOrGr return response, nil } -// ParseListTodolistGroupsResponse parses an HTTP response from a ListTodolistGroupsWithResponse call -func ParseListTodolistGroupsResponse(rsp *http.Response) (*ListTodolistGroupsResponse, error) { +// ParseListTodosResponse parses an HTTP response from a ListTodosWithResponse call +func ParseListTodosResponse(rsp *http.Response) (*ListTodosResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } - response := &ListTodolistGroupsResponse{ + response := &ListTodosResponse{ Body: bodyBytes, HTTPResponse: rsp, } switch { case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest ListTodolistGroupsResponseContent + var dest ListTodosResponseContent if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } @@ -40289,22 +41561,22 @@ func ParseListTodolistGroupsResponse(rsp *http.Response) (*ListTodolistGroupsRes return response, nil } -// ParseCreateTodolistGroupResponse parses an HTTP response from a CreateTodolistGroupWithResponse call -func ParseCreateTodolistGroupResponse(rsp *http.Response) (*CreateTodolistGroupResponse, error) { +// ParseCreateTodoResponse parses an HTTP response from a CreateTodoWithResponse call +func ParseCreateTodoResponse(rsp *http.Response) (*CreateTodoResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } - response := &CreateTodolistGroupResponse{ + response := &CreateTodoResponse{ Body: bodyBytes, HTTPResponse: rsp, } switch { case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 201: - var dest CreateTodolistGroupResponseContent + var dest CreateTodoResponseContent if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } @@ -40350,22 +41622,22 @@ func ParseCreateTodolistGroupResponse(rsp *http.Response) (*CreateTodolistGroupR return response, nil } -// ParseListTodosResponse parses an HTTP response from a ListTodosWithResponse call -func ParseListTodosResponse(rsp *http.Response) (*ListTodosResponse, error) { +// ParseGetEverythingCompletedTodosResponse parses an HTTP response from a GetEverythingCompletedTodosWithResponse call +func ParseGetEverythingCompletedTodosResponse(rsp *http.Response) (*GetEverythingCompletedTodosResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } - response := &ListTodosResponse{ + response := &GetEverythingCompletedTodosResponse{ Body: bodyBytes, HTTPResponse: rsp, } switch { case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest ListTodosResponseContent + var dest GetEverythingCompletedTodosResponseContent if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } @@ -40404,26 +41676,26 @@ func ParseListTodosResponse(rsp *http.Response) (*ListTodosResponse, error) { return response, nil } -// ParseCreateTodoResponse parses an HTTP response from a CreateTodoWithResponse call -func ParseCreateTodoResponse(rsp *http.Response) (*CreateTodoResponse, error) { +// ParseGetEverythingNoDueDateTodosResponse parses an HTTP response from a GetEverythingNoDueDateTodosWithResponse call +func ParseGetEverythingNoDueDateTodosResponse(rsp *http.Response) (*GetEverythingNoDueDateTodosResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } - response := &CreateTodoResponse{ + response := &GetEverythingNoDueDateTodosResponse{ Body: bodyBytes, HTTPResponse: rsp, } switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 201: - var dest CreateTodoResponseContent + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest GetEverythingNoDueDateTodosResponseContent if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } - response.JSON201 = &dest + response.JSON200 = &dest case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: var dest UnauthorizedErrorResponseContent @@ -40439,12 +41711,59 @@ func ParseCreateTodoResponse(rsp *http.Response) (*CreateTodoResponse, error) { } response.JSON403 = &dest - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 422: - var dest ValidationErrorResponseContent + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 429: + var dest RateLimitErrorResponseContent if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } - response.JSON422 = &dest + response.JSON429 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: + var dest InternalServerErrorResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON500 = &dest + + } + + return response, nil +} + +// ParseGetEverythingOpenTodosResponse parses an HTTP response from a GetEverythingOpenTodosWithResponse call +func ParseGetEverythingOpenTodosResponse(rsp *http.Response) (*GetEverythingOpenTodosResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetEverythingOpenTodosResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest GetEverythingOpenTodosResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: + var dest UnauthorizedErrorResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON401 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 403: + var dest ForbiddenErrorResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON403 = &dest case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 429: var dest RateLimitErrorResponseContent @@ -40512,6 +41831,60 @@ func ParseGetEverythingOverdueTodosResponse(rsp *http.Response) (*GetEverythingO return response, nil } +// ParseGetEverythingUnassignedTodosResponse parses an HTTP response from a GetEverythingUnassignedTodosWithResponse call +func ParseGetEverythingUnassignedTodosResponse(rsp *http.Response) (*GetEverythingUnassignedTodosResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetEverythingUnassignedTodosResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest GetEverythingUnassignedTodosResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: + var dest UnauthorizedErrorResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON401 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 403: + var dest ForbiddenErrorResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON403 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 429: + var dest RateLimitErrorResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON429 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: + var dest InternalServerErrorResponseContent + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON500 = &dest + + } + + return response, nil +} + // ParseTrashTodoResponse parses an HTTP response from a TrashTodoWithResponse call func ParseTrashTodoResponse(rsp *http.Response) (*TrashTodoResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) diff --git a/kotlin/generator/src/main/kotlin/com/basecamp/sdk/generator/Config.kt b/kotlin/generator/src/main/kotlin/com/basecamp/sdk/generator/Config.kt index 0a6e1c54..f803890b 100644 --- a/kotlin/generator/src/main/kotlin/com/basecamp/sdk/generator/Config.kt +++ b/kotlin/generator/src/main/kotlin/com/basecamp/sdk/generator/Config.kt @@ -312,6 +312,8 @@ val TYPE_ALIASES = mapOf( "ClientReply" to "ClientReply", "Boost" to "Boost", "EverythingFile" to "EverythingFile", + "BucketTodosGroup" to "BucketTodosGroup", + "BucketCardsGroup" to "BucketCardsGroup", "TimelineEvent" to "TimelineEvent", "TimesheetEntry" to "TimesheetEntry", "HillChart" to "HillChart", diff --git a/kotlin/sdk/src/commonMain/kotlin/com/basecamp/sdk/generated/Metadata.kt b/kotlin/sdk/src/commonMain/kotlin/com/basecamp/sdk/generated/Metadata.kt index e036882b..65922083 100644 --- a/kotlin/sdk/src/commonMain/kotlin/com/basecamp/sdk/generated/Metadata.kt +++ b/kotlin/sdk/src/commonMain/kotlin/com/basecamp/sdk/generated/Metadata.kt @@ -88,11 +88,20 @@ object Metadata { "GetEverythingBoosts" to OperationConfig(false, RetryConfig(3, 1000L, "exponential", setOf(429, 503))), "GetEverythingCheckins" to OperationConfig(false, RetryConfig(3, 1000L, "exponential", setOf(429, 503))), "GetEverythingComments" to OperationConfig(false, RetryConfig(3, 1000L, "exponential", setOf(429, 503))), + "GetEverythingCompletedCards" to OperationConfig(false, RetryConfig(3, 1000L, "exponential", setOf(429, 503))), + "GetEverythingCompletedTodos" to OperationConfig(false, RetryConfig(3, 1000L, "exponential", setOf(429, 503))), "GetEverythingFiles" to OperationConfig(false, RetryConfig(3, 1000L, "exponential", setOf(429, 503))), "GetEverythingForwards" to OperationConfig(false, RetryConfig(3, 1000L, "exponential", setOf(429, 503))), "GetEverythingMessages" to OperationConfig(false, RetryConfig(3, 1000L, "exponential", setOf(429, 503))), + "GetEverythingNoDueDateCards" to OperationConfig(false, RetryConfig(3, 1000L, "exponential", setOf(429, 503))), + "GetEverythingNoDueDateTodos" to OperationConfig(false, RetryConfig(3, 1000L, "exponential", setOf(429, 503))), + "GetEverythingNotNowCards" to OperationConfig(false, RetryConfig(3, 1000L, "exponential", setOf(429, 503))), + "GetEverythingOpenCards" to OperationConfig(false, RetryConfig(3, 1000L, "exponential", setOf(429, 503))), + "GetEverythingOpenTodos" to OperationConfig(false, RetryConfig(3, 1000L, "exponential", setOf(429, 503))), "GetEverythingOverdueCards" to OperationConfig(false, RetryConfig(3, 1000L, "exponential", setOf(429, 503))), "GetEverythingOverdueTodos" to OperationConfig(false, RetryConfig(3, 1000L, "exponential", setOf(429, 503))), + "GetEverythingUnassignedCards" to OperationConfig(false, RetryConfig(3, 1000L, "exponential", setOf(429, 503))), + "GetEverythingUnassignedTodos" to OperationConfig(false, RetryConfig(3, 1000L, "exponential", setOf(429, 503))), "GetForward" to OperationConfig(false, RetryConfig(3, 1000L, "exponential", setOf(429, 503))), "GetForwardReply" to OperationConfig(false, RetryConfig(3, 1000L, "exponential", setOf(429, 503))), "GetGaugeNeedle" to OperationConfig(false, RetryConfig(3, 1000L, "exponential", setOf(429, 503))), diff --git a/kotlin/sdk/src/commonMain/kotlin/com/basecamp/sdk/generated/models/BucketCardsGroup.kt b/kotlin/sdk/src/commonMain/kotlin/com/basecamp/sdk/generated/models/BucketCardsGroup.kt new file mode 100644 index 00000000..91189eeb --- /dev/null +++ b/kotlin/sdk/src/commonMain/kotlin/com/basecamp/sdk/generated/models/BucketCardsGroup.kt @@ -0,0 +1,17 @@ +package com.basecamp.sdk.generated.models + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.JsonObject + +/** + * BucketCardsGroup entity from the Basecamp API. + * + * @generated from OpenAPI spec — do not edit directly + */ +@Serializable +data class BucketCardsGroup( + val bucket: RecordingBucket? = null, + val cards: List = emptyList() +) diff --git a/kotlin/sdk/src/commonMain/kotlin/com/basecamp/sdk/generated/models/BucketTodosGroup.kt b/kotlin/sdk/src/commonMain/kotlin/com/basecamp/sdk/generated/models/BucketTodosGroup.kt new file mode 100644 index 00000000..a37d7364 --- /dev/null +++ b/kotlin/sdk/src/commonMain/kotlin/com/basecamp/sdk/generated/models/BucketTodosGroup.kt @@ -0,0 +1,17 @@ +package com.basecamp.sdk.generated.models + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.JsonObject + +/** + * BucketTodosGroup entity from the Basecamp API. + * + * @generated from OpenAPI spec — do not edit directly + */ +@Serializable +data class BucketTodosGroup( + val bucket: RecordingBucket? = null, + val todos: List = emptyList() +) diff --git a/kotlin/sdk/src/commonMain/kotlin/com/basecamp/sdk/generated/services/everything.kt b/kotlin/sdk/src/commonMain/kotlin/com/basecamp/sdk/generated/services/everything.kt index f40d8e95..d8b04ed8 100644 --- a/kotlin/sdk/src/commonMain/kotlin/com/basecamp/sdk/generated/services/everything.kt +++ b/kotlin/sdk/src/commonMain/kotlin/com/basecamp/sdk/generated/services/everything.kt @@ -32,6 +32,86 @@ class EverythingService(client: AccountClient) : BaseService(client) { } } + /** + * Get completed cards across all accessible projects, grouped by project + * @param options Optional query parameters and pagination control + */ + suspend fun everythingCompletedCards(options: PaginationOptions? = null): ListResult { + val info = OperationInfo( + service = "Everything", + operation = "GetEverythingCompletedCards", + resourceType = "everything_completed_card", + isMutation = false, + projectId = null, + resourceId = null, + ) + return requestPaginated(info, options, { + httpGet("/cards/completed.json", operationName = info.operation) + }) { body -> + json.decodeFromString>(body) + } + } + + /** + * Get open cards with no due date across all accessible projects, grouped by + * @param options Optional query parameters and pagination control + */ + suspend fun everythingNoDueDateCards(options: PaginationOptions? = null): ListResult { + val info = OperationInfo( + service = "Everything", + operation = "GetEverythingNoDueDateCards", + resourceType = "everything_no_due_date_card", + isMutation = false, + projectId = null, + resourceId = null, + ) + return requestPaginated(info, options, { + httpGet("/cards/no_due_date.json", operationName = info.operation) + }) { body -> + json.decodeFromString>(body) + } + } + + /** + * Get cards parked in a project's "Not now" column across all accessible + * @param options Optional query parameters and pagination control + */ + suspend fun everythingNotNowCards(options: PaginationOptions? = null): ListResult { + val info = OperationInfo( + service = "Everything", + operation = "GetEverythingNotNowCards", + resourceType = "everything_not_now_card", + isMutation = false, + projectId = null, + resourceId = null, + ) + return requestPaginated(info, options, { + httpGet("/cards/not_now.json", operationName = info.operation) + }) { body -> + json.decodeFromString>(body) + } + } + + /** + * Get incomplete cards in active columns across all accessible projects, + * @param options Optional query parameters and pagination control + */ + suspend fun everythingOpenCards(options: PaginationOptions? = null): ListResult { + val info = OperationInfo( + service = "Everything", + operation = "GetEverythingOpenCards", + resourceType = "everything_open_card", + isMutation = false, + projectId = null, + resourceId = null, + ) + return requestPaginated(info, options, { + httpGet("/cards/open.json", operationName = info.operation) + }) { body -> + json.decodeFromString>(body) + } + } + /** * Get every overdue card across all accessible projects — a complete, */ @@ -51,6 +131,26 @@ class EverythingService(client: AccountClient) : BaseService(client) { } } + /** + * Get open, unassigned cards across all accessible projects, grouped by + * @param options Optional query parameters and pagination control + */ + suspend fun everythingUnassignedCards(options: PaginationOptions? = null): ListResult { + val info = OperationInfo( + service = "Everything", + operation = "GetEverythingUnassignedCards", + resourceType = "everything_unassigned_card", + isMutation = false, + projectId = null, + resourceId = null, + ) + return requestPaginated(info, options, { + httpGet("/cards/unassigned.json", operationName = info.operation) + }) { body -> + json.decodeFromString>(body) + } + } + /** * Get every automatic check-in answer across all accessible projects, * @param options Optional query parameters and pagination control @@ -155,6 +255,66 @@ class EverythingService(client: AccountClient) : BaseService(client) { } } + /** + * Get completed to-dos across all accessible projects, grouped by project + * @param options Optional query parameters and pagination control + */ + suspend fun everythingCompletedTodos(options: PaginationOptions? = null): ListResult { + val info = OperationInfo( + service = "Everything", + operation = "GetEverythingCompletedTodos", + resourceType = "everything_completed_todo", + isMutation = false, + projectId = null, + resourceId = null, + ) + return requestPaginated(info, options, { + httpGet("/todos/completed.json", operationName = info.operation) + }) { body -> + json.decodeFromString>(body) + } + } + + /** + * Get open to-dos with no due date across all accessible projects, grouped by + * @param options Optional query parameters and pagination control + */ + suspend fun everythingNoDueDateTodos(options: PaginationOptions? = null): ListResult { + val info = OperationInfo( + service = "Everything", + operation = "GetEverythingNoDueDateTodos", + resourceType = "everything_no_due_date_todo", + isMutation = false, + projectId = null, + resourceId = null, + ) + return requestPaginated(info, options, { + httpGet("/todos/no_due_date.json", operationName = info.operation) + }) { body -> + json.decodeFromString>(body) + } + } + + /** + * Get active, incomplete to-dos across all accessible projects, grouped by + * @param options Optional query parameters and pagination control + */ + suspend fun everythingOpenTodos(options: PaginationOptions? = null): ListResult { + val info = OperationInfo( + service = "Everything", + operation = "GetEverythingOpenTodos", + resourceType = "everything_open_todo", + isMutation = false, + projectId = null, + resourceId = null, + ) + return requestPaginated(info, options, { + httpGet("/todos/open.json", operationName = info.operation) + }) { body -> + json.decodeFromString>(body) + } + } + /** * Get every overdue to-do across all accessible projects — a complete, */ @@ -173,4 +333,24 @@ class EverythingService(client: AccountClient) : BaseService(client) { json.decodeFromString>(body) } } + + /** + * Get open, unassigned to-dos across all accessible projects, grouped by + * @param options Optional query parameters and pagination control + */ + suspend fun everythingUnassignedTodos(options: PaginationOptions? = null): ListResult { + val info = OperationInfo( + service = "Everything", + operation = "GetEverythingUnassignedTodos", + resourceType = "everything_unassigned_todo", + isMutation = false, + projectId = null, + resourceId = null, + ) + return requestPaginated(info, options, { + httpGet("/todos/unassigned.json", operationName = info.operation) + }) { body -> + json.decodeFromString>(body) + } + } } diff --git a/openapi.json b/openapi.json index 6a639af2..e32db37a 100644 --- a/openapi.json +++ b/openapi.json @@ -3187,10 +3187,10 @@ } } }, - "/{accountId}/cards/overdue.json": { + "/{accountId}/cards/completed.json": { "get": { - "description": "Get every overdue card across all accessible projects — a complete,\noldest-due-date-first array (unpaginated). Each item embeds its `bucket`.", - "operationId": "GetEverythingOverdueCards", + "description": "Get completed cards across all accessible projects, grouped by project\n(paginated).", + "operationId": "GetEverythingCompletedCards", "parameters": [ { "name": "accountId", @@ -3206,11 +3206,11 @@ ], "responses": { "200": { - "description": "GetEverythingOverdueCards 200 response", + "description": "GetEverythingCompletedCards 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetEverythingOverdueCardsResponseContent" + "$ref": "#/components/schemas/GetEverythingCompletedCardsResponseContent" } } } @@ -3235,6 +3235,16 @@ } } }, + "429": { + "description": "RateLimitError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RateLimitErrorResponseContent" + } + } + } + }, "500": { "description": "InternalServerError 500 response", "content": { @@ -3249,6 +3259,11 @@ "tags": [ "Everything" ], + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -3260,10 +3275,10 @@ } } }, - "/{accountId}/categories.json": { + "/{accountId}/cards/no_due_date.json": { "get": { - "description": "List message types in a project\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", - "operationId": "ListMessageTypes", + "description": "Get open cards with no due date across all accessible projects, grouped by\nproject (paginated).", + "operationId": "GetEverythingNoDueDateCards", "parameters": [ { "name": "accountId", @@ -3279,11 +3294,11 @@ ], "responses": { "200": { - "description": "ListMessageTypes 200 response", + "description": "GetEverythingNoDueDateCards 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListMessageTypesResponseContent" + "$ref": "#/components/schemas/GetEverythingNoDueDateCardsResponseContent" } } } @@ -3330,7 +3345,7 @@ } }, "tags": [ - "Messages" + "Everything" ], "x-basecamp-pagination": { "style": "link", @@ -3346,20 +3361,12 @@ 503 ] } - }, - "post": { - "description": "Create a new message type in a project", - "operationId": "CreateMessageType", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateMessageTypeRequestContent" - } - } - }, - "required": true - }, + } + }, + "/{accountId}/cards/not_now.json": { + "get": { + "description": "Get cards parked in a project's \"Not now\" column across all accessible\nprojects, grouped by project (paginated).", + "operationId": "GetEverythingNotNowCards", "parameters": [ { "name": "accountId", @@ -3374,12 +3381,12 @@ } ], "responses": { - "201": { - "description": "CreateMessageType 201 response", + "200": { + "description": "GetEverythingNotNowCards 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateMessageTypeResponseContent" + "$ref": "#/components/schemas/GetEverythingNotNowCardsResponseContent" } } } @@ -3404,16 +3411,6 @@ } } }, - "422": { - "description": "ValidationError 422 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" - } - } - } - }, "429": { "description": "RateLimitError 429 response", "content": { @@ -3436,10 +3433,15 @@ } }, "tags": [ - "Messages" + "Everything" ], + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + }, "x-basecamp-retry": { - "maxAttempts": 2, + "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -3449,10 +3451,10 @@ } } }, - "/{accountId}/categories/{typeId}": { - "delete": { - "description": "Delete a message type", - "operationId": "DeleteMessageType", + "/{accountId}/cards/open.json": { + "get": { + "description": "Get incomplete cards in active columns across all accessible projects,\ngrouped by project (paginated). Each bucket entry carries the matching cards\nand their steps.", + "operationId": "GetEverythingOpenCards", "parameters": [ { "name": "accountId", @@ -3464,20 +3466,18 @@ "description": "Basecamp account ID (numeric string)" }, "required": true - }, - { - "name": "typeId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true } ], "responses": { - "204": { - "description": "DeleteMessageType 204 response" + "200": { + "description": "GetEverythingOpenCards 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetEverythingOpenCardsResponseContent" + } + } + } }, "401": { "description": "UnauthorizedError 401 response", @@ -3499,12 +3499,12 @@ } } }, - "404": { - "description": "NotFoundError 404 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -3521,10 +3521,12 @@ } }, "tags": [ - "Messages" + "Everything" ], - "x-basecamp-idempotent": { - "natural": true + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 }, "x-basecamp-retry": { "maxAttempts": 3, @@ -3535,10 +3537,12 @@ 503 ] } - }, + } + }, + "/{accountId}/cards/overdue.json": { "get": { - "description": "Get a single message type by id", - "operationId": "GetMessageType", + "description": "Get every overdue card across all accessible projects — a complete,\noldest-due-date-first array (unpaginated). Each item embeds its `bucket`.", + "operationId": "GetEverythingOverdueCards", "parameters": [ { "name": "accountId", @@ -3550,24 +3554,15 @@ "description": "Basecamp account ID (numeric string)" }, "required": true - }, - { - "name": "typeId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true } ], "responses": { "200": { - "description": "GetMessageType 200 response", + "description": "GetEverythingOverdueCards 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetMessageTypeResponseContent" + "$ref": "#/components/schemas/GetEverythingOverdueCardsResponseContent" } } } @@ -3592,16 +3587,6 @@ } } }, - "404": { - "description": "NotFoundError 404 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" - } - } - } - }, "500": { "description": "InternalServerError 500 response", "content": { @@ -3614,7 +3599,7 @@ } }, "tags": [ - "Messages" + "Everything" ], "x-basecamp-retry": { "maxAttempts": 3, @@ -3625,19 +3610,12 @@ 503 ] } - }, - "put": { - "description": "Update an existing message type", - "operationId": "UpdateMessageType", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateMessageTypeRequestContent" - } - } - } - }, + } + }, + "/{accountId}/cards/unassigned.json": { + "get": { + "description": "Get open, unassigned cards across all accessible projects, grouped by\nproject (paginated).", + "operationId": "GetEverythingUnassignedCards", "parameters": [ { "name": "accountId", @@ -3649,24 +3627,15 @@ "description": "Basecamp account ID (numeric string)" }, "required": true - }, - { - "name": "typeId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true } ], "responses": { "200": { - "description": "UpdateMessageType 200 response", + "description": "GetEverythingUnassignedCards 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateMessageTypeResponseContent" + "$ref": "#/components/schemas/GetEverythingUnassignedCardsResponseContent" } } } @@ -3691,22 +3660,12 @@ } } }, - "404": { - "description": "NotFoundError 404 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" - } - } - } - }, - "422": { - "description": "ValidationError 422 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -3723,10 +3682,12 @@ } }, "tags": [ - "Messages" + "Everything" ], - "x-basecamp-idempotent": { - "natural": true + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 }, "x-basecamp-retry": { "maxAttempts": 3, @@ -3739,10 +3700,10 @@ } } }, - "/{accountId}/chats.json": { + "/{accountId}/categories.json": { "get": { - "description": "List all campfires across the account\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", - "operationId": "ListCampfires", + "description": "List message types in a project\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", + "operationId": "ListMessageTypes", "parameters": [ { "name": "accountId", @@ -3758,11 +3719,11 @@ ], "responses": { "200": { - "description": "ListCampfires 200 response", + "description": "ListMessageTypes 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListCampfiresResponseContent" + "$ref": "#/components/schemas/ListMessageTypesResponseContent" } } } @@ -3809,7 +3770,7 @@ } }, "tags": [ - "Campfire" + "Messages" ], "x-basecamp-pagination": { "style": "link", @@ -3825,12 +3786,20 @@ 503 ] } - } - }, - "/{accountId}/chats/{campfireId}": { - "get": { - "description": "Get a campfire by ID", - "operationId": "GetCampfire", + }, + "post": { + "description": "Create a new message type in a project", + "operationId": "CreateMessageType", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateMessageTypeRequestContent" + } + } + }, + "required": true + }, "parameters": [ { "name": "accountId", @@ -3842,24 +3811,15 @@ "description": "Basecamp account ID (numeric string)" }, "required": true - }, - { - "name": "campfireId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true } ], "responses": { - "200": { - "description": "GetCampfire 200 response", + "201": { + "description": "CreateMessageType 201 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetCampfireResponseContent" + "$ref": "#/components/schemas/CreateMessageTypeResponseContent" } } } @@ -3884,12 +3844,22 @@ } } }, - "404": { - "description": "NotFoundError 404 response", + "422": { + "description": "ValidationError 422 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/ValidationErrorResponseContent" + } + } + } + }, + "429": { + "description": "RateLimitError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -3906,10 +3876,10 @@ } }, "tags": [ - "Campfire" + "Messages" ], "x-basecamp-retry": { - "maxAttempts": 3, + "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -3919,10 +3889,10 @@ } } }, - "/{accountId}/chats/{campfireId}/integrations.json": { - "get": { - "description": "List all chatbots for a campfire\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", - "operationId": "ListChatbots", + "/{accountId}/categories/{typeId}": { + "delete": { + "description": "Delete a message type", + "operationId": "DeleteMessageType", "parameters": [ { "name": "accountId", @@ -3936,7 +3906,7 @@ "required": true }, { - "name": "campfireId", + "name": "typeId", "in": "path", "schema": { "type": "integer", @@ -3946,15 +3916,8 @@ } ], "responses": { - "200": { - "description": "ListChatbots 200 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ListChatbotsResponseContent" - } - } - } + "204": { + "description": "DeleteMessageType 204 response" }, "401": { "description": "UnauthorizedError 401 response", @@ -3976,12 +3939,12 @@ } } }, - "429": { - "description": "RateLimitError 429 response", + "404": { + "description": "NotFoundError 404 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" } } } @@ -3998,12 +3961,10 @@ } }, "tags": [ - "Campfire" + "Messages" ], - "x-basecamp-pagination": { - "style": "link", - "totalCountHeader": "X-Total-Count", - "maxPageSize": 50 + "x-basecamp-idempotent": { + "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, @@ -4015,19 +3976,9 @@ ] } }, - "post": { - "description": "Create a new chatbot for a campfire", - "operationId": "CreateChatbot", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateChatbotRequestContent" - } - } - }, - "required": true - }, + "get": { + "description": "Get a single message type by id", + "operationId": "GetMessageType", "parameters": [ { "name": "accountId", @@ -4041,7 +3992,7 @@ "required": true }, { - "name": "campfireId", + "name": "typeId", "in": "path", "schema": { "type": "integer", @@ -4051,12 +4002,12 @@ } ], "responses": { - "201": { - "description": "CreateChatbot 201 response", + "200": { + "description": "GetMessageType 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateChatbotResponseContent" + "$ref": "#/components/schemas/GetMessageTypeResponseContent" } } } @@ -4081,22 +4032,12 @@ } } }, - "422": { - "description": "ValidationError 422 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" - } - } - } - }, - "429": { - "description": "RateLimitError 429 response", + "404": { + "description": "NotFoundError 404 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" } } } @@ -4113,10 +4054,10 @@ } }, "tags": [ - "Campfire" + "Messages" ], "x-basecamp-retry": { - "maxAttempts": 2, + "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -4124,12 +4065,19 @@ 503 ] } - } - }, - "/{accountId}/chats/{campfireId}/integrations/{chatbotId}": { - "delete": { - "description": "Delete a chatbot", - "operationId": "DeleteChatbot", + }, + "put": { + "description": "Update an existing message type", + "operationId": "UpdateMessageType", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateMessageTypeRequestContent" + } + } + } + }, "parameters": [ { "name": "accountId", @@ -4143,16 +4091,7 @@ "required": true }, { - "name": "campfireId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true - }, - { - "name": "chatbotId", + "name": "typeId", "in": "path", "schema": { "type": "integer", @@ -4162,8 +4101,15 @@ } ], "responses": { - "204": { - "description": "DeleteChatbot 204 response" + "200": { + "description": "UpdateMessageType 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateMessageTypeResponseContent" + } + } + } }, "401": { "description": "UnauthorizedError 401 response", @@ -4195,6 +4141,16 @@ } } }, + "422": { + "description": "ValidationError 422 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponseContent" + } + } + } + }, "500": { "description": "InternalServerError 500 response", "content": { @@ -4207,7 +4163,7 @@ } }, "tags": [ - "Campfire" + "Messages" ], "x-basecamp-idempotent": { "natural": true @@ -4221,10 +4177,12 @@ 503 ] } - }, + } + }, + "/{accountId}/chats.json": { "get": { - "description": "Get a chatbot by ID", - "operationId": "GetChatbot", + "description": "List all campfires across the account\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", + "operationId": "ListCampfires", "parameters": [ { "name": "accountId", @@ -4236,33 +4194,15 @@ "description": "Basecamp account ID (numeric string)" }, "required": true - }, - { - "name": "campfireId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true - }, - { - "name": "chatbotId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true } ], "responses": { "200": { - "description": "GetChatbot 200 response", + "description": "ListCampfires 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetChatbotResponseContent" + "$ref": "#/components/schemas/ListCampfiresResponseContent" } } } @@ -4287,12 +4227,12 @@ } } }, - "404": { - "description": "NotFoundError 404 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -4311,6 +4251,11 @@ "tags": [ "Campfire" ], + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -4320,20 +4265,12 @@ 503 ] } - }, - "put": { - "description": "Update an existing chatbot", - "operationId": "UpdateChatbot", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateChatbotRequestContent" - } - } - }, - "required": true - }, + } + }, + "/{accountId}/chats/{campfireId}": { + "get": { + "description": "Get a campfire by ID", + "operationId": "GetCampfire", "parameters": [ { "name": "accountId", @@ -4354,24 +4291,15 @@ "format": "int64" }, "required": true - }, - { - "name": "chatbotId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true } ], "responses": { "200": { - "description": "UpdateChatbot 200 response", + "description": "GetCampfire 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateChatbotResponseContent" + "$ref": "#/components/schemas/GetCampfireResponseContent" } } } @@ -4406,16 +4334,6 @@ } } }, - "422": { - "description": "ValidationError 422 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" - } - } - } - }, "500": { "description": "InternalServerError 500 response", "content": { @@ -4430,9 +4348,6 @@ "tags": [ "Campfire" ], - "x-basecamp-idempotent": { - "natural": true - }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -4444,10 +4359,10 @@ } } }, - "/{accountId}/chats/{campfireId}/lines.json": { + "/{accountId}/chats/{campfireId}/integrations.json": { "get": { - "description": "List all lines (messages) in a campfire\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", - "operationId": "ListCampfireLines", + "description": "List all chatbots for a campfire\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", + "operationId": "ListChatbots", "parameters": [ { "name": "accountId", @@ -4468,33 +4383,15 @@ "format": "int64" }, "required": true - }, - { - "name": "sort", - "in": "query", - "description": "created_at|updated_at", - "schema": { - "type": "string", - "description": "created_at|updated_at" - } - }, - { - "name": "direction", - "in": "query", - "description": "asc|desc", - "schema": { - "type": "string", - "description": "asc|desc" - } } ], "responses": { "200": { - "description": "ListCampfireLines 200 response", + "description": "ListChatbots 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListCampfireLinesResponseContent" + "$ref": "#/components/schemas/ListChatbotsResponseContent" } } } @@ -4559,13 +4456,13 @@ } }, "post": { - "description": "Create a new line (message) in a campfire", - "operationId": "CreateCampfireLine", + "description": "Create a new chatbot for a campfire", + "operationId": "CreateChatbot", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateCampfireLineRequestContent" + "$ref": "#/components/schemas/CreateChatbotRequestContent" } } }, @@ -4595,11 +4492,11 @@ ], "responses": { "201": { - "description": "CreateCampfireLine 201 response", + "description": "CreateChatbot 201 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateCampfireLineResponseContent" + "$ref": "#/components/schemas/CreateChatbotResponseContent" } } } @@ -4669,10 +4566,10 @@ } } }, - "/{accountId}/chats/{campfireId}/lines/{lineId}": { + "/{accountId}/chats/{campfireId}/integrations/{chatbotId}": { "delete": { - "description": "Delete a campfire line; allowed for the line's creator or an admin.\nThe API responds 403 Forbidden otherwise.", - "operationId": "DeleteCampfireLine", + "description": "Delete a chatbot", + "operationId": "DeleteChatbot", "parameters": [ { "name": "accountId", @@ -4695,7 +4592,7 @@ "required": true }, { - "name": "lineId", + "name": "chatbotId", "in": "path", "schema": { "type": "integer", @@ -4706,7 +4603,7 @@ ], "responses": { "204": { - "description": "DeleteCampfireLine 204 response" + "description": "DeleteChatbot 204 response" }, "401": { "description": "UnauthorizedError 401 response", @@ -4766,8 +4663,8 @@ } }, "get": { - "description": "Get a campfire line by ID", - "operationId": "GetCampfireLine", + "description": "Get a chatbot by ID", + "operationId": "GetChatbot", "parameters": [ { "name": "accountId", @@ -4790,7 +4687,7 @@ "required": true }, { - "name": "lineId", + "name": "chatbotId", "in": "path", "schema": { "type": "integer", @@ -4801,11 +4698,11 @@ ], "responses": { "200": { - "description": "GetCampfireLine 200 response", + "description": "GetChatbot 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetCampfireLineResponseContent" + "$ref": "#/components/schemas/GetChatbotResponseContent" } } } @@ -4865,13 +4762,13 @@ } }, "put": { - "description": "Update an existing campfire line; the content is always treated as rich text (HTML).\nThe server coerces every edited line to rich text and ignores any content\ntype hint. Only the line's creator may edit it, and only text and\nrich-text lines are editable.", - "operationId": "UpdateCampfireLine", + "description": "Update an existing chatbot", + "operationId": "UpdateChatbot", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateCampfireLineRequestContent" + "$ref": "#/components/schemas/UpdateChatbotRequestContent" } } }, @@ -4899,7 +4796,7 @@ "required": true }, { - "name": "lineId", + "name": "chatbotId", "in": "path", "schema": { "type": "integer", @@ -4909,8 +4806,15 @@ } ], "responses": { - "204": { - "description": "UpdateCampfireLine 204 response" + "200": { + "description": "UpdateChatbot 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateChatbotResponseContent" + } + } + } }, "401": { "description": "UnauthorizedError 401 response", @@ -4952,16 +4856,6 @@ } } }, - "429": { - "description": "RateLimitError 429 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" - } - } - } - }, "500": { "description": "InternalServerError 500 response", "content": { @@ -4990,10 +4884,10 @@ } } }, - "/{accountId}/chats/{campfireId}/uploads.json": { + "/{accountId}/chats/{campfireId}/lines.json": { "get": { - "description": "List uploaded files in a campfire\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", - "operationId": "ListCampfireUploads", + "description": "List all lines (messages) in a campfire\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", + "operationId": "ListCampfireLines", "parameters": [ { "name": "accountId", @@ -5036,11 +4930,11 @@ ], "responses": { "200": { - "description": "ListCampfireUploads 200 response", + "description": "ListCampfireLines 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListCampfireUploadsResponseContent" + "$ref": "#/components/schemas/ListCampfireLinesResponseContent" } } } @@ -5105,13 +4999,13 @@ } }, "post": { - "description": "Upload a file to a campfire", - "operationId": "CreateCampfireUpload", + "description": "Create a new line (message) in a campfire", + "operationId": "CreateCampfireLine", "requestBody": { "content": { - "application/octet-stream": { + "application/json": { "schema": { - "$ref": "#/components/schemas/CreateCampfireUploadInputPayload" + "$ref": "#/components/schemas/CreateCampfireLineRequestContent" } } }, @@ -5137,25 +5031,15 @@ "format": "int64" }, "required": true - }, - { - "name": "name", - "in": "query", - "description": "Filename for the uploaded file (e.g. \"report.pdf\").", - "schema": { - "type": "string", - "description": "Filename for the uploaded file (e.g. \"report.pdf\")." - }, - "required": true } ], "responses": { "201": { - "description": "CreateCampfireUpload 201 response", + "description": "CreateCampfireLine 201 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateCampfireUploadResponseContent" + "$ref": "#/components/schemas/CreateCampfireLineResponseContent" } } } @@ -5215,8 +5099,8 @@ "Campfire" ], "x-basecamp-retry": { - "maxAttempts": 3, - "baseDelayMs": 2000, + "maxAttempts": 2, + "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, @@ -5225,10 +5109,10 @@ } } }, - "/{accountId}/checkins.json": { - "get": { - "description": "Get every automatic check-in answer across all accessible projects,\nnewest-first (paginated). Each item embeds its `bucket`.", - "operationId": "GetEverythingCheckins", + "/{accountId}/chats/{campfireId}/lines/{lineId}": { + "delete": { + "description": "Delete a campfire line; allowed for the line's creator or an admin.\nThe API responds 403 Forbidden otherwise.", + "operationId": "DeleteCampfireLine", "parameters": [ { "name": "accountId", @@ -5240,18 +5124,29 @@ "description": "Basecamp account ID (numeric string)" }, "required": true + }, + { + "name": "campfireId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true + }, + { + "name": "lineId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true } ], "responses": { - "200": { - "description": "GetEverythingCheckins 200 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/GetEverythingCheckinsResponseContent" - } - } - } + "204": { + "description": "DeleteCampfireLine 204 response" }, "401": { "description": "UnauthorizedError 401 response", @@ -5273,12 +5168,12 @@ } } }, - "429": { - "description": "RateLimitError 429 response", + "404": { + "description": "NotFoundError 404 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" } } } @@ -5295,12 +5190,10 @@ } }, "tags": [ - "Everything" + "Campfire" ], - "x-basecamp-pagination": { - "style": "link", - "totalCountHeader": "X-Total-Count", - "maxPageSize": 50 + "x-basecamp-idempotent": { + "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, @@ -5311,12 +5204,10 @@ 503 ] } - } - }, - "/{accountId}/circles/people.json": { + }, "get": { - "description": "List all account users who can be pinged\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", - "operationId": "ListPingablePeople", + "description": "Get a campfire line by ID", + "operationId": "GetCampfireLine", "parameters": [ { "name": "accountId", @@ -5328,15 +5219,33 @@ "description": "Basecamp account ID (numeric string)" }, "required": true + }, + { + "name": "campfireId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true + }, + { + "name": "lineId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true } ], "responses": { "200": { - "description": "ListPingablePeople 200 response", + "description": "GetCampfireLine 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListPingablePeopleResponseContent" + "$ref": "#/components/schemas/GetCampfireLineResponseContent" } } } @@ -5361,12 +5270,12 @@ } } }, - "429": { - "description": "RateLimitError 429 response", + "404": { + "description": "NotFoundError 404 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" } } } @@ -5383,13 +5292,8 @@ } }, "tags": [ - "People" + "Campfire" ], - "x-basecamp-pagination": { - "style": "link", - "totalCountHeader": "X-Total-Count", - "maxPageSize": 50 - }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -5399,12 +5303,20 @@ 503 ] } - } - }, - "/{accountId}/client/approvals.json": { - "get": { - "description": "List all client approvals in a project\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", - "operationId": "ListClientApprovals", + }, + "put": { + "description": "Update an existing campfire line; the content is always treated as rich text (HTML).\nThe server coerces every edited line to rich text and ignores any content\ntype hint. Only the line's creator may edit it, and only text and\nrich-text lines are editable.", + "operationId": "UpdateCampfireLine", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateCampfireLineRequestContent" + } + } + }, + "required": true + }, "parameters": [ { "name": "accountId", @@ -5418,34 +5330,27 @@ "required": true }, { - "name": "sort", - "in": "query", - "description": "created_at|updated_at", + "name": "campfireId", + "in": "path", "schema": { - "type": "string", - "description": "created_at|updated_at" - } + "type": "integer", + "format": "int64" + }, + "required": true }, { - "name": "direction", - "in": "query", - "description": "asc|desc", + "name": "lineId", + "in": "path", "schema": { - "type": "string", - "description": "asc|desc" - } + "type": "integer", + "format": "int64" + }, + "required": true } ], "responses": { - "200": { - "description": "ListClientApprovals 200 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ListClientApprovalsResponseContent" - } - } - } + "204": { + "description": "UpdateCampfireLine 204 response" }, "401": { "description": "UnauthorizedError 401 response", @@ -5467,6 +5372,26 @@ } } }, + "404": { + "description": "NotFoundError 404 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotFoundErrorResponseContent" + } + } + } + }, + "422": { + "description": "ValidationError 422 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponseContent" + } + } + } + }, "429": { "description": "RateLimitError 429 response", "content": { @@ -5489,12 +5414,10 @@ } }, "tags": [ - "ClientFeatures" + "Campfire" ], - "x-basecamp-pagination": { - "style": "link", - "totalCountHeader": "X-Total-Count", - "maxPageSize": 50 + "x-basecamp-idempotent": { + "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, @@ -5507,10 +5430,10 @@ } } }, - "/{accountId}/client/approvals/{approvalId}": { + "/{accountId}/chats/{campfireId}/uploads.json": { "get": { - "description": "Get a single client approval by id", - "operationId": "GetClientApproval", + "description": "List uploaded files in a campfire\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", + "operationId": "ListCampfireUploads", "parameters": [ { "name": "accountId", @@ -5524,22 +5447,40 @@ "required": true }, { - "name": "approvalId", + "name": "campfireId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true + }, + { + "name": "sort", + "in": "query", + "description": "created_at|updated_at", + "schema": { + "type": "string", + "description": "created_at|updated_at" + } + }, + { + "name": "direction", + "in": "query", + "description": "asc|desc", + "schema": { + "type": "string", + "description": "asc|desc" + } } ], "responses": { "200": { - "description": "GetClientApproval 200 response", + "description": "ListCampfireUploads 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetClientApprovalResponseContent" + "$ref": "#/components/schemas/ListCampfireUploadsResponseContent" } } } @@ -5564,12 +5505,12 @@ } } }, - "404": { - "description": "NotFoundError 404 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -5586,8 +5527,13 @@ } }, "tags": [ - "ClientFeatures" + "Campfire" ], + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -5597,12 +5543,20 @@ 503 ] } - } - }, - "/{accountId}/client/correspondences.json": { - "get": { - "description": "List all client correspondences in a project\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", - "operationId": "ListClientCorrespondences", + }, + "post": { + "description": "Upload a file to a campfire", + "operationId": "CreateCampfireUpload", + "requestBody": { + "content": { + "application/octet-stream": { + "schema": { + "$ref": "#/components/schemas/CreateCampfireUploadInputPayload" + } + } + }, + "required": true + }, "parameters": [ { "name": "accountId", @@ -5616,31 +5570,32 @@ "required": true }, { - "name": "sort", - "in": "query", - "description": "created_at|updated_at", + "name": "campfireId", + "in": "path", "schema": { - "type": "string", - "description": "created_at|updated_at" - } + "type": "integer", + "format": "int64" + }, + "required": true }, { - "name": "direction", + "name": "name", "in": "query", - "description": "asc|desc", + "description": "Filename for the uploaded file (e.g. \"report.pdf\").", "schema": { "type": "string", - "description": "asc|desc" - } + "description": "Filename for the uploaded file (e.g. \"report.pdf\")." + }, + "required": true } ], "responses": { - "200": { - "description": "ListClientCorrespondences 200 response", + "201": { + "description": "CreateCampfireUpload 201 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListClientCorrespondencesResponseContent" + "$ref": "#/components/schemas/CreateCampfireUploadResponseContent" } } } @@ -5665,6 +5620,16 @@ } } }, + "422": { + "description": "ValidationError 422 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponseContent" + } + } + } + }, "429": { "description": "RateLimitError 429 response", "content": { @@ -5687,16 +5652,11 @@ } }, "tags": [ - "ClientFeatures" + "Campfire" ], - "x-basecamp-pagination": { - "style": "link", - "totalCountHeader": "X-Total-Count", - "maxPageSize": 50 - }, "x-basecamp-retry": { "maxAttempts": 3, - "baseDelayMs": 1000, + "baseDelayMs": 2000, "backoff": "exponential", "retryOn": [ 429, @@ -5705,10 +5665,10 @@ } } }, - "/{accountId}/client/correspondences/{correspondenceId}": { + "/{accountId}/checkins.json": { "get": { - "description": "Get a single client correspondence by id", - "operationId": "GetClientCorrespondence", + "description": "Get every automatic check-in answer across all accessible projects,\nnewest-first (paginated). Each item embeds its `bucket`.", + "operationId": "GetEverythingCheckins", "parameters": [ { "name": "accountId", @@ -5720,24 +5680,15 @@ "description": "Basecamp account ID (numeric string)" }, "required": true - }, - { - "name": "correspondenceId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true } ], "responses": { "200": { - "description": "GetClientCorrespondence 200 response", + "description": "GetEverythingCheckins 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetClientCorrespondenceResponseContent" + "$ref": "#/components/schemas/GetEverythingCheckinsResponseContent" } } } @@ -5762,12 +5713,12 @@ } } }, - "404": { - "description": "NotFoundError 404 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -5784,8 +5735,13 @@ } }, "tags": [ - "ClientFeatures" + "Everything" ], + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -5797,10 +5753,10 @@ } } }, - "/{accountId}/client/recordings/{recordingId}/replies.json": { + "/{accountId}/circles/people.json": { "get": { - "description": "List all client replies for a recording (correspondence or approval)\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", - "operationId": "ListClientReplies", + "description": "List all account users who can be pinged\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", + "operationId": "ListPingablePeople", "parameters": [ { "name": "accountId", @@ -5812,24 +5768,15 @@ "description": "Basecamp account ID (numeric string)" }, "required": true - }, - { - "name": "recordingId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true } ], "responses": { "200": { - "description": "ListClientReplies 200 response", + "description": "ListPingablePeople 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListClientRepliesResponseContent" + "$ref": "#/components/schemas/ListPingablePeopleResponseContent" } } } @@ -5876,7 +5823,7 @@ } }, "tags": [ - "ClientFeatures" + "People" ], "x-basecamp-pagination": { "style": "link", @@ -5894,10 +5841,10 @@ } } }, - "/{accountId}/client/recordings/{recordingId}/replies/{replyId}": { + "/{accountId}/client/approvals.json": { "get": { - "description": "Get a single client reply by id", - "operationId": "GetClientReply", + "description": "List all client approvals in a project\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", + "operationId": "ListClientApprovals", "parameters": [ { "name": "accountId", @@ -5911,31 +5858,31 @@ "required": true }, { - "name": "recordingId", - "in": "path", + "name": "sort", + "in": "query", + "description": "created_at|updated_at", "schema": { - "type": "integer", - "format": "int64" - }, - "required": true + "type": "string", + "description": "created_at|updated_at" + } }, { - "name": "replyId", - "in": "path", + "name": "direction", + "in": "query", + "description": "asc|desc", "schema": { - "type": "integer", - "format": "int64" - }, - "required": true + "type": "string", + "description": "asc|desc" + } } ], "responses": { "200": { - "description": "GetClientReply 200 response", + "description": "ListClientApprovals 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetClientReplyResponseContent" + "$ref": "#/components/schemas/ListClientApprovalsResponseContent" } } } @@ -5960,12 +5907,12 @@ } } }, - "404": { - "description": "NotFoundError 404 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -5984,6 +5931,11 @@ "tags": [ "ClientFeatures" ], + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -5995,10 +5947,10 @@ } } }, - "/{accountId}/comments.json": { + "/{accountId}/client/approvals/{approvalId}": { "get": { - "description": "Get every comment across all accessible projects, newest-first (paginated).\nEach item embeds its `bucket`.", - "operationId": "GetEverythingComments", + "description": "Get a single client approval by id", + "operationId": "GetClientApproval", "parameters": [ { "name": "accountId", @@ -6010,15 +5962,24 @@ "description": "Basecamp account ID (numeric string)" }, "required": true + }, + { + "name": "approvalId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true } ], "responses": { "200": { - "description": "GetEverythingComments 200 response", + "description": "GetClientApproval 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetEverythingCommentsResponseContent" + "$ref": "#/components/schemas/GetClientApprovalResponseContent" } } } @@ -6043,12 +6004,12 @@ } } }, - "429": { - "description": "RateLimitError 429 response", + "404": { + "description": "NotFoundError 404 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" } } } @@ -6065,13 +6026,8 @@ } }, "tags": [ - "Everything" + "ClientFeatures" ], - "x-basecamp-pagination": { - "style": "link", - "totalCountHeader": "X-Total-Count", - "maxPageSize": 50 - }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -6083,10 +6039,10 @@ } } }, - "/{accountId}/comments/{commentId}": { + "/{accountId}/client/correspondences.json": { "get": { - "description": "Get a single comment by id", - "operationId": "GetComment", + "description": "List all client correspondences in a project\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", + "operationId": "ListClientCorrespondences", "parameters": [ { "name": "accountId", @@ -6100,22 +6056,31 @@ "required": true }, { - "name": "commentId", - "in": "path", + "name": "sort", + "in": "query", + "description": "created_at|updated_at", "schema": { - "type": "integer", - "format": "int64" - }, - "required": true + "type": "string", + "description": "created_at|updated_at" + } + }, + { + "name": "direction", + "in": "query", + "description": "asc|desc", + "schema": { + "type": "string", + "description": "asc|desc" + } } ], "responses": { "200": { - "description": "GetComment 200 response", + "description": "ListClientCorrespondences 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetCommentResponseContent" + "$ref": "#/components/schemas/ListClientCorrespondencesResponseContent" } } } @@ -6140,12 +6105,12 @@ } } }, - "404": { - "description": "NotFoundError 404 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -6162,8 +6127,13 @@ } }, "tags": [ - "Messages" + "ClientFeatures" ], + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -6173,20 +6143,12 @@ 503 ] } - }, - "put": { - "description": "Update an existing comment", - "operationId": "UpdateComment", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateCommentRequestContent" - } - } - }, - "required": true - }, + } + }, + "/{accountId}/client/correspondences/{correspondenceId}": { + "get": { + "description": "Get a single client correspondence by id", + "operationId": "GetClientCorrespondence", "parameters": [ { "name": "accountId", @@ -6200,7 +6162,7 @@ "required": true }, { - "name": "commentId", + "name": "correspondenceId", "in": "path", "schema": { "type": "integer", @@ -6211,11 +6173,11 @@ ], "responses": { "200": { - "description": "UpdateComment 200 response", + "description": "GetClientCorrespondence 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateCommentResponseContent" + "$ref": "#/components/schemas/GetClientCorrespondenceResponseContent" } } } @@ -6250,16 +6212,6 @@ } } }, - "422": { - "description": "ValidationError 422 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" - } - } - } - }, "500": { "description": "InternalServerError 500 response", "content": { @@ -6272,11 +6224,8 @@ } }, "tags": [ - "Messages" + "ClientFeatures" ], - "x-basecamp-idempotent": { - "natural": true - }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -6288,10 +6237,10 @@ } } }, - "/{accountId}/dock/tools/{toolId}": { - "delete": { - "description": "Delete a tool (trash it)", - "operationId": "DeleteTool", + "/{accountId}/client/recordings/{recordingId}/replies.json": { + "get": { + "description": "List all client replies for a recording (correspondence or approval)\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", + "operationId": "ListClientReplies", "parameters": [ { "name": "accountId", @@ -6305,7 +6254,7 @@ "required": true }, { - "name": "toolId", + "name": "recordingId", "in": "path", "schema": { "type": "integer", @@ -6315,8 +6264,15 @@ } ], "responses": { - "204": { - "description": "DeleteTool 204 response" + "200": { + "description": "ListClientReplies 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListClientRepliesResponseContent" + } + } + } }, "401": { "description": "UnauthorizedError 401 response", @@ -6338,12 +6294,12 @@ } } }, - "404": { - "description": "NotFoundError 404 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -6360,10 +6316,12 @@ } }, "tags": [ - "Automation" + "ClientFeatures" ], - "x-basecamp-idempotent": { - "natural": true + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 }, "x-basecamp-retry": { "maxAttempts": 3, @@ -6374,10 +6332,12 @@ 503 ] } - }, + } + }, + "/{accountId}/client/recordings/{recordingId}/replies/{replyId}": { "get": { - "description": "Get a dock tool by id", - "operationId": "GetTool", + "description": "Get a single client reply by id", + "operationId": "GetClientReply", "parameters": [ { "name": "accountId", @@ -6391,7 +6351,16 @@ "required": true }, { - "name": "toolId", + "name": "recordingId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true + }, + { + "name": "replyId", "in": "path", "schema": { "type": "integer", @@ -6402,11 +6371,11 @@ ], "responses": { "200": { - "description": "GetTool 200 response", + "description": "GetClientReply 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetToolResponseContent" + "$ref": "#/components/schemas/GetClientReplyResponseContent" } } } @@ -6453,7 +6422,7 @@ } }, "tags": [ - "Automation" + "ClientFeatures" ], "x-basecamp-retry": { "maxAttempts": 3, @@ -6464,20 +6433,12 @@ 503 ] } - }, - "put": { - "description": "Update (rename) an existing tool", - "operationId": "UpdateTool", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateToolRequestContent" - } - } - }, - "required": true - }, + } + }, + "/{accountId}/comments.json": { + "get": { + "description": "Get every comment across all accessible projects, newest-first (paginated).\nEach item embeds its `bucket`.", + "operationId": "GetEverythingComments", "parameters": [ { "name": "accountId", @@ -6489,24 +6450,15 @@ "description": "Basecamp account ID (numeric string)" }, "required": true - }, - { - "name": "toolId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true } ], "responses": { "200": { - "description": "UpdateTool 200 response", + "description": "GetEverythingComments 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateToolResponseContent" + "$ref": "#/components/schemas/GetEverythingCommentsResponseContent" } } } @@ -6531,22 +6483,12 @@ } } }, - "404": { - "description": "NotFoundError 404 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" - } - } - } - }, - "422": { - "description": "ValidationError 422 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -6563,10 +6505,12 @@ } }, "tags": [ - "Automation" + "Everything" ], - "x-basecamp-idempotent": { - "natural": true + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 }, "x-basecamp-retry": { "maxAttempts": 3, @@ -6579,10 +6523,10 @@ } } }, - "/{accountId}/documents/{documentId}": { + "/{accountId}/comments/{commentId}": { "get": { - "description": "Get a single document by id", - "operationId": "GetDocument", + "description": "Get a single comment by id", + "operationId": "GetComment", "parameters": [ { "name": "accountId", @@ -6596,7 +6540,7 @@ "required": true }, { - "name": "documentId", + "name": "commentId", "in": "path", "schema": { "type": "integer", @@ -6607,11 +6551,11 @@ ], "responses": { "200": { - "description": "GetDocument 200 response", + "description": "GetComment 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetDocumentResponseContent" + "$ref": "#/components/schemas/GetCommentResponseContent" } } } @@ -6658,7 +6602,7 @@ } }, "tags": [ - "Files" + "Messages" ], "x-basecamp-retry": { "maxAttempts": 3, @@ -6671,16 +6615,17 @@ } }, "put": { - "description": "Update an existing document", - "operationId": "UpdateDocument", + "description": "Update an existing comment", + "operationId": "UpdateComment", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateDocumentRequestContent" + "$ref": "#/components/schemas/UpdateCommentRequestContent" } } - } + }, + "required": true }, "parameters": [ { @@ -6695,7 +6640,7 @@ "required": true }, { - "name": "documentId", + "name": "commentId", "in": "path", "schema": { "type": "integer", @@ -6706,11 +6651,11 @@ ], "responses": { "200": { - "description": "UpdateDocument 200 response", + "description": "UpdateComment 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateDocumentResponseContent" + "$ref": "#/components/schemas/UpdateCommentResponseContent" } } } @@ -6767,7 +6712,7 @@ } }, "tags": [ - "Files" + "Messages" ], "x-basecamp-idempotent": { "natural": true @@ -6783,10 +6728,10 @@ } } }, - "/{accountId}/files.json": { - "get": { - "description": "Get every file recording across all accessible projects, newest-first\n(paginated). Heterogeneous: uploads and Basecamp documents carry their\nstandard recording shapes, while rich-text attachments are wrapped in a\nrecording envelope plus an `attachable_sgid` and blob metadata. Modeled as\nan optional-field superset (EverythingFile) so one element type decodes any\nvariant.", - "operationId": "GetEverythingFiles", + "/{accountId}/dock/tools/{toolId}": { + "delete": { + "description": "Delete a tool (trash it)", + "operationId": "DeleteTool", "parameters": [ { "name": "accountId", @@ -6800,41 +6745,18 @@ "required": true }, { - "name": "kind", - "in": "query", - "description": "Filter by file kind: all (default), images, pdfs, documents, or videos.", - "schema": { - "type": "string", - "description": "Filter by file kind: all (default), images, pdfs, documents, or videos." - } - }, - { - "name": "people_ids[]", - "in": "query", - "description": "Restrict to files created by the given people (repeatable).", - "style": "form", + "name": "toolId", + "in": "path", "schema": { - "type": "array", - "items": { - "type": "integer", - "format": "int64" - }, - "description": "Restrict to files created by the given people (repeatable).", - "x-go-type-skip-optional-pointer": false + "type": "integer", + "format": "int64" }, - "explode": true + "required": true } ], "responses": { - "200": { - "description": "GetEverythingFiles 200 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/GetEverythingFilesResponseContent" - } - } - } + "204": { + "description": "DeleteTool 204 response" }, "401": { "description": "UnauthorizedError 401 response", @@ -6856,12 +6778,12 @@ } } }, - "429": { - "description": "RateLimitError 429 response", + "404": { + "description": "NotFoundError 404 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" } } } @@ -6878,12 +6800,10 @@ } }, "tags": [ - "Everything" + "Automation" ], - "x-basecamp-pagination": { - "style": "link", - "totalCountHeader": "X-Total-Count", - "maxPageSize": 50 + "x-basecamp-idempotent": { + "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, @@ -6894,12 +6814,10 @@ 503 ] } - } - }, - "/{accountId}/forwards.json": { + }, "get": { - "description": "Get every inbox forward across all accessible projects, newest-first\n(paginated). Each item embeds its `bucket`.", - "operationId": "GetEverythingForwards", + "description": "Get a dock tool by id", + "operationId": "GetTool", "parameters": [ { "name": "accountId", @@ -6911,15 +6829,24 @@ "description": "Basecamp account ID (numeric string)" }, "required": true + }, + { + "name": "toolId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true } ], "responses": { "200": { - "description": "GetEverythingForwards 200 response", + "description": "GetTool 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetEverythingForwardsResponseContent" + "$ref": "#/components/schemas/GetToolResponseContent" } } } @@ -6944,12 +6871,12 @@ } } }, - "429": { - "description": "RateLimitError 429 response", + "404": { + "description": "NotFoundError 404 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" } } } @@ -6966,13 +6893,8 @@ } }, "tags": [ - "Everything" + "Automation" ], - "x-basecamp-pagination": { - "style": "link", - "totalCountHeader": "X-Total-Count", - "maxPageSize": 50 - }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -6982,12 +6904,20 @@ 503 ] } - } - }, - "/{accountId}/gauge_needles/{needleId}": { - "delete": { - "description": "Destroy a gauge needle", - "operationId": "DestroyGaugeNeedle", + }, + "put": { + "description": "Update (rename) an existing tool", + "operationId": "UpdateTool", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateToolRequestContent" + } + } + }, + "required": true + }, "parameters": [ { "name": "accountId", @@ -7001,7 +6931,7 @@ "required": true }, { - "name": "needleId", + "name": "toolId", "in": "path", "schema": { "type": "integer", @@ -7011,8 +6941,15 @@ } ], "responses": { - "204": { - "description": "DestroyGaugeNeedle 204 response" + "200": { + "description": "UpdateTool 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateToolResponseContent" + } + } + } }, "401": { "description": "UnauthorizedError 401 response", @@ -7044,12 +6981,12 @@ } } }, - "429": { - "description": "RateLimitError 429 response", + "422": { + "description": "ValidationError 422 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" + "$ref": "#/components/schemas/ValidationErrorResponseContent" } } } @@ -7066,13 +7003,13 @@ } }, "tags": [ - "Gauges" + "Automation" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { - "maxAttempts": 2, + "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -7080,10 +7017,12 @@ 503 ] } - }, + } + }, + "/{accountId}/documents/{documentId}": { "get": { - "description": "Get a gauge needle by ID", - "operationId": "GetGaugeNeedle", + "description": "Get a single document by id", + "operationId": "GetDocument", "parameters": [ { "name": "accountId", @@ -7097,7 +7036,7 @@ "required": true }, { - "name": "needleId", + "name": "documentId", "in": "path", "schema": { "type": "integer", @@ -7108,11 +7047,11 @@ ], "responses": { "200": { - "description": "GetGaugeNeedle 200 response", + "description": "GetDocument 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetGaugeNeedleResponseContent" + "$ref": "#/components/schemas/GetDocumentResponseContent" } } } @@ -7159,7 +7098,7 @@ } }, "tags": [ - "Gauges" + "Files" ], "x-basecamp-retry": { "maxAttempts": 3, @@ -7172,13 +7111,13 @@ } }, "put": { - "description": "Update a gauge needle's description. Position and color are immutable.", - "operationId": "UpdateGaugeNeedle", + "description": "Update an existing document", + "operationId": "UpdateDocument", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateGaugeNeedleRequestContent" + "$ref": "#/components/schemas/UpdateDocumentRequestContent" } } } @@ -7196,7 +7135,7 @@ "required": true }, { - "name": "needleId", + "name": "documentId", "in": "path", "schema": { "type": "integer", @@ -7207,11 +7146,11 @@ ], "responses": { "200": { - "description": "UpdateGaugeNeedle 200 response", + "description": "UpdateDocument 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateGaugeNeedleResponseContent" + "$ref": "#/components/schemas/UpdateDocumentResponseContent" } } } @@ -7256,16 +7195,6 @@ } } }, - "429": { - "description": "RateLimitError 429 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" - } - } - } - }, "500": { "description": "InternalServerError 500 response", "content": { @@ -7278,13 +7207,13 @@ } }, "tags": [ - "Gauges" + "Files" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { - "maxAttempts": 2, + "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -7294,10 +7223,10 @@ } } }, - "/{accountId}/inbox_forwards/{forwardId}": { + "/{accountId}/files.json": { "get": { - "description": "Get a forward by ID", - "operationId": "GetForward", + "description": "Get every file recording across all accessible projects, newest-first\n(paginated). Heterogeneous: uploads and Basecamp documents carry their\nstandard recording shapes, while rich-text attachments are wrapped in a\nrecording envelope plus an `attachable_sgid` and blob metadata. Modeled as\nan optional-field superset (EverythingFile) so one element type decodes any\nvariant.", + "operationId": "GetEverythingFiles", "parameters": [ { "name": "accountId", @@ -7311,22 +7240,38 @@ "required": true }, { - "name": "forwardId", - "in": "path", + "name": "kind", + "in": "query", + "description": "Filter by file kind: all (default), images, pdfs, documents, or videos.", "schema": { - "type": "integer", - "format": "int64" + "type": "string", + "description": "Filter by file kind: all (default), images, pdfs, documents, or videos." + } + }, + { + "name": "people_ids[]", + "in": "query", + "description": "Restrict to files created by the given people (repeatable).", + "style": "form", + "schema": { + "type": "array", + "items": { + "type": "integer", + "format": "int64" + }, + "description": "Restrict to files created by the given people (repeatable).", + "x-go-type-skip-optional-pointer": false }, - "required": true + "explode": true } ], "responses": { "200": { - "description": "GetForward 200 response", + "description": "GetEverythingFiles 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetForwardResponseContent" + "$ref": "#/components/schemas/GetEverythingFilesResponseContent" } } } @@ -7351,12 +7296,12 @@ } } }, - "404": { - "description": "NotFoundError 404 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -7373,8 +7318,13 @@ } }, "tags": [ - "Forwards" + "Everything" ], + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -7386,10 +7336,10 @@ } } }, - "/{accountId}/inbox_forwards/{forwardId}/replies.json": { + "/{accountId}/forwards.json": { "get": { - "description": "List all replies to a forward\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", - "operationId": "ListForwardReplies", + "description": "Get every inbox forward across all accessible projects, newest-first\n(paginated). Each item embeds its `bucket`.", + "operationId": "GetEverythingForwards", "parameters": [ { "name": "accountId", @@ -7401,24 +7351,15 @@ "description": "Basecamp account ID (numeric string)" }, "required": true - }, - { - "name": "forwardId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true } ], "responses": { "200": { - "description": "ListForwardReplies 200 response", + "description": "GetEverythingForwards 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListForwardRepliesResponseContent" + "$ref": "#/components/schemas/GetEverythingForwardsResponseContent" } } } @@ -7465,7 +7406,7 @@ } }, "tags": [ - "Forwards" + "Everything" ], "x-basecamp-pagination": { "style": "link", @@ -7481,20 +7422,12 @@ 503 ] } - }, - "post": { - "description": "Create a reply to a forward", - "operationId": "CreateForwardReply", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateForwardReplyRequestContent" - } - } - }, - "required": true - }, + } + }, + "/{accountId}/gauge_needles/{needleId}": { + "delete": { + "description": "Destroy a gauge needle", + "operationId": "DestroyGaugeNeedle", "parameters": [ { "name": "accountId", @@ -7508,7 +7441,7 @@ "required": true }, { - "name": "forwardId", + "name": "needleId", "in": "path", "schema": { "type": "integer", @@ -7518,15 +7451,8 @@ } ], "responses": { - "201": { - "description": "CreateForwardReply 201 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateForwardReplyResponseContent" - } - } - } + "204": { + "description": "DestroyGaugeNeedle 204 response" }, "401": { "description": "UnauthorizedError 401 response", @@ -7548,12 +7474,12 @@ } } }, - "422": { - "description": "ValidationError 422 response", + "404": { + "description": "NotFoundError 404 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" } } } @@ -7580,9 +7506,12 @@ } }, "tags": [ - "Forwards" + "Gauges" ], - "x-basecamp-retry": { + "x-basecamp-idempotent": { + "natural": true + }, + "x-basecamp-retry": { "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", @@ -7591,12 +7520,10 @@ 503 ] } - } - }, - "/{accountId}/inbox_forwards/{forwardId}/replies/{replyId}": { + }, "get": { - "description": "Get a forward reply by ID", - "operationId": "GetForwardReply", + "description": "Get a gauge needle by ID", + "operationId": "GetGaugeNeedle", "parameters": [ { "name": "accountId", @@ -7610,16 +7537,7 @@ "required": true }, { - "name": "forwardId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true - }, - { - "name": "replyId", + "name": "needleId", "in": "path", "schema": { "type": "integer", @@ -7630,11 +7548,11 @@ ], "responses": { "200": { - "description": "GetForwardReply 200 response", + "description": "GetGaugeNeedle 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetForwardReplyResponseContent" + "$ref": "#/components/schemas/GetGaugeNeedleResponseContent" } } } @@ -7681,7 +7599,7 @@ } }, "tags": [ - "Forwards" + "Gauges" ], "x-basecamp-retry": { "maxAttempts": 3, @@ -7692,12 +7610,19 @@ 503 ] } - } - }, - "/{accountId}/inboxes/{inboxId}": { - "get": { - "description": "Get an inbox by ID", - "operationId": "GetInbox", + }, + "put": { + "description": "Update a gauge needle's description. Position and color are immutable.", + "operationId": "UpdateGaugeNeedle", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateGaugeNeedleRequestContent" + } + } + } + }, "parameters": [ { "name": "accountId", @@ -7711,7 +7636,7 @@ "required": true }, { - "name": "inboxId", + "name": "needleId", "in": "path", "schema": { "type": "integer", @@ -7722,11 +7647,11 @@ ], "responses": { "200": { - "description": "GetInbox 200 response", + "description": "UpdateGaugeNeedle 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetInboxResponseContent" + "$ref": "#/components/schemas/UpdateGaugeNeedleResponseContent" } } } @@ -7761,6 +7686,26 @@ } } }, + "422": { + "description": "ValidationError 422 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponseContent" + } + } + } + }, + "429": { + "description": "RateLimitError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RateLimitErrorResponseContent" + } + } + } + }, "500": { "description": "InternalServerError 500 response", "content": { @@ -7773,10 +7718,13 @@ } }, "tags": [ - "Forwards" + "Gauges" ], + "x-basecamp-idempotent": { + "natural": true + }, "x-basecamp-retry": { - "maxAttempts": 3, + "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -7786,10 +7734,10 @@ } } }, - "/{accountId}/inboxes/{inboxId}/forwards.json": { + "/{accountId}/inbox_forwards/{forwardId}": { "get": { - "description": "List all forwards in an inbox\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", - "operationId": "ListForwards", + "description": "Get a forward by ID", + "operationId": "GetForward", "parameters": [ { "name": "accountId", @@ -7803,40 +7751,22 @@ "required": true }, { - "name": "inboxId", + "name": "forwardId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true - }, - { - "name": "sort", - "in": "query", - "description": "created_at|updated_at", - "schema": { - "type": "string", - "description": "created_at|updated_at" - } - }, - { - "name": "direction", - "in": "query", - "description": "asc|desc", - "schema": { - "type": "string", - "description": "asc|desc" - } } ], "responses": { "200": { - "description": "ListForwards 200 response", + "description": "GetForward 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListForwardsResponseContent" + "$ref": "#/components/schemas/GetForwardResponseContent" } } } @@ -7861,12 +7791,12 @@ } } }, - "429": { - "description": "RateLimitError 429 response", + "404": { + "description": "NotFoundError 404 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" } } } @@ -7885,11 +7815,6 @@ "tags": [ "Forwards" ], - "x-basecamp-pagination": { - "style": "link", - "totalCountHeader": "X-Total-Count", - "maxPageSize": 50 - }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -7901,10 +7826,10 @@ } } }, - "/{accountId}/lineup/markers.json": { + "/{accountId}/inbox_forwards/{forwardId}/replies.json": { "get": { - "description": "List all lineup markers for the account", - "operationId": "ListLineupMarkers", + "description": "List all replies to a forward\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", + "operationId": "ListForwardReplies", "parameters": [ { "name": "accountId", @@ -7916,15 +7841,24 @@ "description": "Basecamp account ID (numeric string)" }, "required": true + }, + { + "name": "forwardId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true } ], "responses": { "200": { - "description": "ListLineupMarkers 200 response", + "description": "ListForwardReplies 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListLineupMarkersResponseContent" + "$ref": "#/components/schemas/ListForwardRepliesResponseContent" } } } @@ -7971,8 +7905,13 @@ } }, "tags": [ - "Automation" + "Forwards" ], + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -7984,13 +7923,13 @@ } }, "post": { - "description": "Create a new lineup marker", - "operationId": "CreateLineupMarker", + "description": "Create a reply to a forward", + "operationId": "CreateForwardReply", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateLineupMarkerRequestContent" + "$ref": "#/components/schemas/CreateForwardReplyRequestContent" } } }, @@ -8007,11 +7946,27 @@ "description": "Basecamp account ID (numeric string)" }, "required": true + }, + { + "name": "forwardId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true } ], "responses": { "201": { - "description": "CreateLineupMarker 201 response" + "description": "CreateForwardReply 201 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateForwardReplyResponseContent" + } + } + } }, "401": { "description": "UnauthorizedError 401 response", @@ -8065,7 +8020,7 @@ } }, "tags": [ - "Automation" + "Forwards" ], "x-basecamp-retry": { "maxAttempts": 2, @@ -8078,10 +8033,10 @@ } } }, - "/{accountId}/lineup/markers/{markerId}": { - "delete": { - "description": "Delete a lineup marker", - "operationId": "DeleteLineupMarker", + "/{accountId}/inbox_forwards/{forwardId}/replies/{replyId}": { + "get": { + "description": "Get a forward reply by ID", + "operationId": "GetForwardReply", "parameters": [ { "name": "accountId", @@ -8095,7 +8050,16 @@ "required": true }, { - "name": "markerId", + "name": "forwardId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true + }, + { + "name": "replyId", "in": "path", "schema": { "type": "integer", @@ -8105,8 +8069,15 @@ } ], "responses": { - "204": { - "description": "DeleteLineupMarker 204 response" + "200": { + "description": "GetForwardReply 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetForwardReplyResponseContent" + } + } + } }, "401": { "description": "UnauthorizedError 401 response", @@ -8150,11 +8121,8 @@ } }, "tags": [ - "Automation" + "Forwards" ], - "x-basecamp-idempotent": { - "natural": true - }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -8164,19 +8132,12 @@ 503 ] } - }, - "put": { - "description": "Update an existing lineup marker", - "operationId": "UpdateLineupMarker", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateLineupMarkerRequestContent" - } - } - } - }, + } + }, + "/{accountId}/inboxes/{inboxId}": { + "get": { + "description": "Get an inbox by ID", + "operationId": "GetInbox", "parameters": [ { "name": "accountId", @@ -8190,7 +8151,7 @@ "required": true }, { - "name": "markerId", + "name": "inboxId", "in": "path", "schema": { "type": "integer", @@ -8201,7 +8162,14 @@ ], "responses": { "200": { - "description": "UpdateLineupMarker 200 response" + "description": "GetInbox 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetInboxResponseContent" + } + } + } }, "401": { "description": "UnauthorizedError 401 response", @@ -8233,16 +8201,6 @@ } } }, - "422": { - "description": "ValidationError 422 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" - } - } - } - }, "500": { "description": "InternalServerError 500 response", "content": { @@ -8255,11 +8213,8 @@ } }, "tags": [ - "Automation" + "Forwards" ], - "x-basecamp-idempotent": { - "natural": true - }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -8271,10 +8226,10 @@ } } }, - "/{accountId}/message_boards/{boardId}": { + "/{accountId}/inboxes/{inboxId}/forwards.json": { "get": { - "description": "Get a message board", - "operationId": "GetMessageBoard", + "description": "List all forwards in an inbox\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", + "operationId": "ListForwards", "parameters": [ { "name": "accountId", @@ -8288,22 +8243,40 @@ "required": true }, { - "name": "boardId", + "name": "inboxId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true + }, + { + "name": "sort", + "in": "query", + "description": "created_at|updated_at", + "schema": { + "type": "string", + "description": "created_at|updated_at" + } + }, + { + "name": "direction", + "in": "query", + "description": "asc|desc", + "schema": { + "type": "string", + "description": "asc|desc" + } } ], "responses": { "200": { - "description": "GetMessageBoard 200 response", + "description": "ListForwards 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetMessageBoardResponseContent" + "$ref": "#/components/schemas/ListForwardsResponseContent" } } } @@ -8328,12 +8301,12 @@ } } }, - "404": { - "description": "NotFoundError 404 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -8350,8 +8323,13 @@ } }, "tags": [ - "Messages" + "Forwards" ], + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -8363,10 +8341,10 @@ } } }, - "/{accountId}/message_boards/{boardId}/messages.json": { + "/{accountId}/lineup/markers.json": { "get": { - "description": "List messages on a message board\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", - "operationId": "ListMessages", + "description": "List all lineup markers for the account", + "operationId": "ListLineupMarkers", "parameters": [ { "name": "accountId", @@ -8378,42 +8356,15 @@ "description": "Basecamp account ID (numeric string)" }, "required": true - }, - { - "name": "boardId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true - }, - { - "name": "sort", - "in": "query", - "description": "created_at|updated_at", - "schema": { - "type": "string", - "description": "created_at|updated_at" - } - }, - { - "name": "direction", - "in": "query", - "description": "asc|desc", - "schema": { - "type": "string", - "description": "asc|desc" - } } ], "responses": { "200": { - "description": "ListMessages 200 response", + "description": "ListLineupMarkers 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListMessagesResponseContent" + "$ref": "#/components/schemas/ListLineupMarkersResponseContent" } } } @@ -8460,13 +8411,8 @@ } }, "tags": [ - "Messages" + "Automation" ], - "x-basecamp-pagination": { - "style": "link", - "totalCountHeader": "X-Total-Count", - "maxPageSize": 50 - }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -8478,13 +8424,13 @@ } }, "post": { - "description": "Create a new message on a message board", - "operationId": "CreateMessage", + "description": "Create a new lineup marker", + "operationId": "CreateLineupMarker", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateMessageRequestContent" + "$ref": "#/components/schemas/CreateLineupMarkerRequestContent" } } }, @@ -8501,27 +8447,11 @@ "description": "Basecamp account ID (numeric string)" }, "required": true - }, - { - "name": "boardId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true } ], "responses": { "201": { - "description": "CreateMessage 201 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateMessageResponseContent" - } - } - } + "description": "CreateLineupMarker 201 response" }, "401": { "description": "UnauthorizedError 401 response", @@ -8575,7 +8505,7 @@ } }, "tags": [ - "Messages" + "Automation" ], "x-basecamp-retry": { "maxAttempts": 2, @@ -8588,10 +8518,10 @@ } } }, - "/{accountId}/messages.json": { - "get": { - "description": "Get every message across all accessible projects, newest-first (paginated).\nEach item embeds its `bucket` for project context.", - "operationId": "GetEverythingMessages", + "/{accountId}/lineup/markers/{markerId}": { + "delete": { + "description": "Delete a lineup marker", + "operationId": "DeleteLineupMarker", "parameters": [ { "name": "accountId", @@ -8603,18 +8533,20 @@ "description": "Basecamp account ID (numeric string)" }, "required": true + }, + { + "name": "markerId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true } ], "responses": { - "200": { - "description": "GetEverythingMessages 200 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/GetEverythingMessagesResponseContent" - } - } - } + "204": { + "description": "DeleteLineupMarker 204 response" }, "401": { "description": "UnauthorizedError 401 response", @@ -8636,12 +8568,12 @@ } } }, - "429": { - "description": "RateLimitError 429 response", + "404": { + "description": "NotFoundError 404 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" } } } @@ -8658,12 +8590,10 @@ } }, "tags": [ - "Everything" + "Automation" ], - "x-basecamp-pagination": { - "style": "link", - "totalCountHeader": "X-Total-Count", - "maxPageSize": 50 + "x-basecamp-idempotent": { + "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, @@ -8674,12 +8604,19 @@ 503 ] } - } - }, - "/{accountId}/messages/{messageId}": { - "get": { - "description": "Get a single message by id", - "operationId": "GetMessage", + }, + "put": { + "description": "Update an existing lineup marker", + "operationId": "UpdateLineupMarker", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateLineupMarkerRequestContent" + } + } + } + }, "parameters": [ { "name": "accountId", @@ -8693,7 +8630,7 @@ "required": true }, { - "name": "messageId", + "name": "markerId", "in": "path", "schema": { "type": "integer", @@ -8704,14 +8641,7 @@ ], "responses": { "200": { - "description": "GetMessage 200 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/GetMessageResponseContent" - } - } - } + "description": "UpdateLineupMarker 200 response" }, "401": { "description": "UnauthorizedError 401 response", @@ -8743,6 +8673,16 @@ } } }, + "422": { + "description": "ValidationError 422 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponseContent" + } + } + } + }, "500": { "description": "InternalServerError 500 response", "content": { @@ -8755,8 +8695,11 @@ } }, "tags": [ - "Messages" + "Automation" ], + "x-basecamp-idempotent": { + "natural": true + }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -8766,19 +8709,12 @@ 503 ] } - }, - "put": { - "description": "Update an existing message", - "operationId": "UpdateMessage", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateMessageRequestContent" - } - } - } - }, + } + }, + "/{accountId}/message_boards/{boardId}": { + "get": { + "description": "Get a message board", + "operationId": "GetMessageBoard", "parameters": [ { "name": "accountId", @@ -8792,7 +8728,7 @@ "required": true }, { - "name": "messageId", + "name": "boardId", "in": "path", "schema": { "type": "integer", @@ -8803,11 +8739,11 @@ ], "responses": { "200": { - "description": "UpdateMessage 200 response", + "description": "GetMessageBoard 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateMessageResponseContent" + "$ref": "#/components/schemas/GetMessageBoardResponseContent" } } } @@ -8842,16 +8778,6 @@ } } }, - "422": { - "description": "ValidationError 422 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" - } - } - } - }, "500": { "description": "InternalServerError 500 response", "content": { @@ -8866,9 +8792,6 @@ "tags": [ "Messages" ], - "x-basecamp-idempotent": { - "natural": true - }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -8880,10 +8803,10 @@ } } }, - "/{accountId}/my/assignments.json": { + "/{accountId}/message_boards/{boardId}/messages.json": { "get": { - "description": "Get the current user's active assignments grouped into priorities and non_priorities.\nCard table steps are normalized to their parent card with steps as children.\nThis endpoint is not paginated.", - "operationId": "GetMyAssignments", + "description": "List messages on a message board\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", + "operationId": "ListMessages", "parameters": [ { "name": "accountId", @@ -8895,21 +8818,48 @@ "description": "Basecamp account ID (numeric string)" }, "required": true - } - ], - "responses": { - "200": { - "description": "GetMyAssignments 200 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/GetMyAssignmentsResponseContent" - } - } - } }, - "401": { - "description": "UnauthorizedError 401 response", + { + "name": "boardId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true + }, + { + "name": "sort", + "in": "query", + "description": "created_at|updated_at", + "schema": { + "type": "string", + "description": "created_at|updated_at" + } + }, + { + "name": "direction", + "in": "query", + "description": "asc|desc", + "schema": { + "type": "string", + "description": "asc|desc" + } + } + ], + "responses": { + "200": { + "description": "ListMessages 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListMessagesResponseContent" + } + } + } + }, + "401": { + "description": "UnauthorizedError 401 response", "content": { "application/json": { "schema": { @@ -8928,6 +8878,16 @@ } } }, + "429": { + "description": "RateLimitError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RateLimitErrorResponseContent" + } + } + } + }, "500": { "description": "InternalServerError 500 response", "content": { @@ -8940,8 +8900,13 @@ } }, "tags": [ - "MyAssignments" + "Messages" ], + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -8951,12 +8916,20 @@ 503 ] } - } - }, - "/{accountId}/my/assignments/completed.json": { - "get": { - "description": "Get the current user's completed assignments.\nArchived and trashed recordings are excluded. This endpoint is not paginated.", - "operationId": "GetMyCompletedAssignments", + }, + "post": { + "description": "Create a new message on a message board", + "operationId": "CreateMessage", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateMessageRequestContent" + } + } + }, + "required": true + }, "parameters": [ { "name": "accountId", @@ -8968,15 +8941,24 @@ "description": "Basecamp account ID (numeric string)" }, "required": true + }, + { + "name": "boardId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true } ], "responses": { - "200": { - "description": "GetMyCompletedAssignments 200 response", + "201": { + "description": "CreateMessage 201 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetMyCompletedAssignmentsResponseContent" + "$ref": "#/components/schemas/CreateMessageResponseContent" } } } @@ -9001,6 +8983,26 @@ } } }, + "422": { + "description": "ValidationError 422 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponseContent" + } + } + } + }, + "429": { + "description": "RateLimitError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RateLimitErrorResponseContent" + } + } + } + }, "500": { "description": "InternalServerError 500 response", "content": { @@ -9013,10 +9015,10 @@ } }, "tags": [ - "MyAssignments" + "Messages" ], "x-basecamp-retry": { - "maxAttempts": 3, + "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -9026,10 +9028,10 @@ } } }, - "/{accountId}/my/assignments/due.json": { + "/{accountId}/messages.json": { "get": { - "description": "Get the current user's assignments filtered by due date scope.\nDefaults to overdue when no scope is provided. This endpoint is not paginated.", - "operationId": "GetMyDueAssignments", + "description": "Get every message across all accessible projects, newest-first (paginated).\nEach item embeds its `bucket` for project context.", + "operationId": "GetEverythingMessages", "parameters": [ { "name": "accountId", @@ -9041,54 +9043,45 @@ "description": "Basecamp account ID (numeric string)" }, "required": true - }, - { - "name": "scope", - "in": "query", - "description": "Filter by due date range: overdue, due_today, due_tomorrow,\ndue_later_this_week, due_next_week, due_later", - "schema": { - "type": "string", - "description": "Filter by due date range: overdue, due_today, due_tomorrow,\ndue_later_this_week, due_next_week, due_later" - } } ], "responses": { "200": { - "description": "GetMyDueAssignments 200 response", + "description": "GetEverythingMessages 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetMyDueAssignmentsResponseContent" + "$ref": "#/components/schemas/GetEverythingMessagesResponseContent" } } } }, - "400": { - "description": "BadRequestError 400 response", + "401": { + "description": "UnauthorizedError 401 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/BadRequestErrorResponseContent" + "$ref": "#/components/schemas/UnauthorizedErrorResponseContent" } } } }, - "401": { - "description": "UnauthorizedError 401 response", + "403": { + "description": "ForbiddenError 403 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UnauthorizedErrorResponseContent" + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" } } } }, - "403": { - "description": "ForbiddenError 403 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -9105,8 +9098,13 @@ } }, "tags": [ - "MyAssignments" + "Everything" ], + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -9118,10 +9116,10 @@ } } }, - "/{accountId}/my/preferences.json": { + "/{accountId}/messages/{messageId}": { "get": { - "description": "Get the current user's preferences", - "operationId": "GetMyPreferences", + "description": "Get a single message by id", + "operationId": "GetMessage", "parameters": [ { "name": "accountId", @@ -9133,15 +9131,24 @@ "description": "Basecamp account ID (numeric string)" }, "required": true + }, + { + "name": "messageId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true } ], "responses": { "200": { - "description": "GetMyPreferences 200 response", + "description": "GetMessage 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetMyPreferencesResponseContent" + "$ref": "#/components/schemas/GetMessageResponseContent" } } } @@ -9166,6 +9173,16 @@ } } }, + "404": { + "description": "NotFoundError 404 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotFoundErrorResponseContent" + } + } + } + }, "500": { "description": "InternalServerError 500 response", "content": { @@ -9178,7 +9195,7 @@ } }, "tags": [ - "People" + "Messages" ], "x-basecamp-retry": { "maxAttempts": 3, @@ -9191,17 +9208,16 @@ } }, "put": { - "description": "Update the current user's preferences", - "operationId": "UpdateMyPreferences", + "description": "Update an existing message", + "operationId": "UpdateMessage", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateMyPreferencesRequestContent" + "$ref": "#/components/schemas/UpdateMessageRequestContent" } } - }, - "required": true + } }, "parameters": [ { @@ -9214,15 +9230,24 @@ "description": "Basecamp account ID (numeric string)" }, "required": true + }, + { + "name": "messageId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true } ], "responses": { "200": { - "description": "UpdateMyPreferences 200 response", + "description": "UpdateMessage 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateMyPreferencesResponseContent" + "$ref": "#/components/schemas/UpdateMessageResponseContent" } } } @@ -9247,22 +9272,22 @@ } } }, - "422": { - "description": "ValidationError 422 response", + "404": { + "description": "NotFoundError 404 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" } } } }, - "429": { - "description": "RateLimitError 429 response", + "422": { + "description": "ValidationError 422 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" + "$ref": "#/components/schemas/ValidationErrorResponseContent" } } } @@ -9279,13 +9304,13 @@ } }, "tags": [ - "People" + "Messages" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { - "maxAttempts": 2, + "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -9295,10 +9320,10 @@ } } }, - "/{accountId}/my/profile.json": { + "/{accountId}/my/assignments.json": { "get": { - "description": "Get the current authenticated user's profile", - "operationId": "GetMyProfile", + "description": "Get the current user's active assignments grouped into priorities and non_priorities.\nCard table steps are normalized to their parent card with steps as children.\nThis endpoint is not paginated.", + "operationId": "GetMyAssignments", "parameters": [ { "name": "accountId", @@ -9314,11 +9339,11 @@ ], "responses": { "200": { - "description": "GetMyProfile 200 response", + "description": "GetMyAssignments 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetMyProfileResponseContent" + "$ref": "#/components/schemas/GetMyAssignmentsResponseContent" } } } @@ -9343,16 +9368,6 @@ } } }, - "404": { - "description": "NotFoundError 404 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" - } - } - } - }, "500": { "description": "InternalServerError 500 response", "content": { @@ -9365,7 +9380,7 @@ } }, "tags": [ - "People" + "MyAssignments" ], "x-basecamp-retry": { "maxAttempts": 3, @@ -9376,19 +9391,12 @@ 503 ] } - }, - "put": { - "description": "Update the current authenticated user's profile (returns 204 No Content)", - "operationId": "UpdateMyProfile", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateMyProfileRequestContent" - } - } - } - }, + } + }, + "/{accountId}/my/assignments/completed.json": { + "get": { + "description": "Get the current user's completed assignments.\nArchived and trashed recordings are excluded. This endpoint is not paginated.", + "operationId": "GetMyCompletedAssignments", "parameters": [ { "name": "accountId", @@ -9403,35 +9411,32 @@ } ], "responses": { - "204": { - "description": "UpdateMyProfile 204 response" - }, - "401": { - "description": "UnauthorizedError 401 response", + "200": { + "description": "GetMyCompletedAssignments 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UnauthorizedErrorResponseContent" + "$ref": "#/components/schemas/GetMyCompletedAssignmentsResponseContent" } } } }, - "403": { - "description": "ForbiddenError 403 response", + "401": { + "description": "UnauthorizedError 401 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + "$ref": "#/components/schemas/UnauthorizedErrorResponseContent" } } } }, - "422": { - "description": "ValidationError 422 response", + "403": { + "description": "ForbiddenError 403 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" } } } @@ -9448,11 +9453,8 @@ } }, "tags": [ - "People" + "MyAssignments" ], - "x-basecamp-idempotent": { - "natural": true - }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -9464,10 +9466,10 @@ } } }, - "/{accountId}/my/question_reminders.json": { + "/{accountId}/my/assignments/due.json": { "get": { - "description": "Get pending check-in reminders for the current user\n\nReturns questions that are pending a response from the authenticated user.\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages.", - "operationId": "GetQuestionReminders", + "description": "Get the current user's assignments filtered by due date scope.\nDefaults to overdue when no scope is provided. This endpoint is not paginated.", + "operationId": "GetMyDueAssignments", "parameters": [ { "name": "accountId", @@ -9479,45 +9481,54 @@ "description": "Basecamp account ID (numeric string)" }, "required": true + }, + { + "name": "scope", + "in": "query", + "description": "Filter by due date range: overdue, due_today, due_tomorrow,\ndue_later_this_week, due_next_week, due_later", + "schema": { + "type": "string", + "description": "Filter by due date range: overdue, due_today, due_tomorrow,\ndue_later_this_week, due_next_week, due_later" + } } ], "responses": { "200": { - "description": "GetQuestionReminders 200 response", + "description": "GetMyDueAssignments 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetQuestionRemindersResponseContent" + "$ref": "#/components/schemas/GetMyDueAssignmentsResponseContent" } } } }, - "401": { - "description": "UnauthorizedError 401 response", + "400": { + "description": "BadRequestError 400 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UnauthorizedErrorResponseContent" + "$ref": "#/components/schemas/BadRequestErrorResponseContent" } } } }, - "403": { - "description": "ForbiddenError 403 response", + "401": { + "description": "UnauthorizedError 401 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + "$ref": "#/components/schemas/UnauthorizedErrorResponseContent" } } } }, - "429": { - "description": "RateLimitError 429 response", + "403": { + "description": "ForbiddenError 403 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" } } } @@ -9533,10 +9544,9 @@ } } }, - "x-basecamp-pagination": { - "style": "link", - "maxPageSize": 50 - }, + "tags": [ + "MyAssignments" + ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -9548,10 +9558,10 @@ } } }, - "/{accountId}/my/readings.json": { + "/{accountId}/my/preferences.json": { "get": { - "description": "Get the current user's notification inbox (the \"Hey!\" menu).\nNotifications are grouped into unreads, reads, bubble-ups, and\nscheduled bubble-ups (`memories` remains as an always-empty\nplaceholder on BC5). Reads are paginated (50 per page). Unreads are\ncapped at 100. Bubble-ups are capped per `limit_bubble_ups`.", - "operationId": "GetMyNotifications", + "description": "Get the current user's preferences", + "operationId": "GetMyPreferences", "parameters": [ { "name": "accountId", @@ -9563,34 +9573,15 @@ "description": "Basecamp account ID (numeric string)" }, "required": true - }, - { - "name": "page", - "in": "query", - "description": "Page number for paginating through read items. Defaults to 1.", - "schema": { - "type": "integer", - "description": "Page number for paginating through read items. Defaults to 1.", - "format": "int32" - } - }, - { - "name": "limit_bubble_ups", - "in": "query", - "description": "Set to true to cap `bubble_ups` at 2 current bubble-ups and omit the\n`scheduled_bubble_ups` key entirely. Defaults to false. Use the dedicated\nbubble-ups endpoint (GetBubbleUps) to page through all current and\nscheduled bubble-ups.", - "schema": { - "type": "boolean", - "description": "Set to true to cap `bubble_ups` at 2 current bubble-ups and omit the\n`scheduled_bubble_ups` key entirely. Defaults to false. Use the dedicated\nbubble-ups endpoint (GetBubbleUps) to page through all current and\nscheduled bubble-ups." - } } ], "responses": { "200": { - "description": "GetMyNotifications 200 response", + "description": "GetMyPreferences 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetMyNotificationsResponseContent" + "$ref": "#/components/schemas/GetMyPreferencesResponseContent" } } } @@ -9627,7 +9618,7 @@ } }, "tags": [ - "MyNotifications" + "People" ], "x-basecamp-retry": { "maxAttempts": 3, @@ -9638,12 +9629,20 @@ 503 ] } - } - }, - "/{accountId}/my/readings/bubble_ups.json": { - "get": { - "description": "Get the current user's current and scheduled bubble-ups as a paginated\nlist (50 per page). Current bubble-ups are returned first, ordered by most\nrecently bubbled up; scheduled bubble-ups follow, ordered by scheduled\nbubble-up time. Each item uses the same notification object shape as\nGetMyNotifications.", - "operationId": "GetBubbleUps", + }, + "put": { + "description": "Update the current user's preferences", + "operationId": "UpdateMyPreferences", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateMyPreferencesRequestContent" + } + } + }, + "required": true + }, "parameters": [ { "name": "accountId", @@ -9655,25 +9654,15 @@ "description": "Basecamp account ID (numeric string)" }, "required": true - }, - { - "name": "page", - "in": "query", - "description": "Page number. Defaults to 1.", - "schema": { - "type": "integer", - "description": "Page number. Defaults to 1.", - "format": "int32" - } } ], "responses": { "200": { - "description": "GetBubbleUps 200 response", + "description": "UpdateMyPreferences 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetBubbleUpsResponseContent" + "$ref": "#/components/schemas/UpdateMyPreferencesResponseContent" } } } @@ -9698,6 +9687,16 @@ } } }, + "422": { + "description": "ValidationError 422 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponseContent" + } + } + } + }, "429": { "description": "RateLimitError 429 response", "content": { @@ -9720,15 +9719,13 @@ } }, "tags": [ - "MyNotifications" + "People" ], - "x-basecamp-pagination": { - "style": "link", - "totalCountHeader": "X-Total-Count", - "maxPageSize": 50 + "x-basecamp-idempotent": { + "natural": true }, "x-basecamp-retry": { - "maxAttempts": 3, + "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -9738,20 +9735,10 @@ } } }, - "/{accountId}/my/unreads.json": { - "put": { - "description": "Mark specified items as read", - "operationId": "MarkAsRead", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/MarkAsReadRequestContent" - } - } - }, - "required": true - }, + "/{accountId}/my/profile.json": { + "get": { + "description": "Get the current authenticated user's profile", + "operationId": "GetMyProfile", "parameters": [ { "name": "accountId", @@ -9767,7 +9754,14 @@ ], "responses": { "200": { - "description": "MarkAsRead 200 response" + "description": "GetMyProfile 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetMyProfileResponseContent" + } + } + } }, "401": { "description": "UnauthorizedError 401 response", @@ -9789,12 +9783,12 @@ } } }, - "429": { - "description": "RateLimitError 429 response", + "404": { + "description": "NotFoundError 404 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" } } } @@ -9811,13 +9805,10 @@ } }, "tags": [ - "MyNotifications" + "People" ], - "x-basecamp-idempotent": { - "natural": true - }, "x-basecamp-retry": { - "maxAttempts": 2, + "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -9825,12 +9816,19 @@ 503 ] } - } - }, - "/{accountId}/people.json": { - "get": { - "description": "List all people visible to the current user\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", - "operationId": "ListPeople", + }, + "put": { + "description": "Update the current authenticated user's profile (returns 204 No Content)", + "operationId": "UpdateMyProfile", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateMyProfileRequestContent" + } + } + } + }, "parameters": [ { "name": "accountId", @@ -9845,15 +9843,8 @@ } ], "responses": { - "200": { - "description": "ListPeople 200 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ListPeopleResponseContent" - } - } - } + "204": { + "description": "UpdateMyProfile 204 response" }, "401": { "description": "UnauthorizedError 401 response", @@ -9875,12 +9866,12 @@ } } }, - "429": { - "description": "RateLimitError 429 response", + "422": { + "description": "ValidationError 422 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" + "$ref": "#/components/schemas/ValidationErrorResponseContent" } } } @@ -9899,10 +9890,8 @@ "tags": [ "People" ], - "x-basecamp-pagination": { - "style": "link", - "totalCountHeader": "X-Total-Count", - "maxPageSize": 50 + "x-basecamp-idempotent": { + "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, @@ -9915,10 +9904,10 @@ } } }, - "/{accountId}/people/{personId}": { + "/{accountId}/my/question_reminders.json": { "get": { - "description": "Get a person by ID", - "operationId": "GetPerson", + "description": "Get pending check-in reminders for the current user\n\nReturns questions that are pending a response from the authenticated user.\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages.", + "operationId": "GetQuestionReminders", "parameters": [ { "name": "accountId", @@ -9930,24 +9919,15 @@ "description": "Basecamp account ID (numeric string)" }, "required": true - }, - { - "name": "personId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true } ], "responses": { "200": { - "description": "GetPerson 200 response", + "description": "GetQuestionReminders 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetPersonResponseContent" + "$ref": "#/components/schemas/GetQuestionRemindersResponseContent" } } } @@ -9972,12 +9952,12 @@ } } }, - "404": { - "description": "NotFoundError 404 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -9993,9 +9973,10 @@ } } }, - "tags": [ - "People" - ], + "x-basecamp-pagination": { + "style": "link", + "maxPageSize": 50 + }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -10007,10 +9988,10 @@ } } }, - "/{accountId}/people/{personId}/out_of_office.json": { - "delete": { - "description": "Disable out of office for a person.\nAdmins on Pro Pack accounts can manage others; otherwise self only.", - "operationId": "DisableOutOfOffice", + "/{accountId}/my/readings.json": { + "get": { + "description": "Get the current user's notification inbox (the \"Hey!\" menu).\nNotifications are grouped into unreads, reads, bubble-ups, and\nscheduled bubble-ups (`memories` remains as an always-empty\nplaceholder on BC5). Reads are paginated (50 per page). Unreads are\ncapped at 100. Bubble-ups are capped per `limit_bubble_ups`.", + "operationId": "GetMyNotifications", "parameters": [ { "name": "accountId", @@ -10024,45 +10005,52 @@ "required": true }, { - "name": "personId", - "in": "path", + "name": "page", + "in": "query", + "description": "Page number for paginating through read items. Defaults to 1.", "schema": { "type": "integer", - "format": "int64" - }, - "required": true + "description": "Page number for paginating through read items. Defaults to 1.", + "format": "int32" + } + }, + { + "name": "limit_bubble_ups", + "in": "query", + "description": "Set to true to cap `bubble_ups` at 2 current bubble-ups and omit the\n`scheduled_bubble_ups` key entirely. Defaults to false. Use the dedicated\nbubble-ups endpoint (GetBubbleUps) to page through all current and\nscheduled bubble-ups.", + "schema": { + "type": "boolean", + "description": "Set to true to cap `bubble_ups` at 2 current bubble-ups and omit the\n`scheduled_bubble_ups` key entirely. Defaults to false. Use the dedicated\nbubble-ups endpoint (GetBubbleUps) to page through all current and\nscheduled bubble-ups." + } } ], "responses": { - "204": { - "description": "DisableOutOfOffice 204 response" - }, - "401": { - "description": "UnauthorizedError 401 response", + "200": { + "description": "GetMyNotifications 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UnauthorizedErrorResponseContent" + "$ref": "#/components/schemas/GetMyNotificationsResponseContent" } } } }, - "403": { - "description": "ForbiddenError 403 response", + "401": { + "description": "UnauthorizedError 401 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + "$ref": "#/components/schemas/UnauthorizedErrorResponseContent" } } } }, - "429": { - "description": "RateLimitError 429 response", + "403": { + "description": "ForbiddenError 403 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" } } } @@ -10079,13 +10067,10 @@ } }, "tags": [ - "People" + "MyNotifications" ], - "x-basecamp-idempotent": { - "natural": true - }, "x-basecamp-retry": { - "maxAttempts": 2, + "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -10093,10 +10078,12 @@ 503 ] } - }, + } + }, + "/{accountId}/my/readings/bubble_ups.json": { "get": { - "description": "Get the out of office status for a person", - "operationId": "GetOutOfOffice", + "description": "Get the current user's current and scheduled bubble-ups as a paginated\nlist (50 per page). Current bubble-ups are returned first, ordered by most\nrecently bubbled up; scheduled bubble-ups follow, ordered by scheduled\nbubble-up time. Each item uses the same notification object shape as\nGetMyNotifications.", + "operationId": "GetBubbleUps", "parameters": [ { "name": "accountId", @@ -10110,22 +10097,23 @@ "required": true }, { - "name": "personId", - "in": "path", + "name": "page", + "in": "query", + "description": "Page number. Defaults to 1.", "schema": { "type": "integer", - "format": "int64" - }, - "required": true + "description": "Page number. Defaults to 1.", + "format": "int32" + } } ], "responses": { "200": { - "description": "GetOutOfOffice 200 response", + "description": "GetBubbleUps 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetOutOfOfficeResponseContent" + "$ref": "#/components/schemas/GetBubbleUpsResponseContent" } } } @@ -10150,12 +10138,12 @@ } } }, - "404": { - "description": "NotFoundError 404 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -10172,8 +10160,13 @@ } }, "tags": [ - "People" + "MyNotifications" ], + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -10183,15 +10176,17 @@ 503 ] } - }, - "post": { - "description": "Enable or replace out of office for a person.\nAdmins on Pro Pack accounts can manage others; otherwise self only.", - "operationId": "EnableOutOfOffice", + } + }, + "/{accountId}/my/unreads.json": { + "put": { + "description": "Mark specified items as read", + "operationId": "MarkAsRead", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/EnableOutOfOfficeRequestContent" + "$ref": "#/components/schemas/MarkAsReadRequestContent" } } }, @@ -10208,27 +10203,11 @@ "description": "Basecamp account ID (numeric string)" }, "required": true - }, - { - "name": "personId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true } ], "responses": { "200": { - "description": "EnableOutOfOffice 200 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/EnableOutOfOfficeResponseContent" - } - } - } + "description": "MarkAsRead 200 response" }, "401": { "description": "UnauthorizedError 401 response", @@ -10250,16 +10229,6 @@ } } }, - "422": { - "description": "ValidationError 422 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" - } - } - } - }, "429": { "description": "RateLimitError 429 response", "content": { @@ -10282,8 +10251,11 @@ } }, "tags": [ - "People" + "MyNotifications" ], + "x-basecamp-idempotent": { + "natural": true + }, "x-basecamp-retry": { "maxAttempts": 2, "baseDelayMs": 1000, @@ -10295,10 +10267,10 @@ } } }, - "/{accountId}/projects.json": { + "/{accountId}/people.json": { "get": { - "description": "List projects (active by default; optionally archived/trashed)\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", - "operationId": "ListProjects", + "description": "List all people visible to the current user\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", + "operationId": "ListPeople", "parameters": [ { "name": "accountId", @@ -10310,24 +10282,15 @@ "description": "Basecamp account ID (numeric string)" }, "required": true - }, - { - "name": "status", - "in": "query", - "description": "active|archived|trashed", - "schema": { - "type": "string", - "description": "active|archived|trashed" - } } ], "responses": { "200": { - "description": "ListProjects 200 response", + "description": "ListPeople 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListProjectsResponseContent" + "$ref": "#/components/schemas/ListPeopleResponseContent" } } } @@ -10374,7 +10337,7 @@ } }, "tags": [ - "Projects" + "People" ], "x-basecamp-pagination": { "style": "link", @@ -10390,20 +10353,12 @@ 503 ] } - }, - "post": { - "description": "Create a new project", - "operationId": "CreateProject", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateProjectRequestContent" - } - } - }, - "required": true - }, + } + }, + "/{accountId}/people/{personId}": { + "get": { + "description": "Get a person by ID", + "operationId": "GetPerson", "parameters": [ { "name": "accountId", @@ -10415,15 +10370,24 @@ "description": "Basecamp account ID (numeric string)" }, "required": true + }, + { + "name": "personId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true } ], "responses": { - "201": { - "description": "CreateProject 201 response", + "200": { + "description": "GetPerson 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateProjectResponseContent" + "$ref": "#/components/schemas/GetPersonResponseContent" } } } @@ -10448,22 +10412,12 @@ } } }, - "422": { - "description": "ValidationError 422 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" - } - } - } - }, - "429": { - "description": "RateLimitError 429 response", + "404": { + "description": "NotFoundError 404 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" } } } @@ -10480,7 +10434,7 @@ } }, "tags": [ - "Projects" + "People" ], "x-basecamp-retry": { "maxAttempts": 3, @@ -10493,10 +10447,10 @@ } } }, - "/{accountId}/projects/recordings.json": { - "get": { - "description": "List recordings of a given type across projects\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", - "operationId": "ListRecordings", + "/{accountId}/people/{personId}/out_of_office.json": { + "delete": { + "description": "Disable out of office for a person.\nAdmins on Pro Pack accounts can manage others; otherwise self only.", + "operationId": "DisableOutOfOffice", "parameters": [ { "name": "accountId", @@ -10507,114 +10461,21 @@ "pattern": "^[0-9]+$", "description": "Basecamp account ID (numeric string)" }, - "required": true, - "examples": { - "ListRecordings_example1": { - "summary": "List Todo recordings", - "description": "Use simple type name for basic resources", - "value": "999" - }, - "ListRecordings_example2": { - "summary": "List Kanban Card recordings", - "description": "Use double-colon notation for nested types", - "value": "999" - }, - "ListRecordings_example3": { - "summary": "List Question Answer recordings", - "description": "Another nested type example", - "value": "999" - } - } + "required": true }, { - "name": "type", - "in": "query", - "description": "Comment|Document|Door|Kanban::Card|Kanban::Step|Message|Question::Answer|Schedule::Entry|Todo|Todolist|Upload|Vault", + "name": "personId", + "in": "path", "schema": { - "type": "string", - "description": "Comment|Document|Door|Kanban::Card|Kanban::Step|Message|Question::Answer|Schedule::Entry|Todo|Todolist|Upload|Vault" + "type": "integer", + "format": "int64" }, - "required": true, - "examples": { - "ListRecordings_example1": { - "summary": "List Todo recordings", - "description": "Use simple type name for basic resources", - "value": "Todo" - }, - "ListRecordings_example2": { - "summary": "List Kanban Card recordings", - "description": "Use double-colon notation for nested types", - "value": "Kanban::Card" - }, - "ListRecordings_example3": { - "summary": "List Question Answer recordings", - "description": "Another nested type example", - "value": "Question::Answer" - } - } - }, - { - "name": "bucket", - "in": "query", - "schema": { - "type": "string" - } - }, - { - "name": "status", - "in": "query", - "description": "active|archived|trashed", - "schema": { - "type": "string", - "description": "active|archived|trashed" - } - }, - { - "name": "sort", - "in": "query", - "description": "created_at|updated_at", - "schema": { - "type": "string", - "description": "created_at|updated_at" - } - }, - { - "name": "direction", - "in": "query", - "description": "asc|desc", - "schema": { - "type": "string", - "description": "asc|desc" - } + "required": true } ], "responses": { - "200": { - "description": "ListRecordings 200 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ListRecordingsResponseContent" - }, - "examples": { - "ListRecordings_example1": { - "summary": "List Todo recordings", - "description": "Use simple type name for basic resources", - "value": {} - }, - "ListRecordings_example2": { - "summary": "List Kanban Card recordings", - "description": "Use double-colon notation for nested types", - "value": {} - }, - "ListRecordings_example3": { - "summary": "List Question Answer recordings", - "description": "Another nested type example", - "value": {} - } - } - } - } + "204": { + "description": "DisableOutOfOffice 204 response" }, "401": { "description": "UnauthorizedError 401 response", @@ -10658,15 +10519,13 @@ } }, "tags": [ - "Automation" + "People" ], - "x-basecamp-pagination": { - "style": "link", - "totalCountHeader": "X-Total-Count", - "maxPageSize": 50 + "x-basecamp-idempotent": { + "natural": true }, "x-basecamp-retry": { - "maxAttempts": 3, + "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -10674,12 +10533,10 @@ 503 ] } - } - }, - "/{accountId}/projects/{projectId}": { - "delete": { - "description": "Trash a project (returns 204 No Content)", - "operationId": "TrashProject", + }, + "get": { + "description": "Get the out of office status for a person", + "operationId": "GetOutOfOffice", "parameters": [ { "name": "accountId", @@ -10693,7 +10550,7 @@ "required": true }, { - "name": "projectId", + "name": "personId", "in": "path", "schema": { "type": "integer", @@ -10703,8 +10560,15 @@ } ], "responses": { - "204": { - "description": "TrashProject 204 response" + "200": { + "description": "GetOutOfOffice 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetOutOfOfficeResponseContent" + } + } + } }, "401": { "description": "UnauthorizedError 401 response", @@ -10748,11 +10612,8 @@ } }, "tags": [ - "Projects" + "People" ], - "x-basecamp-idempotent": { - "natural": true - }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -10763,9 +10624,19 @@ ] } }, - "get": { - "description": "Get a single project by id", - "operationId": "GetProject", + "post": { + "description": "Enable or replace out of office for a person.\nAdmins on Pro Pack accounts can manage others; otherwise self only.", + "operationId": "EnableOutOfOffice", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EnableOutOfOfficeRequestContent" + } + } + }, + "required": true + }, "parameters": [ { "name": "accountId", @@ -10779,7 +10650,7 @@ "required": true }, { - "name": "projectId", + "name": "personId", "in": "path", "schema": { "type": "integer", @@ -10790,11 +10661,11 @@ ], "responses": { "200": { - "description": "GetProject 200 response", + "description": "EnableOutOfOffice 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetProjectResponseContent" + "$ref": "#/components/schemas/EnableOutOfOfficeResponseContent" } } } @@ -10819,12 +10690,22 @@ } } }, - "404": { - "description": "NotFoundError 404 response", + "422": { + "description": "ValidationError 422 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/ValidationErrorResponseContent" + } + } + } + }, + "429": { + "description": "RateLimitError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -10841,10 +10722,10 @@ } }, "tags": [ - "Projects" + "People" ], "x-basecamp-retry": { - "maxAttempts": 3, + "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -10852,20 +10733,12 @@ 503 ] } - }, - "put": { - "description": "Update an existing project", - "operationId": "UpdateProject", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateProjectRequestContent" - } - } - }, - "required": true - }, + } + }, + "/{accountId}/projects.json": { + "get": { + "description": "List projects (active by default; optionally archived/trashed)\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", + "operationId": "ListProjects", "parameters": [ { "name": "accountId", @@ -10879,22 +10752,22 @@ "required": true }, { - "name": "projectId", - "in": "path", + "name": "status", + "in": "query", + "description": "active|archived|trashed", "schema": { - "type": "integer", - "format": "int64" - }, - "required": true + "type": "string", + "description": "active|archived|trashed" + } } ], "responses": { "200": { - "description": "UpdateProject 200 response", + "description": "ListProjects 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateProjectResponseContent" + "$ref": "#/components/schemas/ListProjectsResponseContent" } } } @@ -10919,22 +10792,12 @@ } } }, - "404": { - "description": "NotFoundError 404 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" - } - } - } - }, - "422": { - "description": "ValidationError 422 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -10953,8 +10816,10 @@ "tags": [ "Projects" ], - "x-basecamp-idempotent": { - "natural": true + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 }, "x-basecamp-retry": { "maxAttempts": 3, @@ -10965,17 +10830,15 @@ 503 ] } - } - }, - "/{accountId}/projects/{projectId}/gauge.json": { - "put": { - "description": "Enable or disable the gauge for a project. Only project admins can toggle gauges.", - "operationId": "ToggleGauge", + }, + "post": { + "description": "Create a new project", + "operationId": "CreateProject", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ToggleGaugeRequestContent" + "$ref": "#/components/schemas/CreateProjectRequestContent" } } }, @@ -10992,20 +10855,18 @@ "description": "Basecamp account ID (numeric string)" }, "required": true - }, - { - "name": "projectId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true } ], "responses": { - "200": { - "description": "ToggleGauge 200 response" + "201": { + "description": "CreateProject 201 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateProjectResponseContent" + } + } + } }, "401": { "description": "UnauthorizedError 401 response", @@ -11027,6 +10888,16 @@ } } }, + "422": { + "description": "ValidationError 422 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponseContent" + } + } + } + }, "429": { "description": "RateLimitError 429 response", "content": { @@ -11049,13 +10920,10 @@ } }, "tags": [ - "Gauges" + "Projects" ], - "x-basecamp-idempotent": { - "natural": true - }, "x-basecamp-retry": { - "maxAttempts": 2, + "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -11065,10 +10933,10 @@ } } }, - "/{accountId}/projects/{projectId}/gauge/needles.json": { + "/{accountId}/projects/recordings.json": { "get": { - "description": "List gauge needles for a project, ordered newest first.", - "operationId": "ListGaugeNeedles", + "description": "List recordings of a given type across projects\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", + "operationId": "ListRecordings", "parameters": [ { "name": "accountId", @@ -11079,25 +10947,111 @@ "pattern": "^[0-9]+$", "description": "Basecamp account ID (numeric string)" }, - "required": true + "required": true, + "examples": { + "ListRecordings_example1": { + "summary": "List Todo recordings", + "description": "Use simple type name for basic resources", + "value": "999" + }, + "ListRecordings_example2": { + "summary": "List Kanban Card recordings", + "description": "Use double-colon notation for nested types", + "value": "999" + }, + "ListRecordings_example3": { + "summary": "List Question Answer recordings", + "description": "Another nested type example", + "value": "999" + } + } }, { - "name": "projectId", - "in": "path", + "name": "type", + "in": "query", + "description": "Comment|Document|Door|Kanban::Card|Kanban::Step|Message|Question::Answer|Schedule::Entry|Todo|Todolist|Upload|Vault", "schema": { - "type": "integer", - "format": "int64" + "type": "string", + "description": "Comment|Document|Door|Kanban::Card|Kanban::Step|Message|Question::Answer|Schedule::Entry|Todo|Todolist|Upload|Vault" }, - "required": true + "required": true, + "examples": { + "ListRecordings_example1": { + "summary": "List Todo recordings", + "description": "Use simple type name for basic resources", + "value": "Todo" + }, + "ListRecordings_example2": { + "summary": "List Kanban Card recordings", + "description": "Use double-colon notation for nested types", + "value": "Kanban::Card" + }, + "ListRecordings_example3": { + "summary": "List Question Answer recordings", + "description": "Another nested type example", + "value": "Question::Answer" + } + } + }, + { + "name": "bucket", + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "status", + "in": "query", + "description": "active|archived|trashed", + "schema": { + "type": "string", + "description": "active|archived|trashed" + } + }, + { + "name": "sort", + "in": "query", + "description": "created_at|updated_at", + "schema": { + "type": "string", + "description": "created_at|updated_at" + } + }, + { + "name": "direction", + "in": "query", + "description": "asc|desc", + "schema": { + "type": "string", + "description": "asc|desc" + } } ], "responses": { "200": { - "description": "ListGaugeNeedles 200 response", + "description": "ListRecordings 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListGaugeNeedlesResponseContent" + "$ref": "#/components/schemas/ListRecordingsResponseContent" + }, + "examples": { + "ListRecordings_example1": { + "summary": "List Todo recordings", + "description": "Use simple type name for basic resources", + "value": {} + }, + "ListRecordings_example2": { + "summary": "List Kanban Card recordings", + "description": "Use double-colon notation for nested types", + "value": {} + }, + "ListRecordings_example3": { + "summary": "List Question Answer recordings", + "description": "Another nested type example", + "value": {} + } } } } @@ -11122,16 +11076,6 @@ } } }, - "404": { - "description": "NotFoundError 404 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" - } - } - } - }, "429": { "description": "RateLimitError 429 response", "content": { @@ -11154,7 +11098,7 @@ } }, "tags": [ - "Gauges" + "Automation" ], "x-basecamp-pagination": { "style": "link", @@ -11170,20 +11114,12 @@ 503 ] } - }, - "post": { - "description": "Create a gauge needle (progress update) for a project", - "operationId": "CreateGaugeNeedle", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateGaugeNeedleRequestContent" - } - } - }, - "required": true - }, + } + }, + "/{accountId}/projects/{projectId}": { + "delete": { + "description": "Trash a project (returns 204 No Content)", + "operationId": "TrashProject", "parameters": [ { "name": "accountId", @@ -11207,15 +11143,8 @@ } ], "responses": { - "201": { - "description": "CreateGaugeNeedle 201 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateGaugeNeedleResponseContent" - } - } - } + "204": { + "description": "TrashProject 204 response" }, "401": { "description": "UnauthorizedError 401 response", @@ -11237,22 +11166,12 @@ } } }, - "422": { - "description": "ValidationError 422 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" - } - } - } - }, - "429": { - "description": "RateLimitError 429 response", + "404": { + "description": "NotFoundError 404 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" } } } @@ -11269,10 +11188,13 @@ } }, "tags": [ - "Gauges" + "Projects" ], + "x-basecamp-idempotent": { + "natural": true + }, "x-basecamp-retry": { - "maxAttempts": 2, + "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -11280,12 +11202,10 @@ 503 ] } - } - }, - "/{accountId}/projects/{projectId}/people.json": { + }, "get": { - "description": "List all active people on a project\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", - "operationId": "ListProjectPeople", + "description": "Get a single project by id", + "operationId": "GetProject", "parameters": [ { "name": "accountId", @@ -11310,11 +11230,11 @@ ], "responses": { "200": { - "description": "ListProjectPeople 200 response", + "description": "GetProject 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListProjectPeopleResponseContent" + "$ref": "#/components/schemas/GetProjectResponseContent" } } } @@ -11339,12 +11259,12 @@ } } }, - "429": { - "description": "RateLimitError 429 response", + "404": { + "description": "NotFoundError 404 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" } } } @@ -11361,13 +11281,8 @@ } }, "tags": [ - "People" + "Projects" ], - "x-basecamp-pagination": { - "style": "link", - "totalCountHeader": "X-Total-Count", - "maxPageSize": 50 - }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -11377,53 +11292,19 @@ 503 ] } - } - }, - "/{accountId}/projects/{projectId}/people/users.json": { + }, "put": { - "description": "Update project access (grant/revoke/create people)", - "operationId": "UpdateProjectAccess", + "description": "Update an existing project", + "operationId": "UpdateProject", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateProjectAccessRequestContent" - }, - "examples": { - "UpdateProjectAccess_example1": { - "summary": "Grant access to existing users", - "description": "Use grant array with person IDs", - "value": { - "grant": [ - 111, - 222 - ] - } - }, - "UpdateProjectAccess_example2": { - "summary": "Revoke access", - "description": "Use revoke array to remove users", - "value": { - "revoke": [ - 333 - ] - } - }, - "UpdateProjectAccess_example3": { - "summary": "Invite new users", - "description": "Use create array for new users without accounts", - "value": { - "create": [ - { - "name": "Jane", - "email_address": "jane@example.com" - } - ] - } - } + "$ref": "#/components/schemas/UpdateProjectRequestContent" } } - } + }, + "required": true }, "parameters": [ { @@ -11435,24 +11316,7 @@ "pattern": "^[0-9]+$", "description": "Basecamp account ID (numeric string)" }, - "required": true, - "examples": { - "UpdateProjectAccess_example1": { - "summary": "Grant access to existing users", - "description": "Use grant array with person IDs", - "value": "999" - }, - "UpdateProjectAccess_example2": { - "summary": "Revoke access", - "description": "Use revoke array to remove users", - "value": "999" - }, - "UpdateProjectAccess_example3": { - "summary": "Invite new users", - "description": "Use create array for new users without accounts", - "value": "999" - } - } + "required": true }, { "name": "projectId", @@ -11461,50 +11325,16 @@ "type": "integer", "format": "int64" }, - "required": true, - "examples": { - "UpdateProjectAccess_example1": { - "summary": "Grant access to existing users", - "description": "Use grant array with person IDs", - "value": 12345678 - }, - "UpdateProjectAccess_example2": { - "summary": "Revoke access", - "description": "Use revoke array to remove users", - "value": 12345678 - }, - "UpdateProjectAccess_example3": { - "summary": "Invite new users", - "description": "Use create array for new users without accounts", - "value": 12345678 - } - } + "required": true } ], "responses": { "200": { - "description": "UpdateProjectAccess 200 response", + "description": "UpdateProject 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateProjectAccessResponseContent" - }, - "examples": { - "UpdateProjectAccess_example1": { - "summary": "Grant access to existing users", - "description": "Use grant array with person IDs", - "value": {} - }, - "UpdateProjectAccess_example2": { - "summary": "Revoke access", - "description": "Use revoke array to remove users", - "value": {} - }, - "UpdateProjectAccess_example3": { - "summary": "Invite new users", - "description": "Use create array for new users without accounts", - "value": {} - } + "$ref": "#/components/schemas/UpdateProjectResponseContent" } } } @@ -11549,16 +11379,6 @@ } } }, - "429": { - "description": "RateLimitError 429 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" - } - } - } - }, "500": { "description": "InternalServerError 500 response", "content": { @@ -11571,7 +11391,7 @@ } }, "tags": [ - "People" + "Projects" ], "x-basecamp-idempotent": { "natural": true @@ -11587,10 +11407,20 @@ } } }, - "/{accountId}/projects/{projectId}/timeline.json": { - "get": { - "description": "Get project timeline", - "operationId": "GetProjectTimeline", + "/{accountId}/projects/{projectId}/gauge.json": { + "put": { + "description": "Enable or disable the gauge for a project. Only project admins can toggle gauges.", + "operationId": "ToggleGauge", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ToggleGaugeRequestContent" + } + } + }, + "required": true + }, "parameters": [ { "name": "accountId", @@ -11615,14 +11445,7 @@ ], "responses": { "200": { - "description": "GetProjectTimeline 200 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/GetProjectTimelineResponseContent" - } - } - } + "description": "ToggleGauge 200 response" }, "401": { "description": "UnauthorizedError 401 response", @@ -11644,16 +11467,6 @@ } } }, - "404": { - "description": "NotFoundError 404 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" - } - } - } - }, "429": { "description": "RateLimitError 429 response", "content": { @@ -11675,13 +11488,14 @@ } } }, - "x-basecamp-pagination": { - "style": "link", - "totalCountHeader": "X-Total-Count", - "maxPageSize": 50 + "tags": [ + "Gauges" + ], + "x-basecamp-idempotent": { + "natural": true }, "x-basecamp-retry": { - "maxAttempts": 3, + "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -11691,10 +11505,10 @@ } } }, - "/{accountId}/projects/{projectId}/timesheet.json": { + "/{accountId}/projects/{projectId}/gauge/needles.json": { "get": { - "description": "Get timesheet for a specific project", - "operationId": "GetProjectTimesheet", + "description": "List gauge needles for a project, ordered newest first.", + "operationId": "ListGaugeNeedles", "parameters": [ { "name": "accountId", @@ -11715,37 +11529,15 @@ "format": "int64" }, "required": true - }, - { - "name": "from", - "in": "query", - "schema": { - "type": "string" - } - }, - { - "name": "to", - "in": "query", - "schema": { - "type": "string" - } - }, - { - "name": "person_id", - "in": "query", - "schema": { - "type": "integer", - "format": "int64" - } } ], "responses": { "200": { - "description": "GetProjectTimesheet 200 response", + "description": "ListGaugeNeedles 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetProjectTimesheetResponseContent" + "$ref": "#/components/schemas/ListGaugeNeedlesResponseContent" } } } @@ -11780,6 +11572,16 @@ } } }, + "429": { + "description": "RateLimitError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RateLimitErrorResponseContent" + } + } + } + }, "500": { "description": "InternalServerError 500 response", "content": { @@ -11792,7 +11594,7 @@ } }, "tags": [ - "Schedule" + "Gauges" ], "x-basecamp-pagination": { "style": "link", @@ -11808,12 +11610,20 @@ 503 ] } - } - }, - "/{accountId}/question_answers/{answerId}": { - "get": { - "description": "Get a single answer by id", - "operationId": "GetAnswer", + }, + "post": { + "description": "Create a gauge needle (progress update) for a project", + "operationId": "CreateGaugeNeedle", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateGaugeNeedleRequestContent" + } + } + }, + "required": true + }, "parameters": [ { "name": "accountId", @@ -11827,7 +11637,7 @@ "required": true }, { - "name": "answerId", + "name": "projectId", "in": "path", "schema": { "type": "integer", @@ -11837,12 +11647,12 @@ } ], "responses": { - "200": { - "description": "GetAnswer 200 response", + "201": { + "description": "CreateGaugeNeedle 201 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetAnswerResponseContent" + "$ref": "#/components/schemas/CreateGaugeNeedleResponseContent" } } } @@ -11867,12 +11677,22 @@ } } }, - "404": { - "description": "NotFoundError 404 response", + "422": { + "description": "ValidationError 422 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/ValidationErrorResponseContent" + } + } + } + }, + "429": { + "description": "RateLimitError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -11889,10 +11709,10 @@ } }, "tags": [ - "Automation" + "Gauges" ], "x-basecamp-retry": { - "maxAttempts": 3, + "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -11900,20 +11720,12 @@ 503 ] } - }, - "put": { - "description": "Update an existing answer", - "operationId": "UpdateAnswer", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/QuestionAnswerUpdatePayload" - } - } - }, - "required": true - }, + } + }, + "/{accountId}/projects/{projectId}/people.json": { + "get": { + "description": "List all active people on a project\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", + "operationId": "ListProjectPeople", "parameters": [ { "name": "accountId", @@ -11927,7 +11739,7 @@ "required": true }, { - "name": "answerId", + "name": "projectId", "in": "path", "schema": { "type": "integer", @@ -11937,45 +11749,42 @@ } ], "responses": { - "204": { - "description": "UpdateAnswer 204 response" - }, - "401": { - "description": "UnauthorizedError 401 response", + "200": { + "description": "ListProjectPeople 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UnauthorizedErrorResponseContent" + "$ref": "#/components/schemas/ListProjectPeopleResponseContent" } } } }, - "403": { - "description": "ForbiddenError 403 response", + "401": { + "description": "UnauthorizedError 401 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + "$ref": "#/components/schemas/UnauthorizedErrorResponseContent" } } } }, - "404": { - "description": "NotFoundError 404 response", + "403": { + "description": "ForbiddenError 403 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" } } } }, - "422": { - "description": "ValidationError 422 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -11992,10 +11801,12 @@ } }, "tags": [ - "Automation" + "People" ], - "x-basecamp-idempotent": { - "natural": true + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 }, "x-basecamp-retry": { "maxAttempts": 3, @@ -12008,10 +11819,52 @@ } } }, - "/{accountId}/questionnaires/{questionnaireId}": { - "get": { - "description": "Get a questionnaire (automatic check-ins container) by id", - "operationId": "GetQuestionnaire", + "/{accountId}/projects/{projectId}/people/users.json": { + "put": { + "description": "Update project access (grant/revoke/create people)", + "operationId": "UpdateProjectAccess", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateProjectAccessRequestContent" + }, + "examples": { + "UpdateProjectAccess_example1": { + "summary": "Grant access to existing users", + "description": "Use grant array with person IDs", + "value": { + "grant": [ + 111, + 222 + ] + } + }, + "UpdateProjectAccess_example2": { + "summary": "Revoke access", + "description": "Use revoke array to remove users", + "value": { + "revoke": [ + 333 + ] + } + }, + "UpdateProjectAccess_example3": { + "summary": "Invite new users", + "description": "Use create array for new users without accounts", + "value": { + "create": [ + { + "name": "Jane", + "email_address": "jane@example.com" + } + ] + } + } + } + } + } + }, "parameters": [ { "name": "accountId", @@ -12022,25 +11875,76 @@ "pattern": "^[0-9]+$", "description": "Basecamp account ID (numeric string)" }, - "required": true + "required": true, + "examples": { + "UpdateProjectAccess_example1": { + "summary": "Grant access to existing users", + "description": "Use grant array with person IDs", + "value": "999" + }, + "UpdateProjectAccess_example2": { + "summary": "Revoke access", + "description": "Use revoke array to remove users", + "value": "999" + }, + "UpdateProjectAccess_example3": { + "summary": "Invite new users", + "description": "Use create array for new users without accounts", + "value": "999" + } + } }, { - "name": "questionnaireId", + "name": "projectId", "in": "path", "schema": { "type": "integer", "format": "int64" }, - "required": true + "required": true, + "examples": { + "UpdateProjectAccess_example1": { + "summary": "Grant access to existing users", + "description": "Use grant array with person IDs", + "value": 12345678 + }, + "UpdateProjectAccess_example2": { + "summary": "Revoke access", + "description": "Use revoke array to remove users", + "value": 12345678 + }, + "UpdateProjectAccess_example3": { + "summary": "Invite new users", + "description": "Use create array for new users without accounts", + "value": 12345678 + } + } } ], "responses": { "200": { - "description": "GetQuestionnaire 200 response", + "description": "UpdateProjectAccess 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetQuestionnaireResponseContent" + "$ref": "#/components/schemas/UpdateProjectAccessResponseContent" + }, + "examples": { + "UpdateProjectAccess_example1": { + "summary": "Grant access to existing users", + "description": "Use grant array with person IDs", + "value": {} + }, + "UpdateProjectAccess_example2": { + "summary": "Revoke access", + "description": "Use revoke array to remove users", + "value": {} + }, + "UpdateProjectAccess_example3": { + "summary": "Invite new users", + "description": "Use create array for new users without accounts", + "value": {} + } } } } @@ -12075,6 +11979,26 @@ } } }, + "422": { + "description": "ValidationError 422 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponseContent" + } + } + } + }, + "429": { + "description": "RateLimitError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RateLimitErrorResponseContent" + } + } + } + }, "500": { "description": "InternalServerError 500 response", "content": { @@ -12087,8 +12011,11 @@ } }, "tags": [ - "Automation" + "People" ], + "x-basecamp-idempotent": { + "natural": true + }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -12100,10 +12027,10 @@ } } }, - "/{accountId}/questionnaires/{questionnaireId}/questions.json": { + "/{accountId}/projects/{projectId}/timeline.json": { "get": { - "description": "List all questions in a questionnaire\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", - "operationId": "ListQuestions", + "description": "Get project timeline", + "operationId": "GetProjectTimeline", "parameters": [ { "name": "accountId", @@ -12117,7 +12044,7 @@ "required": true }, { - "name": "questionnaireId", + "name": "projectId", "in": "path", "schema": { "type": "integer", @@ -12128,11 +12055,11 @@ ], "responses": { "200": { - "description": "ListQuestions 200 response", + "description": "GetProjectTimeline 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListQuestionsResponseContent" + "$ref": "#/components/schemas/GetProjectTimelineResponseContent" } } } @@ -12157,6 +12084,16 @@ } } }, + "404": { + "description": "NotFoundError 404 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotFoundErrorResponseContent" + } + } + } + }, "429": { "description": "RateLimitError 429 response", "content": { @@ -12178,9 +12115,6 @@ } } }, - "tags": [ - "Automation" - ], "x-basecamp-pagination": { "style": "link", "totalCountHeader": "X-Total-Count", @@ -12195,20 +12129,12 @@ 503 ] } - }, - "post": { - "description": "Create a new question in a questionnaire", - "operationId": "CreateQuestion", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateQuestionRequestContent" - } - } - }, - "required": true - }, + } + }, + "/{accountId}/projects/{projectId}/timesheet.json": { + "get": { + "description": "Get timesheet for a specific project", + "operationId": "GetProjectTimesheet", "parameters": [ { "name": "accountId", @@ -12222,22 +12148,44 @@ "required": true }, { - "name": "questionnaireId", + "name": "projectId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true + }, + { + "name": "from", + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "to", + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "person_id", + "in": "query", + "schema": { + "type": "integer", + "format": "int64" + } } ], "responses": { - "201": { - "description": "CreateQuestion 201 response", + "200": { + "description": "GetProjectTimesheet 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateQuestionResponseContent" + "$ref": "#/components/schemas/GetProjectTimesheetResponseContent" } } } @@ -12262,42 +12210,37 @@ } } }, - "422": { - "description": "ValidationError 422 response", + "404": { + "description": "NotFoundError 404 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" } } } }, - "429": { - "description": "RateLimitError 429 response", + "500": { + "description": "InternalServerError 500 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" - } - } - } - }, - "500": { - "description": "InternalServerError 500 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/InternalServerErrorResponseContent" + "$ref": "#/components/schemas/InternalServerErrorResponseContent" } } } } }, "tags": [ - "Automation" + "Schedule" ], + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + }, "x-basecamp-retry": { - "maxAttempts": 2, + "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -12307,10 +12250,10 @@ } } }, - "/{accountId}/questions/{questionId}": { + "/{accountId}/question_answers/{answerId}": { "get": { - "description": "Get a single question by id", - "operationId": "GetQuestion", + "description": "Get a single answer by id", + "operationId": "GetAnswer", "parameters": [ { "name": "accountId", @@ -12324,7 +12267,7 @@ "required": true }, { - "name": "questionId", + "name": "answerId", "in": "path", "schema": { "type": "integer", @@ -12335,11 +12278,11 @@ ], "responses": { "200": { - "description": "GetQuestion 200 response", + "description": "GetAnswer 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetQuestionResponseContent" + "$ref": "#/components/schemas/GetAnswerResponseContent" } } } @@ -12399,16 +12342,17 @@ } }, "put": { - "description": "Update an existing question", - "operationId": "UpdateQuestion", + "description": "Update an existing answer", + "operationId": "UpdateAnswer", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateQuestionRequestContent" + "$ref": "#/components/schemas/QuestionAnswerUpdatePayload" } } - } + }, + "required": true }, "parameters": [ { @@ -12423,7 +12367,7 @@ "required": true }, { - "name": "questionId", + "name": "answerId", "in": "path", "schema": { "type": "integer", @@ -12433,15 +12377,8 @@ } ], "responses": { - "200": { - "description": "UpdateQuestion 200 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateQuestionResponseContent" - } - } - } + "204": { + "description": "UpdateAnswer 204 response" }, "401": { "description": "UnauthorizedError 401 response", @@ -12511,10 +12448,10 @@ } } }, - "/{accountId}/questions/{questionId}/answers.json": { + "/{accountId}/questionnaires/{questionnaireId}": { "get": { - "description": "List all answers for a question\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", - "operationId": "ListAnswers", + "description": "Get a questionnaire (automatic check-ins container) by id", + "operationId": "GetQuestionnaire", "parameters": [ { "name": "accountId", @@ -12528,7 +12465,7 @@ "required": true }, { - "name": "questionId", + "name": "questionnaireId", "in": "path", "schema": { "type": "integer", @@ -12539,11 +12476,11 @@ ], "responses": { "200": { - "description": "ListAnswers 200 response", + "description": "GetQuestionnaire 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListAnswersResponseContent" + "$ref": "#/components/schemas/GetQuestionnaireResponseContent" } } } @@ -12568,12 +12505,12 @@ } } }, - "429": { - "description": "RateLimitError 429 response", + "404": { + "description": "NotFoundError 404 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" } } } @@ -12592,11 +12529,6 @@ "tags": [ "Automation" ], - "x-basecamp-pagination": { - "style": "link", - "totalCountHeader": "X-Total-Count", - "maxPageSize": 50 - }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -12606,20 +12538,12 @@ 503 ] } - }, - "post": { - "description": "Create a new answer for a question", - "operationId": "CreateAnswer", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/QuestionAnswerPayload" - } - } - }, - "required": true - }, + } + }, + "/{accountId}/questionnaires/{questionnaireId}/questions.json": { + "get": { + "description": "List all questions in a questionnaire\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", + "operationId": "ListQuestions", "parameters": [ { "name": "accountId", @@ -12633,7 +12557,7 @@ "required": true }, { - "name": "questionId", + "name": "questionnaireId", "in": "path", "schema": { "type": "integer", @@ -12643,12 +12567,12 @@ } ], "responses": { - "201": { - "description": "CreateAnswer 201 response", + "200": { + "description": "ListQuestions 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateAnswerResponseContent" + "$ref": "#/components/schemas/ListQuestionsResponseContent" } } } @@ -12673,16 +12597,6 @@ } } }, - "422": { - "description": "ValidationError 422 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" - } - } - } - }, "429": { "description": "RateLimitError 429 response", "content": { @@ -12707,8 +12621,13 @@ "tags": [ "Automation" ], + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + }, "x-basecamp-retry": { - "maxAttempts": 2, + "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -12716,12 +12635,20 @@ 503 ] } - } - }, - "/{accountId}/questions/{questionId}/answers/by.json": { - "get": { - "description": "List all people who have answered a question (answerers)\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages.", - "operationId": "ListQuestionAnswerers", + }, + "post": { + "description": "Create a new question in a questionnaire", + "operationId": "CreateQuestion", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateQuestionRequestContent" + } + } + }, + "required": true + }, "parameters": [ { "name": "accountId", @@ -12735,7 +12662,7 @@ "required": true }, { - "name": "questionId", + "name": "questionnaireId", "in": "path", "schema": { "type": "integer", @@ -12745,12 +12672,12 @@ } ], "responses": { - "200": { - "description": "ListQuestionAnswerers 200 response", + "201": { + "description": "CreateQuestion 201 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListQuestionAnswerersResponseContent" + "$ref": "#/components/schemas/CreateQuestionResponseContent" } } } @@ -12775,12 +12702,12 @@ } } }, - "404": { - "description": "NotFoundError 404 response", + "422": { + "description": "ValidationError 422 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/ValidationErrorResponseContent" } } } @@ -12806,12 +12733,11 @@ } } }, - "x-basecamp-pagination": { - "style": "link", - "maxPageSize": 50 - }, + "tags": [ + "Automation" + ], "x-basecamp-retry": { - "maxAttempts": 3, + "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -12821,10 +12747,10 @@ } } }, - "/{accountId}/questions/{questionId}/answers/by/{personId}": { + "/{accountId}/questions/{questionId}": { "get": { - "description": "Get all answers from a specific person for a question\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages.", - "operationId": "GetAnswersByPerson", + "description": "Get a single question by id", + "operationId": "GetQuestion", "parameters": [ { "name": "accountId", @@ -12845,24 +12771,15 @@ "format": "int64" }, "required": true - }, - { - "name": "personId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true } ], "responses": { "200": { - "description": "GetAnswersByPerson 200 response", + "description": "GetQuestion 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetAnswersByPersonResponseContent" + "$ref": "#/components/schemas/GetQuestionResponseContent" } } } @@ -12897,16 +12814,6 @@ } } }, - "429": { - "description": "RateLimitError 429 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" - } - } - } - }, "500": { "description": "InternalServerError 500 response", "content": { @@ -12918,10 +12825,9 @@ } } }, - "x-basecamp-pagination": { - "style": "link", - "maxPageSize": 50 - }, + "tags": [ + "Automation" + ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -12931,17 +12837,15 @@ 503 ] } - } - }, - "/{accountId}/questions/{questionId}/notification_settings.json": { + }, "put": { - "description": "Update notification settings for a check-in question", - "operationId": "UpdateQuestionNotificationSettings", + "description": "Update an existing question", + "operationId": "UpdateQuestion", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateQuestionNotificationSettingsRequestContent" + "$ref": "#/components/schemas/UpdateQuestionRequestContent" } } } @@ -12970,11 +12874,11 @@ ], "responses": { "200": { - "description": "UpdateQuestionNotificationSettings 200 response", + "description": "UpdateQuestion 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateQuestionNotificationSettingsResponseContent" + "$ref": "#/components/schemas/UpdateQuestionResponseContent" } } } @@ -13030,6 +12934,9 @@ } } }, + "tags": [ + "Automation" + ], "x-basecamp-idempotent": { "natural": true }, @@ -13044,10 +12951,10 @@ } } }, - "/{accountId}/questions/{questionId}/pause.json": { - "delete": { - "description": "Resume a paused check-in question (resumes sending reminders)", - "operationId": "ResumeQuestion", + "/{accountId}/questions/{questionId}/answers.json": { + "get": { + "description": "List all answers for a question\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", + "operationId": "ListAnswers", "parameters": [ { "name": "accountId", @@ -13072,11 +12979,11 @@ ], "responses": { "200": { - "description": "ResumeQuestion 200 response", + "description": "ListAnswers 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ResumeQuestionResponseContent" + "$ref": "#/components/schemas/ListAnswersResponseContent" } } } @@ -13101,12 +13008,12 @@ } } }, - "404": { - "description": "NotFoundError 404 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -13122,8 +13029,13 @@ } } }, - "x-basecamp-idempotent": { - "natural": true + "tags": [ + "Automation" + ], + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 }, "x-basecamp-retry": { "maxAttempts": 3, @@ -13136,19 +13048,29 @@ } }, "post": { - "description": "Pause a check-in question (stops sending reminders)", - "operationId": "PauseQuestion", - "parameters": [ - { - "name": "accountId", - "in": "path", - "description": "Basecamp account ID (numeric string)", - "schema": { - "type": "string", - "pattern": "^[0-9]+$", - "description": "Basecamp account ID (numeric string)" - }, - "required": true + "description": "Create a new answer for a question", + "operationId": "CreateAnswer", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/QuestionAnswerPayload" + } + } + }, + "required": true + }, + "parameters": [ + { + "name": "accountId", + "in": "path", + "description": "Basecamp account ID (numeric string)", + "schema": { + "type": "string", + "pattern": "^[0-9]+$", + "description": "Basecamp account ID (numeric string)" + }, + "required": true }, { "name": "questionId", @@ -13161,12 +13083,12 @@ } ], "responses": { - "200": { - "description": "PauseQuestion 200 response", + "201": { + "description": "CreateAnswer 201 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PauseQuestionResponseContent" + "$ref": "#/components/schemas/CreateAnswerResponseContent" } } } @@ -13191,12 +13113,12 @@ } } }, - "404": { - "description": "NotFoundError 404 response", + "422": { + "description": "ValidationError 422 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/ValidationErrorResponseContent" } } } @@ -13222,11 +13144,11 @@ } } }, - "x-basecamp-idempotent": { - "natural": true - }, + "tags": [ + "Automation" + ], "x-basecamp-retry": { - "maxAttempts": 3, + "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -13236,10 +13158,10 @@ } } }, - "/{accountId}/recordings/{messageId}/pin.json": { - "delete": { - "description": "Unpin a message from the message board", - "operationId": "UnpinMessage", + "/{accountId}/questions/{questionId}/answers/by.json": { + "get": { + "description": "List all people who have answered a question (answerers)\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages.", + "operationId": "ListQuestionAnswerers", "parameters": [ { "name": "accountId", @@ -13253,7 +13175,7 @@ "required": true }, { - "name": "messageId", + "name": "questionId", "in": "path", "schema": { "type": "integer", @@ -13263,8 +13185,15 @@ } ], "responses": { - "204": { - "description": "UnpinMessage 204 response" + "200": { + "description": "ListQuestionAnswerers 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListQuestionAnswerersResponseContent" + } + } + } }, "401": { "description": "UnauthorizedError 401 response", @@ -13296,6 +13225,16 @@ } } }, + "429": { + "description": "RateLimitError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RateLimitErrorResponseContent" + } + } + } + }, "500": { "description": "InternalServerError 500 response", "content": { @@ -13307,11 +13246,9 @@ } } }, - "tags": [ - "Messages" - ], - "x-basecamp-idempotent": { - "natural": true + "x-basecamp-pagination": { + "style": "link", + "maxPageSize": 50 }, "x-basecamp-retry": { "maxAttempts": 3, @@ -13322,10 +13259,12 @@ 503 ] } - }, - "post": { - "description": "Pin a message to the top of the message board", - "operationId": "PinMessage", + } + }, + "/{accountId}/questions/{questionId}/answers/by/{personId}": { + "get": { + "description": "Get all answers from a specific person for a question\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages.", + "operationId": "GetAnswersByPerson", "parameters": [ { "name": "accountId", @@ -13339,7 +13278,16 @@ "required": true }, { - "name": "messageId", + "name": "questionId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true + }, + { + "name": "personId", "in": "path", "schema": { "type": "integer", @@ -13349,8 +13297,15 @@ } ], "responses": { - "204": { - "description": "PinMessage 204 response" + "200": { + "description": "GetAnswersByPerson 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetAnswersByPersonResponseContent" + } + } + } }, "401": { "description": "UnauthorizedError 401 response", @@ -13372,12 +13327,12 @@ } } }, - "422": { - "description": "ValidationError 422 response", + "404": { + "description": "NotFoundError 404 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" } } } @@ -13403,11 +13358,12 @@ } } }, - "tags": [ - "Messages" - ], + "x-basecamp-pagination": { + "style": "link", + "maxPageSize": 50 + }, "x-basecamp-retry": { - "maxAttempts": 2, + "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -13417,10 +13373,19 @@ } } }, - "/{accountId}/recordings/{recordingId}": { - "get": { - "description": "Get a single recording by id", - "operationId": "GetRecording", + "/{accountId}/questions/{questionId}/notification_settings.json": { + "put": { + "description": "Update notification settings for a check-in question", + "operationId": "UpdateQuestionNotificationSettings", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateQuestionNotificationSettingsRequestContent" + } + } + } + }, "parameters": [ { "name": "accountId", @@ -13434,7 +13399,7 @@ "required": true }, { - "name": "recordingId", + "name": "questionId", "in": "path", "schema": { "type": "integer", @@ -13445,11 +13410,11 @@ ], "responses": { "200": { - "description": "GetRecording 200 response", + "description": "UpdateQuestionNotificationSettings 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetRecordingResponseContent" + "$ref": "#/components/schemas/UpdateQuestionNotificationSettingsResponseContent" } } } @@ -13484,6 +13449,16 @@ } } }, + "422": { + "description": "ValidationError 422 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponseContent" + } + } + } + }, "500": { "description": "InternalServerError 500 response", "content": { @@ -13495,9 +13470,9 @@ } } }, - "tags": [ - "Automation" - ], + "x-basecamp-idempotent": { + "natural": true + }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -13509,10 +13484,10 @@ } } }, - "/{accountId}/recordings/{recordingId}/boosts.json": { - "get": { - "description": "List boosts on a recording", - "operationId": "ListRecordingBoosts", + "/{accountId}/questions/{questionId}/pause.json": { + "delete": { + "description": "Resume a paused check-in question (resumes sending reminders)", + "operationId": "ResumeQuestion", "parameters": [ { "name": "accountId", @@ -13526,7 +13501,7 @@ "required": true }, { - "name": "recordingId", + "name": "questionId", "in": "path", "schema": { "type": "integer", @@ -13537,11 +13512,11 @@ ], "responses": { "200": { - "description": "ListRecordingBoosts 200 response", + "description": "ResumeQuestion 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListRecordingBoostsResponseContent" + "$ref": "#/components/schemas/ResumeQuestionResponseContent" } } } @@ -13587,13 +13562,8 @@ } } }, - "tags": [ - "Boosts" - ], - "x-basecamp-pagination": { - "style": "link", - "totalCountHeader": "X-Total-Count", - "maxPageSize": 50 + "x-basecamp-idempotent": { + "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, @@ -13606,18 +13576,8 @@ } }, "post": { - "description": "Create a boost on a recording", - "operationId": "CreateRecordingBoost", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateRecordingBoostRequestContent" - } - } - }, - "required": true - }, + "description": "Pause a check-in question (stops sending reminders)", + "operationId": "PauseQuestion", "parameters": [ { "name": "accountId", @@ -13631,7 +13591,7 @@ "required": true }, { - "name": "recordingId", + "name": "questionId", "in": "path", "schema": { "type": "integer", @@ -13641,12 +13601,12 @@ } ], "responses": { - "201": { - "description": "CreateRecordingBoost 201 response", + "200": { + "description": "PauseQuestion 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateRecordingBoostResponseContent" + "$ref": "#/components/schemas/PauseQuestionResponseContent" } } } @@ -13671,12 +13631,12 @@ } } }, - "422": { - "description": "ValidationError 422 response", + "404": { + "description": "NotFoundError 404 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" } } } @@ -13702,11 +13662,11 @@ } } }, - "tags": [ - "Boosts" - ], + "x-basecamp-idempotent": { + "natural": true + }, "x-basecamp-retry": { - "maxAttempts": 2, + "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -13716,20 +13676,10 @@ } } }, - "/{accountId}/recordings/{recordingId}/client_visibility.json": { - "put": { - "description": "Set client visibility for a recording", - "operationId": "SetClientVisibility", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/SetClientVisibilityRequestContent" - } - } - }, - "required": true - }, + "/{accountId}/recordings/{messageId}/pin.json": { + "delete": { + "description": "Unpin a message from the message board", + "operationId": "UnpinMessage", "parameters": [ { "name": "accountId", @@ -13743,7 +13693,7 @@ "required": true }, { - "name": "recordingId", + "name": "messageId", "in": "path", "schema": { "type": "integer", @@ -13753,22 +13703,15 @@ } ], "responses": { - "200": { - "description": "SetClientVisibility 200 response", + "204": { + "description": "UnpinMessage 204 response" + }, + "401": { + "description": "UnauthorizedError 401 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SetClientVisibilityResponseContent" - } - } - } - }, - "401": { - "description": "UnauthorizedError 401 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UnauthorizedErrorResponseContent" + "$ref": "#/components/schemas/UnauthorizedErrorResponseContent" } } } @@ -13793,16 +13736,6 @@ } } }, - "422": { - "description": "ValidationError 422 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" - } - } - } - }, "500": { "description": "InternalServerError 500 response", "content": { @@ -13815,7 +13748,7 @@ } }, "tags": [ - "ClientFeatures" + "Messages" ], "x-basecamp-idempotent": { "natural": true @@ -13829,117 +13762,10 @@ 503 ] } - } - }, - "/{accountId}/recordings/{recordingId}/comments.json": { - "get": { - "description": "List comments on a recording\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", - "operationId": "ListComments", - "parameters": [ - { - "name": "accountId", - "in": "path", - "description": "Basecamp account ID (numeric string)", - "schema": { - "type": "string", - "pattern": "^[0-9]+$", - "description": "Basecamp account ID (numeric string)" - }, - "required": true - }, - { - "name": "recordingId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true - } - ], - "responses": { - "200": { - "description": "ListComments 200 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ListCommentsResponseContent" - } - } - } - }, - "401": { - "description": "UnauthorizedError 401 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UnauthorizedErrorResponseContent" - } - } - } - }, - "403": { - "description": "ForbiddenError 403 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ForbiddenErrorResponseContent" - } - } - } - }, - "429": { - "description": "RateLimitError 429 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" - } - } - } - }, - "500": { - "description": "InternalServerError 500 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/InternalServerErrorResponseContent" - } - } - } - } - }, - "tags": [ - "Messages" - ], - "x-basecamp-pagination": { - "style": "link", - "totalCountHeader": "X-Total-Count", - "maxPageSize": 50 - }, - "x-basecamp-retry": { - "maxAttempts": 3, - "baseDelayMs": 1000, - "backoff": "exponential", - "retryOn": [ - 429, - 503 - ] - } }, "post": { - "description": "Create a new comment on a recording", - "operationId": "CreateComment", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateCommentRequestContent" - } - } - }, - "required": true - }, + "description": "Pin a message to the top of the message board", + "operationId": "PinMessage", "parameters": [ { "name": "accountId", @@ -13953,7 +13779,7 @@ "required": true }, { - "name": "recordingId", + "name": "messageId", "in": "path", "schema": { "type": "integer", @@ -13963,15 +13789,8 @@ } ], "responses": { - "201": { - "description": "CreateComment 201 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateCommentResponseContent" - } - } - } + "204": { + "description": "PinMessage 204 response" }, "401": { "description": "UnauthorizedError 401 response", @@ -14038,10 +13857,10 @@ } } }, - "/{accountId}/recordings/{recordingId}/events.json": { + "/{accountId}/recordings/{recordingId}": { "get": { - "description": "List all events for a recording\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", - "operationId": "ListEvents", + "description": "Get a single recording by id", + "operationId": "GetRecording", "parameters": [ { "name": "accountId", @@ -14066,11 +13885,11 @@ ], "responses": { "200": { - "description": "ListEvents 200 response", + "description": "GetRecording 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListEventsResponseContent" + "$ref": "#/components/schemas/GetRecordingResponseContent" } } } @@ -14095,12 +13914,12 @@ } } }, - "429": { - "description": "RateLimitError 429 response", + "404": { + "description": "NotFoundError 404 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" } } } @@ -14119,11 +13938,6 @@ "tags": [ "Automation" ], - "x-basecamp-pagination": { - "style": "link", - "totalCountHeader": "X-Total-Count", - "maxPageSize": 50 - }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -14135,10 +13949,10 @@ } } }, - "/{accountId}/recordings/{recordingId}/events/{eventId}/boosts.json": { + "/{accountId}/recordings/{recordingId}/boosts.json": { "get": { - "description": "List boosts on a specific event within a recording", - "operationId": "ListEventBoosts", + "description": "List boosts on a recording", + "operationId": "ListRecordingBoosts", "parameters": [ { "name": "accountId", @@ -14159,24 +13973,15 @@ "format": "int64" }, "required": true - }, - { - "name": "eventId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true } ], "responses": { "200": { - "description": "ListEventBoosts 200 response", + "description": "ListRecordingBoosts 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListEventBoostsResponseContent" + "$ref": "#/components/schemas/ListRecordingBoostsResponseContent" } } } @@ -14241,13 +14046,13 @@ } }, "post": { - "description": "Create a boost on a specific event within a recording", - "operationId": "CreateEventBoost", + "description": "Create a boost on a recording", + "operationId": "CreateRecordingBoost", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateEventBoostRequestContent" + "$ref": "#/components/schemas/CreateRecordingBoostRequestContent" } } }, @@ -14273,24 +14078,15 @@ "format": "int64" }, "required": true - }, - { - "name": "eventId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true } ], "responses": { "201": { - "description": "CreateEventBoost 201 response", + "description": "CreateRecordingBoost 201 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateEventBoostResponseContent" + "$ref": "#/components/schemas/CreateRecordingBoostResponseContent" } } } @@ -14360,10 +14156,20 @@ } } }, - "/{accountId}/recordings/{recordingId}/status/active.json": { + "/{accountId}/recordings/{recordingId}/client_visibility.json": { "put": { - "description": "Unarchive a recording (restore to active status)", - "operationId": "UnarchiveRecording", + "description": "Set client visibility for a recording", + "operationId": "SetClientVisibility", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SetClientVisibilityRequestContent" + } + } + }, + "required": true + }, "parameters": [ { "name": "accountId", @@ -14387,8 +14193,15 @@ } ], "responses": { - "204": { - "description": "UnarchiveRecording 204 response" + "200": { + "description": "SetClientVisibility 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SetClientVisibilityResponseContent" + } + } + } }, "401": { "description": "UnauthorizedError 401 response", @@ -14442,7 +14255,7 @@ } }, "tags": [ - "Automation" + "ClientFeatures" ], "x-basecamp-idempotent": { "natural": true @@ -14458,10 +14271,10 @@ } } }, - "/{accountId}/recordings/{recordingId}/status/archived.json": { - "put": { - "description": "Archive a recording", - "operationId": "ArchiveRecording", + "/{accountId}/recordings/{recordingId}/comments.json": { + "get": { + "description": "List comments on a recording\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", + "operationId": "ListComments", "parameters": [ { "name": "accountId", @@ -14485,8 +14298,15 @@ } ], "responses": { - "204": { - "description": "ArchiveRecording 204 response" + "200": { + "description": "ListComments 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListCommentsResponseContent" + } + } + } }, "401": { "description": "UnauthorizedError 401 response", @@ -14508,22 +14328,12 @@ } } }, - "404": { - "description": "NotFoundError 404 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" - } - } - } - }, - "422": { - "description": "ValidationError 422 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -14540,10 +14350,12 @@ } }, "tags": [ - "Automation" + "Messages" ], - "x-basecamp-idempotent": { - "natural": true + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 }, "x-basecamp-retry": { "maxAttempts": 3, @@ -14554,12 +14366,20 @@ 503 ] } - } - }, - "/{accountId}/recordings/{recordingId}/status/trashed.json": { - "put": { - "description": "Trash a recording", - "operationId": "TrashRecording", + }, + "post": { + "description": "Create a new comment on a recording", + "operationId": "CreateComment", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateCommentRequestContent" + } + } + }, + "required": true + }, "parameters": [ { "name": "accountId", @@ -14570,14 +14390,7 @@ "pattern": "^[0-9]+$", "description": "Basecamp account ID (numeric string)" }, - "required": true, - "examples": { - "TrashRecording_example1": { - "summary": "Trash any recording type", - "description": "Works on comments, messages, documents, cards - any recording", - "value": "999" - } - } + "required": true }, { "name": "recordingId", @@ -14586,19 +14399,19 @@ "type": "integer", "format": "int64" }, - "required": true, - "examples": { - "TrashRecording_example1": { - "summary": "Trash any recording type", - "description": "Works on comments, messages, documents, cards - any recording", - "value": 555666 - } - } + "required": true } ], "responses": { - "204": { - "description": "TrashRecording 204 response" + "201": { + "description": "CreateComment 201 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateCommentResponseContent" + } + } + } }, "401": { "description": "UnauthorizedError 401 response", @@ -14620,22 +14433,22 @@ } } }, - "404": { - "description": "NotFoundError 404 response", + "422": { + "description": "ValidationError 422 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/ValidationErrorResponseContent" } } } }, - "422": { - "description": "ValidationError 422 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -14652,13 +14465,10 @@ } }, "tags": [ - "Automation" + "Messages" ], - "x-basecamp-idempotent": { - "natural": true - }, "x-basecamp-retry": { - "maxAttempts": 3, + "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -14668,10 +14478,10 @@ } } }, - "/{accountId}/recordings/{recordingId}/subscription.json": { - "delete": { - "description": "Unsubscribe the current user from a recording", - "operationId": "Unsubscribe", + "/{accountId}/recordings/{recordingId}/events.json": { + "get": { + "description": "List all events for a recording\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", + "operationId": "ListEvents", "parameters": [ { "name": "accountId", @@ -14695,8 +14505,15 @@ } ], "responses": { - "204": { - "description": "Unsubscribe 204 response" + "200": { + "description": "ListEvents 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListEventsResponseContent" + } + } + } }, "401": { "description": "UnauthorizedError 401 response", @@ -14718,12 +14535,12 @@ } } }, - "404": { - "description": "NotFoundError 404 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -14740,10 +14557,12 @@ } }, "tags": [ - "People" + "Automation" ], - "x-basecamp-idempotent": { - "natural": true + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 }, "x-basecamp-retry": { "maxAttempts": 3, @@ -14754,10 +14573,12 @@ 503 ] } - }, + } + }, + "/{accountId}/recordings/{recordingId}/events/{eventId}/boosts.json": { "get": { - "description": "Get subscription information for a recording", - "operationId": "GetSubscription", + "description": "List boosts on a specific event within a recording", + "operationId": "ListEventBoosts", "parameters": [ { "name": "accountId", @@ -14778,15 +14599,24 @@ "format": "int64" }, "required": true + }, + { + "name": "eventId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true } ], "responses": { "200": { - "description": "GetSubscription 200 response", + "description": "ListEventBoosts 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetSubscriptionResponseContent" + "$ref": "#/components/schemas/ListEventBoostsResponseContent" } } } @@ -14833,8 +14663,13 @@ } }, "tags": [ - "People" + "Boosts" ], + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -14846,8 +14681,18 @@ } }, "post": { - "description": "Subscribe the current user to a recording", - "operationId": "Subscribe", + "description": "Create a boost on a specific event within a recording", + "operationId": "CreateEventBoost", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateEventBoostRequestContent" + } + } + }, + "required": true + }, "parameters": [ { "name": "accountId", @@ -14868,15 +14713,24 @@ "format": "int64" }, "required": true + }, + { + "name": "eventId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true } ], "responses": { - "200": { - "description": "Subscribe 200 response", + "201": { + "description": "CreateEventBoost 201 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SubscribeResponseContent" + "$ref": "#/components/schemas/CreateEventBoostResponseContent" } } } @@ -14933,7 +14787,7 @@ } }, "tags": [ - "People" + "Boosts" ], "x-basecamp-retry": { "maxAttempts": 2, @@ -14944,40 +14798,12 @@ 503 ] } - }, + } + }, + "/{accountId}/recordings/{recordingId}/status/active.json": { "put": { - "description": "Update subscriptions by adding or removing specific users", - "operationId": "UpdateSubscription", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateSubscriptionRequestContent" - }, - "examples": { - "UpdateSubscription_example1": { - "summary": "Add subscribers", - "description": "", - "value": { - "subscriptions": [ - 111, - 222 - ] - } - }, - "UpdateSubscription_example2": { - "summary": "Remove subscribers", - "description": "", - "value": { - "unsubscriptions": [ - 333 - ] - } - } - } - } - } - }, + "description": "Unarchive a recording (restore to active status)", + "operationId": "UnarchiveRecording", "parameters": [ { "name": "accountId", @@ -14988,19 +14814,7 @@ "pattern": "^[0-9]+$", "description": "Basecamp account ID (numeric string)" }, - "required": true, - "examples": { - "UpdateSubscription_example1": { - "summary": "Add subscribers", - "description": "", - "value": "999" - }, - "UpdateSubscription_example2": { - "summary": "Remove subscribers", - "description": "", - "value": "999" - } - } + "required": true }, { "name": "recordingId", @@ -15009,46 +14823,15 @@ "type": "integer", "format": "int64" }, - "required": true, - "examples": { - "UpdateSubscription_example1": { - "summary": "Add subscribers", - "description": "", - "value": 987654 - }, - "UpdateSubscription_example2": { - "summary": "Remove subscribers", - "description": "", - "value": 987654 - } - } + "required": true } ], "responses": { - "200": { - "description": "UpdateSubscription 200 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateSubscriptionResponseContent" - }, - "examples": { - "UpdateSubscription_example1": { - "summary": "Add subscribers", - "description": "", - "value": {} - }, - "UpdateSubscription_example2": { - "summary": "Remove subscribers", - "description": "", - "value": {} - } - } - } - } - }, - "401": { - "description": "UnauthorizedError 401 response", + "204": { + "description": "UnarchiveRecording 204 response" + }, + "401": { + "description": "UnauthorizedError 401 response", "content": { "application/json": { "schema": { @@ -15099,7 +14882,7 @@ } }, "tags": [ - "People" + "Automation" ], "x-basecamp-idempotent": { "natural": true @@ -15115,10 +14898,10 @@ } } }, - "/{accountId}/recordings/{recordingId}/timesheet.json": { - "get": { - "description": "Get timesheet for a specific recording", - "operationId": "GetRecordingTimesheet", + "/{accountId}/recordings/{recordingId}/status/archived.json": { + "put": { + "description": "Archive a recording", + "operationId": "ArchiveRecording", "parameters": [ { "name": "accountId", @@ -15139,40 +14922,11 @@ "format": "int64" }, "required": true - }, - { - "name": "from", - "in": "query", - "schema": { - "type": "string" - } - }, - { - "name": "to", - "in": "query", - "schema": { - "type": "string" - } - }, - { - "name": "person_id", - "in": "query", - "schema": { - "type": "integer", - "format": "int64" - } } ], "responses": { - "200": { - "description": "GetRecordingTimesheet 200 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/GetRecordingTimesheetResponseContent" - } - } - } + "204": { + "description": "ArchiveRecording 204 response" }, "401": { "description": "UnauthorizedError 401 response", @@ -15204,6 +14958,16 @@ } } }, + "422": { + "description": "ValidationError 422 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponseContent" + } + } + } + }, "500": { "description": "InternalServerError 500 response", "content": { @@ -15216,12 +14980,10 @@ } }, "tags": [ - "Schedule" + "Automation" ], - "x-basecamp-pagination": { - "style": "link", - "totalCountHeader": "X-Total-Count", - "maxPageSize": 50 + "x-basecamp-idempotent": { + "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, @@ -15234,20 +14996,10 @@ } } }, - "/{accountId}/recordings/{recordingId}/timesheet/entries.json": { - "post": { - "description": "Create a timesheet entry on a recording", - "operationId": "CreateTimesheetEntry", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateTimesheetEntryRequestContent" - } - } - }, - "required": true - }, + "/{accountId}/recordings/{recordingId}/status/trashed.json": { + "put": { + "description": "Trash a recording", + "operationId": "TrashRecording", "parameters": [ { "name": "accountId", @@ -15258,7 +15010,14 @@ "pattern": "^[0-9]+$", "description": "Basecamp account ID (numeric string)" }, - "required": true + "required": true, + "examples": { + "TrashRecording_example1": { + "summary": "Trash any recording type", + "description": "Works on comments, messages, documents, cards - any recording", + "value": "999" + } + } }, { "name": "recordingId", @@ -15267,19 +15026,19 @@ "type": "integer", "format": "int64" }, - "required": true + "required": true, + "examples": { + "TrashRecording_example1": { + "summary": "Trash any recording type", + "description": "Works on comments, messages, documents, cards - any recording", + "value": 555666 + } + } } ], "responses": { - "201": { - "description": "CreateTimesheetEntry 201 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateTimesheetEntryResponseContent" - } - } - } + "204": { + "description": "TrashRecording 204 response" }, "401": { "description": "UnauthorizedError 401 response", @@ -15301,22 +15060,22 @@ } } }, - "422": { - "description": "ValidationError 422 response", + "404": { + "description": "NotFoundError 404 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" } } } }, - "429": { - "description": "RateLimitError 429 response", + "422": { + "description": "ValidationError 422 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" + "$ref": "#/components/schemas/ValidationErrorResponseContent" } } } @@ -15333,8 +15092,11 @@ } }, "tags": [ - "Schedule" + "Automation" ], + "x-basecamp-idempotent": { + "natural": true + }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -15346,10 +15108,10 @@ } } }, - "/{accountId}/recordings/{toolId}/position.json": { + "/{accountId}/recordings/{recordingId}/subscription.json": { "delete": { - "description": "Disable a tool (hide it from the project dock)", - "operationId": "DisableTool", + "description": "Unsubscribe the current user from a recording", + "operationId": "Unsubscribe", "parameters": [ { "name": "accountId", @@ -15363,7 +15125,7 @@ "required": true }, { - "name": "toolId", + "name": "recordingId", "in": "path", "schema": { "type": "integer", @@ -15374,7 +15136,7 @@ ], "responses": { "204": { - "description": "DisableTool 204 response" + "description": "Unsubscribe 204 response" }, "401": { "description": "UnauthorizedError 401 response", @@ -15418,7 +15180,7 @@ } }, "tags": [ - "Automation" + "People" ], "x-basecamp-idempotent": { "natural": true @@ -15433,9 +15195,9 @@ ] } }, - "post": { - "description": "Enable a tool (show it on the project dock)", - "operationId": "EnableTool", + "get": { + "description": "Get subscription information for a recording", + "operationId": "GetSubscription", "parameters": [ { "name": "accountId", @@ -15449,7 +15211,7 @@ "required": true }, { - "name": "toolId", + "name": "recordingId", "in": "path", "schema": { "type": "integer", @@ -15459,45 +15221,42 @@ } ], "responses": { - "201": { - "description": "EnableTool 201 response" - }, - "401": { - "description": "UnauthorizedError 401 response", + "200": { + "description": "GetSubscription 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UnauthorizedErrorResponseContent" + "$ref": "#/components/schemas/GetSubscriptionResponseContent" } } } }, - "403": { - "description": "ForbiddenError 403 response", + "401": { + "description": "UnauthorizedError 401 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + "$ref": "#/components/schemas/UnauthorizedErrorResponseContent" } } } }, - "422": { - "description": "ValidationError 422 response", + "403": { + "description": "ForbiddenError 403 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" } } } }, - "429": { - "description": "RateLimitError 429 response", + "404": { + "description": "NotFoundError 404 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" } } } @@ -15514,10 +15273,10 @@ } }, "tags": [ - "Automation" + "People" ], "x-basecamp-retry": { - "maxAttempts": 2, + "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -15526,19 +15285,9 @@ ] } }, - "put": { - "description": "Reposition a tool on the project dock", - "operationId": "RepositionTool", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/RepositionToolRequestContent" - } - } - }, - "required": true - }, + "post": { + "description": "Subscribe the current user to a recording", + "operationId": "Subscribe", "parameters": [ { "name": "accountId", @@ -15552,7 +15301,7 @@ "required": true }, { - "name": "toolId", + "name": "recordingId", "in": "path", "schema": { "type": "integer", @@ -15563,7 +15312,14 @@ ], "responses": { "200": { - "description": "RepositionTool 200 response" + "description": "Subscribe 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SubscribeResponseContent" + } + } + } }, "401": { "description": "UnauthorizedError 401 response", @@ -15585,22 +15341,22 @@ } } }, - "404": { - "description": "NotFoundError 404 response", + "422": { + "description": "ValidationError 422 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/ValidationErrorResponseContent" } } } }, - "422": { - "description": "ValidationError 422 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -15617,13 +15373,10 @@ } }, "tags": [ - "Automation" + "People" ], - "x-basecamp-idempotent": { - "natural": true - }, "x-basecamp-retry": { - "maxAttempts": 3, + "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -15631,41 +15384,915 @@ 503 ] } - } - }, - "/{accountId}/reports/gauges.json": { - "get": { - "description": "List gauges across all projects the authenticated user has access to.\nGauges are sorted by risk level (red, yellow, green), then alphabetically.", - "operationId": "ListGauges", - "parameters": [ - { - "name": "accountId", - "in": "path", - "description": "Basecamp account ID (numeric string)", - "schema": { - "type": "string", - "pattern": "^[0-9]+$", + }, + "put": { + "description": "Update subscriptions by adding or removing specific users", + "operationId": "UpdateSubscription", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateSubscriptionRequestContent" + }, + "examples": { + "UpdateSubscription_example1": { + "summary": "Add subscribers", + "description": "", + "value": { + "subscriptions": [ + 111, + 222 + ] + } + }, + "UpdateSubscription_example2": { + "summary": "Remove subscribers", + "description": "", + "value": { + "unsubscriptions": [ + 333 + ] + } + } + } + } + } + }, + "parameters": [ + { + "name": "accountId", + "in": "path", + "description": "Basecamp account ID (numeric string)", + "schema": { + "type": "string", + "pattern": "^[0-9]+$", + "description": "Basecamp account ID (numeric string)" + }, + "required": true, + "examples": { + "UpdateSubscription_example1": { + "summary": "Add subscribers", + "description": "", + "value": "999" + }, + "UpdateSubscription_example2": { + "summary": "Remove subscribers", + "description": "", + "value": "999" + } + } + }, + { + "name": "recordingId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true, + "examples": { + "UpdateSubscription_example1": { + "summary": "Add subscribers", + "description": "", + "value": 987654 + }, + "UpdateSubscription_example2": { + "summary": "Remove subscribers", + "description": "", + "value": 987654 + } + } + } + ], + "responses": { + "200": { + "description": "UpdateSubscription 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateSubscriptionResponseContent" + }, + "examples": { + "UpdateSubscription_example1": { + "summary": "Add subscribers", + "description": "", + "value": {} + }, + "UpdateSubscription_example2": { + "summary": "Remove subscribers", + "description": "", + "value": {} + } + } + } + } + }, + "401": { + "description": "UnauthorizedError 401 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnauthorizedErrorResponseContent" + } + } + } + }, + "403": { + "description": "ForbiddenError 403 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + } + } + } + }, + "404": { + "description": "NotFoundError 404 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotFoundErrorResponseContent" + } + } + } + }, + "422": { + "description": "ValidationError 422 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponseContent" + } + } + } + }, + "500": { + "description": "InternalServerError 500 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InternalServerErrorResponseContent" + } + } + } + } + }, + "tags": [ + "People" + ], + "x-basecamp-idempotent": { + "natural": true + }, + "x-basecamp-retry": { + "maxAttempts": 3, + "baseDelayMs": 1000, + "backoff": "exponential", + "retryOn": [ + 429, + 503 + ] + } + } + }, + "/{accountId}/recordings/{recordingId}/timesheet.json": { + "get": { + "description": "Get timesheet for a specific recording", + "operationId": "GetRecordingTimesheet", + "parameters": [ + { + "name": "accountId", + "in": "path", + "description": "Basecamp account ID (numeric string)", + "schema": { + "type": "string", + "pattern": "^[0-9]+$", + "description": "Basecamp account ID (numeric string)" + }, + "required": true + }, + { + "name": "recordingId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true + }, + { + "name": "from", + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "to", + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "person_id", + "in": "query", + "schema": { + "type": "integer", + "format": "int64" + } + } + ], + "responses": { + "200": { + "description": "GetRecordingTimesheet 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetRecordingTimesheetResponseContent" + } + } + } + }, + "401": { + "description": "UnauthorizedError 401 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnauthorizedErrorResponseContent" + } + } + } + }, + "403": { + "description": "ForbiddenError 403 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + } + } + } + }, + "404": { + "description": "NotFoundError 404 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotFoundErrorResponseContent" + } + } + } + }, + "500": { + "description": "InternalServerError 500 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InternalServerErrorResponseContent" + } + } + } + } + }, + "tags": [ + "Schedule" + ], + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + }, + "x-basecamp-retry": { + "maxAttempts": 3, + "baseDelayMs": 1000, + "backoff": "exponential", + "retryOn": [ + 429, + 503 + ] + } + } + }, + "/{accountId}/recordings/{recordingId}/timesheet/entries.json": { + "post": { + "description": "Create a timesheet entry on a recording", + "operationId": "CreateTimesheetEntry", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateTimesheetEntryRequestContent" + } + } + }, + "required": true + }, + "parameters": [ + { + "name": "accountId", + "in": "path", + "description": "Basecamp account ID (numeric string)", + "schema": { + "type": "string", + "pattern": "^[0-9]+$", + "description": "Basecamp account ID (numeric string)" + }, + "required": true + }, + { + "name": "recordingId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true + } + ], + "responses": { + "201": { + "description": "CreateTimesheetEntry 201 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateTimesheetEntryResponseContent" + } + } + } + }, + "401": { + "description": "UnauthorizedError 401 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnauthorizedErrorResponseContent" + } + } + } + }, + "403": { + "description": "ForbiddenError 403 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + } + } + } + }, + "422": { + "description": "ValidationError 422 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponseContent" + } + } + } + }, + "429": { + "description": "RateLimitError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RateLimitErrorResponseContent" + } + } + } + }, + "500": { + "description": "InternalServerError 500 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InternalServerErrorResponseContent" + } + } + } + } + }, + "tags": [ + "Schedule" + ], + "x-basecamp-retry": { + "maxAttempts": 3, + "baseDelayMs": 1000, + "backoff": "exponential", + "retryOn": [ + 429, + 503 + ] + } + } + }, + "/{accountId}/recordings/{toolId}/position.json": { + "delete": { + "description": "Disable a tool (hide it from the project dock)", + "operationId": "DisableTool", + "parameters": [ + { + "name": "accountId", + "in": "path", + "description": "Basecamp account ID (numeric string)", + "schema": { + "type": "string", + "pattern": "^[0-9]+$", + "description": "Basecamp account ID (numeric string)" + }, + "required": true + }, + { + "name": "toolId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true + } + ], + "responses": { + "204": { + "description": "DisableTool 204 response" + }, + "401": { + "description": "UnauthorizedError 401 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnauthorizedErrorResponseContent" + } + } + } + }, + "403": { + "description": "ForbiddenError 403 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + } + } + } + }, + "404": { + "description": "NotFoundError 404 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotFoundErrorResponseContent" + } + } + } + }, + "500": { + "description": "InternalServerError 500 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InternalServerErrorResponseContent" + } + } + } + } + }, + "tags": [ + "Automation" + ], + "x-basecamp-idempotent": { + "natural": true + }, + "x-basecamp-retry": { + "maxAttempts": 3, + "baseDelayMs": 1000, + "backoff": "exponential", + "retryOn": [ + 429, + 503 + ] + } + }, + "post": { + "description": "Enable a tool (show it on the project dock)", + "operationId": "EnableTool", + "parameters": [ + { + "name": "accountId", + "in": "path", + "description": "Basecamp account ID (numeric string)", + "schema": { + "type": "string", + "pattern": "^[0-9]+$", + "description": "Basecamp account ID (numeric string)" + }, + "required": true + }, + { + "name": "toolId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true + } + ], + "responses": { + "201": { + "description": "EnableTool 201 response" + }, + "401": { + "description": "UnauthorizedError 401 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnauthorizedErrorResponseContent" + } + } + } + }, + "403": { + "description": "ForbiddenError 403 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + } + } + } + }, + "422": { + "description": "ValidationError 422 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponseContent" + } + } + } + }, + "429": { + "description": "RateLimitError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RateLimitErrorResponseContent" + } + } + } + }, + "500": { + "description": "InternalServerError 500 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InternalServerErrorResponseContent" + } + } + } + } + }, + "tags": [ + "Automation" + ], + "x-basecamp-retry": { + "maxAttempts": 2, + "baseDelayMs": 1000, + "backoff": "exponential", + "retryOn": [ + 429, + 503 + ] + } + }, + "put": { + "description": "Reposition a tool on the project dock", + "operationId": "RepositionTool", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RepositionToolRequestContent" + } + } + }, + "required": true + }, + "parameters": [ + { + "name": "accountId", + "in": "path", + "description": "Basecamp account ID (numeric string)", + "schema": { + "type": "string", + "pattern": "^[0-9]+$", + "description": "Basecamp account ID (numeric string)" + }, + "required": true + }, + { + "name": "toolId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true + } + ], + "responses": { + "200": { + "description": "RepositionTool 200 response" + }, + "401": { + "description": "UnauthorizedError 401 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnauthorizedErrorResponseContent" + } + } + } + }, + "403": { + "description": "ForbiddenError 403 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + } + } + } + }, + "404": { + "description": "NotFoundError 404 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotFoundErrorResponseContent" + } + } + } + }, + "422": { + "description": "ValidationError 422 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponseContent" + } + } + } + }, + "500": { + "description": "InternalServerError 500 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InternalServerErrorResponseContent" + } + } + } + } + }, + "tags": [ + "Automation" + ], + "x-basecamp-idempotent": { + "natural": true + }, + "x-basecamp-retry": { + "maxAttempts": 3, + "baseDelayMs": 1000, + "backoff": "exponential", + "retryOn": [ + 429, + 503 + ] + } + } + }, + "/{accountId}/reports/gauges.json": { + "get": { + "description": "List gauges across all projects the authenticated user has access to.\nGauges are sorted by risk level (red, yellow, green), then alphabetically.", + "operationId": "ListGauges", + "parameters": [ + { + "name": "accountId", + "in": "path", + "description": "Basecamp account ID (numeric string)", + "schema": { + "type": "string", + "pattern": "^[0-9]+$", + "description": "Basecamp account ID (numeric string)" + }, + "required": true + }, + { + "name": "bucket_ids", + "in": "query", + "description": "Comma-separated list of project IDs. When provided, results are returned\nin the order specified instead of by risk level.", + "schema": { + "type": "string", + "description": "Comma-separated list of project IDs. When provided, results are returned\nin the order specified instead of by risk level." + } + } + ], + "responses": { + "200": { + "description": "ListGauges 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListGaugesResponseContent" + } + } + } + }, + "401": { + "description": "UnauthorizedError 401 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnauthorizedErrorResponseContent" + } + } + } + }, + "403": { + "description": "ForbiddenError 403 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + } + } + } + }, + "429": { + "description": "RateLimitError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RateLimitErrorResponseContent" + } + } + } + }, + "500": { + "description": "InternalServerError 500 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InternalServerErrorResponseContent" + } + } + } + } + }, + "tags": [ + "Gauges" + ], + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + }, + "x-basecamp-retry": { + "maxAttempts": 3, + "baseDelayMs": 1000, + "backoff": "exponential", + "retryOn": [ + 429, + 503 + ] + } + } + }, + "/{accountId}/reports/progress.json": { + "get": { + "description": "Get account-wide activity feed (progress report)", + "operationId": "GetProgressReport", + "parameters": [ + { + "name": "accountId", + "in": "path", + "description": "Basecamp account ID (numeric string)", + "schema": { + "type": "string", + "pattern": "^[0-9]+$", + "description": "Basecamp account ID (numeric string)" + }, + "required": true + } + ], + "responses": { + "200": { + "description": "GetProgressReport 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetProgressReportResponseContent" + } + } + } + }, + "401": { + "description": "UnauthorizedError 401 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnauthorizedErrorResponseContent" + } + } + } + }, + "403": { + "description": "ForbiddenError 403 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + } + } + } + }, + "429": { + "description": "RateLimitError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RateLimitErrorResponseContent" + } + } + } + }, + "500": { + "description": "InternalServerError 500 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InternalServerErrorResponseContent" + } + } + } + } + }, + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + }, + "x-basecamp-retry": { + "maxAttempts": 3, + "baseDelayMs": 1000, + "backoff": "exponential", + "retryOn": [ + 429, + 503 + ] + } + } + }, + "/{accountId}/reports/schedules/upcoming.json": { + "get": { + "description": "Get upcoming schedule entries and assignable items within a date window.\nThis endpoint is preserved as the canonical API path on BC5;\nthe BC5 `/calendar` web view is HTML-only.", + "operationId": "GetUpcomingSchedule", + "parameters": [ + { + "name": "accountId", + "in": "path", + "description": "Basecamp account ID (numeric string)", + "schema": { + "type": "string", + "pattern": "^[0-9]+$", "description": "Basecamp account ID (numeric string)" }, "required": true }, { - "name": "bucket_ids", + "name": "window_starts_on", "in": "query", - "description": "Comma-separated list of project IDs. When provided, results are returned\nin the order specified instead of by risk level.", "schema": { - "type": "string", - "description": "Comma-separated list of project IDs. When provided, results are returned\nin the order specified instead of by risk level." + "type": "string" + } + }, + { + "name": "window_ends_on", + "in": "query", + "schema": { + "type": "string" } } ], "responses": { "200": { - "description": "ListGauges 200 response", + "description": "GetUpcomingSchedule 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListGaugesResponseContent" + "$ref": "#/components/schemas/GetUpcomingScheduleResponseContent" } } } @@ -15711,13 +16338,190 @@ } } }, + "x-basecamp-retry": { + "maxAttempts": 3, + "baseDelayMs": 1000, + "backoff": "exponential", + "retryOn": [ + 429, + 503 + ] + } + } + }, + "/{accountId}/reports/timesheet.json": { + "get": { + "description": "Get account-wide timesheet report", + "operationId": "GetTimesheetReport", + "parameters": [ + { + "name": "accountId", + "in": "path", + "description": "Basecamp account ID (numeric string)", + "schema": { + "type": "string", + "pattern": "^[0-9]+$", + "description": "Basecamp account ID (numeric string)" + }, + "required": true + }, + { + "name": "from", + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "to", + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "person_id", + "in": "query", + "schema": { + "type": "integer", + "format": "int64" + } + } + ], + "responses": { + "200": { + "description": "GetTimesheetReport 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetTimesheetReportResponseContent" + } + } + } + }, + "401": { + "description": "UnauthorizedError 401 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnauthorizedErrorResponseContent" + } + } + } + }, + "403": { + "description": "ForbiddenError 403 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + } + } + } + }, + "404": { + "description": "NotFoundError 404 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotFoundErrorResponseContent" + } + } + } + }, + "500": { + "description": "InternalServerError 500 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InternalServerErrorResponseContent" + } + } + } + } + }, "tags": [ - "Gauges" + "Schedule" ], - "x-basecamp-pagination": { - "style": "link", - "totalCountHeader": "X-Total-Count", - "maxPageSize": 50 + "x-basecamp-retry": { + "maxAttempts": 3, + "baseDelayMs": 1000, + "backoff": "exponential", + "retryOn": [ + 429, + 503 + ] + } + } + }, + "/{accountId}/reports/todos/assigned.json": { + "get": { + "description": "List people who can be assigned todos", + "operationId": "ListAssignablePeople", + "parameters": [ + { + "name": "accountId", + "in": "path", + "description": "Basecamp account ID (numeric string)", + "schema": { + "type": "string", + "pattern": "^[0-9]+$", + "description": "Basecamp account ID (numeric string)" + }, + "required": true + } + ], + "responses": { + "200": { + "description": "ListAssignablePeople 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListAssignablePeopleResponseContent" + } + } + } + }, + "401": { + "description": "UnauthorizedError 401 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnauthorizedErrorResponseContent" + } + } + } + }, + "403": { + "description": "ForbiddenError 403 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + } + } + } + }, + "429": { + "description": "RateLimitError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RateLimitErrorResponseContent" + } + } + } + }, + "500": { + "description": "InternalServerError 500 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InternalServerErrorResponseContent" + } + } + } + } }, "x-basecamp-retry": { "maxAttempts": 3, @@ -15730,10 +16534,10 @@ } } }, - "/{accountId}/reports/progress.json": { + "/{accountId}/reports/todos/assigned/{personId}": { "get": { - "description": "Get account-wide activity feed (progress report)", - "operationId": "GetProgressReport", + "description": "Get todos assigned to a specific person", + "operationId": "GetAssignedTodos", "parameters": [ { "name": "accountId", @@ -15741,19 +16545,37 @@ "description": "Basecamp account ID (numeric string)", "schema": { "type": "string", - "pattern": "^[0-9]+$", - "description": "Basecamp account ID (numeric string)" - }, - "required": true + "pattern": "^[0-9]+$", + "description": "Basecamp account ID (numeric string)" + }, + "required": true + }, + { + "name": "personId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true + }, + { + "name": "group_by", + "in": "query", + "description": "Group by \"bucket\" or \"date\"", + "schema": { + "type": "string", + "description": "Group by \"bucket\" or \"date\"" + } } ], "responses": { "200": { - "description": "GetProgressReport 200 response", + "description": "GetAssignedTodos 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetProgressReportResponseContent" + "$ref": "#/components/schemas/GetAssignedTodosResponseContent" } } } @@ -15778,6 +16600,16 @@ } } }, + "404": { + "description": "NotFoundError 404 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotFoundErrorResponseContent" + } + } + } + }, "429": { "description": "RateLimitError 429 response", "content": { @@ -15799,11 +16631,6 @@ } } }, - "x-basecamp-pagination": { - "style": "link", - "totalCountHeader": "X-Total-Count", - "maxPageSize": 50 - }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -15815,10 +16642,10 @@ } } }, - "/{accountId}/reports/schedules/upcoming.json": { + "/{accountId}/reports/todos/overdue.json": { "get": { - "description": "Get upcoming schedule entries and assignable items within a date window.\nThis endpoint is preserved as the canonical API path on BC5;\nthe BC5 `/calendar` web view is HTML-only.", - "operationId": "GetUpcomingSchedule", + "description": "Get overdue todos grouped by lateness", + "operationId": "GetOverdueTodos", "parameters": [ { "name": "accountId", @@ -15830,29 +16657,15 @@ "description": "Basecamp account ID (numeric string)" }, "required": true - }, - { - "name": "window_starts_on", - "in": "query", - "schema": { - "type": "string" - } - }, - { - "name": "window_ends_on", - "in": "query", - "schema": { - "type": "string" - } } ], "responses": { "200": { - "description": "GetUpcomingSchedule 200 response", + "description": "GetOverdueTodos 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetUpcomingScheduleResponseContent" + "$ref": "#/components/schemas/GetOverdueTodosResponseContent" } } } @@ -15909,10 +16722,10 @@ } } }, - "/{accountId}/reports/timesheet.json": { + "/{accountId}/reports/users/progress/{personId}.json": { "get": { - "description": "Get account-wide timesheet report", - "operationId": "GetTimesheetReport", + "description": "Get a person's activity timeline", + "operationId": "GetPersonProgress", "parameters": [ { "name": "accountId", @@ -15926,35 +16739,22 @@ "required": true }, { - "name": "from", - "in": "query", - "schema": { - "type": "string" - } - }, - { - "name": "to", - "in": "query", - "schema": { - "type": "string" - } - }, - { - "name": "person_id", - "in": "query", + "name": "personId", + "in": "path", "schema": { "type": "integer", "format": "int64" - } + }, + "required": true } ], "responses": { "200": { - "description": "GetTimesheetReport 200 response", + "description": "GetPersonProgress 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetTimesheetReportResponseContent" + "$ref": "#/components/schemas/GetPersonProgressResponseContent" } } } @@ -15989,6 +16789,16 @@ } } }, + "429": { + "description": "RateLimitError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RateLimitErrorResponseContent" + } + } + } + }, "500": { "description": "InternalServerError 500 response", "content": { @@ -16000,9 +16810,12 @@ } } }, - "tags": [ - "Schedule" - ], + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50, + "key": "events" + }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -16014,10 +16827,10 @@ } } }, - "/{accountId}/reports/todos/assigned.json": { + "/{accountId}/schedule_entries/{entryId}": { "get": { - "description": "List people who can be assigned todos", - "operationId": "ListAssignablePeople", + "description": "Get a single schedule entry by id.\nNote: Recurring entries will redirect (302) to their recordable URL.\nUse GetScheduleEntryOccurrence for recurring entries instead.", + "operationId": "GetScheduleEntry", "parameters": [ { "name": "accountId", @@ -16029,15 +16842,24 @@ "description": "Basecamp account ID (numeric string)" }, "required": true + }, + { + "name": "entryId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true } ], "responses": { "200": { - "description": "ListAssignablePeople 200 response", + "description": "GetScheduleEntry 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListAssignablePeopleResponseContent" + "$ref": "#/components/schemas/GetScheduleEntryResponseContent" } } } @@ -16062,12 +16884,12 @@ } } }, - "429": { - "description": "RateLimitError 429 response", + "404": { + "description": "NotFoundError 404 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" } } } @@ -16083,6 +16905,9 @@ } } }, + "tags": [ + "Schedule" + ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -16092,12 +16917,19 @@ 503 ] } - } - }, - "/{accountId}/reports/todos/assigned/{personId}": { - "get": { - "description": "Get todos assigned to a specific person", - "operationId": "GetAssignedTodos", + }, + "put": { + "description": "Update an existing schedule entry", + "operationId": "UpdateScheduleEntry", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateScheduleEntryRequestContent" + } + } + } + }, "parameters": [ { "name": "accountId", @@ -16111,31 +16943,22 @@ "required": true }, { - "name": "personId", + "name": "entryId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true - }, - { - "name": "group_by", - "in": "query", - "description": "Group by \"bucket\" or \"date\"", - "schema": { - "type": "string", - "description": "Group by \"bucket\" or \"date\"" - } } ], "responses": { "200": { - "description": "GetAssignedTodos 200 response", + "description": "UpdateScheduleEntry 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetAssignedTodosResponseContent" + "$ref": "#/components/schemas/UpdateScheduleEntryResponseContent" } } } @@ -16170,12 +16993,12 @@ } } }, - "429": { - "description": "RateLimitError 429 response", + "422": { + "description": "ValidationError 422 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" + "$ref": "#/components/schemas/ValidationErrorResponseContent" } } } @@ -16191,6 +17014,12 @@ } } }, + "tags": [ + "Schedule" + ], + "x-basecamp-idempotent": { + "natural": true + }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -16202,10 +17031,10 @@ } } }, - "/{accountId}/reports/todos/overdue.json": { + "/{accountId}/schedule_entries/{entryId}/occurrences/{date}": { "get": { - "description": "Get overdue todos grouped by lateness", - "operationId": "GetOverdueTodos", + "description": "Get a specific occurrence of a recurring schedule entry", + "operationId": "GetScheduleEntryOccurrence", "parameters": [ { "name": "accountId", @@ -16217,15 +17046,32 @@ "description": "Basecamp account ID (numeric string)" }, "required": true + }, + { + "name": "entryId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true + }, + { + "name": "date", + "in": "path", + "schema": { + "type": "string" + }, + "required": true } ], "responses": { "200": { - "description": "GetOverdueTodos 200 response", + "description": "GetScheduleEntryOccurrence 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetOverdueTodosResponseContent" + "$ref": "#/components/schemas/GetScheduleEntryOccurrenceResponseContent" } } } @@ -16250,12 +17096,12 @@ } } }, - "429": { - "description": "RateLimitError 429 response", + "404": { + "description": "NotFoundError 404 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" } } } @@ -16271,6 +17117,9 @@ } } }, + "tags": [ + "Schedule" + ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -16282,10 +17131,10 @@ } } }, - "/{accountId}/reports/users/progress/{personId}.json": { + "/{accountId}/schedules/{scheduleId}": { "get": { - "description": "Get a person's activity timeline", - "operationId": "GetPersonProgress", + "description": "Get a schedule", + "operationId": "GetSchedule", "parameters": [ { "name": "accountId", @@ -16299,7 +17148,7 @@ "required": true }, { - "name": "personId", + "name": "scheduleId", "in": "path", "schema": { "type": "integer", @@ -16310,11 +17159,11 @@ ], "responses": { "200": { - "description": "GetPersonProgress 200 response", + "description": "GetSchedule 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetPersonProgressResponseContent" + "$ref": "#/components/schemas/GetScheduleResponseContent" } } } @@ -16349,16 +17198,6 @@ } } }, - "429": { - "description": "RateLimitError 429 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" - } - } - } - }, "500": { "description": "InternalServerError 500 response", "content": { @@ -16370,12 +17209,9 @@ } } }, - "x-basecamp-pagination": { - "style": "link", - "totalCountHeader": "X-Total-Count", - "maxPageSize": 50, - "key": "events" - }, + "tags": [ + "Schedule" + ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -16385,12 +17221,20 @@ 503 ] } - } - }, - "/{accountId}/schedule_entries/{entryId}": { - "get": { - "description": "Get a single schedule entry by id.\nNote: Recurring entries will redirect (302) to their recordable URL.\nUse GetScheduleEntryOccurrence for recurring entries instead.", - "operationId": "GetScheduleEntry", + }, + "put": { + "description": "Update schedule settings", + "operationId": "UpdateScheduleSettings", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateScheduleSettingsRequestContent" + } + } + }, + "required": true + }, "parameters": [ { "name": "accountId", @@ -16404,7 +17248,7 @@ "required": true }, { - "name": "entryId", + "name": "scheduleId", "in": "path", "schema": { "type": "integer", @@ -16415,11 +17259,11 @@ ], "responses": { "200": { - "description": "GetScheduleEntry 200 response", + "description": "UpdateScheduleSettings 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetScheduleEntryResponseContent" + "$ref": "#/components/schemas/UpdateScheduleSettingsResponseContent" } } } @@ -16454,6 +17298,16 @@ } } }, + "422": { + "description": "ValidationError 422 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponseContent" + } + } + } + }, "500": { "description": "InternalServerError 500 response", "content": { @@ -16468,6 +17322,9 @@ "tags": [ "Schedule" ], + "x-basecamp-idempotent": { + "natural": true + }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -16477,19 +17334,12 @@ 503 ] } - }, - "put": { - "description": "Update an existing schedule entry", - "operationId": "UpdateScheduleEntry", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateScheduleEntryRequestContent" - } - } - } - }, + } + }, + "/{accountId}/schedules/{scheduleId}/entries.json": { + "get": { + "description": "List entries on a schedule\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", + "operationId": "ListScheduleEntries", "parameters": [ { "name": "accountId", @@ -16503,22 +17353,31 @@ "required": true }, { - "name": "entryId", + "name": "scheduleId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true + }, + { + "name": "status", + "in": "query", + "description": "active|archived|trashed", + "schema": { + "type": "string", + "description": "active|archived|trashed" + } } ], "responses": { "200": { - "description": "UpdateScheduleEntry 200 response", + "description": "ListScheduleEntries 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateScheduleEntryResponseContent" + "$ref": "#/components/schemas/ListScheduleEntriesResponseContent" } } } @@ -16543,22 +17402,12 @@ } } }, - "404": { - "description": "NotFoundError 404 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" - } - } - } - }, - "422": { - "description": "ValidationError 422 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -16577,8 +17426,10 @@ "tags": [ "Schedule" ], - "x-basecamp-idempotent": { - "natural": true + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 }, "x-basecamp-retry": { "maxAttempts": 3, @@ -16589,12 +17440,20 @@ 503 ] } - } - }, - "/{accountId}/schedule_entries/{entryId}/occurrences/{date}": { - "get": { - "description": "Get a specific occurrence of a recurring schedule entry", - "operationId": "GetScheduleEntryOccurrence", + }, + "post": { + "description": "Create a new schedule entry", + "operationId": "CreateScheduleEntry", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateScheduleEntryRequestContent" + } + } + }, + "required": true + }, "parameters": [ { "name": "accountId", @@ -16608,30 +17467,22 @@ "required": true }, { - "name": "entryId", + "name": "scheduleId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true - }, - { - "name": "date", - "in": "path", - "schema": { - "type": "string" - }, - "required": true } ], "responses": { - "200": { - "description": "GetScheduleEntryOccurrence 200 response", + "201": { + "description": "CreateScheduleEntry 201 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetScheduleEntryOccurrenceResponseContent" + "$ref": "#/components/schemas/CreateScheduleEntryResponseContent" } } } @@ -16656,12 +17507,22 @@ } } }, - "404": { - "description": "NotFoundError 404 response", + "422": { + "description": "ValidationError 422 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/ValidationErrorResponseContent" + } + } + } + }, + "429": { + "description": "RateLimitError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -16681,7 +17542,7 @@ "Schedule" ], "x-basecamp-retry": { - "maxAttempts": 3, + "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -16691,10 +17552,10 @@ } } }, - "/{accountId}/schedules/{scheduleId}": { + "/{accountId}/search.json": { "get": { - "description": "Get a schedule", - "operationId": "GetSchedule", + "description": "Search for content across the account", + "operationId": "Search", "parameters": [ { "name": "accountId", @@ -16708,22 +17569,142 @@ "required": true }, { - "name": "scheduleId", - "in": "path", + "name": "q", + "in": "query", + "schema": { + "type": "string" + }, + "required": true + }, + { + "name": "type_names[]", + "in": "query", + "description": "Recording types to include. Use `key` values from the metadata\nendpoint's `recording_search_types`. Available since Basecamp 5.", + "style": "form", + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Recording types to include. Use `key` values from the metadata\nendpoint's `recording_search_types`. Available since Basecamp 5.", + "x-go-type-skip-optional-pointer": false + }, + "explode": true + }, + { + "name": "bucket_ids[]", + "in": "query", + "description": "Project IDs to filter by. Available since Basecamp 5.", + "style": "form", + "schema": { + "type": "array", + "items": { + "type": "integer", + "format": "int64" + }, + "description": "Project IDs to filter by. Available since Basecamp 5.", + "x-go-type-skip-optional-pointer": false + }, + "explode": true + }, + { + "name": "creator_ids[]", + "in": "query", + "description": "Creator person IDs to filter by. Available since Basecamp 5.", + "style": "form", + "schema": { + "type": "array", + "items": { + "type": "integer", + "format": "int64" + }, + "description": "Creator person IDs to filter by. Available since Basecamp 5.", + "x-go-type-skip-optional-pointer": false + }, + "explode": true + }, + { + "name": "file_type", + "in": "query", + "description": "Filter attachments by type. Use `key` values from the metadata\nendpoint's `file_search_types`.", + "schema": { + "type": "string", + "description": "Filter attachments by type. Use `key` values from the metadata\nendpoint's `file_search_types`." + } + }, + { + "name": "exclude_chat", + "in": "query", + "description": "Set to true to exclude chat results.", + "schema": { + "type": "boolean", + "description": "Set to true to exclude chat results." + } + }, + { + "name": "since", + "in": "query", + "description": "last_7_days|last_30_days|last_90_days|last_12_months|forever", + "schema": { + "type": "string", + "description": "last_7_days|last_30_days|last_90_days|last_12_months|forever" + } + }, + { + "name": "sort", + "in": "query", + "description": "best_match|recency", + "schema": { + "type": "string", + "description": "best_match|recency" + } + }, + { + "name": "type", + "in": "query", + "description": "Deprecated: prefer type_names[].", + "schema": { + "type": "string", + "deprecated": true, + "description": "Deprecated: prefer type_names[].\nThis shape is deprecated since 2026-07: Use typeNames (type_names[]) instead" + }, + "deprecated": true, + "x-deprecated-reason": "prefer type_names[]." + }, + { + "name": "bucket_id", + "in": "query", + "description": "Deprecated: prefer bucket_ids[].", + "schema": { + "type": "integer", + "deprecated": true, + "description": "Deprecated: prefer bucket_ids[].\nThis shape is deprecated since 2026-07: Use bucketIds (bucket_ids[]) instead", + "format": "int64" + }, + "deprecated": true, + "x-deprecated-reason": "prefer bucket_ids[]." + }, + { + "name": "creator_id", + "in": "query", + "description": "Deprecated: prefer creator_ids[].", "schema": { "type": "integer", + "deprecated": true, + "description": "Deprecated: prefer creator_ids[].\nThis shape is deprecated since 2026-07: Use creatorIds (creator_ids[]) instead", "format": "int64" }, - "required": true + "deprecated": true, + "x-deprecated-reason": "prefer creator_ids[]." } ], "responses": { "200": { - "description": "GetSchedule 200 response", + "description": "Search 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetScheduleResponseContent" + "$ref": "#/components/schemas/SearchResponseContent" } } } @@ -16748,12 +17729,12 @@ } } }, - "404": { - "description": "NotFoundError 404 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -16770,8 +17751,13 @@ } }, "tags": [ - "Schedule" + "Automation" ], + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -16781,20 +17767,12 @@ 503 ] } - }, - "put": { - "description": "Update schedule settings", - "operationId": "UpdateScheduleSettings", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateScheduleSettingsRequestContent" - } - } - }, - "required": true - }, + } + }, + "/{accountId}/searches/metadata.json": { + "get": { + "description": "Get search metadata (available filter options)", + "operationId": "GetSearchMetadata", "parameters": [ { "name": "accountId", @@ -16806,24 +17784,15 @@ "description": "Basecamp account ID (numeric string)" }, "required": true - }, - { - "name": "scheduleId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true } ], "responses": { "200": { - "description": "UpdateScheduleSettings 200 response", + "description": "GetSearchMetadata 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateScheduleSettingsResponseContent" + "$ref": "#/components/schemas/GetSearchMetadataResponseContent" } } } @@ -16858,16 +17827,6 @@ } } }, - "422": { - "description": "ValidationError 422 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" - } - } - } - }, "500": { "description": "InternalServerError 500 response", "content": { @@ -16880,11 +17839,8 @@ } }, "tags": [ - "Schedule" + "Automation" ], - "x-basecamp-idempotent": { - "natural": true - }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -16896,10 +17852,10 @@ } } }, - "/{accountId}/schedules/{scheduleId}/entries.json": { + "/{accountId}/templates.json": { "get": { - "description": "List entries on a schedule\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", - "operationId": "ListScheduleEntries", + "description": "List all templates visible to the current user\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", + "operationId": "ListTemplates", "parameters": [ { "name": "accountId", @@ -16912,15 +17868,6 @@ }, "required": true }, - { - "name": "scheduleId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true - }, { "name": "status", "in": "query", @@ -16933,11 +17880,11 @@ ], "responses": { "200": { - "description": "ListScheduleEntries 200 response", + "description": "ListTemplates 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListScheduleEntriesResponseContent" + "$ref": "#/components/schemas/ListTemplatesResponseContent" } } } @@ -16984,7 +17931,7 @@ } }, "tags": [ - "Schedule" + "Automation" ], "x-basecamp-pagination": { "style": "link", @@ -17002,13 +17949,13 @@ } }, "post": { - "description": "Create a new schedule entry", - "operationId": "CreateScheduleEntry", + "description": "Create a new template", + "operationId": "CreateTemplate", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateScheduleEntryRequestContent" + "$ref": "#/components/schemas/CreateTemplateRequestContent" } } }, @@ -17025,24 +17972,15 @@ "description": "Basecamp account ID (numeric string)" }, "required": true - }, - { - "name": "scheduleId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true } ], "responses": { "201": { - "description": "CreateScheduleEntry 201 response", + "description": "CreateTemplate 201 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateScheduleEntryResponseContent" + "$ref": "#/components/schemas/CreateTemplateResponseContent" } } } @@ -17050,224 +17988,97 @@ "401": { "description": "UnauthorizedError 401 response", "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UnauthorizedErrorResponseContent" - } - } - } - }, - "403": { - "description": "ForbiddenError 403 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ForbiddenErrorResponseContent" - } - } - } - }, - "422": { - "description": "ValidationError 422 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" - } - } - } - }, - "429": { - "description": "RateLimitError 429 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" - } - } - } - }, - "500": { - "description": "InternalServerError 500 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/InternalServerErrorResponseContent" - } - } - } - } - }, - "tags": [ - "Schedule" - ], - "x-basecamp-retry": { - "maxAttempts": 2, - "baseDelayMs": 1000, - "backoff": "exponential", - "retryOn": [ - 429, - 503 - ] - } - } - }, - "/{accountId}/search.json": { - "get": { - "description": "Search for content across the account", - "operationId": "Search", - "parameters": [ - { - "name": "accountId", - "in": "path", - "description": "Basecamp account ID (numeric string)", - "schema": { - "type": "string", - "pattern": "^[0-9]+$", - "description": "Basecamp account ID (numeric string)" - }, - "required": true - }, - { - "name": "q", - "in": "query", - "schema": { - "type": "string" - }, - "required": true - }, - { - "name": "type_names[]", - "in": "query", - "description": "Recording types to include. Use `key` values from the metadata\nendpoint's `recording_search_types`. Available since Basecamp 5.", - "style": "form", - "schema": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Recording types to include. Use `key` values from the metadata\nendpoint's `recording_search_types`. Available since Basecamp 5.", - "x-go-type-skip-optional-pointer": false - }, - "explode": true - }, - { - "name": "bucket_ids[]", - "in": "query", - "description": "Project IDs to filter by. Available since Basecamp 5.", - "style": "form", - "schema": { - "type": "array", - "items": { - "type": "integer", - "format": "int64" - }, - "description": "Project IDs to filter by. Available since Basecamp 5.", - "x-go-type-skip-optional-pointer": false - }, - "explode": true - }, - { - "name": "creator_ids[]", - "in": "query", - "description": "Creator person IDs to filter by. Available since Basecamp 5.", - "style": "form", - "schema": { - "type": "array", - "items": { - "type": "integer", - "format": "int64" - }, - "description": "Creator person IDs to filter by. Available since Basecamp 5.", - "x-go-type-skip-optional-pointer": false - }, - "explode": true - }, - { - "name": "file_type", - "in": "query", - "description": "Filter attachments by type. Use `key` values from the metadata\nendpoint's `file_search_types`.", - "schema": { - "type": "string", - "description": "Filter attachments by type. Use `key` values from the metadata\nendpoint's `file_search_types`." + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnauthorizedErrorResponseContent" + } + } } }, - { - "name": "exclude_chat", - "in": "query", - "description": "Set to true to exclude chat results.", - "schema": { - "type": "boolean", - "description": "Set to true to exclude chat results." + "403": { + "description": "ForbiddenError 403 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + } + } } }, - { - "name": "since", - "in": "query", - "description": "last_7_days|last_30_days|last_90_days|last_12_months|forever", - "schema": { - "type": "string", - "description": "last_7_days|last_30_days|last_90_days|last_12_months|forever" + "422": { + "description": "ValidationError 422 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponseContent" + } + } } }, - { - "name": "sort", - "in": "query", - "description": "best_match|recency", - "schema": { - "type": "string", - "description": "best_match|recency" + "429": { + "description": "RateLimitError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RateLimitErrorResponseContent" + } + } } }, + "500": { + "description": "InternalServerError 500 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InternalServerErrorResponseContent" + } + } + } + } + }, + "tags": [ + "Automation" + ], + "x-basecamp-retry": { + "maxAttempts": 2, + "baseDelayMs": 1000, + "backoff": "exponential", + "retryOn": [ + 429, + 503 + ] + } + } + }, + "/{accountId}/templates/{templateId}": { + "delete": { + "description": "Delete a template (trash it)", + "operationId": "DeleteTemplate", + "parameters": [ { - "name": "type", - "in": "query", - "description": "Deprecated: prefer type_names[].", + "name": "accountId", + "in": "path", + "description": "Basecamp account ID (numeric string)", "schema": { "type": "string", - "deprecated": true, - "description": "Deprecated: prefer type_names[].\nThis shape is deprecated since 2026-07: Use typeNames (type_names[]) instead" - }, - "deprecated": true, - "x-deprecated-reason": "prefer type_names[]." - }, - { - "name": "bucket_id", - "in": "query", - "description": "Deprecated: prefer bucket_ids[].", - "schema": { - "type": "integer", - "deprecated": true, - "description": "Deprecated: prefer bucket_ids[].\nThis shape is deprecated since 2026-07: Use bucketIds (bucket_ids[]) instead", - "format": "int64" + "pattern": "^[0-9]+$", + "description": "Basecamp account ID (numeric string)" }, - "deprecated": true, - "x-deprecated-reason": "prefer bucket_ids[]." + "required": true }, { - "name": "creator_id", - "in": "query", - "description": "Deprecated: prefer creator_ids[].", + "name": "templateId", + "in": "path", "schema": { "type": "integer", - "deprecated": true, - "description": "Deprecated: prefer creator_ids[].\nThis shape is deprecated since 2026-07: Use creatorIds (creator_ids[]) instead", "format": "int64" }, - "deprecated": true, - "x-deprecated-reason": "prefer creator_ids[]." + "required": true } ], "responses": { - "200": { - "description": "Search 200 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/SearchResponseContent" - } - } - } + "204": { + "description": "DeleteTemplate 204 response" }, "401": { "description": "UnauthorizedError 401 response", @@ -17289,12 +18100,12 @@ } } }, - "429": { - "description": "RateLimitError 429 response", + "404": { + "description": "NotFoundError 404 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" } } } @@ -17313,10 +18124,8 @@ "tags": [ "Automation" ], - "x-basecamp-pagination": { - "style": "link", - "totalCountHeader": "X-Total-Count", - "maxPageSize": 50 + "x-basecamp-idempotent": { + "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, @@ -17327,12 +18136,10 @@ 503 ] } - } - }, - "/{accountId}/searches/metadata.json": { + }, "get": { - "description": "Get search metadata (available filter options)", - "operationId": "GetSearchMetadata", + "description": "Get a single template by id", + "operationId": "GetTemplate", "parameters": [ { "name": "accountId", @@ -17344,15 +18151,24 @@ "description": "Basecamp account ID (numeric string)" }, "required": true + }, + { + "name": "templateId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true } ], "responses": { "200": { - "description": "GetSearchMetadata 200 response", + "description": "GetTemplate 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetSearchMetadataResponseContent" + "$ref": "#/components/schemas/GetTemplateResponseContent" } } } @@ -17410,12 +18226,19 @@ 503 ] } - } - }, - "/{accountId}/templates.json": { - "get": { - "description": "List all templates visible to the current user\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", - "operationId": "ListTemplates", + }, + "put": { + "description": "Update an existing template", + "operationId": "UpdateTemplate", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateTemplateRequestContent" + } + } + } + }, "parameters": [ { "name": "accountId", @@ -17429,22 +18252,22 @@ "required": true }, { - "name": "status", - "in": "query", - "description": "active|archived|trashed", + "name": "templateId", + "in": "path", "schema": { - "type": "string", - "description": "active|archived|trashed" - } + "type": "integer", + "format": "int64" + }, + "required": true } ], "responses": { "200": { - "description": "ListTemplates 200 response", + "description": "UpdateTemplate 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListTemplatesResponseContent" + "$ref": "#/components/schemas/UpdateTemplateResponseContent" } } } @@ -17469,12 +18292,22 @@ } } }, - "429": { - "description": "RateLimitError 429 response", + "404": { + "description": "NotFoundError 404 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" + } + } + } + }, + "422": { + "description": "ValidationError 422 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponseContent" } } } @@ -17493,10 +18326,8 @@ "tags": [ "Automation" ], - "x-basecamp-pagination": { - "style": "link", - "totalCountHeader": "X-Total-Count", - "maxPageSize": 50 + "x-basecamp-idempotent": { + "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, @@ -17507,15 +18338,17 @@ 503 ] } - }, + } + }, + "/{accountId}/templates/{templateId}/project_constructions.json": { "post": { - "description": "Create a new template", - "operationId": "CreateTemplate", + "description": "Create a project from a template (asynchronous)", + "operationId": "CreateProjectFromTemplate", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateTemplateRequestContent" + "$ref": "#/components/schemas/CreateProjectFromTemplateRequestContent" } } }, @@ -17532,15 +18365,24 @@ "description": "Basecamp account ID (numeric string)" }, "required": true + }, + { + "name": "templateId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true } ], "responses": { "201": { - "description": "CreateTemplate 201 response", + "description": "CreateProjectFromTemplate 201 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateTemplateResponseContent" + "$ref": "#/components/schemas/CreateProjectFromTemplateResponseContent" } } } @@ -17610,10 +18452,10 @@ } } }, - "/{accountId}/templates/{templateId}": { - "delete": { - "description": "Delete a template (trash it)", - "operationId": "DeleteTemplate", + "/{accountId}/templates/{templateId}/project_constructions/{constructionId}": { + "get": { + "description": "Get the status of a project construction", + "operationId": "GetProjectConstruction", "parameters": [ { "name": "accountId", @@ -17627,7 +18469,16 @@ "required": true }, { - "name": "templateId", + "name": "templateId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true + }, + { + "name": "constructionId", "in": "path", "schema": { "type": "integer", @@ -17637,8 +18488,15 @@ } ], "responses": { - "204": { - "description": "DeleteTemplate 204 response" + "200": { + "description": "GetProjectConstruction 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetProjectConstructionResponseContent" + } + } + } }, "401": { "description": "UnauthorizedError 401 response", @@ -17684,9 +18542,6 @@ "tags": [ "Automation" ], - "x-basecamp-idempotent": { - "natural": true - }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -17696,10 +18551,12 @@ 503 ] } - }, + } + }, + "/{accountId}/timesheet_entries/{entryId}": { "get": { - "description": "Get a single template by id", - "operationId": "GetTemplate", + "description": "Get a single timesheet entry", + "operationId": "GetTimesheetEntry", "parameters": [ { "name": "accountId", @@ -17713,7 +18570,7 @@ "required": true }, { - "name": "templateId", + "name": "entryId", "in": "path", "schema": { "type": "integer", @@ -17724,11 +18581,11 @@ ], "responses": { "200": { - "description": "GetTemplate 200 response", + "description": "GetTimesheetEntry 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetTemplateResponseContent" + "$ref": "#/components/schemas/GetTimesheetEntryResponseContent" } } } @@ -17775,7 +18632,7 @@ } }, "tags": [ - "Automation" + "Schedule" ], "x-basecamp-retry": { "maxAttempts": 3, @@ -17788,13 +18645,13 @@ } }, "put": { - "description": "Update an existing template", - "operationId": "UpdateTemplate", + "description": "Update a timesheet entry", + "operationId": "UpdateTimesheetEntry", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateTemplateRequestContent" + "$ref": "#/components/schemas/UpdateTimesheetEntryRequestContent" } } } @@ -17812,7 +18669,7 @@ "required": true }, { - "name": "templateId", + "name": "entryId", "in": "path", "schema": { "type": "integer", @@ -17823,11 +18680,11 @@ ], "responses": { "200": { - "description": "UpdateTemplate 200 response", + "description": "UpdateTimesheetEntry 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateTemplateResponseContent" + "$ref": "#/components/schemas/UpdateTimesheetEntryResponseContent" } } } @@ -17884,7 +18741,7 @@ } }, "tags": [ - "Automation" + "Schedule" ], "x-basecamp-idempotent": { "natural": true @@ -17900,15 +18757,15 @@ } } }, - "/{accountId}/templates/{templateId}/project_constructions.json": { - "post": { - "description": "Create a project from a template (asynchronous)", - "operationId": "CreateProjectFromTemplate", + "/{accountId}/todolists/{groupId}/position.json": { + "put": { + "description": "Reposition a todolist group", + "operationId": "RepositionTodolistGroup", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateProjectFromTemplateRequestContent" + "$ref": "#/components/schemas/RepositionTodolistGroupRequestContent" } } }, @@ -17927,7 +18784,7 @@ "required": true }, { - "name": "templateId", + "name": "groupId", "in": "path", "schema": { "type": "integer", @@ -17937,15 +18794,8 @@ } ], "responses": { - "201": { - "description": "CreateProjectFromTemplate 201 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateProjectFromTemplateResponseContent" - } - } - } + "200": { + "description": "RepositionTodolistGroup 200 response" }, "401": { "description": "UnauthorizedError 401 response", @@ -17967,22 +18817,22 @@ } } }, - "422": { - "description": "ValidationError 422 response", + "404": { + "description": "NotFoundError 404 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" } } } }, - "429": { - "description": "RateLimitError 429 response", + "422": { + "description": "ValidationError 422 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" + "$ref": "#/components/schemas/ValidationErrorResponseContent" } } } @@ -17999,10 +18849,13 @@ } }, "tags": [ - "Automation" + "Todos" ], + "x-basecamp-idempotent": { + "natural": true + }, "x-basecamp-retry": { - "maxAttempts": 2, + "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -18012,10 +18865,10 @@ } } }, - "/{accountId}/templates/{templateId}/project_constructions/{constructionId}": { + "/{accountId}/todolists/{id}": { "get": { - "description": "Get the status of a project construction", - "operationId": "GetProjectConstruction", + "description": "Get a single todolist or todolist group by id\nThe endpoint is polymorphic - the same URI returns either a Todolist or TodolistGroup", + "operationId": "GetTodolistOrGroup", "parameters": [ { "name": "accountId", @@ -18026,34 +18879,130 @@ "pattern": "^[0-9]+$", "description": "Basecamp account ID (numeric string)" }, - "required": true - }, - { - "name": "templateId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true + "required": true, + "examples": { + "GetTodolistOrGroup_example1": { + "summary": "Get a Todolist", + "description": "Returns a Todolist when ID refers to a todolist", + "value": "999" + }, + "GetTodolistOrGroup_example2": { + "summary": "Get a TodolistGroup", + "description": "Returns a TodolistGroup when ID refers to a group", + "value": "999" + } + } }, { - "name": "constructionId", + "name": "id", "in": "path", "schema": { "type": "integer", "format": "int64" }, - "required": true + "required": true, + "examples": { + "GetTodolistOrGroup_example1": { + "summary": "Get a Todolist", + "description": "Returns a Todolist when ID refers to a todolist", + "value": 987654 + }, + "GetTodolistOrGroup_example2": { + "summary": "Get a TodolistGroup", + "description": "Returns a TodolistGroup when ID refers to a group", + "value": 111222 + } + } } ], "responses": { "200": { - "description": "GetProjectConstruction 200 response", + "description": "GetTodolistOrGroup 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetProjectConstructionResponseContent" + "$ref": "#/components/schemas/GetTodolistOrGroupResponseContent" + }, + "examples": { + "GetTodolistOrGroup_example1": { + "summary": "Get a Todolist", + "description": "Returns a Todolist when ID refers to a todolist", + "value": { + "result": { + "todolist": { + "id": 987654, + "status": "active", + "name": "Launch Tasks", + "visible_to_clients": false, + "created_at": "2025-01-01T00:00:00Z", + "updated_at": "2025-01-01T00:00:00Z", + "title": "Launch Tasks", + "inherits_status": true, + "type": "Todolist", + "description_attachments": [], + "url": "https://3.basecampapi.com/999/buckets/12345678/todolists/987654.json", + "app_url": "https://3.basecamp.com/999/buckets/12345678/todolists/987654", + "creator": { + "id": 1, + "name": "Someone", + "created_at": "2025-01-01T00:00:00Z", + "updated_at": "2025-01-01T00:00:00Z" + }, + "bucket": { + "id": 12345678, + "name": "My Project", + "type": "Project" + }, + "parent": { + "id": 99999, + "title": "To-dos", + "type": "Todoset", + "url": "https://3.basecampapi.com/999/buckets/12345678/todosets/99999.json", + "app_url": "https://3.basecamp.com/999/buckets/12345678/todosets/99999" + } + } + } + } + }, + "GetTodolistOrGroup_example2": { + "summary": "Get a TodolistGroup", + "description": "Returns a TodolistGroup when ID refers to a group", + "value": { + "result": { + "group": { + "id": 111222, + "status": "active", + "name": "Q1 Milestones", + "visible_to_clients": false, + "created_at": "2025-01-01T00:00:00Z", + "updated_at": "2025-01-01T00:00:00Z", + "title": "Q1 Milestones", + "inherits_status": true, + "type": "TodolistGroup", + "url": "https://3.basecampapi.com/999/buckets/12345678/todolists/111222.json", + "app_url": "https://3.basecamp.com/999/buckets/12345678/todolists/111222", + "creator": { + "id": 1, + "name": "Someone", + "created_at": "2025-01-01T00:00:00Z", + "updated_at": "2025-01-01T00:00:00Z" + }, + "bucket": { + "id": 12345678, + "name": "My Project", + "type": "Project" + }, + "parent": { + "id": 99999, + "title": "To-dos", + "type": "Todoset", + "url": "https://3.basecampapi.com/999/buckets/12345678/todosets/99999.json", + "app_url": "https://3.basecamp.com/999/buckets/12345678/todosets/99999" + } + } + } + } + } } } } @@ -18100,7 +19049,7 @@ } }, "tags": [ - "Automation" + "Todos" ], "x-basecamp-retry": { "maxAttempts": 3, @@ -18111,12 +19060,19 @@ 503 ] } - } - }, - "/{accountId}/timesheet_entries/{entryId}": { - "get": { - "description": "Get a single timesheet entry", - "operationId": "GetTimesheetEntry", + }, + "put": { + "description": "Update an existing todolist or todolist group\nThe endpoint is polymorphic - updates either a Todolist or TodolistGroup", + "operationId": "UpdateTodolistOrGroup", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateTodolistOrGroupRequestContent" + } + } + } + }, "parameters": [ { "name": "accountId", @@ -18130,7 +19086,7 @@ "required": true }, { - "name": "entryId", + "name": "id", "in": "path", "schema": { "type": "integer", @@ -18141,11 +19097,11 @@ ], "responses": { "200": { - "description": "GetTimesheetEntry 200 response", + "description": "UpdateTodolistOrGroup 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetTimesheetEntryResponseContent" + "$ref": "#/components/schemas/UpdateTodolistOrGroupResponseContent" } } } @@ -18175,7 +19131,17 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" + } + } + } + }, + "422": { + "description": "ValidationError 422 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponseContent" } } } @@ -18192,8 +19158,11 @@ } }, "tags": [ - "Schedule" + "Todos" ], + "x-basecamp-idempotent": { + "natural": true + }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -18203,19 +19172,12 @@ 503 ] } - }, - "put": { - "description": "Update a timesheet entry", - "operationId": "UpdateTimesheetEntry", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateTimesheetEntryRequestContent" - } - } - } - }, + } + }, + "/{accountId}/todolists/{todolistId}/groups.json": { + "get": { + "description": "List groups in a todolist\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", + "operationId": "ListTodolistGroups", "parameters": [ { "name": "accountId", @@ -18229,7 +19191,7 @@ "required": true }, { - "name": "entryId", + "name": "todolistId", "in": "path", "schema": { "type": "integer", @@ -18240,11 +19202,11 @@ ], "responses": { "200": { - "description": "UpdateTimesheetEntry 200 response", + "description": "ListTodolistGroups 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateTimesheetEntryResponseContent" + "$ref": "#/components/schemas/ListTodolistGroupsResponseContent" } } } @@ -18269,22 +19231,12 @@ } } }, - "404": { - "description": "NotFoundError 404 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" - } - } - } - }, - "422": { - "description": "ValidationError 422 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -18301,10 +19253,12 @@ } }, "tags": [ - "Schedule" + "Todos" ], - "x-basecamp-idempotent": { - "natural": true + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 }, "x-basecamp-retry": { "maxAttempts": 3, @@ -18315,17 +19269,15 @@ 503 ] } - } - }, - "/{accountId}/todolists/{groupId}/position.json": { - "put": { - "description": "Reposition a todolist group", - "operationId": "RepositionTodolistGroup", + }, + "post": { + "description": "Create a new group in a todolist", + "operationId": "CreateTodolistGroup", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RepositionTodolistGroupRequestContent" + "$ref": "#/components/schemas/CreateTodolistGroupRequestContent" } } }, @@ -18344,7 +19296,7 @@ "required": true }, { - "name": "groupId", + "name": "todolistId", "in": "path", "schema": { "type": "integer", @@ -18354,8 +19306,15 @@ } ], "responses": { - "200": { - "description": "RepositionTodolistGroup 200 response" + "201": { + "description": "CreateTodolistGroup 201 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateTodolistGroupResponseContent" + } + } + } }, "401": { "description": "UnauthorizedError 401 response", @@ -18377,22 +19336,22 @@ } } }, - "404": { - "description": "NotFoundError 404 response", + "422": { + "description": "ValidationError 422 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/ValidationErrorResponseContent" } } } }, - "422": { - "description": "ValidationError 422 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -18411,11 +19370,8 @@ "tags": [ "Todos" ], - "x-basecamp-idempotent": { - "natural": true - }, "x-basecamp-retry": { - "maxAttempts": 3, + "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -18425,10 +19381,10 @@ } } }, - "/{accountId}/todolists/{id}": { + "/{accountId}/todolists/{todolistId}/todos.json": { "get": { - "description": "Get a single todolist or todolist group by id\nThe endpoint is polymorphic - the same URI returns either a Todolist or TodolistGroup", - "operationId": "GetTodolistOrGroup", + "description": "List todos in a todolist\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", + "operationId": "ListTodos", "parameters": [ { "name": "accountId", @@ -18439,130 +19395,41 @@ "pattern": "^[0-9]+$", "description": "Basecamp account ID (numeric string)" }, - "required": true, - "examples": { - "GetTodolistOrGroup_example1": { - "summary": "Get a Todolist", - "description": "Returns a Todolist when ID refers to a todolist", - "value": "999" - }, - "GetTodolistOrGroup_example2": { - "summary": "Get a TodolistGroup", - "description": "Returns a TodolistGroup when ID refers to a group", - "value": "999" - } - } + "required": true }, { - "name": "id", + "name": "todolistId", "in": "path", "schema": { "type": "integer", "format": "int64" }, - "required": true, - "examples": { - "GetTodolistOrGroup_example1": { - "summary": "Get a Todolist", - "description": "Returns a Todolist when ID refers to a todolist", - "value": 987654 - }, - "GetTodolistOrGroup_example2": { - "summary": "Get a TodolistGroup", - "description": "Returns a TodolistGroup when ID refers to a group", - "value": 111222 - } + "required": true + }, + { + "name": "status", + "in": "query", + "description": "active|archived|trashed", + "schema": { + "type": "string", + "description": "active|archived|trashed" + } + }, + { + "name": "completed", + "in": "query", + "schema": { + "type": "boolean" } } ], "responses": { "200": { - "description": "GetTodolistOrGroup 200 response", + "description": "ListTodos 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetTodolistOrGroupResponseContent" - }, - "examples": { - "GetTodolistOrGroup_example1": { - "summary": "Get a Todolist", - "description": "Returns a Todolist when ID refers to a todolist", - "value": { - "result": { - "todolist": { - "id": 987654, - "status": "active", - "name": "Launch Tasks", - "visible_to_clients": false, - "created_at": "2025-01-01T00:00:00Z", - "updated_at": "2025-01-01T00:00:00Z", - "title": "Launch Tasks", - "inherits_status": true, - "type": "Todolist", - "description_attachments": [], - "url": "https://3.basecampapi.com/999/buckets/12345678/todolists/987654.json", - "app_url": "https://3.basecamp.com/999/buckets/12345678/todolists/987654", - "creator": { - "id": 1, - "name": "Someone", - "created_at": "2025-01-01T00:00:00Z", - "updated_at": "2025-01-01T00:00:00Z" - }, - "bucket": { - "id": 12345678, - "name": "My Project", - "type": "Project" - }, - "parent": { - "id": 99999, - "title": "To-dos", - "type": "Todoset", - "url": "https://3.basecampapi.com/999/buckets/12345678/todosets/99999.json", - "app_url": "https://3.basecamp.com/999/buckets/12345678/todosets/99999" - } - } - } - } - }, - "GetTodolistOrGroup_example2": { - "summary": "Get a TodolistGroup", - "description": "Returns a TodolistGroup when ID refers to a group", - "value": { - "result": { - "group": { - "id": 111222, - "status": "active", - "name": "Q1 Milestones", - "visible_to_clients": false, - "created_at": "2025-01-01T00:00:00Z", - "updated_at": "2025-01-01T00:00:00Z", - "title": "Q1 Milestones", - "inherits_status": true, - "type": "TodolistGroup", - "url": "https://3.basecampapi.com/999/buckets/12345678/todolists/111222.json", - "app_url": "https://3.basecamp.com/999/buckets/12345678/todolists/111222", - "creator": { - "id": 1, - "name": "Someone", - "created_at": "2025-01-01T00:00:00Z", - "updated_at": "2025-01-01T00:00:00Z" - }, - "bucket": { - "id": 12345678, - "name": "My Project", - "type": "Project" - }, - "parent": { - "id": 99999, - "title": "To-dos", - "type": "Todoset", - "url": "https://3.basecampapi.com/999/buckets/12345678/todosets/99999.json", - "app_url": "https://3.basecamp.com/999/buckets/12345678/todosets/99999" - } - } - } - } - } + "$ref": "#/components/schemas/ListTodosResponseContent" } } } @@ -18587,12 +19454,12 @@ } } }, - "404": { - "description": "NotFoundError 404 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -18611,6 +19478,11 @@ "tags": [ "Todos" ], + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -18621,17 +19493,18 @@ ] } }, - "put": { - "description": "Update an existing todolist or todolist group\nThe endpoint is polymorphic - updates either a Todolist or TodolistGroup", - "operationId": "UpdateTodolistOrGroup", + "post": { + "description": "Create a new todo in a todolist", + "operationId": "CreateTodo", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateTodolistOrGroupRequestContent" + "$ref": "#/components/schemas/CreateTodoRequestContent" } } - } + }, + "required": true }, "parameters": [ { @@ -18646,7 +19519,7 @@ "required": true }, { - "name": "id", + "name": "todolistId", "in": "path", "schema": { "type": "integer", @@ -18656,12 +19529,12 @@ } ], "responses": { - "200": { - "description": "UpdateTodolistOrGroup 200 response", + "201": { + "description": "CreateTodo 201 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateTodolistOrGroupResponseContent" + "$ref": "#/components/schemas/CreateTodoResponseContent" } } } @@ -18686,22 +19559,22 @@ } } }, - "404": { - "description": "NotFoundError 404 response", + "422": { + "description": "ValidationError 422 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/ValidationErrorResponseContent" } } } }, - "422": { - "description": "ValidationError 422 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -18720,9 +19593,6 @@ "tags": [ "Todos" ], - "x-basecamp-idempotent": { - "natural": true - }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -18734,10 +19604,10 @@ } } }, - "/{accountId}/todolists/{todolistId}/groups.json": { + "/{accountId}/todos/completed.json": { "get": { - "description": "List groups in a todolist\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", - "operationId": "ListTodolistGroups", + "description": "Get completed to-dos across all accessible projects, grouped by project\n(paginated).", + "operationId": "GetEverythingCompletedTodos", "parameters": [ { "name": "accountId", @@ -18749,24 +19619,15 @@ "description": "Basecamp account ID (numeric string)" }, "required": true - }, - { - "name": "todolistId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true } ], "responses": { "200": { - "description": "ListTodolistGroups 200 response", + "description": "GetEverythingCompletedTodos 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListTodolistGroupsResponseContent" + "$ref": "#/components/schemas/GetEverythingCompletedTodosResponseContent" } } } @@ -18813,7 +19674,7 @@ } }, "tags": [ - "Todos" + "Everything" ], "x-basecamp-pagination": { "style": "link", @@ -18829,20 +19690,12 @@ 503 ] } - }, - "post": { - "description": "Create a new group in a todolist", - "operationId": "CreateTodolistGroup", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateTodolistGroupRequestContent" - } - } - }, - "required": true - }, + } + }, + "/{accountId}/todos/no_due_date.json": { + "get": { + "description": "Get open to-dos with no due date across all accessible projects, grouped by\nproject (paginated).", + "operationId": "GetEverythingNoDueDateTodos", "parameters": [ { "name": "accountId", @@ -18854,24 +19707,15 @@ "description": "Basecamp account ID (numeric string)" }, "required": true - }, - { - "name": "todolistId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true } ], "responses": { - "201": { - "description": "CreateTodolistGroup 201 response", + "200": { + "description": "GetEverythingNoDueDateTodos 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateTodolistGroupResponseContent" + "$ref": "#/components/schemas/GetEverythingNoDueDateTodosResponseContent" } } } @@ -18896,16 +19740,6 @@ } } }, - "422": { - "description": "ValidationError 422 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" - } - } - } - }, "429": { "description": "RateLimitError 429 response", "content": { @@ -18928,10 +19762,15 @@ } }, "tags": [ - "Todos" + "Everything" ], + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + }, "x-basecamp-retry": { - "maxAttempts": 2, + "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -18941,10 +19780,10 @@ } } }, - "/{accountId}/todolists/{todolistId}/todos.json": { + "/{accountId}/todos/open.json": { "get": { - "description": "List todos in a todolist\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", - "operationId": "ListTodos", + "description": "Get active, incomplete to-dos across all accessible projects, grouped by\nproject (paginated). Each bucket entry carries the matching to-dos and their\nsteps.", + "operationId": "GetEverythingOpenTodos", "parameters": [ { "name": "accountId", @@ -18956,40 +19795,15 @@ "description": "Basecamp account ID (numeric string)" }, "required": true - }, - { - "name": "todolistId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true - }, - { - "name": "status", - "in": "query", - "description": "active|archived|trashed", - "schema": { - "type": "string", - "description": "active|archived|trashed" - } - }, - { - "name": "completed", - "in": "query", - "schema": { - "type": "boolean" - } } ], "responses": { "200": { - "description": "ListTodos 200 response", + "description": "GetEverythingOpenTodos 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListTodosResponseContent" + "$ref": "#/components/schemas/GetEverythingOpenTodosResponseContent" } } } @@ -19036,7 +19850,7 @@ } }, "tags": [ - "Todos" + "Everything" ], "x-basecamp-pagination": { "style": "link", @@ -19052,20 +19866,12 @@ 503 ] } - }, - "post": { - "description": "Create a new todo in a todolist", - "operationId": "CreateTodo", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateTodoRequestContent" - } - } - }, - "required": true - }, + } + }, + "/{accountId}/todos/overdue.json": { + "get": { + "description": "Get every overdue to-do across all accessible projects — a complete,\noldest-due-date-first array (unpaginated). Each item embeds its `bucket`.", + "operationId": "GetEverythingOverdueTodos", "parameters": [ { "name": "accountId", @@ -19077,24 +19883,15 @@ "description": "Basecamp account ID (numeric string)" }, "required": true - }, - { - "name": "todolistId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true } ], "responses": { - "201": { - "description": "CreateTodo 201 response", + "200": { + "description": "GetEverythingOverdueTodos 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateTodoResponseContent" + "$ref": "#/components/schemas/GetEverythingOverdueTodosResponseContent" } } } @@ -19119,26 +19916,6 @@ } } }, - "422": { - "description": "ValidationError 422 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" - } - } - } - }, - "429": { - "description": "RateLimitError 429 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" - } - } - } - }, "500": { "description": "InternalServerError 500 response", "content": { @@ -19151,7 +19928,7 @@ } }, "tags": [ - "Todos" + "Everything" ], "x-basecamp-retry": { "maxAttempts": 3, @@ -19164,10 +19941,10 @@ } } }, - "/{accountId}/todos/overdue.json": { + "/{accountId}/todos/unassigned.json": { "get": { - "description": "Get every overdue to-do across all accessible projects — a complete,\noldest-due-date-first array (unpaginated). Each item embeds its `bucket`.", - "operationId": "GetEverythingOverdueTodos", + "description": "Get open, unassigned to-dos across all accessible projects, grouped by\nproject (paginated).", + "operationId": "GetEverythingUnassignedTodos", "parameters": [ { "name": "accountId", @@ -19183,11 +19960,11 @@ ], "responses": { "200": { - "description": "GetEverythingOverdueTodos 200 response", + "description": "GetEverythingUnassignedTodos 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetEverythingOverdueTodosResponseContent" + "$ref": "#/components/schemas/GetEverythingUnassignedTodosResponseContent" } } } @@ -19212,6 +19989,16 @@ } } }, + "429": { + "description": "RateLimitError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RateLimitErrorResponseContent" + } + } + } + }, "500": { "description": "InternalServerError 500 response", "content": { @@ -19226,6 +20013,11 @@ "tags": [ "Everything" ], + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -22106,6 +22898,36 @@ "id" ] }, + "BucketCardsGroup": { + "type": "object", + "description": "One project's slice of a filtered card listing: the parent project and the\nmatching cards (each carrying its steps).", + "properties": { + "bucket": { + "$ref": "#/components/schemas/RecordingBucket" + }, + "cards": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Card" + } + } + } + }, + "BucketTodosGroup": { + "type": "object", + "description": "One project's slice of a filtered to-do listing: the parent project and the\nmatching to-dos (each carrying its steps).", + "properties": { + "bucket": { + "$ref": "#/components/schemas/RecordingBucket" + }, + "todos": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Todo" + } + } + } + }, "Campfire": { "type": "object", "properties": { @@ -24954,6 +25776,18 @@ "$ref": "#/components/schemas/Recording" } }, + "GetEverythingCompletedCardsResponseContent": { + "type": "array", + "items": { + "$ref": "#/components/schemas/BucketCardsGroup" + } + }, + "GetEverythingCompletedTodosResponseContent": { + "type": "array", + "items": { + "$ref": "#/components/schemas/BucketTodosGroup" + } + }, "GetEverythingFilesResponseContent": { "type": "array", "items": { @@ -24972,6 +25806,36 @@ "$ref": "#/components/schemas/Recording" } }, + "GetEverythingNoDueDateCardsResponseContent": { + "type": "array", + "items": { + "$ref": "#/components/schemas/BucketCardsGroup" + } + }, + "GetEverythingNoDueDateTodosResponseContent": { + "type": "array", + "items": { + "$ref": "#/components/schemas/BucketTodosGroup" + } + }, + "GetEverythingNotNowCardsResponseContent": { + "type": "array", + "items": { + "$ref": "#/components/schemas/BucketCardsGroup" + } + }, + "GetEverythingOpenCardsResponseContent": { + "type": "array", + "items": { + "$ref": "#/components/schemas/BucketCardsGroup" + } + }, + "GetEverythingOpenTodosResponseContent": { + "type": "array", + "items": { + "$ref": "#/components/schemas/BucketTodosGroup" + } + }, "GetEverythingOverdueCardsResponseContent": { "type": "array", "items": { @@ -24984,6 +25848,18 @@ "$ref": "#/components/schemas/Todo" } }, + "GetEverythingUnassignedCardsResponseContent": { + "type": "array", + "items": { + "$ref": "#/components/schemas/BucketCardsGroup" + } + }, + "GetEverythingUnassignedTodosResponseContent": { + "type": "array", + "items": { + "$ref": "#/components/schemas/BucketTodosGroup" + } + }, "GetForwardReplyResponseContent": { "$ref": "#/components/schemas/ForwardReply" }, diff --git a/python/src/basecamp/generated/metadata.json b/python/src/basecamp/generated/metadata.json index 40aa5d24..6f2b4568 100644 --- a/python/src/basecamp/generated/metadata.json +++ b/python/src/basecamp/generated/metadata.json @@ -761,6 +761,28 @@ ] } }, + "GetEverythingCompletedCards": { + "retry": { + "backoff": "exponential", + "base_delay_ms": 1000, + "max": 3, + "retry_on": [ + 429, + 503 + ] + } + }, + "GetEverythingCompletedTodos": { + "retry": { + "backoff": "exponential", + "base_delay_ms": 1000, + "max": 3, + "retry_on": [ + 429, + 503 + ] + } + }, "GetEverythingFiles": { "retry": { "backoff": "exponential", @@ -794,6 +816,61 @@ ] } }, + "GetEverythingNoDueDateCards": { + "retry": { + "backoff": "exponential", + "base_delay_ms": 1000, + "max": 3, + "retry_on": [ + 429, + 503 + ] + } + }, + "GetEverythingNoDueDateTodos": { + "retry": { + "backoff": "exponential", + "base_delay_ms": 1000, + "max": 3, + "retry_on": [ + 429, + 503 + ] + } + }, + "GetEverythingNotNowCards": { + "retry": { + "backoff": "exponential", + "base_delay_ms": 1000, + "max": 3, + "retry_on": [ + 429, + 503 + ] + } + }, + "GetEverythingOpenCards": { + "retry": { + "backoff": "exponential", + "base_delay_ms": 1000, + "max": 3, + "retry_on": [ + 429, + 503 + ] + } + }, + "GetEverythingOpenTodos": { + "retry": { + "backoff": "exponential", + "base_delay_ms": 1000, + "max": 3, + "retry_on": [ + 429, + 503 + ] + } + }, "GetEverythingOverdueCards": { "retry": { "backoff": "exponential", @@ -816,6 +893,28 @@ ] } }, + "GetEverythingUnassignedCards": { + "retry": { + "backoff": "exponential", + "base_delay_ms": 1000, + "max": 3, + "retry_on": [ + 429, + 503 + ] + } + }, + "GetEverythingUnassignedTodos": { + "retry": { + "backoff": "exponential", + "base_delay_ms": 1000, + "max": 3, + "retry_on": [ + 429, + 503 + ] + } + }, "GetForward": { "retry": { "backoff": "exponential", diff --git a/python/src/basecamp/generated/services/everything.py b/python/src/basecamp/generated/services/everything.py index 81d3484c..1cd9976c 100644 --- a/python/src/basecamp/generated/services/everything.py +++ b/python/src/basecamp/generated/services/everything.py @@ -16,6 +16,30 @@ def get_everything_boosts(self) -> ListResult: OperationInfo(service="everything", operation="get_everything_boosts", is_mutation=False), "/boosts.json" ) + def get_everything_completed_cards(self) -> ListResult: + return self._request_paginated( + OperationInfo(service="everything", operation="get_everything_completed_cards", is_mutation=False), + "/cards/completed.json", + ) + + def get_everything_no_due_date_cards(self) -> ListResult: + return self._request_paginated( + OperationInfo(service="everything", operation="get_everything_no_due_date_cards", is_mutation=False), + "/cards/no_due_date.json", + ) + + def get_everything_not_now_cards(self) -> ListResult: + return self._request_paginated( + OperationInfo(service="everything", operation="get_everything_not_now_cards", is_mutation=False), + "/cards/not_now.json", + ) + + def get_everything_open_cards(self) -> ListResult: + return self._request_paginated( + OperationInfo(service="everything", operation="get_everything_open_cards", is_mutation=False), + "/cards/open.json", + ) + def get_everything_overdue_cards(self) -> dict[str, Any]: return self._request( OperationInfo(service="everything", operation="get_everything_overdue_cards", is_mutation=False), @@ -23,6 +47,12 @@ def get_everything_overdue_cards(self) -> dict[str, Any]: "/cards/overdue.json", ) + def get_everything_unassigned_cards(self) -> ListResult: + return self._request_paginated( + OperationInfo(service="everything", operation="get_everything_unassigned_cards", is_mutation=False), + "/cards/unassigned.json", + ) + def get_everything_checkins(self) -> ListResult: return self._request_paginated( OperationInfo(service="everything", operation="get_everything_checkins", is_mutation=False), @@ -54,6 +84,24 @@ def get_everything_messages(self) -> ListResult: "/messages.json", ) + def get_everything_completed_todos(self) -> ListResult: + return self._request_paginated( + OperationInfo(service="everything", operation="get_everything_completed_todos", is_mutation=False), + "/todos/completed.json", + ) + + def get_everything_no_due_date_todos(self) -> ListResult: + return self._request_paginated( + OperationInfo(service="everything", operation="get_everything_no_due_date_todos", is_mutation=False), + "/todos/no_due_date.json", + ) + + def get_everything_open_todos(self) -> ListResult: + return self._request_paginated( + OperationInfo(service="everything", operation="get_everything_open_todos", is_mutation=False), + "/todos/open.json", + ) + def get_everything_overdue_todos(self) -> dict[str, Any]: return self._request( OperationInfo(service="everything", operation="get_everything_overdue_todos", is_mutation=False), @@ -61,6 +109,12 @@ def get_everything_overdue_todos(self) -> dict[str, Any]: "/todos/overdue.json", ) + def get_everything_unassigned_todos(self) -> ListResult: + return self._request_paginated( + OperationInfo(service="everything", operation="get_everything_unassigned_todos", is_mutation=False), + "/todos/unassigned.json", + ) + class AsyncEverythingService(AsyncBaseService): async def get_everything_boosts(self) -> ListResult: @@ -68,6 +122,30 @@ async def get_everything_boosts(self) -> ListResult: OperationInfo(service="everything", operation="get_everything_boosts", is_mutation=False), "/boosts.json" ) + async def get_everything_completed_cards(self) -> ListResult: + return await self._request_paginated( + OperationInfo(service="everything", operation="get_everything_completed_cards", is_mutation=False), + "/cards/completed.json", + ) + + async def get_everything_no_due_date_cards(self) -> ListResult: + return await self._request_paginated( + OperationInfo(service="everything", operation="get_everything_no_due_date_cards", is_mutation=False), + "/cards/no_due_date.json", + ) + + async def get_everything_not_now_cards(self) -> ListResult: + return await self._request_paginated( + OperationInfo(service="everything", operation="get_everything_not_now_cards", is_mutation=False), + "/cards/not_now.json", + ) + + async def get_everything_open_cards(self) -> ListResult: + return await self._request_paginated( + OperationInfo(service="everything", operation="get_everything_open_cards", is_mutation=False), + "/cards/open.json", + ) + async def get_everything_overdue_cards(self) -> dict[str, Any]: return await self._request( OperationInfo(service="everything", operation="get_everything_overdue_cards", is_mutation=False), @@ -75,6 +153,12 @@ async def get_everything_overdue_cards(self) -> dict[str, Any]: "/cards/overdue.json", ) + async def get_everything_unassigned_cards(self) -> ListResult: + return await self._request_paginated( + OperationInfo(service="everything", operation="get_everything_unassigned_cards", is_mutation=False), + "/cards/unassigned.json", + ) + async def get_everything_checkins(self) -> ListResult: return await self._request_paginated( OperationInfo(service="everything", operation="get_everything_checkins", is_mutation=False), @@ -106,9 +190,33 @@ async def get_everything_messages(self) -> ListResult: "/messages.json", ) + async def get_everything_completed_todos(self) -> ListResult: + return await self._request_paginated( + OperationInfo(service="everything", operation="get_everything_completed_todos", is_mutation=False), + "/todos/completed.json", + ) + + async def get_everything_no_due_date_todos(self) -> ListResult: + return await self._request_paginated( + OperationInfo(service="everything", operation="get_everything_no_due_date_todos", is_mutation=False), + "/todos/no_due_date.json", + ) + + async def get_everything_open_todos(self) -> ListResult: + return await self._request_paginated( + OperationInfo(service="everything", operation="get_everything_open_todos", is_mutation=False), + "/todos/open.json", + ) + async def get_everything_overdue_todos(self) -> dict[str, Any]: return await self._request( OperationInfo(service="everything", operation="get_everything_overdue_todos", is_mutation=False), "GET", "/todos/overdue.json", ) + + async def get_everything_unassigned_todos(self) -> ListResult: + return await self._request_paginated( + OperationInfo(service="everything", operation="get_everything_unassigned_todos", is_mutation=False), + "/todos/unassigned.json", + ) diff --git a/python/src/basecamp/generated/types.py b/python/src/basecamp/generated/types.py index 82bdbd9a..f3e757a4 100644 --- a/python/src/basecamp/generated/types.py +++ b/python/src/basecamp/generated/types.py @@ -78,6 +78,16 @@ class Boost(TypedDict): recording: NotRequired[RecordingParent] +class BucketCardsGroup(TypedDict): + bucket: NotRequired[RecordingBucket] + cards: NotRequired[list[Card]] + + +class BucketTodosGroup(TypedDict): + bucket: NotRequired[RecordingBucket] + todos: NotRequired[list[Todo]] + + class Campfire(TypedDict): app_url: str bookmark_url: NotRequired[str] diff --git a/ruby/lib/basecamp/generated/metadata.json b/ruby/lib/basecamp/generated/metadata.json index d0bdce4c..9e17fbfd 100644 --- a/ruby/lib/basecamp/generated/metadata.json +++ b/ruby/lib/basecamp/generated/metadata.json @@ -1,7 +1,7 @@ { "$schema": "https://basecamp.com/schemas/sdk-metadata.json", "version": "1.0.0", - "generated": "2026-07-25T05:55:02Z", + "generated": "2026-07-25T06:05:01Z", "operations": { "GetAccount": { "retry": { @@ -395,6 +395,70 @@ ] } }, + "GetEverythingCompletedCards": { + "retry": { + "maxAttempts": 3, + "baseDelayMs": 1000, + "backoff": "exponential", + "retryOn": [ + 429, + 503 + ] + }, + "pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + } + }, + "GetEverythingNoDueDateCards": { + "retry": { + "maxAttempts": 3, + "baseDelayMs": 1000, + "backoff": "exponential", + "retryOn": [ + 429, + 503 + ] + }, + "pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + } + }, + "GetEverythingNotNowCards": { + "retry": { + "maxAttempts": 3, + "baseDelayMs": 1000, + "backoff": "exponential", + "retryOn": [ + 429, + 503 + ] + }, + "pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + } + }, + "GetEverythingOpenCards": { + "retry": { + "maxAttempts": 3, + "baseDelayMs": 1000, + "backoff": "exponential", + "retryOn": [ + 429, + 503 + ] + }, + "pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + } + }, "GetEverythingOverdueCards": { "retry": { "maxAttempts": 3, @@ -406,6 +470,22 @@ ] } }, + "GetEverythingUnassignedCards": { + "retry": { + "maxAttempts": 3, + "baseDelayMs": 1000, + "backoff": "exponential", + "retryOn": [ + 429, + 503 + ] + }, + "pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + } + }, "ListMessageTypes": { "retry": { "maxAttempts": 3, @@ -2455,6 +2535,54 @@ ] } }, + "GetEverythingCompletedTodos": { + "retry": { + "maxAttempts": 3, + "baseDelayMs": 1000, + "backoff": "exponential", + "retryOn": [ + 429, + 503 + ] + }, + "pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + } + }, + "GetEverythingNoDueDateTodos": { + "retry": { + "maxAttempts": 3, + "baseDelayMs": 1000, + "backoff": "exponential", + "retryOn": [ + 429, + 503 + ] + }, + "pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + } + }, + "GetEverythingOpenTodos": { + "retry": { + "maxAttempts": 3, + "baseDelayMs": 1000, + "backoff": "exponential", + "retryOn": [ + 429, + 503 + ] + }, + "pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + } + }, "GetEverythingOverdueTodos": { "retry": { "maxAttempts": 3, @@ -2466,6 +2594,22 @@ ] } }, + "GetEverythingUnassignedTodos": { + "retry": { + "maxAttempts": 3, + "baseDelayMs": 1000, + "backoff": "exponential", + "retryOn": [ + 429, + 503 + ] + }, + "pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + } + }, "GetTodo": { "retry": { "maxAttempts": 3, diff --git a/ruby/lib/basecamp/generated/services/everything_service.rb b/ruby/lib/basecamp/generated/services/everything_service.rb index 9ea7278b..0266a3dd 100644 --- a/ruby/lib/basecamp/generated/services/everything_service.rb +++ b/ruby/lib/basecamp/generated/services/everything_service.rb @@ -15,6 +15,38 @@ def get_everything_boosts() end end + # Get completed cards across all accessible projects, grouped by project + # @return [Enumerator] paginated results + def get_everything_completed_cards() + wrap_paginated(service: "everything", operation: "get_everything_completed_cards", is_mutation: false) do + paginate("/cards/completed.json") + end + end + + # Get open cards with no due date across all accessible projects, grouped by + # @return [Enumerator] paginated results + def get_everything_no_due_date_cards() + wrap_paginated(service: "everything", operation: "get_everything_no_due_date_cards", is_mutation: false) do + paginate("/cards/no_due_date.json") + end + end + + # Get cards parked in a project's "Not now" column across all accessible + # @return [Enumerator] paginated results + def get_everything_not_now_cards() + wrap_paginated(service: "everything", operation: "get_everything_not_now_cards", is_mutation: false) do + paginate("/cards/not_now.json") + end + end + + # Get incomplete cards in active columns across all accessible projects, + # @return [Enumerator] paginated results + def get_everything_open_cards() + wrap_paginated(service: "everything", operation: "get_everything_open_cards", is_mutation: false) do + paginate("/cards/open.json") + end + end + # Get every overdue card across all accessible projects — a complete, # @return [Hash] response data def get_everything_overdue_cards() @@ -23,6 +55,14 @@ def get_everything_overdue_cards() end end + # Get open, unassigned cards across all accessible projects, grouped by + # @return [Enumerator] paginated results + def get_everything_unassigned_cards() + wrap_paginated(service: "everything", operation: "get_everything_unassigned_cards", is_mutation: false) do + paginate("/cards/unassigned.json") + end + end + # Get every automatic check-in answer across all accessible projects, # @return [Enumerator] paginated results def get_everything_checkins() @@ -66,6 +106,30 @@ def get_everything_messages() end end + # Get completed to-dos across all accessible projects, grouped by project + # @return [Enumerator] paginated results + def get_everything_completed_todos() + wrap_paginated(service: "everything", operation: "get_everything_completed_todos", is_mutation: false) do + paginate("/todos/completed.json") + end + end + + # Get open to-dos with no due date across all accessible projects, grouped by + # @return [Enumerator] paginated results + def get_everything_no_due_date_todos() + wrap_paginated(service: "everything", operation: "get_everything_no_due_date_todos", is_mutation: false) do + paginate("/todos/no_due_date.json") + end + end + + # Get active, incomplete to-dos across all accessible projects, grouped by + # @return [Enumerator] paginated results + def get_everything_open_todos() + wrap_paginated(service: "everything", operation: "get_everything_open_todos", is_mutation: false) do + paginate("/todos/open.json") + end + end + # Get every overdue to-do across all accessible projects — a complete, # @return [Hash] response data def get_everything_overdue_todos() @@ -73,6 +137,14 @@ def get_everything_overdue_todos() http_get("/todos/overdue.json").json end end + + # Get open, unassigned to-dos across all accessible projects, grouped by + # @return [Enumerator] paginated results + def get_everything_unassigned_todos() + wrap_paginated(service: "everything", operation: "get_everything_unassigned_todos", is_mutation: false) do + paginate("/todos/unassigned.json") + end + end end end end diff --git a/ruby/lib/basecamp/generated/types.rb b/ruby/lib/basecamp/generated/types.rb index b6ef5d02..8e4079c9 100644 --- a/ruby/lib/basecamp/generated/types.rb +++ b/ruby/lib/basecamp/generated/types.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Auto-generated from OpenAPI spec. Do not edit manually. -# Generated: 2026-07-25T05:55:02Z +# Generated: 2026-07-25T06:05:01Z require "json" require "time" @@ -288,6 +288,50 @@ def to_json(*args) end end + # BucketCardsGroup + class BucketCardsGroup + include TypeHelpers + attr_accessor :bucket, :cards + + def initialize(data = {}) + @bucket = parse_type(data["bucket"], "RecordingBucket") + @cards = parse_array(data["cards"], "Card") + end + + def to_h + { + "bucket" => @bucket, + "cards" => @cards, + }.compact + end + + def to_json(*args) + to_h.to_json(*args) + end + end + + # BucketTodosGroup + class BucketTodosGroup + include TypeHelpers + attr_accessor :bucket, :todos + + def initialize(data = {}) + @bucket = parse_type(data["bucket"], "RecordingBucket") + @todos = parse_array(data["todos"], "Todo") + end + + def to_h + { + "bucket" => @bucket, + "todos" => @todos, + }.compact + end + + def to_json(*args) + to_h.to_json(*args) + end + end + # Campfire class Campfire include TypeHelpers diff --git a/spec/api-gaps/README.md b/spec/api-gaps/README.md index 231e3853..6eb76734 100644 --- a/spec/api-gaps/README.md +++ b/spec/api-gaps/README.md @@ -39,7 +39,7 @@ making the absorption journey publicly auditable. | [calendar](calendar.md) | addressed-in-bc3-pr-12321 | 3b | medium | | [scratchpad](scratchpad.md) | addressed-in-bc3-pr-12322 | 3b | medium | | [step-top-level](step-top-level.md) | absorbed-in-sdk | 3b | low | -| [everything-aggregates](everything-aggregates.md) | partial-coverage | 3c | high | +| [everything-aggregates](everything-aggregates.md) | absorbed-in-sdk | 3c | high | | [activity-timeline](activity-timeline.md) | absorbed-in-sdk | 3d | high | | [recordable-subtypes-doc](recordable-subtypes-doc.md) | partial-coverage | 3a | medium | | [stack-doc-and-smithy](stack-doc-and-smithy.md) | confirmed-not-api-resource | 3b | medium | diff --git a/spec/api-gaps/everything-aggregates.md b/spec/api-gaps/everything-aggregates.md index 7ba1fd39..7dbaeaf4 100644 --- a/spec/api-gaps/everything-aggregates.md +++ b/spec/api-gaps/everything-aggregates.md @@ -1,12 +1,14 @@ --- gap: everything-aggregates -status: partial-coverage +status: absorbed-in-sdk detected: 2026-05-01 sdk_demand: high bc3_pr: 11627 smithy_refs: - "EverythingService flat family: GetEverythingMessages/Comments/Checkins/Forwards/Boosts/Files + GetEverythingOverdueTodos/OverdueCards (spec/basecamp.smithy)" - "EverythingFile superset (spec/basecamp.smithy)" + - "EverythingService bucket-grouped family: GetEverythingOpen/Completed/Unassigned/NoDueDate Todos + Open/Completed/Unassigned/NoDueDate/NotNow Cards (spec/basecamp.smithy)" + - "BucketTodosGroup / BucketCardsGroup (spec/basecamp.smithy)" bc3_refs: introduced_in: five bc3_plan_phase: 3c @@ -115,9 +117,9 @@ merged doc. ## SDK absorption plan when this lands -Absorbed in **two phases** across a stacked PR pair. This entry stays -`partial-coverage` until **both** phases land; it flips to `absorbed-in-sdk` -only when all 17 routes are modeled. +Absorbed in **two phases** across a stacked PR pair. All 17 routes are now +modeled, generated across the six SDKs, Go-wrapped, and decode-tested — the +entry is `absorbed-in-sdk`. **PR-5 (flat family) — DONE.** A new `EverythingService` with the 8 flat-family operations: @@ -143,14 +145,24 @@ operations: - Go wrappers with multi-page Link-following (paginated roots) and plain full-array decode (overdue); the flat-aggregate mirror of `GetMyAssignments`. -**PR-5b (bucket-grouped family) — PENDING.** The 9 todo/card filter sub-routes +**PR-5b (bucket-grouped family) — DONE.** The 9 todo/card filter sub-routes (`/todos/{open,completed,unassigned,no_due_date}.json`, `/cards/{open,completed,unassigned,no_due_date,not_now}.json`) return a -paginated array of `{bucket, todos|cards}` with steps. Not yet modeled. - -**Remaining follow-ups (tracked, not blocking the flat family):** conformance -`paths.json` path-assertion entries + per-runner dispatch for the 8 new ops, and -a live-canary entry per group. These land alongside PR-5b when the entry flips. +Link-paginated array of `{bucket, todos|cards}` (full `Todo`/`Card` recordings +with their embedded steps), modeled as `BucketTodosGroup` / `BucketCardsGroup` +(single-member output, Link pagination → bare array of groups). Go wrappers +(`OpenTodos`/`CompletedTodos`/`UnassignedTodos`/`NoDueDateTodos` and +`OpenCards`/`CompletedCards`/`UnassignedCards`/`NoDueDateCards`/`NotNowCards`) +with multi-page Link-following; Go tests cover multi-page pagination and the +`{bucket, todos|cards}`-with-steps grouping. The generator auto-derives these +onto `EverythingService` from the `Everything` tag (Kotlin needed the two group +types added to `TYPE_ALIASES` to emit typed models). + +**Remaining verification-infra follow-up (supplementary, not the absorption):** +conformance `paths.json` path-assertion entries + per-runner dispatch for the 17 +`GetEverything*` ops, and a live-canary entry per group (the live canary is +dormant pending a safe token mechanism). The modeled surface itself is complete +and covered by the Go + per-language decode tests. Exclusions honored: never model the `//recent.json` aliases (internal web feeds) or the bare `/todos.json` / `/cards.json` roots (HTML shells). diff --git a/spec/basecamp.smithy b/spec/basecamp.smithy index 466f7cfe..34ce2d98 100644 --- a/spec/basecamp.smithy +++ b/spec/basecamp.smithy @@ -296,6 +296,17 @@ service Basecamp { GetEverythingOverdueTodos, GetEverythingOverdueCards, + // Batch 15c - Everything Aggregates (bucket-grouped todo/card family) + GetEverythingOpenTodos, + GetEverythingCompletedTodos, + GetEverythingUnassignedTodos, + GetEverythingNoDueDateTodos, + GetEverythingOpenCards, + GetEverythingCompletedCards, + GetEverythingUnassignedCards, + GetEverythingNoDueDateCards, + GetEverythingNotNowCards, + // Batch 16 - My Notifications GetMyNotifications, GetBubbleUps, @@ -8782,6 +8793,169 @@ structure EverythingFile { description_attachments: RichTextAttachmentList } +// ============================================================================= +// BATCH 15c - Everything Aggregates (bucket-grouped todo/card filter family) +// ============================================================================= +// +// The todo/card filter sub-routes return a paginated array of buckets, each +// entry grouping the matching recordings (with their steps) under their parent +// project. Documented by BC3 #11627 in doc/api/sections/everything.md. The bare +// /todos.json and /cards.json roots stay HTML shells and are never modeled. + +/// Get active, incomplete to-dos across all accessible projects, grouped by +/// project (paginated). Each bucket entry carries the matching to-dos and their +/// steps. +@readonly +@basecampRetry(maxAttempts: 3, baseDelayMs: 1000, backoff: "exponential", retryOn: [429, 503]) +@basecampPagination(style: "link", totalCountHeader: "X-Total-Count", maxPageSize: 50) +@http(method: "GET", uri: "/{accountId}/todos/open.json") +operation GetEverythingOpenTodos { + input: EverythingTodosFilterInput + output: EverythingTodosGroupOutput + errors: [UnauthorizedError, ForbiddenError, RateLimitError, InternalServerError] +} + +/// Get completed to-dos across all accessible projects, grouped by project +/// (paginated). +@readonly +@basecampRetry(maxAttempts: 3, baseDelayMs: 1000, backoff: "exponential", retryOn: [429, 503]) +@basecampPagination(style: "link", totalCountHeader: "X-Total-Count", maxPageSize: 50) +@http(method: "GET", uri: "/{accountId}/todos/completed.json") +operation GetEverythingCompletedTodos { + input: EverythingTodosFilterInput + output: EverythingTodosGroupOutput + errors: [UnauthorizedError, ForbiddenError, RateLimitError, InternalServerError] +} + +/// Get open, unassigned to-dos across all accessible projects, grouped by +/// project (paginated). +@readonly +@basecampRetry(maxAttempts: 3, baseDelayMs: 1000, backoff: "exponential", retryOn: [429, 503]) +@basecampPagination(style: "link", totalCountHeader: "X-Total-Count", maxPageSize: 50) +@http(method: "GET", uri: "/{accountId}/todos/unassigned.json") +operation GetEverythingUnassignedTodos { + input: EverythingTodosFilterInput + output: EverythingTodosGroupOutput + errors: [UnauthorizedError, ForbiddenError, RateLimitError, InternalServerError] +} + +/// Get open to-dos with no due date across all accessible projects, grouped by +/// project (paginated). +@readonly +@basecampRetry(maxAttempts: 3, baseDelayMs: 1000, backoff: "exponential", retryOn: [429, 503]) +@basecampPagination(style: "link", totalCountHeader: "X-Total-Count", maxPageSize: 50) +@http(method: "GET", uri: "/{accountId}/todos/no_due_date.json") +operation GetEverythingNoDueDateTodos { + input: EverythingTodosFilterInput + output: EverythingTodosGroupOutput + errors: [UnauthorizedError, ForbiddenError, RateLimitError, InternalServerError] +} + +/// Get incomplete cards in active columns across all accessible projects, +/// grouped by project (paginated). Each bucket entry carries the matching cards +/// and their steps. +@readonly +@basecampRetry(maxAttempts: 3, baseDelayMs: 1000, backoff: "exponential", retryOn: [429, 503]) +@basecampPagination(style: "link", totalCountHeader: "X-Total-Count", maxPageSize: 50) +@http(method: "GET", uri: "/{accountId}/cards/open.json") +operation GetEverythingOpenCards { + input: EverythingCardsFilterInput + output: EverythingCardsGroupOutput + errors: [UnauthorizedError, ForbiddenError, RateLimitError, InternalServerError] +} + +/// Get completed cards across all accessible projects, grouped by project +/// (paginated). +@readonly +@basecampRetry(maxAttempts: 3, baseDelayMs: 1000, backoff: "exponential", retryOn: [429, 503]) +@basecampPagination(style: "link", totalCountHeader: "X-Total-Count", maxPageSize: 50) +@http(method: "GET", uri: "/{accountId}/cards/completed.json") +operation GetEverythingCompletedCards { + input: EverythingCardsFilterInput + output: EverythingCardsGroupOutput + errors: [UnauthorizedError, ForbiddenError, RateLimitError, InternalServerError] +} + +/// Get open, unassigned cards across all accessible projects, grouped by +/// project (paginated). +@readonly +@basecampRetry(maxAttempts: 3, baseDelayMs: 1000, backoff: "exponential", retryOn: [429, 503]) +@basecampPagination(style: "link", totalCountHeader: "X-Total-Count", maxPageSize: 50) +@http(method: "GET", uri: "/{accountId}/cards/unassigned.json") +operation GetEverythingUnassignedCards { + input: EverythingCardsFilterInput + output: EverythingCardsGroupOutput + errors: [UnauthorizedError, ForbiddenError, RateLimitError, InternalServerError] +} + +/// Get open cards with no due date across all accessible projects, grouped by +/// project (paginated). +@readonly +@basecampRetry(maxAttempts: 3, baseDelayMs: 1000, backoff: "exponential", retryOn: [429, 503]) +@basecampPagination(style: "link", totalCountHeader: "X-Total-Count", maxPageSize: 50) +@http(method: "GET", uri: "/{accountId}/cards/no_due_date.json") +operation GetEverythingNoDueDateCards { + input: EverythingCardsFilterInput + output: EverythingCardsGroupOutput + errors: [UnauthorizedError, ForbiddenError, RateLimitError, InternalServerError] +} + +/// Get cards parked in a project's "Not now" column across all accessible +/// projects, grouped by project (paginated). +@readonly +@basecampRetry(maxAttempts: 3, baseDelayMs: 1000, backoff: "exponential", retryOn: [429, 503]) +@basecampPagination(style: "link", totalCountHeader: "X-Total-Count", maxPageSize: 50) +@http(method: "GET", uri: "/{accountId}/cards/not_now.json") +operation GetEverythingNotNowCards { + input: EverythingCardsFilterInput + output: EverythingCardsGroupOutput + errors: [UnauthorizedError, ForbiddenError, RateLimitError, InternalServerError] +} + +structure EverythingTodosFilterInput { + @required + @httpLabel + accountId: AccountId +} + +structure EverythingTodosGroupOutput { + buckets: BucketTodosGroupList +} + +structure EverythingCardsFilterInput { + @required + @httpLabel + accountId: AccountId +} + +structure EverythingCardsGroupOutput { + buckets: BucketCardsGroupList +} + +// ===== Everything Bucket-Group Shapes ===== + +list BucketTodosGroupList { + member: BucketTodosGroup +} + +/// One project's slice of a filtered to-do listing: the parent project and the +/// matching to-dos (each carrying its steps). +structure BucketTodosGroup { + bucket: RecordingBucket + todos: TodoItems +} + +list BucketCardsGroupList { + member: BucketCardsGroup +} + +/// One project's slice of a filtered card listing: the parent project and the +/// matching cards (each carrying its steps). +structure BucketCardsGroup { + bucket: RecordingBucket + cards: CardList +} + // ===== My Assignment Shapes ===== list MyAssignmentList { diff --git a/spec/overlays/tags.smithy b/spec/overlays/tags.smithy index c910c3b0..9cbca94d 100644 --- a/spec/overlays/tags.smithy +++ b/spec/overlays/tags.smithy @@ -225,6 +225,15 @@ apply GetEverythingBoosts @tags(["Everything"]) apply GetEverythingFiles @tags(["Everything"]) apply GetEverythingOverdueTodos @tags(["Everything"]) apply GetEverythingOverdueCards @tags(["Everything"]) +apply GetEverythingOpenTodos @tags(["Everything"]) +apply GetEverythingCompletedTodos @tags(["Everything"]) +apply GetEverythingUnassignedTodos @tags(["Everything"]) +apply GetEverythingNoDueDateTodos @tags(["Everything"]) +apply GetEverythingOpenCards @tags(["Everything"]) +apply GetEverythingCompletedCards @tags(["Everything"]) +apply GetEverythingUnassignedCards @tags(["Everything"]) +apply GetEverythingNoDueDateCards @tags(["Everything"]) +apply GetEverythingNotNowCards @tags(["Everything"]) // My Notifications apply GetMyNotifications @tags(["MyNotifications"]) diff --git a/swift/Sources/Basecamp/Generated/Metadata.swift b/swift/Sources/Basecamp/Generated/Metadata.swift index 88f45dc5..3d02ce38 100644 --- a/swift/Sources/Basecamp/Generated/Metadata.swift +++ b/swift/Sources/Basecamp/Generated/Metadata.swift @@ -71,11 +71,20 @@ enum Metadata { "GetEverythingBoosts": RetryConfig(maxAttempts: 3, baseDelayMs: 1000, backoff: .exponential, retryOn: [429, 503]), "GetEverythingCheckins": RetryConfig(maxAttempts: 3, baseDelayMs: 1000, backoff: .exponential, retryOn: [429, 503]), "GetEverythingComments": RetryConfig(maxAttempts: 3, baseDelayMs: 1000, backoff: .exponential, retryOn: [429, 503]), + "GetEverythingCompletedCards": RetryConfig(maxAttempts: 3, baseDelayMs: 1000, backoff: .exponential, retryOn: [429, 503]), + "GetEverythingCompletedTodos": RetryConfig(maxAttempts: 3, baseDelayMs: 1000, backoff: .exponential, retryOn: [429, 503]), "GetEverythingFiles": RetryConfig(maxAttempts: 3, baseDelayMs: 1000, backoff: .exponential, retryOn: [429, 503]), "GetEverythingForwards": RetryConfig(maxAttempts: 3, baseDelayMs: 1000, backoff: .exponential, retryOn: [429, 503]), "GetEverythingMessages": RetryConfig(maxAttempts: 3, baseDelayMs: 1000, backoff: .exponential, retryOn: [429, 503]), + "GetEverythingNoDueDateCards": RetryConfig(maxAttempts: 3, baseDelayMs: 1000, backoff: .exponential, retryOn: [429, 503]), + "GetEverythingNoDueDateTodos": RetryConfig(maxAttempts: 3, baseDelayMs: 1000, backoff: .exponential, retryOn: [429, 503]), + "GetEverythingNotNowCards": RetryConfig(maxAttempts: 3, baseDelayMs: 1000, backoff: .exponential, retryOn: [429, 503]), + "GetEverythingOpenCards": RetryConfig(maxAttempts: 3, baseDelayMs: 1000, backoff: .exponential, retryOn: [429, 503]), + "GetEverythingOpenTodos": RetryConfig(maxAttempts: 3, baseDelayMs: 1000, backoff: .exponential, retryOn: [429, 503]), "GetEverythingOverdueCards": RetryConfig(maxAttempts: 3, baseDelayMs: 1000, backoff: .exponential, retryOn: [429, 503]), "GetEverythingOverdueTodos": RetryConfig(maxAttempts: 3, baseDelayMs: 1000, backoff: .exponential, retryOn: [429, 503]), + "GetEverythingUnassignedCards": RetryConfig(maxAttempts: 3, baseDelayMs: 1000, backoff: .exponential, retryOn: [429, 503]), + "GetEverythingUnassignedTodos": RetryConfig(maxAttempts: 3, baseDelayMs: 1000, backoff: .exponential, retryOn: [429, 503]), "GetForward": RetryConfig(maxAttempts: 3, baseDelayMs: 1000, backoff: .exponential, retryOn: [429, 503]), "GetForwardReply": RetryConfig(maxAttempts: 3, baseDelayMs: 1000, backoff: .exponential, retryOn: [429, 503]), "GetGaugeNeedle": RetryConfig(maxAttempts: 3, baseDelayMs: 1000, backoff: .exponential, retryOn: [429, 503]), diff --git a/swift/Sources/Basecamp/Generated/Models/BucketCardsGroup.swift b/swift/Sources/Basecamp/Generated/Models/BucketCardsGroup.swift new file mode 100644 index 00000000..591f87b9 --- /dev/null +++ b/swift/Sources/Basecamp/Generated/Models/BucketCardsGroup.swift @@ -0,0 +1,7 @@ +// @generated from OpenAPI spec — do not edit directly +import Foundation + +public struct BucketCardsGroup: Codable, Sendable { + public var bucket: RecordingBucket? + public var cards: [Card]? +} diff --git a/swift/Sources/Basecamp/Generated/Models/BucketTodosGroup.swift b/swift/Sources/Basecamp/Generated/Models/BucketTodosGroup.swift new file mode 100644 index 00000000..b4d58d45 --- /dev/null +++ b/swift/Sources/Basecamp/Generated/Models/BucketTodosGroup.swift @@ -0,0 +1,7 @@ +// @generated from OpenAPI spec — do not edit directly +import Foundation + +public struct BucketTodosGroup: Codable, Sendable { + public var bucket: RecordingBucket? + public var todos: [Todo]? +} diff --git a/swift/Sources/Basecamp/Generated/Services/EverythingService.swift b/swift/Sources/Basecamp/Generated/Services/EverythingService.swift index a77b4713..a3c66385 100644 --- a/swift/Sources/Basecamp/Generated/Services/EverythingService.swift +++ b/swift/Sources/Basecamp/Generated/Services/EverythingService.swift @@ -25,6 +25,22 @@ public struct EverythingCommentsEverythingOptions: Sendable { } } +public struct EverythingCompletedCardsEverythingOptions: Sendable { + public var maxItems: Int? + + public init(maxItems: Int? = nil) { + self.maxItems = maxItems + } +} + +public struct EverythingCompletedTodosEverythingOptions: Sendable { + public var maxItems: Int? + + public init(maxItems: Int? = nil) { + self.maxItems = maxItems + } +} + public struct EverythingFilesEverythingOptions: Sendable { public var kind: String? public var peopleIds: [Int]? @@ -53,6 +69,62 @@ public struct EverythingMessagesEverythingOptions: Sendable { } } +public struct EverythingNoDueDateCardsEverythingOptions: Sendable { + public var maxItems: Int? + + public init(maxItems: Int? = nil) { + self.maxItems = maxItems + } +} + +public struct EverythingNoDueDateTodosEverythingOptions: Sendable { + public var maxItems: Int? + + public init(maxItems: Int? = nil) { + self.maxItems = maxItems + } +} + +public struct EverythingNotNowCardsEverythingOptions: Sendable { + public var maxItems: Int? + + public init(maxItems: Int? = nil) { + self.maxItems = maxItems + } +} + +public struct EverythingOpenCardsEverythingOptions: Sendable { + public var maxItems: Int? + + public init(maxItems: Int? = nil) { + self.maxItems = maxItems + } +} + +public struct EverythingOpenTodosEverythingOptions: Sendable { + public var maxItems: Int? + + public init(maxItems: Int? = nil) { + self.maxItems = maxItems + } +} + +public struct EverythingUnassignedCardsEverythingOptions: Sendable { + public var maxItems: Int? + + public init(maxItems: Int? = nil) { + self.maxItems = maxItems + } +} + +public struct EverythingUnassignedTodosEverythingOptions: Sendable { + public var maxItems: Int? + + public init(maxItems: Int? = nil) { + self.maxItems = maxItems + } +} + public final class EverythingService: BaseService, @unchecked Sendable { public func everythingBoosts(options: EverythingBoostsEverythingOptions? = nil) async throws -> ListResult { @@ -82,6 +154,24 @@ public final class EverythingService: BaseService, @unchecked Sendable { ) } + public func everythingCompletedCards(options: EverythingCompletedCardsEverythingOptions? = nil) async throws -> ListResult { + return try await requestPaginated( + OperationInfo(service: "Everything", operation: "GetEverythingCompletedCards", resourceType: "everything_completed_card", isMutation: false), + path: "/cards/completed.json", + paginationOpts: options.flatMap { PaginationOptions(maxItems: $0.maxItems) }, + retryConfig: Metadata.retryConfig(for: "GetEverythingCompletedCards") + ) + } + + public func everythingCompletedTodos(options: EverythingCompletedTodosEverythingOptions? = nil) async throws -> ListResult { + return try await requestPaginated( + OperationInfo(service: "Everything", operation: "GetEverythingCompletedTodos", resourceType: "everything_completed_todo", isMutation: false), + path: "/todos/completed.json", + paginationOpts: options.flatMap { PaginationOptions(maxItems: $0.maxItems) }, + retryConfig: Metadata.retryConfig(for: "GetEverythingCompletedTodos") + ) + } + public func everythingFiles(options: EverythingFilesEverythingOptions? = nil) async throws -> ListResult { var queryItems: [URLQueryItem] = [] if let kind = options?.kind { @@ -119,6 +209,51 @@ public final class EverythingService: BaseService, @unchecked Sendable { ) } + public func everythingNoDueDateCards(options: EverythingNoDueDateCardsEverythingOptions? = nil) async throws -> ListResult { + return try await requestPaginated( + OperationInfo(service: "Everything", operation: "GetEverythingNoDueDateCards", resourceType: "everything_no_due_date_card", isMutation: false), + path: "/cards/no_due_date.json", + paginationOpts: options.flatMap { PaginationOptions(maxItems: $0.maxItems) }, + retryConfig: Metadata.retryConfig(for: "GetEverythingNoDueDateCards") + ) + } + + public func everythingNoDueDateTodos(options: EverythingNoDueDateTodosEverythingOptions? = nil) async throws -> ListResult { + return try await requestPaginated( + OperationInfo(service: "Everything", operation: "GetEverythingNoDueDateTodos", resourceType: "everything_no_due_date_todo", isMutation: false), + path: "/todos/no_due_date.json", + paginationOpts: options.flatMap { PaginationOptions(maxItems: $0.maxItems) }, + retryConfig: Metadata.retryConfig(for: "GetEverythingNoDueDateTodos") + ) + } + + public func everythingNotNowCards(options: EverythingNotNowCardsEverythingOptions? = nil) async throws -> ListResult { + return try await requestPaginated( + OperationInfo(service: "Everything", operation: "GetEverythingNotNowCards", resourceType: "everything_not_now_card", isMutation: false), + path: "/cards/not_now.json", + paginationOpts: options.flatMap { PaginationOptions(maxItems: $0.maxItems) }, + retryConfig: Metadata.retryConfig(for: "GetEverythingNotNowCards") + ) + } + + public func everythingOpenCards(options: EverythingOpenCardsEverythingOptions? = nil) async throws -> ListResult { + return try await requestPaginated( + OperationInfo(service: "Everything", operation: "GetEverythingOpenCards", resourceType: "everything_open_card", isMutation: false), + path: "/cards/open.json", + paginationOpts: options.flatMap { PaginationOptions(maxItems: $0.maxItems) }, + retryConfig: Metadata.retryConfig(for: "GetEverythingOpenCards") + ) + } + + public func everythingOpenTodos(options: EverythingOpenTodosEverythingOptions? = nil) async throws -> ListResult { + return try await requestPaginated( + OperationInfo(service: "Everything", operation: "GetEverythingOpenTodos", resourceType: "everything_open_todo", isMutation: false), + path: "/todos/open.json", + paginationOpts: options.flatMap { PaginationOptions(maxItems: $0.maxItems) }, + retryConfig: Metadata.retryConfig(for: "GetEverythingOpenTodos") + ) + } + public func everythingOverdueCards() async throws -> [Card] { return try await request( OperationInfo(service: "Everything", operation: "GetEverythingOverdueCards", resourceType: "everything_overdue_card", isMutation: false), @@ -136,4 +271,22 @@ public final class EverythingService: BaseService, @unchecked Sendable { retryConfig: Metadata.retryConfig(for: "GetEverythingOverdueTodos") ) } + + public func everythingUnassignedCards(options: EverythingUnassignedCardsEverythingOptions? = nil) async throws -> ListResult { + return try await requestPaginated( + OperationInfo(service: "Everything", operation: "GetEverythingUnassignedCards", resourceType: "everything_unassigned_card", isMutation: false), + path: "/cards/unassigned.json", + paginationOpts: options.flatMap { PaginationOptions(maxItems: $0.maxItems) }, + retryConfig: Metadata.retryConfig(for: "GetEverythingUnassignedCards") + ) + } + + public func everythingUnassignedTodos(options: EverythingUnassignedTodosEverythingOptions? = nil) async throws -> ListResult { + return try await requestPaginated( + OperationInfo(service: "Everything", operation: "GetEverythingUnassignedTodos", resourceType: "everything_unassigned_todo", isMutation: false), + path: "/todos/unassigned.json", + paginationOpts: options.flatMap { PaginationOptions(maxItems: $0.maxItems) }, + retryConfig: Metadata.retryConfig(for: "GetEverythingUnassignedTodos") + ) + } } diff --git a/typescript/src/generated/metadata.ts b/typescript/src/generated/metadata.ts index 2972bb17..59cc777f 100644 --- a/typescript/src/generated/metadata.ts +++ b/typescript/src/generated/metadata.ts @@ -37,7 +37,7 @@ export interface MetadataOutput { const metadata: MetadataOutput = { "$schema": "https://basecamp.com/schemas/sdk-metadata.json", "version": "1.0.0", - "generated": "2026-07-25T05:55:01.941Z", + "generated": "2026-07-25T06:05:00.286Z", "operations": { "GetAccount": { "retry": { @@ -431,6 +431,70 @@ const metadata: MetadataOutput = { ] } }, + "GetEverythingCompletedCards": { + "retry": { + "maxAttempts": 3, + "baseDelayMs": 1000, + "backoff": "exponential", + "retryOn": [ + 429, + 503 + ] + }, + "pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + } + }, + "GetEverythingNoDueDateCards": { + "retry": { + "maxAttempts": 3, + "baseDelayMs": 1000, + "backoff": "exponential", + "retryOn": [ + 429, + 503 + ] + }, + "pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + } + }, + "GetEverythingNotNowCards": { + "retry": { + "maxAttempts": 3, + "baseDelayMs": 1000, + "backoff": "exponential", + "retryOn": [ + 429, + 503 + ] + }, + "pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + } + }, + "GetEverythingOpenCards": { + "retry": { + "maxAttempts": 3, + "baseDelayMs": 1000, + "backoff": "exponential", + "retryOn": [ + 429, + 503 + ] + }, + "pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + } + }, "GetEverythingOverdueCards": { "retry": { "maxAttempts": 3, @@ -442,6 +506,22 @@ const metadata: MetadataOutput = { ] } }, + "GetEverythingUnassignedCards": { + "retry": { + "maxAttempts": 3, + "baseDelayMs": 1000, + "backoff": "exponential", + "retryOn": [ + 429, + 503 + ] + }, + "pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + } + }, "ListMessageTypes": { "retry": { "maxAttempts": 3, @@ -2492,6 +2572,54 @@ const metadata: MetadataOutput = { ] } }, + "GetEverythingCompletedTodos": { + "retry": { + "maxAttempts": 3, + "baseDelayMs": 1000, + "backoff": "exponential", + "retryOn": [ + 429, + 503 + ] + }, + "pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + } + }, + "GetEverythingNoDueDateTodos": { + "retry": { + "maxAttempts": 3, + "baseDelayMs": 1000, + "backoff": "exponential", + "retryOn": [ + 429, + 503 + ] + }, + "pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + } + }, + "GetEverythingOpenTodos": { + "retry": { + "maxAttempts": 3, + "baseDelayMs": 1000, + "backoff": "exponential", + "retryOn": [ + 429, + 503 + ] + }, + "pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + } + }, "GetEverythingOverdueTodos": { "retry": { "maxAttempts": 3, @@ -2503,6 +2631,22 @@ const metadata: MetadataOutput = { ] } }, + "GetEverythingUnassignedTodos": { + "retry": { + "maxAttempts": 3, + "baseDelayMs": 1000, + "backoff": "exponential", + "retryOn": [ + 429, + 503 + ] + }, + "pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + } + }, "GetTodo": { "retry": { "maxAttempts": 3, diff --git a/typescript/src/generated/openapi-stripped.json b/typescript/src/generated/openapi-stripped.json index 37df0fb6..2e92a018 100644 --- a/typescript/src/generated/openapi-stripped.json +++ b/typescript/src/generated/openapi-stripped.json @@ -2841,18 +2841,18 @@ } } }, - "/cards/overdue.json": { + "/cards/completed.json": { "get": { - "description": "Get every overdue card across all accessible projects — a complete,\noldest-due-date-first array (unpaginated). Each item embeds its `bucket`.", - "operationId": "GetEverythingOverdueCards", + "description": "Get completed cards across all accessible projects, grouped by project\n(paginated).", + "operationId": "GetEverythingCompletedCards", "parameters": [], "responses": { "200": { - "description": "GetEverythingOverdueCards 200 response", + "description": "GetEverythingCompletedCards 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetEverythingOverdueCardsResponseContent" + "$ref": "#/components/schemas/GetEverythingCompletedCardsResponseContent" } } } @@ -2877,6 +2877,16 @@ } } }, + "429": { + "description": "RateLimitError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RateLimitErrorResponseContent" + } + } + } + }, "500": { "description": "InternalServerError 500 response", "content": { @@ -2891,6 +2901,11 @@ "tags": [ "Everything" ], + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -2902,18 +2917,18 @@ } } }, - "/categories.json": { + "/cards/no_due_date.json": { "get": { - "description": "List message types in a project\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", - "operationId": "ListMessageTypes", + "description": "Get open cards with no due date across all accessible projects, grouped by\nproject (paginated).", + "operationId": "GetEverythingNoDueDateCards", "parameters": [], "responses": { "200": { - "description": "ListMessageTypes 200 response", + "description": "GetEverythingNoDueDateCards 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListMessageTypesResponseContent" + "$ref": "#/components/schemas/GetEverythingNoDueDateCardsResponseContent" } } } @@ -2960,7 +2975,7 @@ } }, "tags": [ - "Messages" + "Everything" ], "x-basecamp-pagination": { "style": "link", @@ -2976,28 +2991,20 @@ 503 ] } - }, - "post": { - "description": "Create a new message type in a project", - "operationId": "CreateMessageType", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateMessageTypeRequestContent" - } - } - }, - "required": true - }, + } + }, + "/cards/not_now.json": { + "get": { + "description": "Get cards parked in a project's \"Not now\" column across all accessible\nprojects, grouped by project (paginated).", + "operationId": "GetEverythingNotNowCards", "parameters": [], "responses": { - "201": { - "description": "CreateMessageType 201 response", + "200": { + "description": "GetEverythingNotNowCards 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateMessageTypeResponseContent" + "$ref": "#/components/schemas/GetEverythingNotNowCardsResponseContent" } } } @@ -3022,16 +3029,6 @@ } } }, - "422": { - "description": "ValidationError 422 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" - } - } - } - }, "429": { "description": "RateLimitError 429 response", "content": { @@ -3054,10 +3051,15 @@ } }, "tags": [ - "Messages" + "Everything" ], + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + }, "x-basecamp-retry": { - "maxAttempts": 2, + "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -3067,24 +3069,21 @@ } } }, - "/categories/{typeId}": { - "delete": { - "description": "Delete a message type", - "operationId": "DeleteMessageType", - "parameters": [ - { - "name": "typeId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true - } - ], + "/cards/open.json": { + "get": { + "description": "Get incomplete cards in active columns across all accessible projects,\ngrouped by project (paginated). Each bucket entry carries the matching cards\nand their steps.", + "operationId": "GetEverythingOpenCards", + "parameters": [], "responses": { - "204": { - "description": "DeleteMessageType 204 response" + "200": { + "description": "GetEverythingOpenCards 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetEverythingOpenCardsResponseContent" + } + } + } }, "401": { "description": "UnauthorizedError 401 response", @@ -3106,12 +3105,12 @@ } } }, - "404": { - "description": "NotFoundError 404 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -3128,10 +3127,12 @@ } }, "tags": [ - "Messages" + "Everything" ], - "x-basecamp-idempotent": { - "natural": true + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 }, "x-basecamp-retry": { "maxAttempts": 3, @@ -3142,28 +3143,20 @@ 503 ] } - }, + } + }, + "/cards/overdue.json": { "get": { - "description": "Get a single message type by id", - "operationId": "GetMessageType", - "parameters": [ - { - "name": "typeId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true - } - ], + "description": "Get every overdue card across all accessible projects — a complete,\noldest-due-date-first array (unpaginated). Each item embeds its `bucket`.", + "operationId": "GetEverythingOverdueCards", + "parameters": [], "responses": { "200": { - "description": "GetMessageType 200 response", + "description": "GetEverythingOverdueCards 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetMessageTypeResponseContent" + "$ref": "#/components/schemas/GetEverythingOverdueCardsResponseContent" } } } @@ -3188,16 +3181,6 @@ } } }, - "404": { - "description": "NotFoundError 404 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" - } - } - } - }, "500": { "description": "InternalServerError 500 response", "content": { @@ -3210,7 +3193,7 @@ } }, "tags": [ - "Messages" + "Everything" ], "x-basecamp-retry": { "maxAttempts": 3, @@ -3221,37 +3204,20 @@ 503 ] } - }, - "put": { - "description": "Update an existing message type", - "operationId": "UpdateMessageType", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateMessageTypeRequestContent" - } - } - } - }, - "parameters": [ - { - "name": "typeId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true - } - ], + } + }, + "/cards/unassigned.json": { + "get": { + "description": "Get open, unassigned cards across all accessible projects, grouped by\nproject (paginated).", + "operationId": "GetEverythingUnassignedCards", + "parameters": [], "responses": { "200": { - "description": "UpdateMessageType 200 response", + "description": "GetEverythingUnassignedCards 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateMessageTypeResponseContent" + "$ref": "#/components/schemas/GetEverythingUnassignedCardsResponseContent" } } } @@ -3276,22 +3242,12 @@ } } }, - "404": { - "description": "NotFoundError 404 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" - } - } - } - }, - "422": { - "description": "ValidationError 422 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -3308,10 +3264,12 @@ } }, "tags": [ - "Messages" + "Everything" ], - "x-basecamp-idempotent": { - "natural": true + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 }, "x-basecamp-retry": { "maxAttempts": 3, @@ -3324,18 +3282,18 @@ } } }, - "/chats.json": { + "/categories.json": { "get": { - "description": "List all campfires across the account\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", - "operationId": "ListCampfires", + "description": "List message types in a project\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", + "operationId": "ListMessageTypes", "parameters": [], "responses": { "200": { - "description": "ListCampfires 200 response", + "description": "ListMessageTypes 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListCampfiresResponseContent" + "$ref": "#/components/schemas/ListMessageTypesResponseContent" } } } @@ -3382,7 +3340,7 @@ } }, "tags": [ - "Campfire" + "Messages" ], "x-basecamp-pagination": { "style": "link", @@ -3398,30 +3356,28 @@ 503 ] } - } - }, - "/chats/{campfireId}": { - "get": { - "description": "Get a campfire by ID", - "operationId": "GetCampfire", - "parameters": [ - { - "name": "campfireId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true - } - ], + }, + "post": { + "description": "Create a new message type in a project", + "operationId": "CreateMessageType", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateMessageTypeRequestContent" + } + } + }, + "required": true + }, + "parameters": [], "responses": { - "200": { - "description": "GetCampfire 200 response", + "201": { + "description": "CreateMessageType 201 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetCampfireResponseContent" + "$ref": "#/components/schemas/CreateMessageTypeResponseContent" } } } @@ -3446,19 +3402,29 @@ } } }, - "404": { - "description": "NotFoundError 404 response", + "422": { + "description": "ValidationError 422 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/ValidationErrorResponseContent" } } } }, - "500": { - "description": "InternalServerError 500 response", - "content": { + "429": { + "description": "RateLimitError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RateLimitErrorResponseContent" + } + } + } + }, + "500": { + "description": "InternalServerError 500 response", + "content": { "application/json": { "schema": { "$ref": "#/components/schemas/InternalServerErrorResponseContent" @@ -3468,10 +3434,10 @@ } }, "tags": [ - "Campfire" + "Messages" ], "x-basecamp-retry": { - "maxAttempts": 3, + "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -3481,13 +3447,13 @@ } } }, - "/chats/{campfireId}/integrations.json": { - "get": { - "description": "List all chatbots for a campfire\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", - "operationId": "ListChatbots", + "/categories/{typeId}": { + "delete": { + "description": "Delete a message type", + "operationId": "DeleteMessageType", "parameters": [ { - "name": "campfireId", + "name": "typeId", "in": "path", "schema": { "type": "integer", @@ -3497,15 +3463,8 @@ } ], "responses": { - "200": { - "description": "ListChatbots 200 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ListChatbotsResponseContent" - } - } - } + "204": { + "description": "DeleteMessageType 204 response" }, "401": { "description": "UnauthorizedError 401 response", @@ -3527,12 +3486,12 @@ } } }, - "429": { - "description": "RateLimitError 429 response", + "404": { + "description": "NotFoundError 404 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" } } } @@ -3549,12 +3508,10 @@ } }, "tags": [ - "Campfire" + "Messages" ], - "x-basecamp-pagination": { - "style": "link", - "totalCountHeader": "X-Total-Count", - "maxPageSize": 50 + "x-basecamp-idempotent": { + "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, @@ -3566,22 +3523,12 @@ ] } }, - "post": { - "description": "Create a new chatbot for a campfire", - "operationId": "CreateChatbot", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateChatbotRequestContent" - } - } - }, - "required": true - }, + "get": { + "description": "Get a single message type by id", + "operationId": "GetMessageType", "parameters": [ { - "name": "campfireId", + "name": "typeId", "in": "path", "schema": { "type": "integer", @@ -3591,12 +3538,12 @@ } ], "responses": { - "201": { - "description": "CreateChatbot 201 response", + "200": { + "description": "GetMessageType 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateChatbotResponseContent" + "$ref": "#/components/schemas/GetMessageTypeResponseContent" } } } @@ -3621,22 +3568,12 @@ } } }, - "422": { - "description": "ValidationError 422 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" - } - } - } - }, - "429": { - "description": "RateLimitError 429 response", + "404": { + "description": "NotFoundError 404 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" } } } @@ -3653,10 +3590,10 @@ } }, "tags": [ - "Campfire" + "Messages" ], "x-basecamp-retry": { - "maxAttempts": 2, + "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -3664,24 +3601,22 @@ 503 ] } - } - }, - "/chats/{campfireId}/integrations/{chatbotId}": { - "delete": { - "description": "Delete a chatbot", - "operationId": "DeleteChatbot", + }, + "put": { + "description": "Update an existing message type", + "operationId": "UpdateMessageType", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateMessageTypeRequestContent" + } + } + } + }, "parameters": [ { - "name": "campfireId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true - }, - { - "name": "chatbotId", + "name": "typeId", "in": "path", "schema": { "type": "integer", @@ -3691,8 +3626,15 @@ } ], "responses": { - "204": { - "description": "DeleteChatbot 204 response" + "200": { + "description": "UpdateMessageType 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateMessageTypeResponseContent" + } + } + } }, "401": { "description": "UnauthorizedError 401 response", @@ -3724,6 +3666,16 @@ } } }, + "422": { + "description": "ValidationError 422 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponseContent" + } + } + } + }, "500": { "description": "InternalServerError 500 response", "content": { @@ -3736,7 +3688,7 @@ } }, "tags": [ - "Campfire" + "Messages" ], "x-basecamp-idempotent": { "natural": true @@ -3750,37 +3702,20 @@ 503 ] } - }, + } + }, + "/chats.json": { "get": { - "description": "Get a chatbot by ID", - "operationId": "GetChatbot", - "parameters": [ - { - "name": "campfireId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true - }, - { - "name": "chatbotId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true - } - ], + "description": "List all campfires across the account\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", + "operationId": "ListCampfires", + "parameters": [], "responses": { "200": { - "description": "GetChatbot 200 response", + "description": "ListCampfires 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetChatbotResponseContent" + "$ref": "#/components/schemas/ListCampfiresResponseContent" } } } @@ -3805,12 +3740,12 @@ } } }, - "404": { - "description": "NotFoundError 404 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -3829,6 +3764,11 @@ "tags": [ "Campfire" ], + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -3838,20 +3778,12 @@ 503 ] } - }, - "put": { - "description": "Update an existing chatbot", - "operationId": "UpdateChatbot", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateChatbotRequestContent" - } - } - }, - "required": true - }, + } + }, + "/chats/{campfireId}": { + "get": { + "description": "Get a campfire by ID", + "operationId": "GetCampfire", "parameters": [ { "name": "campfireId", @@ -3861,24 +3793,15 @@ "format": "int64" }, "required": true - }, - { - "name": "chatbotId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true } ], "responses": { "200": { - "description": "UpdateChatbot 200 response", + "description": "GetCampfire 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateChatbotResponseContent" + "$ref": "#/components/schemas/GetCampfireResponseContent" } } } @@ -3913,16 +3836,6 @@ } } }, - "422": { - "description": "ValidationError 422 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" - } - } - } - }, "500": { "description": "InternalServerError 500 response", "content": { @@ -3937,9 +3850,6 @@ "tags": [ "Campfire" ], - "x-basecamp-idempotent": { - "natural": true - }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -3951,10 +3861,10 @@ } } }, - "/chats/{campfireId}/lines.json": { + "/chats/{campfireId}/integrations.json": { "get": { - "description": "List all lines (messages) in a campfire\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", - "operationId": "ListCampfireLines", + "description": "List all chatbots for a campfire\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", + "operationId": "ListChatbots", "parameters": [ { "name": "campfireId", @@ -3964,33 +3874,15 @@ "format": "int64" }, "required": true - }, - { - "name": "sort", - "in": "query", - "description": "created_at|updated_at", - "schema": { - "type": "string", - "description": "created_at|updated_at" - } - }, - { - "name": "direction", - "in": "query", - "description": "asc|desc", - "schema": { - "type": "string", - "description": "asc|desc" - } } ], "responses": { "200": { - "description": "ListCampfireLines 200 response", + "description": "ListChatbots 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListCampfireLinesResponseContent" + "$ref": "#/components/schemas/ListChatbotsResponseContent" } } } @@ -4055,13 +3947,13 @@ } }, "post": { - "description": "Create a new line (message) in a campfire", - "operationId": "CreateCampfireLine", + "description": "Create a new chatbot for a campfire", + "operationId": "CreateChatbot", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateCampfireLineRequestContent" + "$ref": "#/components/schemas/CreateChatbotRequestContent" } } }, @@ -4080,11 +3972,11 @@ ], "responses": { "201": { - "description": "CreateCampfireLine 201 response", + "description": "CreateChatbot 201 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateCampfireLineResponseContent" + "$ref": "#/components/schemas/CreateChatbotResponseContent" } } } @@ -4154,10 +4046,10 @@ } } }, - "/chats/{campfireId}/lines/{lineId}": { + "/chats/{campfireId}/integrations/{chatbotId}": { "delete": { - "description": "Delete a campfire line; allowed for the line's creator or an admin.\nThe API responds 403 Forbidden otherwise.", - "operationId": "DeleteCampfireLine", + "description": "Delete a chatbot", + "operationId": "DeleteChatbot", "parameters": [ { "name": "campfireId", @@ -4169,7 +4061,7 @@ "required": true }, { - "name": "lineId", + "name": "chatbotId", "in": "path", "schema": { "type": "integer", @@ -4180,7 +4072,7 @@ ], "responses": { "204": { - "description": "DeleteCampfireLine 204 response" + "description": "DeleteChatbot 204 response" }, "401": { "description": "UnauthorizedError 401 response", @@ -4240,8 +4132,8 @@ } }, "get": { - "description": "Get a campfire line by ID", - "operationId": "GetCampfireLine", + "description": "Get a chatbot by ID", + "operationId": "GetChatbot", "parameters": [ { "name": "campfireId", @@ -4253,7 +4145,7 @@ "required": true }, { - "name": "lineId", + "name": "chatbotId", "in": "path", "schema": { "type": "integer", @@ -4264,11 +4156,11 @@ ], "responses": { "200": { - "description": "GetCampfireLine 200 response", + "description": "GetChatbot 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetCampfireLineResponseContent" + "$ref": "#/components/schemas/GetChatbotResponseContent" } } } @@ -4328,13 +4220,13 @@ } }, "put": { - "description": "Update an existing campfire line; the content is always treated as rich text (HTML).\nThe server coerces every edited line to rich text and ignores any content\ntype hint. Only the line's creator may edit it, and only text and\nrich-text lines are editable.", - "operationId": "UpdateCampfireLine", + "description": "Update an existing chatbot", + "operationId": "UpdateChatbot", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateCampfireLineRequestContent" + "$ref": "#/components/schemas/UpdateChatbotRequestContent" } } }, @@ -4351,7 +4243,7 @@ "required": true }, { - "name": "lineId", + "name": "chatbotId", "in": "path", "schema": { "type": "integer", @@ -4361,8 +4253,15 @@ } ], "responses": { - "204": { - "description": "UpdateCampfireLine 204 response" + "200": { + "description": "UpdateChatbot 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateChatbotResponseContent" + } + } + } }, "401": { "description": "UnauthorizedError 401 response", @@ -4404,16 +4303,6 @@ } } }, - "429": { - "description": "RateLimitError 429 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" - } - } - } - }, "500": { "description": "InternalServerError 500 response", "content": { @@ -4442,10 +4331,10 @@ } } }, - "/chats/{campfireId}/uploads.json": { + "/chats/{campfireId}/lines.json": { "get": { - "description": "List uploaded files in a campfire\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", - "operationId": "ListCampfireUploads", + "description": "List all lines (messages) in a campfire\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", + "operationId": "ListCampfireLines", "parameters": [ { "name": "campfireId", @@ -4477,11 +4366,11 @@ ], "responses": { "200": { - "description": "ListCampfireUploads 200 response", + "description": "ListCampfireLines 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListCampfireUploadsResponseContent" + "$ref": "#/components/schemas/ListCampfireLinesResponseContent" } } } @@ -4546,13 +4435,13 @@ } }, "post": { - "description": "Upload a file to a campfire", - "operationId": "CreateCampfireUpload", + "description": "Create a new line (message) in a campfire", + "operationId": "CreateCampfireLine", "requestBody": { "content": { - "application/octet-stream": { + "application/json": { "schema": { - "$ref": "#/components/schemas/CreateCampfireUploadInputPayload" + "$ref": "#/components/schemas/CreateCampfireLineRequestContent" } } }, @@ -4567,25 +4456,15 @@ "format": "int64" }, "required": true - }, - { - "name": "name", - "in": "query", - "description": "Filename for the uploaded file (e.g. \"report.pdf\").", - "schema": { - "type": "string", - "description": "Filename for the uploaded file (e.g. \"report.pdf\")." - }, - "required": true } ], "responses": { "201": { - "description": "CreateCampfireUpload 201 response", + "description": "CreateCampfireLine 201 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateCampfireUploadResponseContent" + "$ref": "#/components/schemas/CreateCampfireLineResponseContent" } } } @@ -4645,8 +4524,8 @@ "Campfire" ], "x-basecamp-retry": { - "maxAttempts": 3, - "baseDelayMs": 2000, + "maxAttempts": 2, + "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, @@ -4655,21 +4534,33 @@ } } }, - "/checkins.json": { - "get": { - "description": "Get every automatic check-in answer across all accessible projects,\nnewest-first (paginated). Each item embeds its `bucket`.", - "operationId": "GetEverythingCheckins", - "parameters": [], + "/chats/{campfireId}/lines/{lineId}": { + "delete": { + "description": "Delete a campfire line; allowed for the line's creator or an admin.\nThe API responds 403 Forbidden otherwise.", + "operationId": "DeleteCampfireLine", + "parameters": [ + { + "name": "campfireId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true + }, + { + "name": "lineId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true + } + ], "responses": { - "200": { - "description": "GetEverythingCheckins 200 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/GetEverythingCheckinsResponseContent" - } - } - } + "204": { + "description": "DeleteCampfireLine 204 response" }, "401": { "description": "UnauthorizedError 401 response", @@ -4691,12 +4582,12 @@ } } }, - "429": { - "description": "RateLimitError 429 response", + "404": { + "description": "NotFoundError 404 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" } } } @@ -4713,12 +4604,10 @@ } }, "tags": [ - "Everything" + "Campfire" ], - "x-basecamp-pagination": { - "style": "link", - "totalCountHeader": "X-Total-Count", - "maxPageSize": 50 + "x-basecamp-idempotent": { + "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, @@ -4729,20 +4618,37 @@ 503 ] } - } - }, - "/circles/people.json": { + }, "get": { - "description": "List all account users who can be pinged\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", - "operationId": "ListPingablePeople", - "parameters": [], + "description": "Get a campfire line by ID", + "operationId": "GetCampfireLine", + "parameters": [ + { + "name": "campfireId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true + }, + { + "name": "lineId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true + } + ], "responses": { "200": { - "description": "ListPingablePeople 200 response", + "description": "GetCampfireLine 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListPingablePeopleResponseContent" + "$ref": "#/components/schemas/GetCampfireLineResponseContent" } } } @@ -4767,12 +4673,12 @@ } } }, - "429": { - "description": "RateLimitError 429 response", + "404": { + "description": "NotFoundError 404 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" } } } @@ -4789,13 +4695,8 @@ } }, "tags": [ - "People" + "Campfire" ], - "x-basecamp-pagination": { - "style": "link", - "totalCountHeader": "X-Total-Count", - "maxPageSize": 50 - }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -4805,42 +4706,43 @@ 503 ] } - } - }, - "/client/approvals.json": { - "get": { - "description": "List all client approvals in a project\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", - "operationId": "ListClientApprovals", + }, + "put": { + "description": "Update an existing campfire line; the content is always treated as rich text (HTML).\nThe server coerces every edited line to rich text and ignores any content\ntype hint. Only the line's creator may edit it, and only text and\nrich-text lines are editable.", + "operationId": "UpdateCampfireLine", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateCampfireLineRequestContent" + } + } + }, + "required": true + }, "parameters": [ { - "name": "sort", - "in": "query", - "description": "created_at|updated_at", + "name": "campfireId", + "in": "path", "schema": { - "type": "string", - "description": "created_at|updated_at" - } + "type": "integer", + "format": "int64" + }, + "required": true }, { - "name": "direction", - "in": "query", - "description": "asc|desc", + "name": "lineId", + "in": "path", "schema": { - "type": "string", - "description": "asc|desc" - } + "type": "integer", + "format": "int64" + }, + "required": true } ], "responses": { - "200": { - "description": "ListClientApprovals 200 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ListClientApprovalsResponseContent" - } - } - } + "204": { + "description": "UpdateCampfireLine 204 response" }, "401": { "description": "UnauthorizedError 401 response", @@ -4862,6 +4764,26 @@ } } }, + "404": { + "description": "NotFoundError 404 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotFoundErrorResponseContent" + } + } + } + }, + "422": { + "description": "ValidationError 422 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponseContent" + } + } + } + }, "429": { "description": "RateLimitError 429 response", "content": { @@ -4884,12 +4806,10 @@ } }, "tags": [ - "ClientFeatures" + "Campfire" ], - "x-basecamp-pagination": { - "style": "link", - "totalCountHeader": "X-Total-Count", - "maxPageSize": 50 + "x-basecamp-idempotent": { + "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, @@ -4902,28 +4822,46 @@ } } }, - "/client/approvals/{approvalId}": { + "/chats/{campfireId}/uploads.json": { "get": { - "description": "Get a single client approval by id", - "operationId": "GetClientApproval", + "description": "List uploaded files in a campfire\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", + "operationId": "ListCampfireUploads", "parameters": [ { - "name": "approvalId", + "name": "campfireId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true + }, + { + "name": "sort", + "in": "query", + "description": "created_at|updated_at", + "schema": { + "type": "string", + "description": "created_at|updated_at" + } + }, + { + "name": "direction", + "in": "query", + "description": "asc|desc", + "schema": { + "type": "string", + "description": "asc|desc" + } } ], "responses": { "200": { - "description": "GetClientApproval 200 response", + "description": "ListCampfireUploads 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetClientApprovalResponseContent" + "$ref": "#/components/schemas/ListCampfireUploadsResponseContent" } } } @@ -4948,12 +4886,12 @@ } } }, - "404": { - "description": "NotFoundError 404 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -4970,8 +4908,13 @@ } }, "tags": [ - "ClientFeatures" + "Campfire" ], + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -4981,39 +4924,48 @@ 503 ] } - } - }, - "/client/correspondences.json": { - "get": { - "description": "List all client correspondences in a project\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", - "operationId": "ListClientCorrespondences", + }, + "post": { + "description": "Upload a file to a campfire", + "operationId": "CreateCampfireUpload", + "requestBody": { + "content": { + "application/octet-stream": { + "schema": { + "$ref": "#/components/schemas/CreateCampfireUploadInputPayload" + } + } + }, + "required": true + }, "parameters": [ { - "name": "sort", - "in": "query", - "description": "created_at|updated_at", + "name": "campfireId", + "in": "path", "schema": { - "type": "string", - "description": "created_at|updated_at" - } + "type": "integer", + "format": "int64" + }, + "required": true }, { - "name": "direction", + "name": "name", "in": "query", - "description": "asc|desc", + "description": "Filename for the uploaded file (e.g. \"report.pdf\").", "schema": { "type": "string", - "description": "asc|desc" - } + "description": "Filename for the uploaded file (e.g. \"report.pdf\")." + }, + "required": true } ], "responses": { - "200": { - "description": "ListClientCorrespondences 200 response", + "201": { + "description": "CreateCampfireUpload 201 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListClientCorrespondencesResponseContent" + "$ref": "#/components/schemas/CreateCampfireUploadResponseContent" } } } @@ -5038,6 +4990,16 @@ } } }, + "422": { + "description": "ValidationError 422 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponseContent" + } + } + } + }, "429": { "description": "RateLimitError 429 response", "content": { @@ -5060,16 +5022,11 @@ } }, "tags": [ - "ClientFeatures" + "Campfire" ], - "x-basecamp-pagination": { - "style": "link", - "totalCountHeader": "X-Total-Count", - "maxPageSize": 50 - }, "x-basecamp-retry": { "maxAttempts": 3, - "baseDelayMs": 1000, + "baseDelayMs": 2000, "backoff": "exponential", "retryOn": [ 429, @@ -5078,28 +5035,18 @@ } } }, - "/client/correspondences/{correspondenceId}": { + "/checkins.json": { "get": { - "description": "Get a single client correspondence by id", - "operationId": "GetClientCorrespondence", - "parameters": [ - { - "name": "correspondenceId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true - } - ], + "description": "Get every automatic check-in answer across all accessible projects,\nnewest-first (paginated). Each item embeds its `bucket`.", + "operationId": "GetEverythingCheckins", + "parameters": [], "responses": { "200": { - "description": "GetClientCorrespondence 200 response", + "description": "GetEverythingCheckins 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetClientCorrespondenceResponseContent" + "$ref": "#/components/schemas/GetEverythingCheckinsResponseContent" } } } @@ -5124,12 +5071,12 @@ } } }, - "404": { - "description": "NotFoundError 404 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -5146,8 +5093,13 @@ } }, "tags": [ - "ClientFeatures" + "Everything" ], + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -5159,28 +5111,18 @@ } } }, - "/client/recordings/{recordingId}/replies.json": { + "/circles/people.json": { "get": { - "description": "List all client replies for a recording (correspondence or approval)\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", - "operationId": "ListClientReplies", - "parameters": [ - { - "name": "recordingId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true - } - ], + "description": "List all account users who can be pinged\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", + "operationId": "ListPingablePeople", + "parameters": [], "responses": { "200": { - "description": "ListClientReplies 200 response", + "description": "ListPingablePeople 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListClientRepliesResponseContent" + "$ref": "#/components/schemas/ListPingablePeopleResponseContent" } } } @@ -5227,7 +5169,7 @@ } }, "tags": [ - "ClientFeatures" + "People" ], "x-basecamp-pagination": { "style": "link", @@ -5245,37 +5187,37 @@ } } }, - "/client/recordings/{recordingId}/replies/{replyId}": { + "/client/approvals.json": { "get": { - "description": "Get a single client reply by id", - "operationId": "GetClientReply", + "description": "List all client approvals in a project\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", + "operationId": "ListClientApprovals", "parameters": [ { - "name": "recordingId", - "in": "path", + "name": "sort", + "in": "query", + "description": "created_at|updated_at", "schema": { - "type": "integer", - "format": "int64" - }, - "required": true + "type": "string", + "description": "created_at|updated_at" + } }, { - "name": "replyId", - "in": "path", + "name": "direction", + "in": "query", + "description": "asc|desc", "schema": { - "type": "integer", - "format": "int64" - }, - "required": true + "type": "string", + "description": "asc|desc" + } } ], "responses": { "200": { - "description": "GetClientReply 200 response", + "description": "ListClientApprovals 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetClientReplyResponseContent" + "$ref": "#/components/schemas/ListClientApprovalsResponseContent" } } } @@ -5300,12 +5242,12 @@ } } }, - "404": { - "description": "NotFoundError 404 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -5324,6 +5266,11 @@ "tags": [ "ClientFeatures" ], + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -5335,18 +5282,28 @@ } } }, - "/comments.json": { + "/client/approvals/{approvalId}": { "get": { - "description": "Get every comment across all accessible projects, newest-first (paginated).\nEach item embeds its `bucket`.", - "operationId": "GetEverythingComments", - "parameters": [], - "responses": { - "200": { - "description": "GetEverythingComments 200 response", - "content": { - "application/json": { + "description": "Get a single client approval by id", + "operationId": "GetClientApproval", + "parameters": [ + { + "name": "approvalId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true + } + ], + "responses": { + "200": { + "description": "GetClientApproval 200 response", + "content": { + "application/json": { "schema": { - "$ref": "#/components/schemas/GetEverythingCommentsResponseContent" + "$ref": "#/components/schemas/GetClientApprovalResponseContent" } } } @@ -5371,12 +5328,12 @@ } } }, - "429": { - "description": "RateLimitError 429 response", + "404": { + "description": "NotFoundError 404 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" } } } @@ -5393,13 +5350,8 @@ } }, "tags": [ - "Everything" + "ClientFeatures" ], - "x-basecamp-pagination": { - "style": "link", - "totalCountHeader": "X-Total-Count", - "maxPageSize": 50 - }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -5411,28 +5363,37 @@ } } }, - "/comments/{commentId}": { + "/client/correspondences.json": { "get": { - "description": "Get a single comment by id", - "operationId": "GetComment", + "description": "List all client correspondences in a project\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", + "operationId": "ListClientCorrespondences", "parameters": [ { - "name": "commentId", - "in": "path", + "name": "sort", + "in": "query", + "description": "created_at|updated_at", "schema": { - "type": "integer", - "format": "int64" - }, - "required": true + "type": "string", + "description": "created_at|updated_at" + } + }, + { + "name": "direction", + "in": "query", + "description": "asc|desc", + "schema": { + "type": "string", + "description": "asc|desc" + } } ], "responses": { "200": { - "description": "GetComment 200 response", + "description": "ListClientCorrespondences 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetCommentResponseContent" + "$ref": "#/components/schemas/ListClientCorrespondencesResponseContent" } } } @@ -5457,12 +5418,12 @@ } } }, - "404": { - "description": "NotFoundError 404 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -5479,8 +5440,13 @@ } }, "tags": [ - "Messages" + "ClientFeatures" ], + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -5490,23 +5456,15 @@ 503 ] } - }, - "put": { - "description": "Update an existing comment", - "operationId": "UpdateComment", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateCommentRequestContent" - } - } - }, - "required": true - }, + } + }, + "/client/correspondences/{correspondenceId}": { + "get": { + "description": "Get a single client correspondence by id", + "operationId": "GetClientCorrespondence", "parameters": [ { - "name": "commentId", + "name": "correspondenceId", "in": "path", "schema": { "type": "integer", @@ -5517,11 +5475,11 @@ ], "responses": { "200": { - "description": "UpdateComment 200 response", + "description": "GetClientCorrespondence 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateCommentResponseContent" + "$ref": "#/components/schemas/GetClientCorrespondenceResponseContent" } } } @@ -5556,16 +5514,6 @@ } } }, - "422": { - "description": "ValidationError 422 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" - } - } - } - }, "500": { "description": "InternalServerError 500 response", "content": { @@ -5578,11 +5526,8 @@ } }, "tags": [ - "Messages" + "ClientFeatures" ], - "x-basecamp-idempotent": { - "natural": true - }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -5594,13 +5539,13 @@ } } }, - "/dock/tools/{toolId}": { - "delete": { - "description": "Delete a tool (trash it)", - "operationId": "DeleteTool", + "/client/recordings/{recordingId}/replies.json": { + "get": { + "description": "List all client replies for a recording (correspondence or approval)\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", + "operationId": "ListClientReplies", "parameters": [ { - "name": "toolId", + "name": "recordingId", "in": "path", "schema": { "type": "integer", @@ -5610,8 +5555,15 @@ } ], "responses": { - "204": { - "description": "DeleteTool 204 response" + "200": { + "description": "ListClientReplies 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListClientRepliesResponseContent" + } + } + } }, "401": { "description": "UnauthorizedError 401 response", @@ -5633,12 +5585,12 @@ } } }, - "404": { - "description": "NotFoundError 404 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -5655,10 +5607,12 @@ } }, "tags": [ - "Automation" + "ClientFeatures" ], - "x-basecamp-idempotent": { - "natural": true + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 }, "x-basecamp-retry": { "maxAttempts": 3, @@ -5669,13 +5623,24 @@ 503 ] } - }, + } + }, + "/client/recordings/{recordingId}/replies/{replyId}": { "get": { - "description": "Get a dock tool by id", - "operationId": "GetTool", + "description": "Get a single client reply by id", + "operationId": "GetClientReply", "parameters": [ { - "name": "toolId", + "name": "recordingId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true + }, + { + "name": "replyId", "in": "path", "schema": { "type": "integer", @@ -5686,11 +5651,11 @@ ], "responses": { "200": { - "description": "GetTool 200 response", + "description": "GetClientReply 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetToolResponseContent" + "$ref": "#/components/schemas/GetClientReplyResponseContent" } } } @@ -5737,7 +5702,7 @@ } }, "tags": [ - "Automation" + "ClientFeatures" ], "x-basecamp-retry": { "maxAttempts": 3, @@ -5748,38 +5713,20 @@ 503 ] } - }, - "put": { - "description": "Update (rename) an existing tool", - "operationId": "UpdateTool", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateToolRequestContent" - } - } - }, - "required": true - }, - "parameters": [ - { - "name": "toolId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true - } - ], + } + }, + "/comments.json": { + "get": { + "description": "Get every comment across all accessible projects, newest-first (paginated).\nEach item embeds its `bucket`.", + "operationId": "GetEverythingComments", + "parameters": [], "responses": { "200": { - "description": "UpdateTool 200 response", + "description": "GetEverythingComments 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateToolResponseContent" + "$ref": "#/components/schemas/GetEverythingCommentsResponseContent" } } } @@ -5804,22 +5751,12 @@ } } }, - "404": { - "description": "NotFoundError 404 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" - } - } - } - }, - "422": { - "description": "ValidationError 422 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -5836,10 +5773,12 @@ } }, "tags": [ - "Automation" + "Everything" ], - "x-basecamp-idempotent": { - "natural": true + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 }, "x-basecamp-retry": { "maxAttempts": 3, @@ -5852,13 +5791,13 @@ } } }, - "/documents/{documentId}": { + "/comments/{commentId}": { "get": { - "description": "Get a single document by id", - "operationId": "GetDocument", + "description": "Get a single comment by id", + "operationId": "GetComment", "parameters": [ { - "name": "documentId", + "name": "commentId", "in": "path", "schema": { "type": "integer", @@ -5869,11 +5808,11 @@ ], "responses": { "200": { - "description": "GetDocument 200 response", + "description": "GetComment 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetDocumentResponseContent" + "$ref": "#/components/schemas/GetCommentResponseContent" } } } @@ -5920,7 +5859,7 @@ } }, "tags": [ - "Files" + "Messages" ], "x-basecamp-retry": { "maxAttempts": 3, @@ -5933,20 +5872,21 @@ } }, "put": { - "description": "Update an existing document", - "operationId": "UpdateDocument", + "description": "Update an existing comment", + "operationId": "UpdateComment", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateDocumentRequestContent" + "$ref": "#/components/schemas/UpdateCommentRequestContent" } } - } + }, + "required": true }, "parameters": [ { - "name": "documentId", + "name": "commentId", "in": "path", "schema": { "type": "integer", @@ -5957,11 +5897,11 @@ ], "responses": { "200": { - "description": "UpdateDocument 200 response", + "description": "UpdateComment 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateDocumentResponseContent" + "$ref": "#/components/schemas/UpdateCommentResponseContent" } } } @@ -6018,7 +5958,7 @@ } }, "tags": [ - "Files" + "Messages" ], "x-basecamp-idempotent": { "natural": true @@ -6034,47 +5974,24 @@ } } }, - "/files.json": { - "get": { - "description": "Get every file recording across all accessible projects, newest-first\n(paginated). Heterogeneous: uploads and Basecamp documents carry their\nstandard recording shapes, while rich-text attachments are wrapped in a\nrecording envelope plus an `attachable_sgid` and blob metadata. Modeled as\nan optional-field superset (EverythingFile) so one element type decodes any\nvariant.", - "operationId": "GetEverythingFiles", + "/dock/tools/{toolId}": { + "delete": { + "description": "Delete a tool (trash it)", + "operationId": "DeleteTool", "parameters": [ { - "name": "kind", - "in": "query", - "description": "Filter by file kind: all (default), images, pdfs, documents, or videos.", - "schema": { - "type": "string", - "description": "Filter by file kind: all (default), images, pdfs, documents, or videos." - } - }, - { - "name": "people_ids[]", - "in": "query", - "description": "Restrict to files created by the given people (repeatable).", - "style": "form", + "name": "toolId", + "in": "path", "schema": { - "type": "array", - "items": { - "type": "integer", - "format": "int64" - }, - "description": "Restrict to files created by the given people (repeatable).", - "x-go-type-skip-optional-pointer": false + "type": "integer", + "format": "int64" }, - "explode": true + "required": true } ], "responses": { - "200": { - "description": "GetEverythingFiles 200 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/GetEverythingFilesResponseContent" - } - } - } + "204": { + "description": "DeleteTool 204 response" }, "401": { "description": "UnauthorizedError 401 response", @@ -6096,12 +6013,12 @@ } } }, - "429": { - "description": "RateLimitError 429 response", + "404": { + "description": "NotFoundError 404 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" } } } @@ -6118,12 +6035,10 @@ } }, "tags": [ - "Everything" + "Automation" ], - "x-basecamp-pagination": { - "style": "link", - "totalCountHeader": "X-Total-Count", - "maxPageSize": 50 + "x-basecamp-idempotent": { + "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, @@ -6134,20 +6049,28 @@ 503 ] } - } - }, - "/forwards.json": { + }, "get": { - "description": "Get every inbox forward across all accessible projects, newest-first\n(paginated). Each item embeds its `bucket`.", - "operationId": "GetEverythingForwards", - "parameters": [], + "description": "Get a dock tool by id", + "operationId": "GetTool", + "parameters": [ + { + "name": "toolId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true + } + ], "responses": { "200": { - "description": "GetEverythingForwards 200 response", + "description": "GetTool 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetEverythingForwardsResponseContent" + "$ref": "#/components/schemas/GetToolResponseContent" } } } @@ -6172,12 +6095,12 @@ } } }, - "429": { - "description": "RateLimitError 429 response", + "404": { + "description": "NotFoundError 404 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" } } } @@ -6194,13 +6117,8 @@ } }, "tags": [ - "Everything" + "Automation" ], - "x-basecamp-pagination": { - "style": "link", - "totalCountHeader": "X-Total-Count", - "maxPageSize": 50 - }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -6210,15 +6128,23 @@ 503 ] } - } - }, - "/gauge_needles/{needleId}": { - "delete": { - "description": "Destroy a gauge needle", - "operationId": "DestroyGaugeNeedle", + }, + "put": { + "description": "Update (rename) an existing tool", + "operationId": "UpdateTool", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateToolRequestContent" + } + } + }, + "required": true + }, "parameters": [ { - "name": "needleId", + "name": "toolId", "in": "path", "schema": { "type": "integer", @@ -6228,8 +6154,15 @@ } ], "responses": { - "204": { - "description": "DestroyGaugeNeedle 204 response" + "200": { + "description": "UpdateTool 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateToolResponseContent" + } + } + } }, "401": { "description": "UnauthorizedError 401 response", @@ -6261,12 +6194,12 @@ } } }, - "429": { - "description": "RateLimitError 429 response", + "422": { + "description": "ValidationError 422 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" + "$ref": "#/components/schemas/ValidationErrorResponseContent" } } } @@ -6283,13 +6216,13 @@ } }, "tags": [ - "Gauges" + "Automation" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { - "maxAttempts": 2, + "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -6297,13 +6230,15 @@ 503 ] } - }, + } + }, + "/documents/{documentId}": { "get": { - "description": "Get a gauge needle by ID", - "operationId": "GetGaugeNeedle", + "description": "Get a single document by id", + "operationId": "GetDocument", "parameters": [ { - "name": "needleId", + "name": "documentId", "in": "path", "schema": { "type": "integer", @@ -6314,11 +6249,11 @@ ], "responses": { "200": { - "description": "GetGaugeNeedle 200 response", + "description": "GetDocument 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetGaugeNeedleResponseContent" + "$ref": "#/components/schemas/GetDocumentResponseContent" } } } @@ -6365,7 +6300,7 @@ } }, "tags": [ - "Gauges" + "Files" ], "x-basecamp-retry": { "maxAttempts": 3, @@ -6378,20 +6313,20 @@ } }, "put": { - "description": "Update a gauge needle's description. Position and color are immutable.", - "operationId": "UpdateGaugeNeedle", + "description": "Update an existing document", + "operationId": "UpdateDocument", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateGaugeNeedleRequestContent" + "$ref": "#/components/schemas/UpdateDocumentRequestContent" } } } }, "parameters": [ { - "name": "needleId", + "name": "documentId", "in": "path", "schema": { "type": "integer", @@ -6402,11 +6337,11 @@ ], "responses": { "200": { - "description": "UpdateGaugeNeedle 200 response", + "description": "UpdateDocument 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateGaugeNeedleResponseContent" + "$ref": "#/components/schemas/UpdateDocumentResponseContent" } } } @@ -6451,16 +6386,6 @@ } } }, - "429": { - "description": "RateLimitError 429 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" - } - } - } - }, "500": { "description": "InternalServerError 500 response", "content": { @@ -6473,13 +6398,13 @@ } }, "tags": [ - "Gauges" + "Files" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { - "maxAttempts": 2, + "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -6489,28 +6414,44 @@ } } }, - "/inbox_forwards/{forwardId}": { + "/files.json": { "get": { - "description": "Get a forward by ID", - "operationId": "GetForward", + "description": "Get every file recording across all accessible projects, newest-first\n(paginated). Heterogeneous: uploads and Basecamp documents carry their\nstandard recording shapes, while rich-text attachments are wrapped in a\nrecording envelope plus an `attachable_sgid` and blob metadata. Modeled as\nan optional-field superset (EverythingFile) so one element type decodes any\nvariant.", + "operationId": "GetEverythingFiles", "parameters": [ { - "name": "forwardId", - "in": "path", + "name": "kind", + "in": "query", + "description": "Filter by file kind: all (default), images, pdfs, documents, or videos.", "schema": { - "type": "integer", - "format": "int64" + "type": "string", + "description": "Filter by file kind: all (default), images, pdfs, documents, or videos." + } + }, + { + "name": "people_ids[]", + "in": "query", + "description": "Restrict to files created by the given people (repeatable).", + "style": "form", + "schema": { + "type": "array", + "items": { + "type": "integer", + "format": "int64" + }, + "description": "Restrict to files created by the given people (repeatable).", + "x-go-type-skip-optional-pointer": false }, - "required": true + "explode": true } ], "responses": { "200": { - "description": "GetForward 200 response", + "description": "GetEverythingFiles 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetForwardResponseContent" + "$ref": "#/components/schemas/GetEverythingFilesResponseContent" } } } @@ -6535,12 +6476,12 @@ } } }, - "404": { - "description": "NotFoundError 404 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -6557,8 +6498,13 @@ } }, "tags": [ - "Forwards" + "Everything" ], + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -6570,28 +6516,18 @@ } } }, - "/inbox_forwards/{forwardId}/replies.json": { + "/forwards.json": { "get": { - "description": "List all replies to a forward\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", - "operationId": "ListForwardReplies", - "parameters": [ - { - "name": "forwardId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true - } - ], + "description": "Get every inbox forward across all accessible projects, newest-first\n(paginated). Each item embeds its `bucket`.", + "operationId": "GetEverythingForwards", + "parameters": [], "responses": { "200": { - "description": "ListForwardReplies 200 response", + "description": "GetEverythingForwards 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListForwardRepliesResponseContent" + "$ref": "#/components/schemas/GetEverythingForwardsResponseContent" } } } @@ -6638,7 +6574,7 @@ } }, "tags": [ - "Forwards" + "Everything" ], "x-basecamp-pagination": { "style": "link", @@ -6654,23 +6590,15 @@ 503 ] } - }, - "post": { - "description": "Create a reply to a forward", - "operationId": "CreateForwardReply", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateForwardReplyRequestContent" - } - } - }, - "required": true - }, + } + }, + "/gauge_needles/{needleId}": { + "delete": { + "description": "Destroy a gauge needle", + "operationId": "DestroyGaugeNeedle", "parameters": [ { - "name": "forwardId", + "name": "needleId", "in": "path", "schema": { "type": "integer", @@ -6680,15 +6608,8 @@ } ], "responses": { - "201": { - "description": "CreateForwardReply 201 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateForwardReplyResponseContent" - } - } - } + "204": { + "description": "DestroyGaugeNeedle 204 response" }, "401": { "description": "UnauthorizedError 401 response", @@ -6710,12 +6631,12 @@ } } }, - "422": { - "description": "ValidationError 422 response", + "404": { + "description": "NotFoundError 404 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" } } } @@ -6742,8 +6663,11 @@ } }, "tags": [ - "Forwards" + "Gauges" ], + "x-basecamp-idempotent": { + "natural": true + }, "x-basecamp-retry": { "maxAttempts": 2, "baseDelayMs": 1000, @@ -6753,24 +6677,13 @@ 503 ] } - } - }, - "/inbox_forwards/{forwardId}/replies/{replyId}": { + }, "get": { - "description": "Get a forward reply by ID", - "operationId": "GetForwardReply", + "description": "Get a gauge needle by ID", + "operationId": "GetGaugeNeedle", "parameters": [ { - "name": "forwardId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true - }, - { - "name": "replyId", + "name": "needleId", "in": "path", "schema": { "type": "integer", @@ -6781,11 +6694,11 @@ ], "responses": { "200": { - "description": "GetForwardReply 200 response", + "description": "GetGaugeNeedle 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetForwardReplyResponseContent" + "$ref": "#/components/schemas/GetGaugeNeedleResponseContent" } } } @@ -6832,7 +6745,7 @@ } }, "tags": [ - "Forwards" + "Gauges" ], "x-basecamp-retry": { "maxAttempts": 3, @@ -6843,15 +6756,22 @@ 503 ] } - } - }, - "/inboxes/{inboxId}": { - "get": { - "description": "Get an inbox by ID", - "operationId": "GetInbox", + }, + "put": { + "description": "Update a gauge needle's description. Position and color are immutable.", + "operationId": "UpdateGaugeNeedle", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateGaugeNeedleRequestContent" + } + } + } + }, "parameters": [ { - "name": "inboxId", + "name": "needleId", "in": "path", "schema": { "type": "integer", @@ -6862,11 +6782,11 @@ ], "responses": { "200": { - "description": "GetInbox 200 response", + "description": "UpdateGaugeNeedle 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetInboxResponseContent" + "$ref": "#/components/schemas/UpdateGaugeNeedleResponseContent" } } } @@ -6901,6 +6821,26 @@ } } }, + "422": { + "description": "ValidationError 422 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponseContent" + } + } + } + }, + "429": { + "description": "RateLimitError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RateLimitErrorResponseContent" + } + } + } + }, "500": { "description": "InternalServerError 500 response", "content": { @@ -6913,10 +6853,13 @@ } }, "tags": [ - "Forwards" + "Gauges" ], + "x-basecamp-idempotent": { + "natural": true + }, "x-basecamp-retry": { - "maxAttempts": 3, + "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -6926,46 +6869,28 @@ } } }, - "/inboxes/{inboxId}/forwards.json": { + "/inbox_forwards/{forwardId}": { "get": { - "description": "List all forwards in an inbox\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", - "operationId": "ListForwards", + "description": "Get a forward by ID", + "operationId": "GetForward", "parameters": [ { - "name": "inboxId", + "name": "forwardId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true - }, - { - "name": "sort", - "in": "query", - "description": "created_at|updated_at", - "schema": { - "type": "string", - "description": "created_at|updated_at" - } - }, - { - "name": "direction", - "in": "query", - "description": "asc|desc", - "schema": { - "type": "string", - "description": "asc|desc" - } } ], "responses": { "200": { - "description": "ListForwards 200 response", + "description": "GetForward 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListForwardsResponseContent" + "$ref": "#/components/schemas/GetForwardResponseContent" } } } @@ -6990,12 +6915,12 @@ } } }, - "429": { - "description": "RateLimitError 429 response", + "404": { + "description": "NotFoundError 404 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" } } } @@ -7014,11 +6939,6 @@ "tags": [ "Forwards" ], - "x-basecamp-pagination": { - "style": "link", - "totalCountHeader": "X-Total-Count", - "maxPageSize": 50 - }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -7030,18 +6950,28 @@ } } }, - "/lineup/markers.json": { + "/inbox_forwards/{forwardId}/replies.json": { "get": { - "description": "List all lineup markers for the account", - "operationId": "ListLineupMarkers", - "parameters": [], + "description": "List all replies to a forward\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", + "operationId": "ListForwardReplies", + "parameters": [ + { + "name": "forwardId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true + } + ], "responses": { "200": { - "description": "ListLineupMarkers 200 response", + "description": "ListForwardReplies 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListLineupMarkersResponseContent" + "$ref": "#/components/schemas/ListForwardRepliesResponseContent" } } } @@ -7088,8 +7018,13 @@ } }, "tags": [ - "Automation" + "Forwards" ], + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -7101,22 +7036,39 @@ } }, "post": { - "description": "Create a new lineup marker", - "operationId": "CreateLineupMarker", + "description": "Create a reply to a forward", + "operationId": "CreateForwardReply", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateLineupMarkerRequestContent" + "$ref": "#/components/schemas/CreateForwardReplyRequestContent" } } }, "required": true }, - "parameters": [], + "parameters": [ + { + "name": "forwardId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true + } + ], "responses": { "201": { - "description": "CreateLineupMarker 201 response" + "description": "CreateForwardReply 201 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateForwardReplyResponseContent" + } + } + } }, "401": { "description": "UnauthorizedError 401 response", @@ -7170,7 +7122,7 @@ } }, "tags": [ - "Automation" + "Forwards" ], "x-basecamp-retry": { "maxAttempts": 2, @@ -7183,13 +7135,22 @@ } } }, - "/lineup/markers/{markerId}": { - "delete": { - "description": "Delete a lineup marker", - "operationId": "DeleteLineupMarker", + "/inbox_forwards/{forwardId}/replies/{replyId}": { + "get": { + "description": "Get a forward reply by ID", + "operationId": "GetForwardReply", "parameters": [ { - "name": "markerId", + "name": "forwardId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true + }, + { + "name": "replyId", "in": "path", "schema": { "type": "integer", @@ -7199,92 +7160,15 @@ } ], "responses": { - "204": { - "description": "DeleteLineupMarker 204 response" - }, - "401": { - "description": "UnauthorizedError 401 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UnauthorizedErrorResponseContent" - } - } - } - }, - "403": { - "description": "ForbiddenError 403 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ForbiddenErrorResponseContent" - } - } - } - }, - "404": { - "description": "NotFoundError 404 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" - } - } - } - }, - "500": { - "description": "InternalServerError 500 response", + "200": { + "description": "GetForwardReply 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/InternalServerErrorResponseContent" + "$ref": "#/components/schemas/GetForwardReplyResponseContent" } } } - } - }, - "tags": [ - "Automation" - ], - "x-basecamp-idempotent": { - "natural": true - }, - "x-basecamp-retry": { - "maxAttempts": 3, - "baseDelayMs": 1000, - "backoff": "exponential", - "retryOn": [ - 429, - 503 - ] - } - }, - "put": { - "description": "Update an existing lineup marker", - "operationId": "UpdateLineupMarker", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateLineupMarkerRequestContent" - } - } - } - }, - "parameters": [ - { - "name": "markerId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true - } - ], - "responses": { - "200": { - "description": "UpdateLineupMarker 200 response" }, "401": { "description": "UnauthorizedError 401 response", @@ -7316,16 +7200,6 @@ } } }, - "422": { - "description": "ValidationError 422 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" - } - } - } - }, "500": { "description": "InternalServerError 500 response", "content": { @@ -7338,11 +7212,8 @@ } }, "tags": [ - "Automation" + "Forwards" ], - "x-basecamp-idempotent": { - "natural": true - }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -7354,13 +7225,13 @@ } } }, - "/message_boards/{boardId}": { + "/inboxes/{inboxId}": { "get": { - "description": "Get a message board", - "operationId": "GetMessageBoard", + "description": "Get an inbox by ID", + "operationId": "GetInbox", "parameters": [ { - "name": "boardId", + "name": "inboxId", "in": "path", "schema": { "type": "integer", @@ -7371,11 +7242,11 @@ ], "responses": { "200": { - "description": "GetMessageBoard 200 response", + "description": "GetInbox 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetMessageBoardResponseContent" + "$ref": "#/components/schemas/GetInboxResponseContent" } } } @@ -7422,7 +7293,7 @@ } }, "tags": [ - "Messages" + "Forwards" ], "x-basecamp-retry": { "maxAttempts": 3, @@ -7435,13 +7306,13 @@ } } }, - "/message_boards/{boardId}/messages.json": { + "/inboxes/{inboxId}/forwards.json": { "get": { - "description": "List messages on a message board\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", - "operationId": "ListMessages", + "description": "List all forwards in an inbox\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", + "operationId": "ListForwards", "parameters": [ { - "name": "boardId", + "name": "inboxId", "in": "path", "schema": { "type": "integer", @@ -7470,11 +7341,11 @@ ], "responses": { "200": { - "description": "ListMessages 200 response", + "description": "ListForwards 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListMessagesResponseContent" + "$ref": "#/components/schemas/ListForwardsResponseContent" } } } @@ -7521,7 +7392,7 @@ } }, "tags": [ - "Messages" + "Forwards" ], "x-basecamp-pagination": { "style": "link", @@ -7537,38 +7408,20 @@ 503 ] } - }, - "post": { - "description": "Create a new message on a message board", - "operationId": "CreateMessage", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateMessageRequestContent" - } - } - }, - "required": true - }, - "parameters": [ - { - "name": "boardId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true - } - ], + } + }, + "/lineup/markers.json": { + "get": { + "description": "List all lineup markers for the account", + "operationId": "ListLineupMarkers", + "parameters": [], "responses": { - "201": { - "description": "CreateMessage 201 response", + "200": { + "description": "ListLineupMarkers 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateMessageResponseContent" + "$ref": "#/components/schemas/ListLineupMarkersResponseContent" } } } @@ -7593,16 +7446,6 @@ } } }, - "422": { - "description": "ValidationError 422 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" - } - } - } - }, "429": { "description": "RateLimitError 429 response", "content": { @@ -7625,10 +7468,10 @@ } }, "tags": [ - "Messages" + "Automation" ], "x-basecamp-retry": { - "maxAttempts": 2, + "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -7636,24 +7479,25 @@ 503 ] } - } - }, - "/messages.json": { - "get": { - "description": "Get every message across all accessible projects, newest-first (paginated).\nEach item embeds its `bucket` for project context.", - "operationId": "GetEverythingMessages", - "parameters": [], - "responses": { - "200": { - "description": "GetEverythingMessages 200 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/GetEverythingMessagesResponseContent" - } + }, + "post": { + "description": "Create a new lineup marker", + "operationId": "CreateLineupMarker", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateLineupMarkerRequestContent" } } }, + "required": true + }, + "parameters": [], + "responses": { + "201": { + "description": "CreateLineupMarker 201 response" + }, "401": { "description": "UnauthorizedError 401 response", "content": { @@ -7674,6 +7518,16 @@ } } }, + "422": { + "description": "ValidationError 422 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponseContent" + } + } + } + }, "429": { "description": "RateLimitError 429 response", "content": { @@ -7696,15 +7550,10 @@ } }, "tags": [ - "Everything" + "Automation" ], - "x-basecamp-pagination": { - "style": "link", - "totalCountHeader": "X-Total-Count", - "maxPageSize": 50 - }, "x-basecamp-retry": { - "maxAttempts": 3, + "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -7714,13 +7563,13 @@ } } }, - "/messages/{messageId}": { - "get": { - "description": "Get a single message by id", - "operationId": "GetMessage", + "/lineup/markers/{markerId}": { + "delete": { + "description": "Delete a lineup marker", + "operationId": "DeleteLineupMarker", "parameters": [ { - "name": "messageId", + "name": "markerId", "in": "path", "schema": { "type": "integer", @@ -7730,15 +7579,8 @@ } ], "responses": { - "200": { - "description": "GetMessage 200 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/GetMessageResponseContent" - } - } - } + "204": { + "description": "DeleteLineupMarker 204 response" }, "401": { "description": "UnauthorizedError 401 response", @@ -7782,8 +7624,11 @@ } }, "tags": [ - "Messages" + "Automation" ], + "x-basecamp-idempotent": { + "natural": true + }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -7795,20 +7640,20 @@ } }, "put": { - "description": "Update an existing message", - "operationId": "UpdateMessage", + "description": "Update an existing lineup marker", + "operationId": "UpdateLineupMarker", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateMessageRequestContent" + "$ref": "#/components/schemas/UpdateLineupMarkerRequestContent" } } } }, "parameters": [ { - "name": "messageId", + "name": "markerId", "in": "path", "schema": { "type": "integer", @@ -7819,14 +7664,7 @@ ], "responses": { "200": { - "description": "UpdateMessage 200 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateMessageResponseContent" - } - } - } + "description": "UpdateLineupMarker 200 response" }, "401": { "description": "UnauthorizedError 401 response", @@ -7880,7 +7718,7 @@ } }, "tags": [ - "Messages" + "Automation" ], "x-basecamp-idempotent": { "natural": true @@ -7896,18 +7734,28 @@ } } }, - "/my/assignments.json": { + "/message_boards/{boardId}": { "get": { - "description": "Get the current user's active assignments grouped into priorities and non_priorities.\nCard table steps are normalized to their parent card with steps as children.\nThis endpoint is not paginated.", - "operationId": "GetMyAssignments", - "parameters": [], + "description": "Get a message board", + "operationId": "GetMessageBoard", + "parameters": [ + { + "name": "boardId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true + } + ], "responses": { "200": { - "description": "GetMyAssignments 200 response", + "description": "GetMessageBoard 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetMyAssignmentsResponseContent" + "$ref": "#/components/schemas/GetMessageBoardResponseContent" } } } @@ -7932,63 +7780,12 @@ } } }, - "500": { - "description": "InternalServerError 500 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/InternalServerErrorResponseContent" - } - } - } - } - }, - "tags": [ - "MyAssignments" - ], - "x-basecamp-retry": { - "maxAttempts": 3, - "baseDelayMs": 1000, - "backoff": "exponential", - "retryOn": [ - 429, - 503 - ] - } - } - }, - "/my/assignments/completed.json": { - "get": { - "description": "Get the current user's completed assignments.\nArchived and trashed recordings are excluded. This endpoint is not paginated.", - "operationId": "GetMyCompletedAssignments", - "parameters": [], - "responses": { - "200": { - "description": "GetMyCompletedAssignments 200 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/GetMyCompletedAssignmentsResponseContent" - } - } - } - }, - "401": { - "description": "UnauthorizedError 401 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UnauthorizedErrorResponseContent" - } - } - } - }, - "403": { - "description": "ForbiddenError 403 response", + "404": { + "description": "NotFoundError 404 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" } } } @@ -8005,7 +7802,7 @@ } }, "tags": [ - "MyAssignments" + "Messages" ], "x-basecamp-retry": { "maxAttempts": 3, @@ -8018,38 +7815,46 @@ } } }, - "/my/assignments/due.json": { + "/message_boards/{boardId}/messages.json": { "get": { - "description": "Get the current user's assignments filtered by due date scope.\nDefaults to overdue when no scope is provided. This endpoint is not paginated.", - "operationId": "GetMyDueAssignments", + "description": "List messages on a message board\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", + "operationId": "ListMessages", "parameters": [ { - "name": "scope", + "name": "boardId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true + }, + { + "name": "sort", "in": "query", - "description": "Filter by due date range: overdue, due_today, due_tomorrow,\ndue_later_this_week, due_next_week, due_later", + "description": "created_at|updated_at", "schema": { "type": "string", - "description": "Filter by due date range: overdue, due_today, due_tomorrow,\ndue_later_this_week, due_next_week, due_later" + "description": "created_at|updated_at" + } + }, + { + "name": "direction", + "in": "query", + "description": "asc|desc", + "schema": { + "type": "string", + "description": "asc|desc" } } ], "responses": { "200": { - "description": "GetMyDueAssignments 200 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/GetMyDueAssignmentsResponseContent" - } - } - } - }, - "400": { - "description": "BadRequestError 400 response", + "description": "ListMessages 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/BadRequestErrorResponseContent" + "$ref": "#/components/schemas/ListMessagesResponseContent" } } } @@ -8074,63 +7879,12 @@ } } }, - "500": { - "description": "InternalServerError 500 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/InternalServerErrorResponseContent" - } - } - } - } - }, - "tags": [ - "MyAssignments" - ], - "x-basecamp-retry": { - "maxAttempts": 3, - "baseDelayMs": 1000, - "backoff": "exponential", - "retryOn": [ - 429, - 503 - ] - } - } - }, - "/my/preferences.json": { - "get": { - "description": "Get the current user's preferences", - "operationId": "GetMyPreferences", - "parameters": [], - "responses": { - "200": { - "description": "GetMyPreferences 200 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/GetMyPreferencesResponseContent" - } - } - } - }, - "401": { - "description": "UnauthorizedError 401 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UnauthorizedErrorResponseContent" - } - } - } - }, - "403": { - "description": "ForbiddenError 403 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -8147,8 +7901,13 @@ } }, "tags": [ - "People" + "Messages" ], + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -8159,27 +7918,37 @@ ] } }, - "put": { - "description": "Update the current user's preferences", - "operationId": "UpdateMyPreferences", + "post": { + "description": "Create a new message on a message board", + "operationId": "CreateMessage", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateMyPreferencesRequestContent" + "$ref": "#/components/schemas/CreateMessageRequestContent" } } }, "required": true }, - "parameters": [], + "parameters": [ + { + "name": "boardId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true + } + ], "responses": { - "200": { - "description": "UpdateMyPreferences 200 response", + "201": { + "description": "CreateMessage 201 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateMyPreferencesResponseContent" + "$ref": "#/components/schemas/CreateMessageResponseContent" } } } @@ -8236,11 +8005,8 @@ } }, "tags": [ - "People" + "Messages" ], - "x-basecamp-idempotent": { - "natural": true - }, "x-basecamp-retry": { "maxAttempts": 2, "baseDelayMs": 1000, @@ -8252,18 +8018,18 @@ } } }, - "/my/profile.json": { + "/messages.json": { "get": { - "description": "Get the current authenticated user's profile", - "operationId": "GetMyProfile", + "description": "Get every message across all accessible projects, newest-first (paginated).\nEach item embeds its `bucket` for project context.", + "operationId": "GetEverythingMessages", "parameters": [], "responses": { "200": { - "description": "GetMyProfile 200 response", + "description": "GetEverythingMessages 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetMyProfileResponseContent" + "$ref": "#/components/schemas/GetEverythingMessagesResponseContent" } } } @@ -8288,12 +8054,12 @@ } } }, - "404": { - "description": "NotFoundError 404 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -8310,8 +8076,13 @@ } }, "tags": [ - "People" + "Everything" ], + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -8321,23 +8092,33 @@ 503 ] } - }, - "put": { - "description": "Update the current authenticated user's profile (returns 204 No Content)", - "operationId": "UpdateMyProfile", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateMyProfileRequestContent" - } - } + } + }, + "/messages/{messageId}": { + "get": { + "description": "Get a single message by id", + "operationId": "GetMessage", + "parameters": [ + { + "name": "messageId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true } - }, - "parameters": [], + ], "responses": { - "204": { - "description": "UpdateMyProfile 204 response" + "200": { + "description": "GetMessage 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetMessageResponseContent" + } + } + } }, "401": { "description": "UnauthorizedError 401 response", @@ -8359,12 +8140,12 @@ } } }, - "422": { - "description": "ValidationError 422 response", + "404": { + "description": "NotFoundError 404 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" } } } @@ -8381,11 +8162,8 @@ } }, "tags": [ - "People" + "Messages" ], - "x-basecamp-idempotent": { - "natural": true - }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -8395,20 +8173,37 @@ 503 ] } - } - }, - "/my/question_reminders.json": { - "get": { - "description": "Get pending check-in reminders for the current user\n\nReturns questions that are pending a response from the authenticated user.\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages.", - "operationId": "GetQuestionReminders", - "parameters": [], + }, + "put": { + "description": "Update an existing message", + "operationId": "UpdateMessage", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateMessageRequestContent" + } + } + } + }, + "parameters": [ + { + "name": "messageId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true + } + ], "responses": { "200": { - "description": "GetQuestionReminders 200 response", + "description": "UpdateMessage 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetQuestionRemindersResponseContent" + "$ref": "#/components/schemas/UpdateMessageResponseContent" } } } @@ -8433,12 +8228,22 @@ } } }, - "429": { - "description": "RateLimitError 429 response", + "404": { + "description": "NotFoundError 404 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" + } + } + } + }, + "422": { + "description": "ValidationError 422 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponseContent" } } } @@ -8454,9 +8259,11 @@ } } }, - "x-basecamp-pagination": { - "style": "link", - "maxPageSize": 50 + "tags": [ + "Messages" + ], + "x-basecamp-idempotent": { + "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, @@ -8469,38 +8276,18 @@ } } }, - "/my/readings.json": { + "/my/assignments.json": { "get": { - "description": "Get the current user's notification inbox (the \"Hey!\" menu).\nNotifications are grouped into unreads, reads, bubble-ups, and\nscheduled bubble-ups (`memories` remains as an always-empty\nplaceholder on BC5). Reads are paginated (50 per page). Unreads are\ncapped at 100. Bubble-ups are capped per `limit_bubble_ups`.", - "operationId": "GetMyNotifications", - "parameters": [ - { - "name": "page", - "in": "query", - "description": "Page number for paginating through read items. Defaults to 1.", - "schema": { - "type": "integer", - "description": "Page number for paginating through read items. Defaults to 1.", - "format": "int32" - } - }, - { - "name": "limit_bubble_ups", - "in": "query", - "description": "Set to true to cap `bubble_ups` at 2 current bubble-ups and omit the\n`scheduled_bubble_ups` key entirely. Defaults to false. Use the dedicated\nbubble-ups endpoint (GetBubbleUps) to page through all current and\nscheduled bubble-ups.", - "schema": { - "type": "boolean", - "description": "Set to true to cap `bubble_ups` at 2 current bubble-ups and omit the\n`scheduled_bubble_ups` key entirely. Defaults to false. Use the dedicated\nbubble-ups endpoint (GetBubbleUps) to page through all current and\nscheduled bubble-ups." - } - } - ], + "description": "Get the current user's active assignments grouped into priorities and non_priorities.\nCard table steps are normalized to their parent card with steps as children.\nThis endpoint is not paginated.", + "operationId": "GetMyAssignments", + "parameters": [], "responses": { "200": { - "description": "GetMyNotifications 200 response", + "description": "GetMyAssignments 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetMyNotificationsResponseContent" + "$ref": "#/components/schemas/GetMyAssignmentsResponseContent" } } } @@ -8537,7 +8324,7 @@ } }, "tags": [ - "MyNotifications" + "MyAssignments" ], "x-basecamp-retry": { "maxAttempts": 3, @@ -8550,29 +8337,18 @@ } } }, - "/my/readings/bubble_ups.json": { + "/my/assignments/completed.json": { "get": { - "description": "Get the current user's current and scheduled bubble-ups as a paginated\nlist (50 per page). Current bubble-ups are returned first, ordered by most\nrecently bubbled up; scheduled bubble-ups follow, ordered by scheduled\nbubble-up time. Each item uses the same notification object shape as\nGetMyNotifications.", - "operationId": "GetBubbleUps", - "parameters": [ - { - "name": "page", - "in": "query", - "description": "Page number. Defaults to 1.", - "schema": { - "type": "integer", - "description": "Page number. Defaults to 1.", - "format": "int32" - } - } - ], + "description": "Get the current user's completed assignments.\nArchived and trashed recordings are excluded. This endpoint is not paginated.", + "operationId": "GetMyCompletedAssignments", + "parameters": [], "responses": { "200": { - "description": "GetBubbleUps 200 response", + "description": "GetMyCompletedAssignments 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetBubbleUpsResponseContent" + "$ref": "#/components/schemas/GetMyCompletedAssignmentsResponseContent" } } } @@ -8597,16 +8373,6 @@ } } }, - "429": { - "description": "RateLimitError 429 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" - } - } - } - }, "500": { "description": "InternalServerError 500 response", "content": { @@ -8619,13 +8385,8 @@ } }, "tags": [ - "MyNotifications" + "MyAssignments" ], - "x-basecamp-pagination": { - "style": "link", - "totalCountHeader": "X-Total-Count", - "maxPageSize": 50 - }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -8637,51 +8398,58 @@ } } }, - "/my/unreads.json": { - "put": { - "description": "Mark specified items as read", - "operationId": "MarkAsRead", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/MarkAsReadRequestContent" - } + "/my/assignments/due.json": { + "get": { + "description": "Get the current user's assignments filtered by due date scope.\nDefaults to overdue when no scope is provided. This endpoint is not paginated.", + "operationId": "GetMyDueAssignments", + "parameters": [ + { + "name": "scope", + "in": "query", + "description": "Filter by due date range: overdue, due_today, due_tomorrow,\ndue_later_this_week, due_next_week, due_later", + "schema": { + "type": "string", + "description": "Filter by due date range: overdue, due_today, due_tomorrow,\ndue_later_this_week, due_next_week, due_later" } - }, - "required": true - }, - "parameters": [], + } + ], "responses": { "200": { - "description": "MarkAsRead 200 response" + "description": "GetMyDueAssignments 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetMyDueAssignmentsResponseContent" + } + } + } }, - "401": { - "description": "UnauthorizedError 401 response", + "400": { + "description": "BadRequestError 400 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UnauthorizedErrorResponseContent" + "$ref": "#/components/schemas/BadRequestErrorResponseContent" } } } }, - "403": { - "description": "ForbiddenError 403 response", + "401": { + "description": "UnauthorizedError 401 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + "$ref": "#/components/schemas/UnauthorizedErrorResponseContent" } } } }, - "429": { - "description": "RateLimitError 429 response", + "403": { + "description": "ForbiddenError 403 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" } } } @@ -8698,13 +8466,10 @@ } }, "tags": [ - "MyNotifications" + "MyAssignments" ], - "x-basecamp-idempotent": { - "natural": true - }, "x-basecamp-retry": { - "maxAttempts": 2, + "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -8714,18 +8479,18 @@ } } }, - "/people.json": { + "/my/preferences.json": { "get": { - "description": "List all people visible to the current user\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", - "operationId": "ListPeople", + "description": "Get the current user's preferences", + "operationId": "GetMyPreferences", "parameters": [], "responses": { "200": { - "description": "ListPeople 200 response", + "description": "GetMyPreferences 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListPeopleResponseContent" + "$ref": "#/components/schemas/GetMyPreferencesResponseContent" } } } @@ -8750,16 +8515,6 @@ } } }, - "429": { - "description": "RateLimitError 429 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" - } - } - } - }, "500": { "description": "InternalServerError 500 response", "content": { @@ -8774,11 +8529,6 @@ "tags": [ "People" ], - "x-basecamp-pagination": { - "style": "link", - "totalCountHeader": "X-Total-Count", - "maxPageSize": 50 - }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -8788,30 +8538,28 @@ 503 ] } - } - }, - "/people/{personId}": { - "get": { - "description": "Get a person by ID", - "operationId": "GetPerson", - "parameters": [ - { - "name": "personId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true - } - ], + }, + "put": { + "description": "Update the current user's preferences", + "operationId": "UpdateMyPreferences", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateMyPreferencesRequestContent" + } + } + }, + "required": true + }, + "parameters": [], "responses": { "200": { - "description": "GetPerson 200 response", + "description": "UpdateMyPreferences 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetPersonResponseContent" + "$ref": "#/components/schemas/UpdateMyPreferencesResponseContent" } } } @@ -8836,12 +8584,22 @@ } } }, - "404": { - "description": "NotFoundError 404 response", + "422": { + "description": "ValidationError 422 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/ValidationErrorResponseContent" + } + } + } + }, + "429": { + "description": "RateLimitError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -8860,8 +8618,11 @@ "tags": [ "People" ], + "x-basecamp-idempotent": { + "natural": true + }, "x-basecamp-retry": { - "maxAttempts": 3, + "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -8871,24 +8632,21 @@ } } }, - "/people/{personId}/out_of_office.json": { - "delete": { - "description": "Disable out of office for a person.\nAdmins on Pro Pack accounts can manage others; otherwise self only.", - "operationId": "DisableOutOfOffice", - "parameters": [ - { - "name": "personId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true - } - ], + "/my/profile.json": { + "get": { + "description": "Get the current authenticated user's profile", + "operationId": "GetMyProfile", + "parameters": [], "responses": { - "204": { - "description": "DisableOutOfOffice 204 response" + "200": { + "description": "GetMyProfile 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetMyProfileResponseContent" + } + } + } }, "401": { "description": "UnauthorizedError 401 response", @@ -8910,12 +8668,12 @@ } } }, - "429": { - "description": "RateLimitError 429 response", + "404": { + "description": "NotFoundError 404 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" } } } @@ -8934,11 +8692,8 @@ "tags": [ "People" ], - "x-basecamp-idempotent": { - "natural": true - }, "x-basecamp-retry": { - "maxAttempts": 2, + "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -8947,30 +8702,22 @@ ] } }, - "get": { - "description": "Get the out of office status for a person", - "operationId": "GetOutOfOffice", - "parameters": [ - { - "name": "personId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true - } - ], - "responses": { - "200": { - "description": "GetOutOfOffice 200 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/GetOutOfOfficeResponseContent" - } + "put": { + "description": "Update the current authenticated user's profile (returns 204 No Content)", + "operationId": "UpdateMyProfile", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateMyProfileRequestContent" } } + } + }, + "parameters": [], + "responses": { + "204": { + "description": "UpdateMyProfile 204 response" }, "401": { "description": "UnauthorizedError 401 response", @@ -8992,12 +8739,12 @@ } } }, - "404": { - "description": "NotFoundError 404 response", + "422": { + "description": "ValidationError 422 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/ValidationErrorResponseContent" } } } @@ -9016,6 +8763,9 @@ "tags": [ "People" ], + "x-basecamp-idempotent": { + "natural": true + }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -9025,38 +8775,20 @@ 503 ] } - }, - "post": { - "description": "Enable or replace out of office for a person.\nAdmins on Pro Pack accounts can manage others; otherwise self only.", - "operationId": "EnableOutOfOffice", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/EnableOutOfOfficeRequestContent" - } - } - }, - "required": true - }, - "parameters": [ - { - "name": "personId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true - } - ], + } + }, + "/my/question_reminders.json": { + "get": { + "description": "Get pending check-in reminders for the current user\n\nReturns questions that are pending a response from the authenticated user.\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages.", + "operationId": "GetQuestionReminders", + "parameters": [], "responses": { "200": { - "description": "EnableOutOfOffice 200 response", + "description": "GetQuestionReminders 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/EnableOutOfOfficeResponseContent" + "$ref": "#/components/schemas/GetQuestionRemindersResponseContent" } } } @@ -9081,16 +8813,6 @@ } } }, - "422": { - "description": "ValidationError 422 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" - } - } - } - }, "429": { "description": "RateLimitError 429 response", "content": { @@ -9112,11 +8834,12 @@ } } }, - "tags": [ - "People" - ], + "x-basecamp-pagination": { + "style": "link", + "maxPageSize": 50 + }, "x-basecamp-retry": { - "maxAttempts": 2, + "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -9126,28 +8849,38 @@ } } }, - "/projects.json": { + "/my/readings.json": { "get": { - "description": "List projects (active by default; optionally archived/trashed)\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", - "operationId": "ListProjects", + "description": "Get the current user's notification inbox (the \"Hey!\" menu).\nNotifications are grouped into unreads, reads, bubble-ups, and\nscheduled bubble-ups (`memories` remains as an always-empty\nplaceholder on BC5). Reads are paginated (50 per page). Unreads are\ncapped at 100. Bubble-ups are capped per `limit_bubble_ups`.", + "operationId": "GetMyNotifications", "parameters": [ { - "name": "status", + "name": "page", "in": "query", - "description": "active|archived|trashed", + "description": "Page number for paginating through read items. Defaults to 1.", "schema": { - "type": "string", - "description": "active|archived|trashed" + "type": "integer", + "description": "Page number for paginating through read items. Defaults to 1.", + "format": "int32" + } + }, + { + "name": "limit_bubble_ups", + "in": "query", + "description": "Set to true to cap `bubble_ups` at 2 current bubble-ups and omit the\n`scheduled_bubble_ups` key entirely. Defaults to false. Use the dedicated\nbubble-ups endpoint (GetBubbleUps) to page through all current and\nscheduled bubble-ups.", + "schema": { + "type": "boolean", + "description": "Set to true to cap `bubble_ups` at 2 current bubble-ups and omit the\n`scheduled_bubble_ups` key entirely. Defaults to false. Use the dedicated\nbubble-ups endpoint (GetBubbleUps) to page through all current and\nscheduled bubble-ups." } } ], "responses": { "200": { - "description": "ListProjects 200 response", + "description": "GetMyNotifications 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListProjectsResponseContent" + "$ref": "#/components/schemas/GetMyNotificationsResponseContent" } } } @@ -9172,16 +8905,6 @@ } } }, - "429": { - "description": "RateLimitError 429 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" - } - } - } - }, "500": { "description": "InternalServerError 500 response", "content": { @@ -9194,13 +8917,8 @@ } }, "tags": [ - "Projects" + "MyNotifications" ], - "x-basecamp-pagination": { - "style": "link", - "totalCountHeader": "X-Total-Count", - "maxPageSize": 50 - }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -9210,28 +8928,31 @@ 503 ] } - }, - "post": { - "description": "Create a new project", - "operationId": "CreateProject", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateProjectRequestContent" - } + } + }, + "/my/readings/bubble_ups.json": { + "get": { + "description": "Get the current user's current and scheduled bubble-ups as a paginated\nlist (50 per page). Current bubble-ups are returned first, ordered by most\nrecently bubbled up; scheduled bubble-ups follow, ordered by scheduled\nbubble-up time. Each item uses the same notification object shape as\nGetMyNotifications.", + "operationId": "GetBubbleUps", + "parameters": [ + { + "name": "page", + "in": "query", + "description": "Page number. Defaults to 1.", + "schema": { + "type": "integer", + "description": "Page number. Defaults to 1.", + "format": "int32" } - }, - "required": true - }, - "parameters": [], + } + ], "responses": { - "201": { - "description": "CreateProject 201 response", + "200": { + "description": "GetBubbleUps 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateProjectResponseContent" + "$ref": "#/components/schemas/GetBubbleUpsResponseContent" } } } @@ -9256,16 +8977,6 @@ } } }, - "422": { - "description": "ValidationError 422 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" - } - } - } - }, "429": { "description": "RateLimitError 429 response", "content": { @@ -9288,8 +8999,13 @@ } }, "tags": [ - "Projects" + "MyNotifications" ], + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -9301,100 +9017,24 @@ } } }, - "/projects/recordings.json": { - "get": { - "description": "List recordings of a given type across projects\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", - "operationId": "ListRecordings", - "parameters": [ - { - "name": "type", - "in": "query", - "description": "Comment|Document|Door|Kanban::Card|Kanban::Step|Message|Question::Answer|Schedule::Entry|Todo|Todolist|Upload|Vault", - "schema": { - "type": "string", - "description": "Comment|Document|Door|Kanban::Card|Kanban::Step|Message|Question::Answer|Schedule::Entry|Todo|Todolist|Upload|Vault" - }, - "required": true, - "examples": { - "ListRecordings_example1": { - "summary": "List Todo recordings", - "description": "Use simple type name for basic resources", - "value": "Todo" - }, - "ListRecordings_example2": { - "summary": "List Kanban Card recordings", - "description": "Use double-colon notation for nested types", - "value": "Kanban::Card" - }, - "ListRecordings_example3": { - "summary": "List Question Answer recordings", - "description": "Another nested type example", - "value": "Question::Answer" + "/my/unreads.json": { + "put": { + "description": "Mark specified items as read", + "operationId": "MarkAsRead", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MarkAsReadRequestContent" } } }, - { - "name": "bucket", - "in": "query", - "schema": { - "type": "string" - } - }, - { - "name": "status", - "in": "query", - "description": "active|archived|trashed", - "schema": { - "type": "string", - "description": "active|archived|trashed" - } - }, - { - "name": "sort", - "in": "query", - "description": "created_at|updated_at", - "schema": { - "type": "string", - "description": "created_at|updated_at" - } - }, - { - "name": "direction", - "in": "query", - "description": "asc|desc", - "schema": { - "type": "string", - "description": "asc|desc" - } - } - ], + "required": true + }, + "parameters": [], "responses": { "200": { - "description": "ListRecordings 200 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ListRecordingsResponseContent" - }, - "examples": { - "ListRecordings_example1": { - "summary": "List Todo recordings", - "description": "Use simple type name for basic resources", - "value": {} - }, - "ListRecordings_example2": { - "summary": "List Kanban Card recordings", - "description": "Use double-colon notation for nested types", - "value": {} - }, - "ListRecordings_example3": { - "summary": "List Question Answer recordings", - "description": "Another nested type example", - "value": {} - } - } - } - } + "description": "MarkAsRead 200 response" }, "401": { "description": "UnauthorizedError 401 response", @@ -9438,15 +9078,13 @@ } }, "tags": [ - "Automation" + "MyNotifications" ], - "x-basecamp-pagination": { - "style": "link", - "totalCountHeader": "X-Total-Count", - "maxPageSize": 50 + "x-basecamp-idempotent": { + "natural": true }, "x-basecamp-retry": { - "maxAttempts": 3, + "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -9456,24 +9094,21 @@ } } }, - "/projects/{projectId}": { - "delete": { - "description": "Trash a project (returns 204 No Content)", - "operationId": "TrashProject", - "parameters": [ - { - "name": "projectId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true - } - ], + "/people.json": { + "get": { + "description": "List all people visible to the current user\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", + "operationId": "ListPeople", + "parameters": [], "responses": { - "204": { - "description": "TrashProject 204 response" + "200": { + "description": "ListPeople 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListPeopleResponseContent" + } + } + } }, "401": { "description": "UnauthorizedError 401 response", @@ -9495,12 +9130,12 @@ } } }, - "404": { - "description": "NotFoundError 404 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -9517,10 +9152,12 @@ } }, "tags": [ - "Projects" + "People" ], - "x-basecamp-idempotent": { - "natural": true + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 }, "x-basecamp-retry": { "maxAttempts": 3, @@ -9531,13 +9168,15 @@ 503 ] } - }, + } + }, + "/people/{personId}": { "get": { - "description": "Get a single project by id", - "operationId": "GetProject", + "description": "Get a person by ID", + "operationId": "GetPerson", "parameters": [ { - "name": "projectId", + "name": "personId", "in": "path", "schema": { "type": "integer", @@ -9548,11 +9187,11 @@ ], "responses": { "200": { - "description": "GetProject 200 response", + "description": "GetPerson 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetProjectResponseContent" + "$ref": "#/components/schemas/GetPersonResponseContent" } } } @@ -9599,7 +9238,7 @@ } }, "tags": [ - "Projects" + "People" ], "x-basecamp-retry": { "maxAttempts": 3, @@ -9610,23 +9249,15 @@ 503 ] } - }, - "put": { - "description": "Update an existing project", - "operationId": "UpdateProject", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateProjectRequestContent" - } - } - }, - "required": true - }, + } + }, + "/people/{personId}/out_of_office.json": { + "delete": { + "description": "Disable out of office for a person.\nAdmins on Pro Pack accounts can manage others; otherwise self only.", + "operationId": "DisableOutOfOffice", "parameters": [ { - "name": "projectId", + "name": "personId", "in": "path", "schema": { "type": "integer", @@ -9636,15 +9267,8 @@ } ], "responses": { - "200": { - "description": "UpdateProject 200 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateProjectResponseContent" - } - } - } + "204": { + "description": "DisableOutOfOffice 204 response" }, "401": { "description": "UnauthorizedError 401 response", @@ -9666,22 +9290,12 @@ } } }, - "404": { - "description": "NotFoundError 404 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" - } - } - } - }, - "422": { - "description": "ValidationError 422 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -9698,13 +9312,13 @@ } }, "tags": [ - "Projects" + "People" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { - "maxAttempts": 3, + "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -9712,25 +9326,13 @@ 503 ] } - } - }, - "/projects/{projectId}/gauge.json": { - "put": { - "description": "Enable or disable the gauge for a project. Only project admins can toggle gauges.", - "operationId": "ToggleGauge", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ToggleGaugeRequestContent" - } - } - }, - "required": true - }, + }, + "get": { + "description": "Get the out of office status for a person", + "operationId": "GetOutOfOffice", "parameters": [ { - "name": "projectId", + "name": "personId", "in": "path", "schema": { "type": "integer", @@ -9741,7 +9343,14 @@ ], "responses": { "200": { - "description": "ToggleGauge 200 response" + "description": "GetOutOfOffice 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetOutOfOfficeResponseContent" + } + } + } }, "401": { "description": "UnauthorizedError 401 response", @@ -9763,12 +9372,12 @@ } } }, - "429": { - "description": "RateLimitError 429 response", + "404": { + "description": "NotFoundError 404 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" } } } @@ -9785,13 +9394,10 @@ } }, "tags": [ - "Gauges" + "People" ], - "x-basecamp-idempotent": { - "natural": true - }, "x-basecamp-retry": { - "maxAttempts": 2, + "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -9799,15 +9405,23 @@ 503 ] } - } - }, - "/projects/{projectId}/gauge/needles.json": { - "get": { - "description": "List gauge needles for a project, ordered newest first.", - "operationId": "ListGaugeNeedles", + }, + "post": { + "description": "Enable or replace out of office for a person.\nAdmins on Pro Pack accounts can manage others; otherwise self only.", + "operationId": "EnableOutOfOffice", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EnableOutOfOfficeRequestContent" + } + } + }, + "required": true + }, "parameters": [ { - "name": "projectId", + "name": "personId", "in": "path", "schema": { "type": "integer", @@ -9818,11 +9432,11 @@ ], "responses": { "200": { - "description": "ListGaugeNeedles 200 response", + "description": "EnableOutOfOffice 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListGaugeNeedlesResponseContent" + "$ref": "#/components/schemas/EnableOutOfOfficeResponseContent" } } } @@ -9847,12 +9461,12 @@ } } }, - "404": { - "description": "NotFoundError 404 response", + "422": { + "description": "ValidationError 422 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/ValidationErrorResponseContent" } } } @@ -9879,15 +9493,10 @@ } }, "tags": [ - "Gauges" + "People" ], - "x-basecamp-pagination": { - "style": "link", - "totalCountHeader": "X-Total-Count", - "maxPageSize": 50 - }, "x-basecamp-retry": { - "maxAttempts": 3, + "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -9895,38 +9504,30 @@ 503 ] } - }, - "post": { - "description": "Create a gauge needle (progress update) for a project", - "operationId": "CreateGaugeNeedle", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateGaugeNeedleRequestContent" - } - } - }, - "required": true - }, + } + }, + "/projects.json": { + "get": { + "description": "List projects (active by default; optionally archived/trashed)\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", + "operationId": "ListProjects", "parameters": [ { - "name": "projectId", - "in": "path", + "name": "status", + "in": "query", + "description": "active|archived|trashed", "schema": { - "type": "integer", - "format": "int64" - }, - "required": true + "type": "string", + "description": "active|archived|trashed" + } } ], "responses": { - "201": { - "description": "CreateGaugeNeedle 201 response", + "200": { + "description": "ListProjects 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateGaugeNeedleResponseContent" + "$ref": "#/components/schemas/ListProjectsResponseContent" } } } @@ -9951,16 +9552,6 @@ } } }, - "422": { - "description": "ValidationError 422 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" - } - } - } - }, "429": { "description": "RateLimitError 429 response", "content": { @@ -9983,10 +9574,15 @@ } }, "tags": [ - "Gauges" + "Projects" ], + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + }, "x-basecamp-retry": { - "maxAttempts": 2, + "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -9994,30 +9590,28 @@ 503 ] } - } - }, - "/projects/{projectId}/people.json": { - "get": { - "description": "List all active people on a project\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", - "operationId": "ListProjectPeople", - "parameters": [ - { - "name": "projectId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true - } - ], + }, + "post": { + "description": "Create a new project", + "operationId": "CreateProject", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateProjectRequestContent" + } + } + }, + "required": true + }, + "parameters": [], "responses": { - "200": { - "description": "ListProjectPeople 200 response", + "201": { + "description": "CreateProject 201 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListProjectPeopleResponseContent" + "$ref": "#/components/schemas/CreateProjectResponseContent" } } } @@ -10042,6 +9636,16 @@ } } }, + "422": { + "description": "ValidationError 422 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponseContent" + } + } + } + }, "429": { "description": "RateLimitError 429 response", "content": { @@ -10064,13 +9668,8 @@ } }, "tags": [ - "People" + "Projects" ], - "x-basecamp-pagination": { - "style": "link", - "totalCountHeader": "X-Total-Count", - "maxPageSize": 50 - }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -10082,102 +9681,95 @@ } } }, - "/projects/{projectId}/people/users.json": { - "put": { - "description": "Update project access (grant/revoke/create people)", - "operationId": "UpdateProjectAccess", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateProjectAccessRequestContent" + "/projects/recordings.json": { + "get": { + "description": "List recordings of a given type across projects\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", + "operationId": "ListRecordings", + "parameters": [ + { + "name": "type", + "in": "query", + "description": "Comment|Document|Door|Kanban::Card|Kanban::Step|Message|Question::Answer|Schedule::Entry|Todo|Todolist|Upload|Vault", + "schema": { + "type": "string", + "description": "Comment|Document|Door|Kanban::Card|Kanban::Step|Message|Question::Answer|Schedule::Entry|Todo|Todolist|Upload|Vault" + }, + "required": true, + "examples": { + "ListRecordings_example1": { + "summary": "List Todo recordings", + "description": "Use simple type name for basic resources", + "value": "Todo" }, - "examples": { - "UpdateProjectAccess_example1": { - "summary": "Grant access to existing users", - "description": "Use grant array with person IDs", - "value": { - "grant": [ - 111, - 222 - ] - } - }, - "UpdateProjectAccess_example2": { - "summary": "Revoke access", - "description": "Use revoke array to remove users", - "value": { - "revoke": [ - 333 - ] - } - }, - "UpdateProjectAccess_example3": { - "summary": "Invite new users", - "description": "Use create array for new users without accounts", - "value": { - "create": [ - { - "name": "Jane", - "email_address": "jane@example.com" - } - ] - } - } + "ListRecordings_example2": { + "summary": "List Kanban Card recordings", + "description": "Use double-colon notation for nested types", + "value": "Kanban::Card" + }, + "ListRecordings_example3": { + "summary": "List Question Answer recordings", + "description": "Another nested type example", + "value": "Question::Answer" } } - } - }, - "parameters": [ + }, { - "name": "projectId", - "in": "path", + "name": "bucket", + "in": "query", "schema": { - "type": "integer", - "format": "int64" - }, - "required": true, - "examples": { - "UpdateProjectAccess_example1": { - "summary": "Grant access to existing users", - "description": "Use grant array with person IDs", - "value": 12345678 - }, - "UpdateProjectAccess_example2": { - "summary": "Revoke access", - "description": "Use revoke array to remove users", - "value": 12345678 - }, - "UpdateProjectAccess_example3": { - "summary": "Invite new users", - "description": "Use create array for new users without accounts", - "value": 12345678 - } + "type": "string" + } + }, + { + "name": "status", + "in": "query", + "description": "active|archived|trashed", + "schema": { + "type": "string", + "description": "active|archived|trashed" + } + }, + { + "name": "sort", + "in": "query", + "description": "created_at|updated_at", + "schema": { + "type": "string", + "description": "created_at|updated_at" + } + }, + { + "name": "direction", + "in": "query", + "description": "asc|desc", + "schema": { + "type": "string", + "description": "asc|desc" } } ], "responses": { "200": { - "description": "UpdateProjectAccess 200 response", + "description": "ListRecordings 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateProjectAccessResponseContent" + "$ref": "#/components/schemas/ListRecordingsResponseContent" }, "examples": { - "UpdateProjectAccess_example1": { - "summary": "Grant access to existing users", - "description": "Use grant array with person IDs", + "ListRecordings_example1": { + "summary": "List Todo recordings", + "description": "Use simple type name for basic resources", "value": {} }, - "UpdateProjectAccess_example2": { - "summary": "Revoke access", - "description": "Use revoke array to remove users", + "ListRecordings_example2": { + "summary": "List Kanban Card recordings", + "description": "Use double-colon notation for nested types", "value": {} }, - "UpdateProjectAccess_example3": { - "summary": "Invite new users", - "description": "Use create array for new users without accounts", + "ListRecordings_example3": { + "summary": "List Question Answer recordings", + "description": "Another nested type example", "value": {} } } @@ -10204,26 +9796,6 @@ } } }, - "404": { - "description": "NotFoundError 404 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" - } - } - } - }, - "422": { - "description": "ValidationError 422 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" - } - } - } - }, "429": { "description": "RateLimitError 429 response", "content": { @@ -10246,10 +9818,12 @@ } }, "tags": [ - "People" + "Automation" ], - "x-basecamp-idempotent": { - "natural": true + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 }, "x-basecamp-retry": { "maxAttempts": 3, @@ -10262,10 +9836,10 @@ } } }, - "/projects/{projectId}/timeline.json": { - "get": { - "description": "Get project timeline", - "operationId": "GetProjectTimeline", + "/projects/{projectId}": { + "delete": { + "description": "Trash a project (returns 204 No Content)", + "operationId": "TrashProject", "parameters": [ { "name": "projectId", @@ -10278,15 +9852,8 @@ } ], "responses": { - "200": { - "description": "GetProjectTimeline 200 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/GetProjectTimelineResponseContent" - } - } - } + "204": { + "description": "TrashProject 204 response" }, "401": { "description": "UnauthorizedError 401 response", @@ -10318,16 +9885,6 @@ } } }, - "429": { - "description": "RateLimitError 429 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" - } - } - } - }, "500": { "description": "InternalServerError 500 response", "content": { @@ -10339,10 +9896,11 @@ } } }, - "x-basecamp-pagination": { - "style": "link", - "totalCountHeader": "X-Total-Count", - "maxPageSize": 50 + "tags": [ + "Projects" + ], + "x-basecamp-idempotent": { + "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, @@ -10353,12 +9911,10 @@ 503 ] } - } - }, - "/projects/{projectId}/timesheet.json": { + }, "get": { - "description": "Get timesheet for a specific project", - "operationId": "GetProjectTimesheet", + "description": "Get a single project by id", + "operationId": "GetProject", "parameters": [ { "name": "projectId", @@ -10368,37 +9924,15 @@ "format": "int64" }, "required": true - }, - { - "name": "from", - "in": "query", - "schema": { - "type": "string" - } - }, - { - "name": "to", - "in": "query", - "schema": { - "type": "string" - } - }, - { - "name": "person_id", - "in": "query", - "schema": { - "type": "integer", - "format": "int64" - } } ], "responses": { "200": { - "description": "GetProjectTimesheet 200 response", + "description": "GetProject 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetProjectTimesheetResponseContent" + "$ref": "#/components/schemas/GetProjectResponseContent" } } } @@ -10445,13 +9979,8 @@ } }, "tags": [ - "Schedule" + "Projects" ], - "x-basecamp-pagination": { - "style": "link", - "totalCountHeader": "X-Total-Count", - "maxPageSize": 50 - }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -10461,15 +9990,23 @@ 503 ] } - } - }, - "/question_answers/{answerId}": { - "get": { - "description": "Get a single answer by id", - "operationId": "GetAnswer", + }, + "put": { + "description": "Update an existing project", + "operationId": "UpdateProject", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateProjectRequestContent" + } + } + }, + "required": true + }, "parameters": [ { - "name": "answerId", + "name": "projectId", "in": "path", "schema": { "type": "integer", @@ -10480,11 +10017,11 @@ ], "responses": { "200": { - "description": "GetAnswer 200 response", + "description": "UpdateProject 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetAnswerResponseContent" + "$ref": "#/components/schemas/UpdateProjectResponseContent" } } } @@ -10519,6 +10056,16 @@ } } }, + "422": { + "description": "ValidationError 422 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponseContent" + } + } + } + }, "500": { "description": "InternalServerError 500 response", "content": { @@ -10531,8 +10078,11 @@ } }, "tags": [ - "Automation" + "Projects" ], + "x-basecamp-idempotent": { + "natural": true + }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -10542,15 +10092,17 @@ 503 ] } - }, + } + }, + "/projects/{projectId}/gauge.json": { "put": { - "description": "Update an existing answer", - "operationId": "UpdateAnswer", + "description": "Enable or disable the gauge for a project. Only project admins can toggle gauges.", + "operationId": "ToggleGauge", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/QuestionAnswerUpdatePayload" + "$ref": "#/components/schemas/ToggleGaugeRequestContent" } } }, @@ -10558,7 +10110,7 @@ }, "parameters": [ { - "name": "answerId", + "name": "projectId", "in": "path", "schema": { "type": "integer", @@ -10568,8 +10120,8 @@ } ], "responses": { - "204": { - "description": "UpdateAnswer 204 response" + "200": { + "description": "ToggleGauge 200 response" }, "401": { "description": "UnauthorizedError 401 response", @@ -10591,22 +10143,12 @@ } } }, - "404": { - "description": "NotFoundError 404 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" - } - } - } - }, - "422": { - "description": "ValidationError 422 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -10623,13 +10165,13 @@ } }, "tags": [ - "Automation" + "Gauges" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { - "maxAttempts": 3, + "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -10639,13 +10181,13 @@ } } }, - "/questionnaires/{questionnaireId}": { + "/projects/{projectId}/gauge/needles.json": { "get": { - "description": "Get a questionnaire (automatic check-ins container) by id", - "operationId": "GetQuestionnaire", + "description": "List gauge needles for a project, ordered newest first.", + "operationId": "ListGaugeNeedles", "parameters": [ { - "name": "questionnaireId", + "name": "projectId", "in": "path", "schema": { "type": "integer", @@ -10656,11 +10198,11 @@ ], "responses": { "200": { - "description": "GetQuestionnaire 200 response", + "description": "ListGaugeNeedles 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetQuestionnaireResponseContent" + "$ref": "#/components/schemas/ListGaugeNeedlesResponseContent" } } } @@ -10695,77 +10237,6 @@ } } }, - "500": { - "description": "InternalServerError 500 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/InternalServerErrorResponseContent" - } - } - } - } - }, - "tags": [ - "Automation" - ], - "x-basecamp-retry": { - "maxAttempts": 3, - "baseDelayMs": 1000, - "backoff": "exponential", - "retryOn": [ - 429, - 503 - ] - } - } - }, - "/questionnaires/{questionnaireId}/questions.json": { - "get": { - "description": "List all questions in a questionnaire\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", - "operationId": "ListQuestions", - "parameters": [ - { - "name": "questionnaireId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true - } - ], - "responses": { - "200": { - "description": "ListQuestions 200 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ListQuestionsResponseContent" - } - } - } - }, - "401": { - "description": "UnauthorizedError 401 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UnauthorizedErrorResponseContent" - } - } - } - }, - "403": { - "description": "ForbiddenError 403 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ForbiddenErrorResponseContent" - } - } - } - }, "429": { "description": "RateLimitError 429 response", "content": { @@ -10788,7 +10259,7 @@ } }, "tags": [ - "Automation" + "Gauges" ], "x-basecamp-pagination": { "style": "link", @@ -10806,13 +10277,13 @@ } }, "post": { - "description": "Create a new question in a questionnaire", - "operationId": "CreateQuestion", + "description": "Create a gauge needle (progress update) for a project", + "operationId": "CreateGaugeNeedle", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateQuestionRequestContent" + "$ref": "#/components/schemas/CreateGaugeNeedleRequestContent" } } }, @@ -10820,7 +10291,7 @@ }, "parameters": [ { - "name": "questionnaireId", + "name": "projectId", "in": "path", "schema": { "type": "integer", @@ -10831,11 +10302,11 @@ ], "responses": { "201": { - "description": "CreateQuestion 201 response", + "description": "CreateGaugeNeedle 201 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateQuestionResponseContent" + "$ref": "#/components/schemas/CreateGaugeNeedleResponseContent" } } } @@ -10892,7 +10363,7 @@ } }, "tags": [ - "Automation" + "Gauges" ], "x-basecamp-retry": { "maxAttempts": 2, @@ -10905,13 +10376,13 @@ } } }, - "/questions/{questionId}": { + "/projects/{projectId}/people.json": { "get": { - "description": "Get a single question by id", - "operationId": "GetQuestion", + "description": "List all active people on a project\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", + "operationId": "ListProjectPeople", "parameters": [ { - "name": "questionId", + "name": "projectId", "in": "path", "schema": { "type": "integer", @@ -10922,11 +10393,11 @@ ], "responses": { "200": { - "description": "GetQuestion 200 response", + "description": "ListProjectPeople 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetQuestionResponseContent" + "$ref": "#/components/schemas/ListProjectPeopleResponseContent" } } } @@ -10951,12 +10422,12 @@ } } }, - "404": { - "description": "NotFoundError 404 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -10973,8 +10444,13 @@ } }, "tags": [ - "Automation" + "People" ], + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -10984,37 +10460,106 @@ 503 ] } - }, + } + }, + "/projects/{projectId}/people/users.json": { "put": { - "description": "Update an existing question", - "operationId": "UpdateQuestion", + "description": "Update project access (grant/revoke/create people)", + "operationId": "UpdateProjectAccess", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateQuestionRequestContent" + "$ref": "#/components/schemas/UpdateProjectAccessRequestContent" + }, + "examples": { + "UpdateProjectAccess_example1": { + "summary": "Grant access to existing users", + "description": "Use grant array with person IDs", + "value": { + "grant": [ + 111, + 222 + ] + } + }, + "UpdateProjectAccess_example2": { + "summary": "Revoke access", + "description": "Use revoke array to remove users", + "value": { + "revoke": [ + 333 + ] + } + }, + "UpdateProjectAccess_example3": { + "summary": "Invite new users", + "description": "Use create array for new users without accounts", + "value": { + "create": [ + { + "name": "Jane", + "email_address": "jane@example.com" + } + ] + } + } } } } }, "parameters": [ { - "name": "questionId", + "name": "projectId", "in": "path", "schema": { "type": "integer", "format": "int64" }, - "required": true + "required": true, + "examples": { + "UpdateProjectAccess_example1": { + "summary": "Grant access to existing users", + "description": "Use grant array with person IDs", + "value": 12345678 + }, + "UpdateProjectAccess_example2": { + "summary": "Revoke access", + "description": "Use revoke array to remove users", + "value": 12345678 + }, + "UpdateProjectAccess_example3": { + "summary": "Invite new users", + "description": "Use create array for new users without accounts", + "value": 12345678 + } + } } ], "responses": { "200": { - "description": "UpdateQuestion 200 response", + "description": "UpdateProjectAccess 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateQuestionResponseContent" + "$ref": "#/components/schemas/UpdateProjectAccessResponseContent" + }, + "examples": { + "UpdateProjectAccess_example1": { + "summary": "Grant access to existing users", + "description": "Use grant array with person IDs", + "value": {} + }, + "UpdateProjectAccess_example2": { + "summary": "Revoke access", + "description": "Use revoke array to remove users", + "value": {} + }, + "UpdateProjectAccess_example3": { + "summary": "Invite new users", + "description": "Use create array for new users without accounts", + "value": {} + } } } } @@ -11059,19 +10604,29 @@ } } }, - "500": { - "description": "InternalServerError 500 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/InternalServerErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" + } + } + } + }, + "500": { + "description": "InternalServerError 500 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InternalServerErrorResponseContent" } } } } }, "tags": [ - "Automation" + "People" ], "x-basecamp-idempotent": { "natural": true @@ -11087,13 +10642,13 @@ } } }, - "/questions/{questionId}/answers.json": { + "/projects/{projectId}/timeline.json": { "get": { - "description": "List all answers for a question\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", - "operationId": "ListAnswers", + "description": "Get project timeline", + "operationId": "GetProjectTimeline", "parameters": [ { - "name": "questionId", + "name": "projectId", "in": "path", "schema": { "type": "integer", @@ -11104,11 +10659,11 @@ ], "responses": { "200": { - "description": "ListAnswers 200 response", + "description": "GetProjectTimeline 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListAnswersResponseContent" + "$ref": "#/components/schemas/GetProjectTimelineResponseContent" } } } @@ -11133,6 +10688,16 @@ } } }, + "404": { + "description": "NotFoundError 404 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotFoundErrorResponseContent" + } + } + } + }, "429": { "description": "RateLimitError 429 response", "content": { @@ -11154,9 +10719,6 @@ } } }, - "tags": [ - "Automation" - ], "x-basecamp-pagination": { "style": "link", "totalCountHeader": "X-Total-Count", @@ -11171,38 +10733,52 @@ 503 ] } - }, - "post": { - "description": "Create a new answer for a question", - "operationId": "CreateAnswer", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/QuestionAnswerPayload" - } - } - }, - "required": true - }, + } + }, + "/projects/{projectId}/timesheet.json": { + "get": { + "description": "Get timesheet for a specific project", + "operationId": "GetProjectTimesheet", "parameters": [ { - "name": "questionId", + "name": "projectId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true + }, + { + "name": "from", + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "to", + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "person_id", + "in": "query", + "schema": { + "type": "integer", + "format": "int64" + } } ], "responses": { - "201": { - "description": "CreateAnswer 201 response", + "200": { + "description": "GetProjectTimesheet 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateAnswerResponseContent" + "$ref": "#/components/schemas/GetProjectTimesheetResponseContent" } } } @@ -11227,22 +10803,12 @@ } } }, - "422": { - "description": "ValidationError 422 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" - } - } - } - }, - "429": { - "description": "RateLimitError 429 response", + "404": { + "description": "NotFoundError 404 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" } } } @@ -11259,10 +10825,15 @@ } }, "tags": [ - "Automation" + "Schedule" ], + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + }, "x-basecamp-retry": { - "maxAttempts": 2, + "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -11272,13 +10843,13 @@ } } }, - "/questions/{questionId}/answers/by.json": { + "/question_answers/{answerId}": { "get": { - "description": "List all people who have answered a question (answerers)\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages.", - "operationId": "ListQuestionAnswerers", + "description": "Get a single answer by id", + "operationId": "GetAnswer", "parameters": [ { - "name": "questionId", + "name": "answerId", "in": "path", "schema": { "type": "integer", @@ -11289,11 +10860,11 @@ ], "responses": { "200": { - "description": "ListQuestionAnswerers 200 response", + "description": "GetAnswer 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListQuestionAnswerersResponseContent" + "$ref": "#/components/schemas/GetAnswerResponseContent" } } } @@ -11328,16 +10899,6 @@ } } }, - "429": { - "description": "RateLimitError 429 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" - } - } - } - }, "500": { "description": "InternalServerError 500 response", "content": { @@ -11349,10 +10910,9 @@ } } }, - "x-basecamp-pagination": { - "style": "link", - "maxPageSize": 50 - }, + "tags": [ + "Automation" + ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -11362,24 +10922,23 @@ 503 ] } - } - }, - "/questions/{questionId}/answers/by/{personId}": { - "get": { - "description": "Get all answers from a specific person for a question\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages.", - "operationId": "GetAnswersByPerson", - "parameters": [ - { - "name": "questionId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true + }, + "put": { + "description": "Update an existing answer", + "operationId": "UpdateAnswer", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/QuestionAnswerUpdatePayload" + } + } }, + "required": true + }, + "parameters": [ { - "name": "personId", + "name": "answerId", "in": "path", "schema": { "type": "integer", @@ -11389,15 +10948,8 @@ } ], "responses": { - "200": { - "description": "GetAnswersByPerson 200 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/GetAnswersByPersonResponseContent" - } - } - } + "204": { + "description": "UpdateAnswer 204 response" }, "401": { "description": "UnauthorizedError 401 response", @@ -11429,12 +10981,12 @@ } } }, - "429": { - "description": "RateLimitError 429 response", + "422": { + "description": "ValidationError 422 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" + "$ref": "#/components/schemas/ValidationErrorResponseContent" } } } @@ -11450,9 +11002,11 @@ } } }, - "x-basecamp-pagination": { - "style": "link", - "maxPageSize": 50 + "tags": [ + "Automation" + ], + "x-basecamp-idempotent": { + "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, @@ -11465,22 +11019,13 @@ } } }, - "/questions/{questionId}/notification_settings.json": { - "put": { - "description": "Update notification settings for a check-in question", - "operationId": "UpdateQuestionNotificationSettings", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateQuestionNotificationSettingsRequestContent" - } - } - } - }, + "/questionnaires/{questionnaireId}": { + "get": { + "description": "Get a questionnaire (automatic check-ins container) by id", + "operationId": "GetQuestionnaire", "parameters": [ { - "name": "questionId", + "name": "questionnaireId", "in": "path", "schema": { "type": "integer", @@ -11491,11 +11036,11 @@ ], "responses": { "200": { - "description": "UpdateQuestionNotificationSettings 200 response", + "description": "GetQuestionnaire 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateQuestionNotificationSettingsResponseContent" + "$ref": "#/components/schemas/GetQuestionnaireResponseContent" } } } @@ -11530,16 +11075,6 @@ } } }, - "422": { - "description": "ValidationError 422 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" - } - } - } - }, "500": { "description": "InternalServerError 500 response", "content": { @@ -11551,9 +11086,9 @@ } } }, - "x-basecamp-idempotent": { - "natural": true - }, + "tags": [ + "Automation" + ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -11565,13 +11100,13 @@ } } }, - "/questions/{questionId}/pause.json": { - "delete": { - "description": "Resume a paused check-in question (resumes sending reminders)", - "operationId": "ResumeQuestion", + "/questionnaires/{questionnaireId}/questions.json": { + "get": { + "description": "List all questions in a questionnaire\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", + "operationId": "ListQuestions", "parameters": [ { - "name": "questionId", + "name": "questionnaireId", "in": "path", "schema": { "type": "integer", @@ -11582,11 +11117,11 @@ ], "responses": { "200": { - "description": "ResumeQuestion 200 response", + "description": "ListQuestions 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ResumeQuestionResponseContent" + "$ref": "#/components/schemas/ListQuestionsResponseContent" } } } @@ -11611,12 +11146,12 @@ } } }, - "404": { - "description": "NotFoundError 404 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -11632,8 +11167,13 @@ } } }, - "x-basecamp-idempotent": { - "natural": true + "tags": [ + "Automation" + ], + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 }, "x-basecamp-retry": { "maxAttempts": 3, @@ -11646,11 +11186,21 @@ } }, "post": { - "description": "Pause a check-in question (stops sending reminders)", - "operationId": "PauseQuestion", + "description": "Create a new question in a questionnaire", + "operationId": "CreateQuestion", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateQuestionRequestContent" + } + } + }, + "required": true + }, "parameters": [ { - "name": "questionId", + "name": "questionnaireId", "in": "path", "schema": { "type": "integer", @@ -11660,12 +11210,12 @@ } ], "responses": { - "200": { - "description": "PauseQuestion 200 response", + "201": { + "description": "CreateQuestion 201 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PauseQuestionResponseContent" + "$ref": "#/components/schemas/CreateQuestionResponseContent" } } } @@ -11690,12 +11240,12 @@ } } }, - "404": { - "description": "NotFoundError 404 response", + "422": { + "description": "ValidationError 422 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/ValidationErrorResponseContent" } } } @@ -11721,11 +11271,11 @@ } } }, - "x-basecamp-idempotent": { - "natural": true - }, + "tags": [ + "Automation" + ], "x-basecamp-retry": { - "maxAttempts": 3, + "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -11735,13 +11285,13 @@ } } }, - "/recordings/{messageId}/pin.json": { - "delete": { - "description": "Unpin a message from the message board", - "operationId": "UnpinMessage", + "/questions/{questionId}": { + "get": { + "description": "Get a single question by id", + "operationId": "GetQuestion", "parameters": [ { - "name": "messageId", + "name": "questionId", "in": "path", "schema": { "type": "integer", @@ -11751,8 +11301,15 @@ } ], "responses": { - "204": { - "description": "UnpinMessage 204 response" + "200": { + "description": "GetQuestion 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetQuestionResponseContent" + } + } + } }, "401": { "description": "UnauthorizedError 401 response", @@ -11796,11 +11353,8 @@ } }, "tags": [ - "Messages" + "Automation" ], - "x-basecamp-idempotent": { - "natural": true - }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -11811,96 +11365,21 @@ ] } }, - "post": { - "description": "Pin a message to the top of the message board", - "operationId": "PinMessage", - "parameters": [ - { - "name": "messageId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true - } - ], - "responses": { - "204": { - "description": "PinMessage 204 response" - }, - "401": { - "description": "UnauthorizedError 401 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UnauthorizedErrorResponseContent" - } - } - } - }, - "403": { - "description": "ForbiddenError 403 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ForbiddenErrorResponseContent" - } - } - } - }, - "422": { - "description": "ValidationError 422 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" - } - } - } - }, - "429": { - "description": "RateLimitError 429 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" - } - } - } - }, - "500": { - "description": "InternalServerError 500 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/InternalServerErrorResponseContent" - } + "put": { + "description": "Update an existing question", + "operationId": "UpdateQuestion", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateQuestionRequestContent" } } } }, - "tags": [ - "Messages" - ], - "x-basecamp-retry": { - "maxAttempts": 2, - "baseDelayMs": 1000, - "backoff": "exponential", - "retryOn": [ - 429, - 503 - ] - } - } - }, - "/recordings/{recordingId}": { - "get": { - "description": "Get a single recording by id", - "operationId": "GetRecording", "parameters": [ { - "name": "recordingId", + "name": "questionId", "in": "path", "schema": { "type": "integer", @@ -11911,11 +11390,11 @@ ], "responses": { "200": { - "description": "GetRecording 200 response", + "description": "UpdateQuestion 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetRecordingResponseContent" + "$ref": "#/components/schemas/UpdateQuestionResponseContent" } } } @@ -11950,6 +11429,16 @@ } } }, + "422": { + "description": "ValidationError 422 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponseContent" + } + } + } + }, "500": { "description": "InternalServerError 500 response", "content": { @@ -11964,6 +11453,9 @@ "tags": [ "Automation" ], + "x-basecamp-idempotent": { + "natural": true + }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -11975,13 +11467,13 @@ } } }, - "/recordings/{recordingId}/boosts.json": { + "/questions/{questionId}/answers.json": { "get": { - "description": "List boosts on a recording", - "operationId": "ListRecordingBoosts", + "description": "List all answers for a question\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", + "operationId": "ListAnswers", "parameters": [ { - "name": "recordingId", + "name": "questionId", "in": "path", "schema": { "type": "integer", @@ -11992,11 +11484,11 @@ ], "responses": { "200": { - "description": "ListRecordingBoosts 200 response", + "description": "ListAnswers 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListRecordingBoostsResponseContent" + "$ref": "#/components/schemas/ListAnswersResponseContent" } } } @@ -12021,12 +11513,12 @@ } } }, - "404": { - "description": "NotFoundError 404 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -12043,7 +11535,7 @@ } }, "tags": [ - "Boosts" + "Automation" ], "x-basecamp-pagination": { "style": "link", @@ -12061,13 +11553,13 @@ } }, "post": { - "description": "Create a boost on a recording", - "operationId": "CreateRecordingBoost", + "description": "Create a new answer for a question", + "operationId": "CreateAnswer", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateRecordingBoostRequestContent" + "$ref": "#/components/schemas/QuestionAnswerPayload" } } }, @@ -12075,7 +11567,7 @@ }, "parameters": [ { - "name": "recordingId", + "name": "questionId", "in": "path", "schema": { "type": "integer", @@ -12086,11 +11578,11 @@ ], "responses": { "201": { - "description": "CreateRecordingBoost 201 response", + "description": "CreateAnswer 201 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateRecordingBoostResponseContent" + "$ref": "#/components/schemas/CreateAnswerResponseContent" } } } @@ -12147,7 +11639,7 @@ } }, "tags": [ - "Boosts" + "Automation" ], "x-basecamp-retry": { "maxAttempts": 2, @@ -12160,23 +11652,13 @@ } } }, - "/recordings/{recordingId}/client_visibility.json": { - "put": { - "description": "Set client visibility for a recording", - "operationId": "SetClientVisibility", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/SetClientVisibilityRequestContent" - } - } - }, - "required": true - }, + "/questions/{questionId}/answers/by.json": { + "get": { + "description": "List all people who have answered a question (answerers)\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages.", + "operationId": "ListQuestionAnswerers", "parameters": [ { - "name": "recordingId", + "name": "questionId", "in": "path", "schema": { "type": "integer", @@ -12187,11 +11669,11 @@ ], "responses": { "200": { - "description": "SetClientVisibility 200 response", + "description": "ListQuestionAnswerers 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SetClientVisibilityResponseContent" + "$ref": "#/components/schemas/ListQuestionAnswerersResponseContent" } } } @@ -12226,12 +11708,12 @@ } } }, - "422": { - "description": "ValidationError 422 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -12247,11 +11729,9 @@ } } }, - "tags": [ - "ClientFeatures" - ], - "x-basecamp-idempotent": { - "natural": true + "x-basecamp-pagination": { + "style": "link", + "maxPageSize": 50 }, "x-basecamp-retry": { "maxAttempts": 3, @@ -12264,13 +11744,22 @@ } } }, - "/recordings/{recordingId}/comments.json": { + "/questions/{questionId}/answers/by/{personId}": { "get": { - "description": "List comments on a recording\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", - "operationId": "ListComments", + "description": "Get all answers from a specific person for a question\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages.", + "operationId": "GetAnswersByPerson", "parameters": [ { - "name": "recordingId", + "name": "questionId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true + }, + { + "name": "personId", "in": "path", "schema": { "type": "integer", @@ -12281,11 +11770,11 @@ ], "responses": { "200": { - "description": "ListComments 200 response", + "description": "GetAnswersByPerson 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListCommentsResponseContent" + "$ref": "#/components/schemas/GetAnswersByPersonResponseContent" } } } @@ -12310,6 +11799,16 @@ } } }, + "404": { + "description": "NotFoundError 404 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotFoundErrorResponseContent" + } + } + } + }, "429": { "description": "RateLimitError 429 response", "content": { @@ -12331,12 +11830,8 @@ } } }, - "tags": [ - "Messages" - ], "x-basecamp-pagination": { "style": "link", - "totalCountHeader": "X-Total-Count", "maxPageSize": 50 }, "x-basecamp-retry": { @@ -12348,23 +11843,24 @@ 503 ] } - }, - "post": { - "description": "Create a new comment on a recording", - "operationId": "CreateComment", + } + }, + "/questions/{questionId}/notification_settings.json": { + "put": { + "description": "Update notification settings for a check-in question", + "operationId": "UpdateQuestionNotificationSettings", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateCommentRequestContent" + "$ref": "#/components/schemas/UpdateQuestionNotificationSettingsRequestContent" } } - }, - "required": true + } }, "parameters": [ { - "name": "recordingId", + "name": "questionId", "in": "path", "schema": { "type": "integer", @@ -12374,12 +11870,12 @@ } ], "responses": { - "201": { - "description": "CreateComment 201 response", + "200": { + "description": "UpdateQuestionNotificationSettings 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateCommentResponseContent" + "$ref": "#/components/schemas/UpdateQuestionNotificationSettingsResponseContent" } } } @@ -12404,22 +11900,22 @@ } } }, - "422": { - "description": "ValidationError 422 response", + "404": { + "description": "NotFoundError 404 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" } } } }, - "429": { - "description": "RateLimitError 429 response", + "422": { + "description": "ValidationError 422 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" + "$ref": "#/components/schemas/ValidationErrorResponseContent" } } } @@ -12435,11 +11931,11 @@ } } }, - "tags": [ - "Messages" - ], + "x-basecamp-idempotent": { + "natural": true + }, "x-basecamp-retry": { - "maxAttempts": 2, + "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -12449,13 +11945,13 @@ } } }, - "/recordings/{recordingId}/events.json": { - "get": { - "description": "List all events for a recording\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", - "operationId": "ListEvents", + "/questions/{questionId}/pause.json": { + "delete": { + "description": "Resume a paused check-in question (resumes sending reminders)", + "operationId": "ResumeQuestion", "parameters": [ { - "name": "recordingId", + "name": "questionId", "in": "path", "schema": { "type": "integer", @@ -12466,11 +11962,11 @@ ], "responses": { "200": { - "description": "ListEvents 200 response", + "description": "ResumeQuestion 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListEventsResponseContent" + "$ref": "#/components/schemas/ResumeQuestionResponseContent" } } } @@ -12495,12 +11991,12 @@ } } }, - "429": { - "description": "RateLimitError 429 response", + "404": { + "description": "NotFoundError 404 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" } } } @@ -12516,13 +12012,8 @@ } } }, - "tags": [ - "Automation" - ], - "x-basecamp-pagination": { - "style": "link", - "totalCountHeader": "X-Total-Count", - "maxPageSize": 50 + "x-basecamp-idempotent": { + "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, @@ -12533,24 +12024,13 @@ 503 ] } - } - }, - "/recordings/{recordingId}/events/{eventId}/boosts.json": { - "get": { - "description": "List boosts on a specific event within a recording", - "operationId": "ListEventBoosts", + }, + "post": { + "description": "Pause a check-in question (stops sending reminders)", + "operationId": "PauseQuestion", "parameters": [ { - "name": "recordingId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true - }, - { - "name": "eventId", + "name": "questionId", "in": "path", "schema": { "type": "integer", @@ -12561,11 +12041,11 @@ ], "responses": { "200": { - "description": "ListEventBoosts 200 response", + "description": "PauseQuestion 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListEventBoostsResponseContent" + "$ref": "#/components/schemas/PauseQuestionResponseContent" } } } @@ -12600,6 +12080,16 @@ } } }, + "429": { + "description": "RateLimitError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RateLimitErrorResponseContent" + } + } + } + }, "500": { "description": "InternalServerError 500 response", "content": { @@ -12611,13 +12101,8 @@ } } }, - "tags": [ - "Boosts" - ], - "x-basecamp-pagination": { - "style": "link", - "totalCountHeader": "X-Total-Count", - "maxPageSize": 50 + "x-basecamp-idempotent": { + "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, @@ -12628,32 +12113,15 @@ 503 ] } - }, - "post": { - "description": "Create a boost on a specific event within a recording", - "operationId": "CreateEventBoost", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateEventBoostRequestContent" - } - } - }, - "required": true - }, + } + }, + "/recordings/{messageId}/pin.json": { + "delete": { + "description": "Unpin a message from the message board", + "operationId": "UnpinMessage", "parameters": [ { - "name": "recordingId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true - }, - { - "name": "eventId", + "name": "messageId", "in": "path", "schema": { "type": "integer", @@ -12663,15 +12131,8 @@ } ], "responses": { - "201": { - "description": "CreateEventBoost 201 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateEventBoostResponseContent" - } - } - } + "204": { + "description": "UnpinMessage 204 response" }, "401": { "description": "UnauthorizedError 401 response", @@ -12693,22 +12154,12 @@ } } }, - "422": { - "description": "ValidationError 422 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" - } - } - } - }, - "429": { - "description": "RateLimitError 429 response", + "404": { + "description": "NotFoundError 404 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" } } } @@ -12725,10 +12176,13 @@ } }, "tags": [ - "Boosts" + "Messages" ], + "x-basecamp-idempotent": { + "natural": true + }, "x-basecamp-retry": { - "maxAttempts": 2, + "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -12736,15 +12190,13 @@ 503 ] } - } - }, - "/recordings/{recordingId}/status/active.json": { - "put": { - "description": "Unarchive a recording (restore to active status)", - "operationId": "UnarchiveRecording", + }, + "post": { + "description": "Pin a message to the top of the message board", + "operationId": "PinMessage", "parameters": [ { - "name": "recordingId", + "name": "messageId", "in": "path", "schema": { "type": "integer", @@ -12755,7 +12207,7 @@ ], "responses": { "204": { - "description": "UnarchiveRecording 204 response" + "description": "PinMessage 204 response" }, "401": { "description": "UnauthorizedError 401 response", @@ -12777,22 +12229,22 @@ } } }, - "404": { - "description": "NotFoundError 404 response", + "422": { + "description": "ValidationError 422 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/ValidationErrorResponseContent" } } } }, - "422": { - "description": "ValidationError 422 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -12809,13 +12261,10 @@ } }, "tags": [ - "Automation" + "Messages" ], - "x-basecamp-idempotent": { - "natural": true - }, "x-basecamp-retry": { - "maxAttempts": 3, + "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -12825,10 +12274,10 @@ } } }, - "/recordings/{recordingId}/status/archived.json": { - "put": { - "description": "Archive a recording", - "operationId": "ArchiveRecording", + "/recordings/{recordingId}": { + "get": { + "description": "Get a single recording by id", + "operationId": "GetRecording", "parameters": [ { "name": "recordingId", @@ -12841,8 +12290,15 @@ } ], "responses": { - "204": { - "description": "ArchiveRecording 204 response" + "200": { + "description": "GetRecording 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetRecordingResponseContent" + } + } + } }, "401": { "description": "UnauthorizedError 401 response", @@ -12874,16 +12330,6 @@ } } }, - "422": { - "description": "ValidationError 422 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" - } - } - } - }, "500": { "description": "InternalServerError 500 response", "content": { @@ -12898,9 +12344,6 @@ "tags": [ "Automation" ], - "x-basecamp-idempotent": { - "natural": true - }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -12912,10 +12355,10 @@ } } }, - "/recordings/{recordingId}/status/trashed.json": { - "put": { - "description": "Trash a recording", - "operationId": "TrashRecording", + "/recordings/{recordingId}/boosts.json": { + "get": { + "description": "List boosts on a recording", + "operationId": "ListRecordingBoosts", "parameters": [ { "name": "recordingId", @@ -12924,19 +12367,19 @@ "type": "integer", "format": "int64" }, - "required": true, - "examples": { - "TrashRecording_example1": { - "summary": "Trash any recording type", - "description": "Works on comments, messages, documents, cards - any recording", - "value": 555666 - } - } + "required": true } ], "responses": { - "204": { - "description": "TrashRecording 204 response" + "200": { + "description": "ListRecordingBoosts 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListRecordingBoostsResponseContent" + } + } + } }, "401": { "description": "UnauthorizedError 401 response", @@ -12968,6 +12411,90 @@ } } }, + "500": { + "description": "InternalServerError 500 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InternalServerErrorResponseContent" + } + } + } + } + }, + "tags": [ + "Boosts" + ], + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + }, + "x-basecamp-retry": { + "maxAttempts": 3, + "baseDelayMs": 1000, + "backoff": "exponential", + "retryOn": [ + 429, + 503 + ] + } + }, + "post": { + "description": "Create a boost on a recording", + "operationId": "CreateRecordingBoost", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateRecordingBoostRequestContent" + } + } + }, + "required": true + }, + "parameters": [ + { + "name": "recordingId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true + } + ], + "responses": { + "201": { + "description": "CreateRecordingBoost 201 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateRecordingBoostResponseContent" + } + } + } + }, + "401": { + "description": "UnauthorizedError 401 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnauthorizedErrorResponseContent" + } + } + } + }, + "403": { + "description": "ForbiddenError 403 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + } + } + } + }, "422": { "description": "ValidationError 422 response", "content": { @@ -12978,6 +12505,16 @@ } } }, + "429": { + "description": "RateLimitError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RateLimitErrorResponseContent" + } + } + } + }, "500": { "description": "InternalServerError 500 response", "content": { @@ -12990,13 +12527,10 @@ } }, "tags": [ - "Automation" + "Boosts" ], - "x-basecamp-idempotent": { - "natural": true - }, "x-basecamp-retry": { - "maxAttempts": 3, + "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -13006,10 +12540,20 @@ } } }, - "/recordings/{recordingId}/subscription.json": { - "delete": { - "description": "Unsubscribe the current user from a recording", - "operationId": "Unsubscribe", + "/recordings/{recordingId}/client_visibility.json": { + "put": { + "description": "Set client visibility for a recording", + "operationId": "SetClientVisibility", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SetClientVisibilityRequestContent" + } + } + }, + "required": true + }, "parameters": [ { "name": "recordingId", @@ -13022,8 +12566,15 @@ } ], "responses": { - "204": { - "description": "Unsubscribe 204 response" + "200": { + "description": "SetClientVisibility 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SetClientVisibilityResponseContent" + } + } + } }, "401": { "description": "UnauthorizedError 401 response", @@ -13055,6 +12606,16 @@ } } }, + "422": { + "description": "ValidationError 422 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponseContent" + } + } + } + }, "500": { "description": "InternalServerError 500 response", "content": { @@ -13067,7 +12628,7 @@ } }, "tags": [ - "People" + "ClientFeatures" ], "x-basecamp-idempotent": { "natural": true @@ -13081,10 +12642,12 @@ 503 ] } - }, + } + }, + "/recordings/{recordingId}/comments.json": { "get": { - "description": "Get subscription information for a recording", - "operationId": "GetSubscription", + "description": "List comments on a recording\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", + "operationId": "ListComments", "parameters": [ { "name": "recordingId", @@ -13098,11 +12661,11 @@ ], "responses": { "200": { - "description": "GetSubscription 200 response", + "description": "ListComments 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetSubscriptionResponseContent" + "$ref": "#/components/schemas/ListCommentsResponseContent" } } } @@ -13127,12 +12690,12 @@ } } }, - "404": { - "description": "NotFoundError 404 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -13149,8 +12712,13 @@ } }, "tags": [ - "People" + "Messages" ], + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -13162,8 +12730,18 @@ } }, "post": { - "description": "Subscribe the current user to a recording", - "operationId": "Subscribe", + "description": "Create a new comment on a recording", + "operationId": "CreateComment", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateCommentRequestContent" + } + } + }, + "required": true + }, "parameters": [ { "name": "recordingId", @@ -13176,12 +12754,12 @@ } ], "responses": { - "200": { - "description": "Subscribe 200 response", + "201": { + "description": "CreateComment 201 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SubscribeResponseContent" + "$ref": "#/components/schemas/CreateCommentResponseContent" } } } @@ -13238,7 +12816,7 @@ } }, "tags": [ - "People" + "Messages" ], "x-basecamp-retry": { "maxAttempts": 2, @@ -13249,40 +12827,12 @@ 503 ] } - }, - "put": { - "description": "Update subscriptions by adding or removing specific users", - "operationId": "UpdateSubscription", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateSubscriptionRequestContent" - }, - "examples": { - "UpdateSubscription_example1": { - "summary": "Add subscribers", - "description": "", - "value": { - "subscriptions": [ - 111, - 222 - ] - } - }, - "UpdateSubscription_example2": { - "summary": "Remove subscribers", - "description": "", - "value": { - "unsubscriptions": [ - 333 - ] - } - } - } - } - } - }, + } + }, + "/recordings/{recordingId}/events.json": { + "get": { + "description": "List all events for a recording\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", + "operationId": "ListEvents", "parameters": [ { "name": "recordingId", @@ -13291,40 +12841,16 @@ "type": "integer", "format": "int64" }, - "required": true, - "examples": { - "UpdateSubscription_example1": { - "summary": "Add subscribers", - "description": "", - "value": 987654 - }, - "UpdateSubscription_example2": { - "summary": "Remove subscribers", - "description": "", - "value": 987654 - } - } + "required": true } ], "responses": { "200": { - "description": "UpdateSubscription 200 response", + "description": "ListEvents 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateSubscriptionResponseContent" - }, - "examples": { - "UpdateSubscription_example1": { - "summary": "Add subscribers", - "description": "", - "value": {} - }, - "UpdateSubscription_example2": { - "summary": "Remove subscribers", - "description": "", - "value": {} - } + "$ref": "#/components/schemas/ListEventsResponseContent" } } } @@ -13349,22 +12875,12 @@ } } }, - "404": { - "description": "NotFoundError 404 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" - } - } - } - }, - "422": { - "description": "ValidationError 422 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -13381,10 +12897,12 @@ } }, "tags": [ - "People" + "Automation" ], - "x-basecamp-idempotent": { - "natural": true + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 }, "x-basecamp-retry": { "maxAttempts": 3, @@ -13397,10 +12915,10 @@ } } }, - "/recordings/{recordingId}/timesheet.json": { + "/recordings/{recordingId}/events/{eventId}/boosts.json": { "get": { - "description": "Get timesheet for a specific recording", - "operationId": "GetRecordingTimesheet", + "description": "List boosts on a specific event within a recording", + "operationId": "ListEventBoosts", "parameters": [ { "name": "recordingId", @@ -13412,35 +12930,22 @@ "required": true }, { - "name": "from", - "in": "query", - "schema": { - "type": "string" - } - }, - { - "name": "to", - "in": "query", - "schema": { - "type": "string" - } - }, - { - "name": "person_id", - "in": "query", + "name": "eventId", + "in": "path", "schema": { "type": "integer", "format": "int64" - } + }, + "required": true } ], "responses": { "200": { - "description": "GetRecordingTimesheet 200 response", + "description": "ListEventBoosts 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetRecordingTimesheetResponseContent" + "$ref": "#/components/schemas/ListEventBoostsResponseContent" } } } @@ -13487,7 +12992,7 @@ } }, "tags": [ - "Schedule" + "Boosts" ], "x-basecamp-pagination": { "style": "link", @@ -13503,17 +13008,15 @@ 503 ] } - } - }, - "/recordings/{recordingId}/timesheet/entries.json": { + }, "post": { - "description": "Create a timesheet entry on a recording", - "operationId": "CreateTimesheetEntry", + "description": "Create a boost on a specific event within a recording", + "operationId": "CreateEventBoost", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateTimesheetEntryRequestContent" + "$ref": "#/components/schemas/CreateEventBoostRequestContent" } } }, @@ -13528,15 +13031,24 @@ "format": "int64" }, "required": true + }, + { + "name": "eventId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true } ], "responses": { "201": { - "description": "CreateTimesheetEntry 201 response", + "description": "CreateEventBoost 201 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateTimesheetEntryResponseContent" + "$ref": "#/components/schemas/CreateEventBoostResponseContent" } } } @@ -13593,10 +13105,10 @@ } }, "tags": [ - "Schedule" + "Boosts" ], "x-basecamp-retry": { - "maxAttempts": 3, + "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -13606,13 +13118,13 @@ } } }, - "/recordings/{toolId}/position.json": { - "delete": { - "description": "Disable a tool (hide it from the project dock)", - "operationId": "DisableTool", + "/recordings/{recordingId}/status/active.json": { + "put": { + "description": "Unarchive a recording (restore to active status)", + "operationId": "UnarchiveRecording", "parameters": [ { - "name": "toolId", + "name": "recordingId", "in": "path", "schema": { "type": "integer", @@ -13623,7 +13135,7 @@ ], "responses": { "204": { - "description": "DisableTool 204 response" + "description": "UnarchiveRecording 204 response" }, "401": { "description": "UnauthorizedError 401 response", @@ -13655,6 +13167,16 @@ } } }, + "422": { + "description": "ValidationError 422 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponseContent" + } + } + } + }, "500": { "description": "InternalServerError 500 response", "content": { @@ -13681,13 +13203,15 @@ 503 ] } - }, - "post": { - "description": "Enable a tool (show it on the project dock)", - "operationId": "EnableTool", + } + }, + "/recordings/{recordingId}/status/archived.json": { + "put": { + "description": "Archive a recording", + "operationId": "ArchiveRecording", "parameters": [ { - "name": "toolId", + "name": "recordingId", "in": "path", "schema": { "type": "integer", @@ -13697,8 +13221,8 @@ } ], "responses": { - "201": { - "description": "EnableTool 201 response" + "204": { + "description": "ArchiveRecording 204 response" }, "401": { "description": "UnauthorizedError 401 response", @@ -13720,22 +13244,22 @@ } } }, - "422": { - "description": "ValidationError 422 response", + "404": { + "description": "NotFoundError 404 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" } } } }, - "429": { - "description": "RateLimitError 429 response", + "422": { + "description": "ValidationError 422 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" + "$ref": "#/components/schemas/ValidationErrorResponseContent" } } } @@ -13754,8 +13278,11 @@ "tags": [ "Automation" ], + "x-basecamp-idempotent": { + "natural": true + }, "x-basecamp-retry": { - "maxAttempts": 2, + "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -13763,34 +13290,33 @@ 503 ] } - }, + } + }, + "/recordings/{recordingId}/status/trashed.json": { "put": { - "description": "Reposition a tool on the project dock", - "operationId": "RepositionTool", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/RepositionToolRequestContent" - } - } - }, - "required": true - }, + "description": "Trash a recording", + "operationId": "TrashRecording", "parameters": [ { - "name": "toolId", + "name": "recordingId", "in": "path", "schema": { "type": "integer", "format": "int64" }, - "required": true + "required": true, + "examples": { + "TrashRecording_example1": { + "summary": "Trash any recording type", + "description": "Works on comments, messages, documents, cards - any recording", + "value": 555666 + } + } } ], "responses": { - "200": { - "description": "RepositionTool 200 response" + "204": { + "description": "TrashRecording 204 response" }, "401": { "description": "UnauthorizedError 401 response", @@ -13860,31 +13386,24 @@ } } }, - "/reports/gauges.json": { - "get": { - "description": "List gauges across all projects the authenticated user has access to.\nGauges are sorted by risk level (red, yellow, green), then alphabetically.", - "operationId": "ListGauges", + "/recordings/{recordingId}/subscription.json": { + "delete": { + "description": "Unsubscribe the current user from a recording", + "operationId": "Unsubscribe", "parameters": [ { - "name": "bucket_ids", - "in": "query", - "description": "Comma-separated list of project IDs. When provided, results are returned\nin the order specified instead of by risk level.", + "name": "recordingId", + "in": "path", "schema": { - "type": "string", - "description": "Comma-separated list of project IDs. When provided, results are returned\nin the order specified instead of by risk level." - } + "type": "integer", + "format": "int64" + }, + "required": true } ], "responses": { - "200": { - "description": "ListGauges 200 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ListGaugesResponseContent" - } - } - } + "204": { + "description": "Unsubscribe 204 response" }, "401": { "description": "UnauthorizedError 401 response", @@ -13906,12 +13425,12 @@ } } }, - "429": { - "description": "RateLimitError 429 response", + "404": { + "description": "NotFoundError 404 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" } } } @@ -13928,12 +13447,10 @@ } }, "tags": [ - "Gauges" + "People" ], - "x-basecamp-pagination": { - "style": "link", - "totalCountHeader": "X-Total-Count", - "maxPageSize": 50 + "x-basecamp-idempotent": { + "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, @@ -13944,20 +13461,28 @@ 503 ] } - } - }, - "/reports/progress.json": { + }, "get": { - "description": "Get account-wide activity feed (progress report)", - "operationId": "GetProgressReport", - "parameters": [], + "description": "Get subscription information for a recording", + "operationId": "GetSubscription", + "parameters": [ + { + "name": "recordingId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true + } + ], "responses": { "200": { - "description": "GetProgressReport 200 response", + "description": "GetSubscription 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetProgressReportResponseContent" + "$ref": "#/components/schemas/GetSubscriptionResponseContent" } } } @@ -13982,12 +13507,12 @@ } } }, - "429": { - "description": "RateLimitError 429 response", + "404": { + "description": "NotFoundError 404 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" } } } @@ -14003,11 +13528,9 @@ } } }, - "x-basecamp-pagination": { - "style": "link", - "totalCountHeader": "X-Total-Count", - "maxPageSize": 50 - }, + "tags": [ + "People" + ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -14017,35 +13540,28 @@ 503 ] } - } - }, - "/reports/schedules/upcoming.json": { - "get": { - "description": "Get upcoming schedule entries and assignable items within a date window.\nThis endpoint is preserved as the canonical API path on BC5;\nthe BC5 `/calendar` web view is HTML-only.", - "operationId": "GetUpcomingSchedule", + }, + "post": { + "description": "Subscribe the current user to a recording", + "operationId": "Subscribe", "parameters": [ { - "name": "window_starts_on", - "in": "query", - "schema": { - "type": "string" - } - }, - { - "name": "window_ends_on", - "in": "query", + "name": "recordingId", + "in": "path", "schema": { - "type": "string" - } + "type": "integer", + "format": "int64" + }, + "required": true } ], "responses": { "200": { - "description": "GetUpcomingSchedule 200 response", + "description": "Subscribe 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetUpcomingScheduleResponseContent" + "$ref": "#/components/schemas/SubscribeResponseContent" } } } @@ -14070,6 +13586,16 @@ } } }, + "422": { + "description": "ValidationError 422 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponseContent" + } + } + } + }, "429": { "description": "RateLimitError 429 response", "content": { @@ -14091,8 +13617,11 @@ } } }, + "tags": [ + "People" + ], "x-basecamp-retry": { - "maxAttempts": 3, + "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -14100,43 +13629,82 @@ 503 ] } - } - }, - "/reports/timesheet.json": { - "get": { - "description": "Get account-wide timesheet report", - "operationId": "GetTimesheetReport", - "parameters": [ - { - "name": "from", - "in": "query", - "schema": { - "type": "string" - } - }, - { - "name": "to", - "in": "query", - "schema": { - "type": "string" + }, + "put": { + "description": "Update subscriptions by adding or removing specific users", + "operationId": "UpdateSubscription", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateSubscriptionRequestContent" + }, + "examples": { + "UpdateSubscription_example1": { + "summary": "Add subscribers", + "description": "", + "value": { + "subscriptions": [ + 111, + 222 + ] + } + }, + "UpdateSubscription_example2": { + "summary": "Remove subscribers", + "description": "", + "value": { + "unsubscriptions": [ + 333 + ] + } + } + } } - }, + } + }, + "parameters": [ { - "name": "person_id", - "in": "query", + "name": "recordingId", + "in": "path", "schema": { "type": "integer", "format": "int64" + }, + "required": true, + "examples": { + "UpdateSubscription_example1": { + "summary": "Add subscribers", + "description": "", + "value": 987654 + }, + "UpdateSubscription_example2": { + "summary": "Remove subscribers", + "description": "", + "value": 987654 + } } } ], "responses": { "200": { - "description": "GetTimesheetReport 200 response", + "description": "UpdateSubscription 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetTimesheetReportResponseContent" + "$ref": "#/components/schemas/UpdateSubscriptionResponseContent" + }, + "examples": { + "UpdateSubscription_example1": { + "summary": "Add subscribers", + "description": "", + "value": {} + }, + "UpdateSubscription_example2": { + "summary": "Remove subscribers", + "description": "", + "value": {} + } } } } @@ -14171,6 +13739,16 @@ } } }, + "422": { + "description": "ValidationError 422 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponseContent" + } + } + } + }, "500": { "description": "InternalServerError 500 response", "content": { @@ -14183,8 +13761,11 @@ } }, "tags": [ - "Schedule" + "People" ], + "x-basecamp-idempotent": { + "natural": true + }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -14196,18 +13777,50 @@ } } }, - "/reports/todos/assigned.json": { + "/recordings/{recordingId}/timesheet.json": { "get": { - "description": "List people who can be assigned todos", - "operationId": "ListAssignablePeople", - "parameters": [], + "description": "Get timesheet for a specific recording", + "operationId": "GetRecordingTimesheet", + "parameters": [ + { + "name": "recordingId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true + }, + { + "name": "from", + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "to", + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "person_id", + "in": "query", + "schema": { + "type": "integer", + "format": "int64" + } + } + ], "responses": { "200": { - "description": "ListAssignablePeople 200 response", + "description": "GetRecordingTimesheet 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListAssignablePeopleResponseContent" + "$ref": "#/components/schemas/GetRecordingTimesheetResponseContent" } } } @@ -14232,12 +13845,12 @@ } } }, - "429": { - "description": "RateLimitError 429 response", + "404": { + "description": "NotFoundError 404 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" } } } @@ -14253,48 +13866,57 @@ } } }, - "x-basecamp-retry": { - "maxAttempts": 3, - "baseDelayMs": 1000, - "backoff": "exponential", - "retryOn": [ - 429, + "tags": [ + "Schedule" + ], + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + }, + "x-basecamp-retry": { + "maxAttempts": 3, + "baseDelayMs": 1000, + "backoff": "exponential", + "retryOn": [ + 429, 503 ] } } }, - "/reports/todos/assigned/{personId}": { - "get": { - "description": "Get todos assigned to a specific person", - "operationId": "GetAssignedTodos", + "/recordings/{recordingId}/timesheet/entries.json": { + "post": { + "description": "Create a timesheet entry on a recording", + "operationId": "CreateTimesheetEntry", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateTimesheetEntryRequestContent" + } + } + }, + "required": true + }, "parameters": [ { - "name": "personId", + "name": "recordingId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true - }, - { - "name": "group_by", - "in": "query", - "description": "Group by \"bucket\" or \"date\"", - "schema": { - "type": "string", - "description": "Group by \"bucket\" or \"date\"" - } } ], "responses": { - "200": { - "description": "GetAssignedTodos 200 response", + "201": { + "description": "CreateTimesheetEntry 201 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetAssignedTodosResponseContent" + "$ref": "#/components/schemas/CreateTimesheetEntryResponseContent" } } } @@ -14319,12 +13941,12 @@ } } }, - "404": { - "description": "NotFoundError 404 response", + "422": { + "description": "ValidationError 422 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/ValidationErrorResponseContent" } } } @@ -14350,6 +13972,9 @@ } } }, + "tags": [ + "Schedule" + ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -14361,21 +13986,24 @@ } } }, - "/reports/todos/overdue.json": { - "get": { - "description": "Get overdue todos grouped by lateness", - "operationId": "GetOverdueTodos", - "parameters": [], + "/recordings/{toolId}/position.json": { + "delete": { + "description": "Disable a tool (hide it from the project dock)", + "operationId": "DisableTool", + "parameters": [ + { + "name": "toolId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true + } + ], "responses": { - "200": { - "description": "GetOverdueTodos 200 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/GetOverdueTodosResponseContent" - } - } - } + "204": { + "description": "DisableTool 204 response" }, "401": { "description": "UnauthorizedError 401 response", @@ -14397,12 +14025,12 @@ } } }, - "429": { - "description": "RateLimitError 429 response", + "404": { + "description": "NotFoundError 404 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" } } } @@ -14418,6 +14046,12 @@ } } }, + "tags": [ + "Automation" + ], + "x-basecamp-idempotent": { + "natural": true + }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -14427,15 +14061,13 @@ 503 ] } - } - }, - "/reports/users/progress/{personId}.json": { - "get": { - "description": "Get a person's activity timeline", - "operationId": "GetPersonProgress", + }, + "post": { + "description": "Enable a tool (show it on the project dock)", + "operationId": "EnableTool", "parameters": [ { - "name": "personId", + "name": "toolId", "in": "path", "schema": { "type": "integer", @@ -14445,15 +14077,8 @@ } ], "responses": { - "200": { - "description": "GetPersonProgress 200 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/GetPersonProgressResponseContent" - } - } - } + "201": { + "description": "EnableTool 201 response" }, "401": { "description": "UnauthorizedError 401 response", @@ -14475,12 +14100,12 @@ } } }, - "404": { - "description": "NotFoundError 404 response", + "422": { + "description": "ValidationError 422 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/ValidationErrorResponseContent" } } } @@ -14506,14 +14131,11 @@ } } }, - "x-basecamp-pagination": { - "style": "link", - "totalCountHeader": "X-Total-Count", - "maxPageSize": 50, - "key": "events" - }, + "tags": [ + "Automation" + ], "x-basecamp-retry": { - "maxAttempts": 3, + "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -14521,15 +14143,23 @@ 503 ] } - } - }, - "/schedule_entries/{entryId}": { - "get": { - "description": "Get a single schedule entry by id.\nNote: Recurring entries will redirect (302) to their recordable URL.\nUse GetScheduleEntryOccurrence for recurring entries instead.", - "operationId": "GetScheduleEntry", + }, + "put": { + "description": "Reposition a tool on the project dock", + "operationId": "RepositionTool", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RepositionToolRequestContent" + } + } + }, + "required": true + }, "parameters": [ { - "name": "entryId", + "name": "toolId", "in": "path", "schema": { "type": "integer", @@ -14540,14 +14170,7 @@ ], "responses": { "200": { - "description": "GetScheduleEntry 200 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/GetScheduleEntryResponseContent" - } - } - } + "description": "RepositionTool 200 response" }, "401": { "description": "UnauthorizedError 401 response", @@ -14579,6 +14202,16 @@ } } }, + "422": { + "description": "ValidationError 422 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponseContent" + } + } + } + }, "500": { "description": "InternalServerError 500 response", "content": { @@ -14591,8 +14224,11 @@ } }, "tags": [ - "Schedule" + "Automation" ], + "x-basecamp-idempotent": { + "natural": true + }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -14602,37 +14238,30 @@ 503 ] } - }, - "put": { - "description": "Update an existing schedule entry", - "operationId": "UpdateScheduleEntry", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateScheduleEntryRequestContent" - } - } - } - }, + } + }, + "/reports/gauges.json": { + "get": { + "description": "List gauges across all projects the authenticated user has access to.\nGauges are sorted by risk level (red, yellow, green), then alphabetically.", + "operationId": "ListGauges", "parameters": [ { - "name": "entryId", - "in": "path", + "name": "bucket_ids", + "in": "query", + "description": "Comma-separated list of project IDs. When provided, results are returned\nin the order specified instead of by risk level.", "schema": { - "type": "integer", - "format": "int64" - }, - "required": true + "type": "string", + "description": "Comma-separated list of project IDs. When provided, results are returned\nin the order specified instead of by risk level." + } } ], "responses": { "200": { - "description": "UpdateScheduleEntry 200 response", + "description": "ListGauges 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateScheduleEntryResponseContent" + "$ref": "#/components/schemas/ListGaugesResponseContent" } } } @@ -14657,22 +14286,12 @@ } } }, - "404": { - "description": "NotFoundError 404 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" - } - } - } - }, - "422": { - "description": "ValidationError 422 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -14689,10 +14308,12 @@ } }, "tags": [ - "Schedule" + "Gauges" ], - "x-basecamp-idempotent": { - "natural": true + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 }, "x-basecamp-retry": { "maxAttempts": 3, @@ -14705,36 +14326,18 @@ } } }, - "/schedule_entries/{entryId}/occurrences/{date}": { + "/reports/progress.json": { "get": { - "description": "Get a specific occurrence of a recurring schedule entry", - "operationId": "GetScheduleEntryOccurrence", - "parameters": [ - { - "name": "entryId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true - }, - { - "name": "date", - "in": "path", - "schema": { - "type": "string" - }, - "required": true - } - ], + "description": "Get account-wide activity feed (progress report)", + "operationId": "GetProgressReport", + "parameters": [], "responses": { "200": { - "description": "GetScheduleEntryOccurrence 200 response", + "description": "GetProgressReport 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetScheduleEntryOccurrenceResponseContent" + "$ref": "#/components/schemas/GetProgressReportResponseContent" } } } @@ -14759,12 +14362,12 @@ } } }, - "404": { - "description": "NotFoundError 404 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -14780,9 +14383,11 @@ } } }, - "tags": [ - "Schedule" - ], + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -14794,28 +14399,33 @@ } } }, - "/schedules/{scheduleId}": { + "/reports/schedules/upcoming.json": { "get": { - "description": "Get a schedule", - "operationId": "GetSchedule", + "description": "Get upcoming schedule entries and assignable items within a date window.\nThis endpoint is preserved as the canonical API path on BC5;\nthe BC5 `/calendar` web view is HTML-only.", + "operationId": "GetUpcomingSchedule", "parameters": [ { - "name": "scheduleId", - "in": "path", + "name": "window_starts_on", + "in": "query", "schema": { - "type": "integer", - "format": "int64" - }, - "required": true + "type": "string" + } + }, + { + "name": "window_ends_on", + "in": "query", + "schema": { + "type": "string" + } } ], "responses": { "200": { - "description": "GetSchedule 200 response", + "description": "GetUpcomingSchedule 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetScheduleResponseContent" + "$ref": "#/components/schemas/GetUpcomingScheduleResponseContent" } } } @@ -14840,12 +14450,12 @@ } } }, - "404": { - "description": "NotFoundError 404 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -14861,9 +14471,6 @@ } } }, - "tags": [ - "Schedule" - ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -14873,38 +14480,43 @@ 503 ] } - }, - "put": { - "description": "Update schedule settings", - "operationId": "UpdateScheduleSettings", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateScheduleSettingsRequestContent" - } + } + }, + "/reports/timesheet.json": { + "get": { + "description": "Get account-wide timesheet report", + "operationId": "GetTimesheetReport", + "parameters": [ + { + "name": "from", + "in": "query", + "schema": { + "type": "string" } }, - "required": true - }, - "parameters": [ { - "name": "scheduleId", - "in": "path", + "name": "to", + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "person_id", + "in": "query", "schema": { "type": "integer", "format": "int64" - }, - "required": true + } } ], "responses": { "200": { - "description": "UpdateScheduleSettings 200 response", + "description": "GetTimesheetReport 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateScheduleSettingsResponseContent" + "$ref": "#/components/schemas/GetTimesheetReportResponseContent" } } } @@ -14939,16 +14551,6 @@ } } }, - "422": { - "description": "ValidationError 422 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" - } - } - } - }, "500": { "description": "InternalServerError 500 response", "content": { @@ -14963,9 +14565,6 @@ "tags": [ "Schedule" ], - "x-basecamp-idempotent": { - "natural": true - }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -14977,37 +14576,18 @@ } } }, - "/schedules/{scheduleId}/entries.json": { + "/reports/todos/assigned.json": { "get": { - "description": "List entries on a schedule\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", - "operationId": "ListScheduleEntries", - "parameters": [ - { - "name": "scheduleId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true - }, - { - "name": "status", - "in": "query", - "description": "active|archived|trashed", - "schema": { - "type": "string", - "description": "active|archived|trashed" - } - } - ], + "description": "List people who can be assigned todos", + "operationId": "ListAssignablePeople", + "parameters": [], "responses": { "200": { - "description": "ListScheduleEntries 200 response", + "description": "ListAssignablePeople 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListScheduleEntriesResponseContent" + "$ref": "#/components/schemas/ListAssignablePeopleResponseContent" } } } @@ -15053,14 +14633,6 @@ } } }, - "tags": [ - "Schedule" - ], - "x-basecamp-pagination": { - "style": "link", - "totalCountHeader": "X-Total-Count", - "maxPageSize": 50 - }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -15070,38 +14642,39 @@ 503 ] } - }, - "post": { - "description": "Create a new schedule entry", - "operationId": "CreateScheduleEntry", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateScheduleEntryRequestContent" - } - } - }, - "required": true - }, + } + }, + "/reports/todos/assigned/{personId}": { + "get": { + "description": "Get todos assigned to a specific person", + "operationId": "GetAssignedTodos", "parameters": [ { - "name": "scheduleId", + "name": "personId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true + }, + { + "name": "group_by", + "in": "query", + "description": "Group by \"bucket\" or \"date\"", + "schema": { + "type": "string", + "description": "Group by \"bucket\" or \"date\"" + } } ], "responses": { - "201": { - "description": "CreateScheduleEntry 201 response", + "200": { + "description": "GetAssignedTodos 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateScheduleEntryResponseContent" + "$ref": "#/components/schemas/GetAssignedTodosResponseContent" } } } @@ -15126,12 +14699,12 @@ } } }, - "422": { - "description": "ValidationError 422 response", + "404": { + "description": "NotFoundError 404 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" } } } @@ -15157,11 +14730,8 @@ } } }, - "tags": [ - "Schedule" - ], "x-basecamp-retry": { - "maxAttempts": 2, + "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -15171,151 +14741,1286 @@ } } }, - "/search.json": { + "/reports/todos/overdue.json": { "get": { - "description": "Search for content across the account", - "operationId": "Search", - "parameters": [ - { - "name": "q", - "in": "query", - "schema": { - "type": "string" - }, - "required": true - }, - { - "name": "type_names[]", - "in": "query", - "description": "Recording types to include. Use `key` values from the metadata\nendpoint's `recording_search_types`. Available since Basecamp 5.", - "style": "form", - "schema": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Recording types to include. Use `key` values from the metadata\nendpoint's `recording_search_types`. Available since Basecamp 5.", - "x-go-type-skip-optional-pointer": false - }, - "explode": true + "description": "Get overdue todos grouped by lateness", + "operationId": "GetOverdueTodos", + "parameters": [], + "responses": { + "200": { + "description": "GetOverdueTodos 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetOverdueTodosResponseContent" + } + } + } }, - { - "name": "bucket_ids[]", - "in": "query", - "description": "Project IDs to filter by. Available since Basecamp 5.", - "style": "form", + "401": { + "description": "UnauthorizedError 401 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnauthorizedErrorResponseContent" + } + } + } + }, + "403": { + "description": "ForbiddenError 403 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + } + } + } + }, + "429": { + "description": "RateLimitError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RateLimitErrorResponseContent" + } + } + } + }, + "500": { + "description": "InternalServerError 500 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InternalServerErrorResponseContent" + } + } + } + } + }, + "x-basecamp-retry": { + "maxAttempts": 3, + "baseDelayMs": 1000, + "backoff": "exponential", + "retryOn": [ + 429, + 503 + ] + } + } + }, + "/reports/users/progress/{personId}.json": { + "get": { + "description": "Get a person's activity timeline", + "operationId": "GetPersonProgress", + "parameters": [ + { + "name": "personId", + "in": "path", "schema": { - "type": "array", - "items": { - "type": "integer", - "format": "int64" - }, - "description": "Project IDs to filter by. Available since Basecamp 5.", - "x-go-type-skip-optional-pointer": false + "type": "integer", + "format": "int64" }, - "explode": true + "required": true + } + ], + "responses": { + "200": { + "description": "GetPersonProgress 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetPersonProgressResponseContent" + } + } + } + }, + "401": { + "description": "UnauthorizedError 401 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnauthorizedErrorResponseContent" + } + } + } + }, + "403": { + "description": "ForbiddenError 403 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + } + } + } + }, + "404": { + "description": "NotFoundError 404 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotFoundErrorResponseContent" + } + } + } + }, + "429": { + "description": "RateLimitError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RateLimitErrorResponseContent" + } + } + } }, + "500": { + "description": "InternalServerError 500 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InternalServerErrorResponseContent" + } + } + } + } + }, + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50, + "key": "events" + }, + "x-basecamp-retry": { + "maxAttempts": 3, + "baseDelayMs": 1000, + "backoff": "exponential", + "retryOn": [ + 429, + 503 + ] + } + } + }, + "/schedule_entries/{entryId}": { + "get": { + "description": "Get a single schedule entry by id.\nNote: Recurring entries will redirect (302) to their recordable URL.\nUse GetScheduleEntryOccurrence for recurring entries instead.", + "operationId": "GetScheduleEntry", + "parameters": [ { - "name": "creator_ids[]", - "in": "query", - "description": "Creator person IDs to filter by. Available since Basecamp 5.", - "style": "form", + "name": "entryId", + "in": "path", "schema": { - "type": "array", - "items": { - "type": "integer", - "format": "int64" - }, - "description": "Creator person IDs to filter by. Available since Basecamp 5.", - "x-go-type-skip-optional-pointer": false + "type": "integer", + "format": "int64" }, - "explode": true + "required": true + } + ], + "responses": { + "200": { + "description": "GetScheduleEntry 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetScheduleEntryResponseContent" + } + } + } + }, + "401": { + "description": "UnauthorizedError 401 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnauthorizedErrorResponseContent" + } + } + } + }, + "403": { + "description": "ForbiddenError 403 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + } + } + } + }, + "404": { + "description": "NotFoundError 404 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotFoundErrorResponseContent" + } + } + } }, + "500": { + "description": "InternalServerError 500 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InternalServerErrorResponseContent" + } + } + } + } + }, + "tags": [ + "Schedule" + ], + "x-basecamp-retry": { + "maxAttempts": 3, + "baseDelayMs": 1000, + "backoff": "exponential", + "retryOn": [ + 429, + 503 + ] + } + }, + "put": { + "description": "Update an existing schedule entry", + "operationId": "UpdateScheduleEntry", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateScheduleEntryRequestContent" + } + } + } + }, + "parameters": [ { - "name": "file_type", - "in": "query", + "name": "entryId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true + } + ], + "responses": { + "200": { + "description": "UpdateScheduleEntry 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateScheduleEntryResponseContent" + } + } + } + }, + "401": { + "description": "UnauthorizedError 401 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnauthorizedErrorResponseContent" + } + } + } + }, + "403": { + "description": "ForbiddenError 403 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + } + } + } + }, + "404": { + "description": "NotFoundError 404 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotFoundErrorResponseContent" + } + } + } + }, + "422": { + "description": "ValidationError 422 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponseContent" + } + } + } + }, + "500": { + "description": "InternalServerError 500 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InternalServerErrorResponseContent" + } + } + } + } + }, + "tags": [ + "Schedule" + ], + "x-basecamp-idempotent": { + "natural": true + }, + "x-basecamp-retry": { + "maxAttempts": 3, + "baseDelayMs": 1000, + "backoff": "exponential", + "retryOn": [ + 429, + 503 + ] + } + } + }, + "/schedule_entries/{entryId}/occurrences/{date}": { + "get": { + "description": "Get a specific occurrence of a recurring schedule entry", + "operationId": "GetScheduleEntryOccurrence", + "parameters": [ + { + "name": "entryId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true + }, + { + "name": "date", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "responses": { + "200": { + "description": "GetScheduleEntryOccurrence 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetScheduleEntryOccurrenceResponseContent" + } + } + } + }, + "401": { + "description": "UnauthorizedError 401 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnauthorizedErrorResponseContent" + } + } + } + }, + "403": { + "description": "ForbiddenError 403 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + } + } + } + }, + "404": { + "description": "NotFoundError 404 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotFoundErrorResponseContent" + } + } + } + }, + "500": { + "description": "InternalServerError 500 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InternalServerErrorResponseContent" + } + } + } + } + }, + "tags": [ + "Schedule" + ], + "x-basecamp-retry": { + "maxAttempts": 3, + "baseDelayMs": 1000, + "backoff": "exponential", + "retryOn": [ + 429, + 503 + ] + } + } + }, + "/schedules/{scheduleId}": { + "get": { + "description": "Get a schedule", + "operationId": "GetSchedule", + "parameters": [ + { + "name": "scheduleId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true + } + ], + "responses": { + "200": { + "description": "GetSchedule 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetScheduleResponseContent" + } + } + } + }, + "401": { + "description": "UnauthorizedError 401 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnauthorizedErrorResponseContent" + } + } + } + }, + "403": { + "description": "ForbiddenError 403 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + } + } + } + }, + "404": { + "description": "NotFoundError 404 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotFoundErrorResponseContent" + } + } + } + }, + "500": { + "description": "InternalServerError 500 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InternalServerErrorResponseContent" + } + } + } + } + }, + "tags": [ + "Schedule" + ], + "x-basecamp-retry": { + "maxAttempts": 3, + "baseDelayMs": 1000, + "backoff": "exponential", + "retryOn": [ + 429, + 503 + ] + } + }, + "put": { + "description": "Update schedule settings", + "operationId": "UpdateScheduleSettings", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateScheduleSettingsRequestContent" + } + } + }, + "required": true + }, + "parameters": [ + { + "name": "scheduleId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true + } + ], + "responses": { + "200": { + "description": "UpdateScheduleSettings 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateScheduleSettingsResponseContent" + } + } + } + }, + "401": { + "description": "UnauthorizedError 401 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnauthorizedErrorResponseContent" + } + } + } + }, + "403": { + "description": "ForbiddenError 403 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + } + } + } + }, + "404": { + "description": "NotFoundError 404 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotFoundErrorResponseContent" + } + } + } + }, + "422": { + "description": "ValidationError 422 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponseContent" + } + } + } + }, + "500": { + "description": "InternalServerError 500 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InternalServerErrorResponseContent" + } + } + } + } + }, + "tags": [ + "Schedule" + ], + "x-basecamp-idempotent": { + "natural": true + }, + "x-basecamp-retry": { + "maxAttempts": 3, + "baseDelayMs": 1000, + "backoff": "exponential", + "retryOn": [ + 429, + 503 + ] + } + } + }, + "/schedules/{scheduleId}/entries.json": { + "get": { + "description": "List entries on a schedule\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", + "operationId": "ListScheduleEntries", + "parameters": [ + { + "name": "scheduleId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true + }, + { + "name": "status", + "in": "query", + "description": "active|archived|trashed", + "schema": { + "type": "string", + "description": "active|archived|trashed" + } + } + ], + "responses": { + "200": { + "description": "ListScheduleEntries 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListScheduleEntriesResponseContent" + } + } + } + }, + "401": { + "description": "UnauthorizedError 401 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnauthorizedErrorResponseContent" + } + } + } + }, + "403": { + "description": "ForbiddenError 403 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + } + } + } + }, + "429": { + "description": "RateLimitError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RateLimitErrorResponseContent" + } + } + } + }, + "500": { + "description": "InternalServerError 500 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InternalServerErrorResponseContent" + } + } + } + } + }, + "tags": [ + "Schedule" + ], + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + }, + "x-basecamp-retry": { + "maxAttempts": 3, + "baseDelayMs": 1000, + "backoff": "exponential", + "retryOn": [ + 429, + 503 + ] + } + }, + "post": { + "description": "Create a new schedule entry", + "operationId": "CreateScheduleEntry", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateScheduleEntryRequestContent" + } + } + }, + "required": true + }, + "parameters": [ + { + "name": "scheduleId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true + } + ], + "responses": { + "201": { + "description": "CreateScheduleEntry 201 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateScheduleEntryResponseContent" + } + } + } + }, + "401": { + "description": "UnauthorizedError 401 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnauthorizedErrorResponseContent" + } + } + } + }, + "403": { + "description": "ForbiddenError 403 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + } + } + } + }, + "422": { + "description": "ValidationError 422 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponseContent" + } + } + } + }, + "429": { + "description": "RateLimitError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RateLimitErrorResponseContent" + } + } + } + }, + "500": { + "description": "InternalServerError 500 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InternalServerErrorResponseContent" + } + } + } + } + }, + "tags": [ + "Schedule" + ], + "x-basecamp-retry": { + "maxAttempts": 2, + "baseDelayMs": 1000, + "backoff": "exponential", + "retryOn": [ + 429, + 503 + ] + } + } + }, + "/search.json": { + "get": { + "description": "Search for content across the account", + "operationId": "Search", + "parameters": [ + { + "name": "q", + "in": "query", + "schema": { + "type": "string" + }, + "required": true + }, + { + "name": "type_names[]", + "in": "query", + "description": "Recording types to include. Use `key` values from the metadata\nendpoint's `recording_search_types`. Available since Basecamp 5.", + "style": "form", + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Recording types to include. Use `key` values from the metadata\nendpoint's `recording_search_types`. Available since Basecamp 5.", + "x-go-type-skip-optional-pointer": false + }, + "explode": true + }, + { + "name": "bucket_ids[]", + "in": "query", + "description": "Project IDs to filter by. Available since Basecamp 5.", + "style": "form", + "schema": { + "type": "array", + "items": { + "type": "integer", + "format": "int64" + }, + "description": "Project IDs to filter by. Available since Basecamp 5.", + "x-go-type-skip-optional-pointer": false + }, + "explode": true + }, + { + "name": "creator_ids[]", + "in": "query", + "description": "Creator person IDs to filter by. Available since Basecamp 5.", + "style": "form", + "schema": { + "type": "array", + "items": { + "type": "integer", + "format": "int64" + }, + "description": "Creator person IDs to filter by. Available since Basecamp 5.", + "x-go-type-skip-optional-pointer": false + }, + "explode": true + }, + { + "name": "file_type", + "in": "query", "description": "Filter attachments by type. Use `key` values from the metadata\nendpoint's `file_search_types`.", "schema": { "type": "string", - "description": "Filter attachments by type. Use `key` values from the metadata\nendpoint's `file_search_types`." + "description": "Filter attachments by type. Use `key` values from the metadata\nendpoint's `file_search_types`." + } + }, + { + "name": "exclude_chat", + "in": "query", + "description": "Set to true to exclude chat results.", + "schema": { + "type": "boolean", + "description": "Set to true to exclude chat results." + } + }, + { + "name": "since", + "in": "query", + "description": "last_7_days|last_30_days|last_90_days|last_12_months|forever", + "schema": { + "type": "string", + "description": "last_7_days|last_30_days|last_90_days|last_12_months|forever" + } + }, + { + "name": "sort", + "in": "query", + "description": "best_match|recency", + "schema": { + "type": "string", + "description": "best_match|recency" + } + }, + { + "name": "type", + "in": "query", + "description": "Deprecated: prefer type_names[].", + "schema": { + "type": "string", + "deprecated": true, + "description": "Deprecated: prefer type_names[].\nThis shape is deprecated since 2026-07: Use typeNames (type_names[]) instead" + }, + "deprecated": true, + "x-deprecated-reason": "prefer type_names[]." + }, + { + "name": "bucket_id", + "in": "query", + "description": "Deprecated: prefer bucket_ids[].", + "schema": { + "type": "integer", + "deprecated": true, + "description": "Deprecated: prefer bucket_ids[].\nThis shape is deprecated since 2026-07: Use bucketIds (bucket_ids[]) instead", + "format": "int64" + }, + "deprecated": true, + "x-deprecated-reason": "prefer bucket_ids[]." + }, + { + "name": "creator_id", + "in": "query", + "description": "Deprecated: prefer creator_ids[].", + "schema": { + "type": "integer", + "deprecated": true, + "description": "Deprecated: prefer creator_ids[].\nThis shape is deprecated since 2026-07: Use creatorIds (creator_ids[]) instead", + "format": "int64" + }, + "deprecated": true, + "x-deprecated-reason": "prefer creator_ids[]." + } + ], + "responses": { + "200": { + "description": "Search 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SearchResponseContent" + } + } + } + }, + "401": { + "description": "UnauthorizedError 401 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnauthorizedErrorResponseContent" + } + } + } + }, + "403": { + "description": "ForbiddenError 403 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + } + } + } + }, + "429": { + "description": "RateLimitError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RateLimitErrorResponseContent" + } + } + } + }, + "500": { + "description": "InternalServerError 500 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InternalServerErrorResponseContent" + } + } + } + } + }, + "tags": [ + "Automation" + ], + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + }, + "x-basecamp-retry": { + "maxAttempts": 3, + "baseDelayMs": 1000, + "backoff": "exponential", + "retryOn": [ + 429, + 503 + ] + } + } + }, + "/searches/metadata.json": { + "get": { + "description": "Get search metadata (available filter options)", + "operationId": "GetSearchMetadata", + "parameters": [], + "responses": { + "200": { + "description": "GetSearchMetadata 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetSearchMetadataResponseContent" + } + } + } + }, + "401": { + "description": "UnauthorizedError 401 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnauthorizedErrorResponseContent" + } + } + } + }, + "403": { + "description": "ForbiddenError 403 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + } + } + } + }, + "404": { + "description": "NotFoundError 404 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotFoundErrorResponseContent" + } + } + } + }, + "500": { + "description": "InternalServerError 500 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InternalServerErrorResponseContent" + } + } + } + } + }, + "tags": [ + "Automation" + ], + "x-basecamp-retry": { + "maxAttempts": 3, + "baseDelayMs": 1000, + "backoff": "exponential", + "retryOn": [ + 429, + 503 + ] + } + } + }, + "/templates.json": { + "get": { + "description": "List all templates visible to the current user\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", + "operationId": "ListTemplates", + "parameters": [ + { + "name": "status", + "in": "query", + "description": "active|archived|trashed", + "schema": { + "type": "string", + "description": "active|archived|trashed" + } + } + ], + "responses": { + "200": { + "description": "ListTemplates 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListTemplatesResponseContent" + } + } + } + }, + "401": { + "description": "UnauthorizedError 401 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnauthorizedErrorResponseContent" + } + } + } + }, + "403": { + "description": "ForbiddenError 403 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + } + } + } + }, + "429": { + "description": "RateLimitError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RateLimitErrorResponseContent" + } + } + } + }, + "500": { + "description": "InternalServerError 500 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InternalServerErrorResponseContent" + } + } + } + } + }, + "tags": [ + "Automation" + ], + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + }, + "x-basecamp-retry": { + "maxAttempts": 3, + "baseDelayMs": 1000, + "backoff": "exponential", + "retryOn": [ + 429, + 503 + ] + } + }, + "post": { + "description": "Create a new template", + "operationId": "CreateTemplate", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateTemplateRequestContent" + } + } + }, + "required": true + }, + "parameters": [], + "responses": { + "201": { + "description": "CreateTemplate 201 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateTemplateResponseContent" + } + } } }, - { - "name": "exclude_chat", - "in": "query", - "description": "Set to true to exclude chat results.", - "schema": { - "type": "boolean", - "description": "Set to true to exclude chat results." + "401": { + "description": "UnauthorizedError 401 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnauthorizedErrorResponseContent" + } + } } }, - { - "name": "since", - "in": "query", - "description": "last_7_days|last_30_days|last_90_days|last_12_months|forever", - "schema": { - "type": "string", - "description": "last_7_days|last_30_days|last_90_days|last_12_months|forever" + "403": { + "description": "ForbiddenError 403 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + } + } } }, - { - "name": "sort", - "in": "query", - "description": "best_match|recency", - "schema": { - "type": "string", - "description": "best_match|recency" + "422": { + "description": "ValidationError 422 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponseContent" + } + } } }, - { - "name": "type", - "in": "query", - "description": "Deprecated: prefer type_names[].", - "schema": { - "type": "string", - "deprecated": true, - "description": "Deprecated: prefer type_names[].\nThis shape is deprecated since 2026-07: Use typeNames (type_names[]) instead" - }, - "deprecated": true, - "x-deprecated-reason": "prefer type_names[]." - }, - { - "name": "bucket_id", - "in": "query", - "description": "Deprecated: prefer bucket_ids[].", - "schema": { - "type": "integer", - "deprecated": true, - "description": "Deprecated: prefer bucket_ids[].\nThis shape is deprecated since 2026-07: Use bucketIds (bucket_ids[]) instead", - "format": "int64" - }, - "deprecated": true, - "x-deprecated-reason": "prefer bucket_ids[]." + "429": { + "description": "RateLimitError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RateLimitErrorResponseContent" + } + } + } }, + "500": { + "description": "InternalServerError 500 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InternalServerErrorResponseContent" + } + } + } + } + }, + "tags": [ + "Automation" + ], + "x-basecamp-retry": { + "maxAttempts": 2, + "baseDelayMs": 1000, + "backoff": "exponential", + "retryOn": [ + 429, + 503 + ] + } + } + }, + "/templates/{templateId}": { + "delete": { + "description": "Delete a template (trash it)", + "operationId": "DeleteTemplate", + "parameters": [ { - "name": "creator_id", - "in": "query", - "description": "Deprecated: prefer creator_ids[].", + "name": "templateId", + "in": "path", "schema": { "type": "integer", - "deprecated": true, - "description": "Deprecated: prefer creator_ids[].\nThis shape is deprecated since 2026-07: Use creatorIds (creator_ids[]) instead", "format": "int64" }, - "deprecated": true, - "x-deprecated-reason": "prefer creator_ids[]." + "required": true } ], "responses": { - "200": { - "description": "Search 200 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/SearchResponseContent" - } - } - } + "204": { + "description": "DeleteTemplate 204 response" }, "401": { "description": "UnauthorizedError 401 response", @@ -15337,12 +16042,12 @@ } } }, - "429": { - "description": "RateLimitError 429 response", + "404": { + "description": "NotFoundError 404 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" } } } @@ -15361,10 +16066,8 @@ "tags": [ "Automation" ], - "x-basecamp-pagination": { - "style": "link", - "totalCountHeader": "X-Total-Count", - "maxPageSize": 50 + "x-basecamp-idempotent": { + "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, @@ -15375,20 +16078,28 @@ 503 ] } - } - }, - "/searches/metadata.json": { + }, "get": { - "description": "Get search metadata (available filter options)", - "operationId": "GetSearchMetadata", - "parameters": [], + "description": "Get a single template by id", + "operationId": "GetTemplate", + "parameters": [ + { + "name": "templateId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true + } + ], "responses": { "200": { - "description": "GetSearchMetadata 200 response", + "description": "GetTemplate 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetSearchMetadataResponseContent" + "$ref": "#/components/schemas/GetTemplateResponseContent" } } } @@ -15446,30 +16157,37 @@ 503 ] } - } - }, - "/templates.json": { - "get": { - "description": "List all templates visible to the current user\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", - "operationId": "ListTemplates", + }, + "put": { + "description": "Update an existing template", + "operationId": "UpdateTemplate", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateTemplateRequestContent" + } + } + } + }, "parameters": [ { - "name": "status", - "in": "query", - "description": "active|archived|trashed", + "name": "templateId", + "in": "path", "schema": { - "type": "string", - "description": "active|archived|trashed" - } + "type": "integer", + "format": "int64" + }, + "required": true } ], "responses": { "200": { - "description": "ListTemplates 200 response", + "description": "UpdateTemplate 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListTemplatesResponseContent" + "$ref": "#/components/schemas/UpdateTemplateResponseContent" } } } @@ -15494,12 +16212,22 @@ } } }, - "429": { - "description": "RateLimitError 429 response", + "404": { + "description": "NotFoundError 404 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" + } + } + } + }, + "422": { + "description": "ValidationError 422 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponseContent" } } } @@ -15518,10 +16246,8 @@ "tags": [ "Automation" ], - "x-basecamp-pagination": { - "style": "link", - "totalCountHeader": "X-Total-Count", - "maxPageSize": 50 + "x-basecamp-idempotent": { + "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, @@ -15532,28 +16258,40 @@ 503 ] } - }, + } + }, + "/templates/{templateId}/project_constructions.json": { "post": { - "description": "Create a new template", - "operationId": "CreateTemplate", + "description": "Create a project from a template (asynchronous)", + "operationId": "CreateProjectFromTemplate", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateTemplateRequestContent" + "$ref": "#/components/schemas/CreateProjectFromTemplateRequestContent" } } }, "required": true }, - "parameters": [], + "parameters": [ + { + "name": "templateId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true + } + ], "responses": { "201": { - "description": "CreateTemplate 201 response", + "description": "CreateProjectFromTemplate 201 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateTemplateResponseContent" + "$ref": "#/components/schemas/CreateProjectFromTemplateResponseContent" } } } @@ -15623,10 +16361,10 @@ } } }, - "/templates/{templateId}": { - "delete": { - "description": "Delete a template (trash it)", - "operationId": "DeleteTemplate", + "/templates/{templateId}/project_constructions/{constructionId}": { + "get": { + "description": "Get the status of a project construction", + "operationId": "GetProjectConstruction", "parameters": [ { "name": "templateId", @@ -15636,11 +16374,27 @@ "format": "int64" }, "required": true + }, + { + "name": "constructionId", + "in": "path", + "schema": { + "type": "integer", + "format": "int64" + }, + "required": true } ], "responses": { - "204": { - "description": "DeleteTemplate 204 response" + "200": { + "description": "GetProjectConstruction 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetProjectConstructionResponseContent" + } + } + } }, "401": { "description": "UnauthorizedError 401 response", @@ -15686,9 +16440,6 @@ "tags": [ "Automation" ], - "x-basecamp-idempotent": { - "natural": true - }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -15698,13 +16449,15 @@ 503 ] } - }, + } + }, + "/timesheet_entries/{entryId}": { "get": { - "description": "Get a single template by id", - "operationId": "GetTemplate", + "description": "Get a single timesheet entry", + "operationId": "GetTimesheetEntry", "parameters": [ { - "name": "templateId", + "name": "entryId", "in": "path", "schema": { "type": "integer", @@ -15715,11 +16468,11 @@ ], "responses": { "200": { - "description": "GetTemplate 200 response", + "description": "GetTimesheetEntry 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetTemplateResponseContent" + "$ref": "#/components/schemas/GetTimesheetEntryResponseContent" } } } @@ -15766,7 +16519,7 @@ } }, "tags": [ - "Automation" + "Schedule" ], "x-basecamp-retry": { "maxAttempts": 3, @@ -15779,20 +16532,20 @@ } }, "put": { - "description": "Update an existing template", - "operationId": "UpdateTemplate", + "description": "Update a timesheet entry", + "operationId": "UpdateTimesheetEntry", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateTemplateRequestContent" + "$ref": "#/components/schemas/UpdateTimesheetEntryRequestContent" } } } }, "parameters": [ { - "name": "templateId", + "name": "entryId", "in": "path", "schema": { "type": "integer", @@ -15803,11 +16556,11 @@ ], "responses": { "200": { - "description": "UpdateTemplate 200 response", + "description": "UpdateTimesheetEntry 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateTemplateResponseContent" + "$ref": "#/components/schemas/UpdateTimesheetEntryResponseContent" } } } @@ -15864,7 +16617,7 @@ } }, "tags": [ - "Automation" + "Schedule" ], "x-basecamp-idempotent": { "natural": true @@ -15880,15 +16633,15 @@ } } }, - "/templates/{templateId}/project_constructions.json": { - "post": { - "description": "Create a project from a template (asynchronous)", - "operationId": "CreateProjectFromTemplate", + "/todolists/{groupId}/position.json": { + "put": { + "description": "Reposition a todolist group", + "operationId": "RepositionTodolistGroup", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateProjectFromTemplateRequestContent" + "$ref": "#/components/schemas/RepositionTodolistGroupRequestContent" } } }, @@ -15896,7 +16649,7 @@ }, "parameters": [ { - "name": "templateId", + "name": "groupId", "in": "path", "schema": { "type": "integer", @@ -15906,15 +16659,8 @@ } ], "responses": { - "201": { - "description": "CreateProjectFromTemplate 201 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateProjectFromTemplateResponseContent" - } - } - } + "200": { + "description": "RepositionTodolistGroup 200 response" }, "401": { "description": "UnauthorizedError 401 response", @@ -15936,22 +16682,22 @@ } } }, - "422": { - "description": "ValidationError 422 response", + "404": { + "description": "NotFoundError 404 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" } } } }, - "429": { - "description": "RateLimitError 429 response", + "422": { + "description": "ValidationError 422 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" + "$ref": "#/components/schemas/ValidationErrorResponseContent" } } } @@ -15968,10 +16714,13 @@ } }, "tags": [ - "Automation" + "Todos" ], + "x-basecamp-idempotent": { + "natural": true + }, "x-basecamp-retry": { - "maxAttempts": 2, + "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -15981,37 +16730,121 @@ } } }, - "/templates/{templateId}/project_constructions/{constructionId}": { + "/todolists/{id}": { "get": { - "description": "Get the status of a project construction", - "operationId": "GetProjectConstruction", + "description": "Get a single todolist or todolist group by id\nThe endpoint is polymorphic - the same URI returns either a Todolist or TodolistGroup", + "operationId": "GetTodolistOrGroup", "parameters": [ { - "name": "templateId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true - }, - { - "name": "constructionId", + "name": "id", "in": "path", "schema": { "type": "integer", "format": "int64" }, - "required": true + "required": true, + "examples": { + "GetTodolistOrGroup_example1": { + "summary": "Get a Todolist", + "description": "Returns a Todolist when ID refers to a todolist", + "value": 987654 + }, + "GetTodolistOrGroup_example2": { + "summary": "Get a TodolistGroup", + "description": "Returns a TodolistGroup when ID refers to a group", + "value": 111222 + } + } } ], "responses": { "200": { - "description": "GetProjectConstruction 200 response", + "description": "GetTodolistOrGroup 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetProjectConstructionResponseContent" + "$ref": "#/components/schemas/GetTodolistOrGroupResponseContent" + }, + "examples": { + "GetTodolistOrGroup_example1": { + "summary": "Get a Todolist", + "description": "Returns a Todolist when ID refers to a todolist", + "value": { + "result": { + "todolist": { + "id": 987654, + "status": "active", + "name": "Launch Tasks", + "visible_to_clients": false, + "created_at": "2025-01-01T00:00:00Z", + "updated_at": "2025-01-01T00:00:00Z", + "title": "Launch Tasks", + "inherits_status": true, + "type": "Todolist", + "description_attachments": [], + "url": "https://3.basecampapi.com/999/buckets/12345678/todolists/987654.json", + "app_url": "https://3.basecamp.com/999/buckets/12345678/todolists/987654", + "creator": { + "id": 1, + "name": "Someone", + "created_at": "2025-01-01T00:00:00Z", + "updated_at": "2025-01-01T00:00:00Z" + }, + "bucket": { + "id": 12345678, + "name": "My Project", + "type": "Project" + }, + "parent": { + "id": 99999, + "title": "To-dos", + "type": "Todoset", + "url": "https://3.basecampapi.com/999/buckets/12345678/todosets/99999.json", + "app_url": "https://3.basecamp.com/999/buckets/12345678/todosets/99999" + } + } + } + } + }, + "GetTodolistOrGroup_example2": { + "summary": "Get a TodolistGroup", + "description": "Returns a TodolistGroup when ID refers to a group", + "value": { + "result": { + "group": { + "id": 111222, + "status": "active", + "name": "Q1 Milestones", + "visible_to_clients": false, + "created_at": "2025-01-01T00:00:00Z", + "updated_at": "2025-01-01T00:00:00Z", + "title": "Q1 Milestones", + "inherits_status": true, + "type": "TodolistGroup", + "url": "https://3.basecampapi.com/999/buckets/12345678/todolists/111222.json", + "app_url": "https://3.basecamp.com/999/buckets/12345678/todolists/111222", + "creator": { + "id": 1, + "name": "Someone", + "created_at": "2025-01-01T00:00:00Z", + "updated_at": "2025-01-01T00:00:00Z" + }, + "bucket": { + "id": 12345678, + "name": "My Project", + "type": "Project" + }, + "parent": { + "id": 99999, + "title": "To-dos", + "type": "Todoset", + "url": "https://3.basecampapi.com/999/buckets/12345678/todosets/99999.json", + "app_url": "https://3.basecamp.com/999/buckets/12345678/todosets/99999" + } + } + } + } + } } } } @@ -16058,7 +16891,7 @@ } }, "tags": [ - "Automation" + "Todos" ], "x-basecamp-retry": { "maxAttempts": 3, @@ -16069,15 +16902,22 @@ 503 ] } - } - }, - "/timesheet_entries/{entryId}": { - "get": { - "description": "Get a single timesheet entry", - "operationId": "GetTimesheetEntry", + }, + "put": { + "description": "Update an existing todolist or todolist group\nThe endpoint is polymorphic - updates either a Todolist or TodolistGroup", + "operationId": "UpdateTodolistOrGroup", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateTodolistOrGroupRequestContent" + } + } + } + }, "parameters": [ { - "name": "entryId", + "name": "id", "in": "path", "schema": { "type": "integer", @@ -16088,11 +16928,11 @@ ], "responses": { "200": { - "description": "GetTimesheetEntry 200 response", + "description": "UpdateTodolistOrGroup 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetTimesheetEntryResponseContent" + "$ref": "#/components/schemas/UpdateTodolistOrGroupResponseContent" } } } @@ -16122,7 +16962,17 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/NotFoundErrorResponseContent" + } + } + } + }, + "422": { + "description": "ValidationError 422 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponseContent" } } } @@ -16139,8 +16989,11 @@ } }, "tags": [ - "Schedule" + "Todos" ], + "x-basecamp-idempotent": { + "natural": true + }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -16150,22 +17003,15 @@ 503 ] } - }, - "put": { - "description": "Update a timesheet entry", - "operationId": "UpdateTimesheetEntry", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateTimesheetEntryRequestContent" - } - } - } - }, + } + }, + "/todolists/{todolistId}/groups.json": { + "get": { + "description": "List groups in a todolist\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", + "operationId": "ListTodolistGroups", "parameters": [ { - "name": "entryId", + "name": "todolistId", "in": "path", "schema": { "type": "integer", @@ -16176,11 +17022,11 @@ ], "responses": { "200": { - "description": "UpdateTimesheetEntry 200 response", + "description": "ListTodolistGroups 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateTimesheetEntryResponseContent" + "$ref": "#/components/schemas/ListTodolistGroupsResponseContent" } } } @@ -16205,22 +17051,12 @@ } } }, - "404": { - "description": "NotFoundError 404 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" - } - } - } - }, - "422": { - "description": "ValidationError 422 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -16237,10 +17073,12 @@ } }, "tags": [ - "Schedule" + "Todos" ], - "x-basecamp-idempotent": { - "natural": true + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 }, "x-basecamp-retry": { "maxAttempts": 3, @@ -16251,17 +17089,15 @@ 503 ] } - } - }, - "/todolists/{groupId}/position.json": { - "put": { - "description": "Reposition a todolist group", - "operationId": "RepositionTodolistGroup", + }, + "post": { + "description": "Create a new group in a todolist", + "operationId": "CreateTodolistGroup", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RepositionTodolistGroupRequestContent" + "$ref": "#/components/schemas/CreateTodolistGroupRequestContent" } } }, @@ -16269,7 +17105,7 @@ }, "parameters": [ { - "name": "groupId", + "name": "todolistId", "in": "path", "schema": { "type": "integer", @@ -16279,8 +17115,15 @@ } ], "responses": { - "200": { - "description": "RepositionTodolistGroup 200 response" + "201": { + "description": "CreateTodolistGroup 201 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateTodolistGroupResponseContent" + } + } + } }, "401": { "description": "UnauthorizedError 401 response", @@ -16302,22 +17145,22 @@ } } }, - "404": { - "description": "NotFoundError 404 response", + "422": { + "description": "ValidationError 422 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/ValidationErrorResponseContent" } } } }, - "422": { - "description": "ValidationError 422 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -16336,11 +17179,8 @@ "tags": [ "Todos" ], - "x-basecamp-idempotent": { - "natural": true - }, "x-basecamp-retry": { - "maxAttempts": 3, + "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -16350,121 +17190,44 @@ } } }, - "/todolists/{id}": { + "/todolists/{todolistId}/todos.json": { "get": { - "description": "Get a single todolist or todolist group by id\nThe endpoint is polymorphic - the same URI returns either a Todolist or TodolistGroup", - "operationId": "GetTodolistOrGroup", + "description": "List todos in a todolist\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", + "operationId": "ListTodos", "parameters": [ { - "name": "id", + "name": "todolistId", "in": "path", "schema": { "type": "integer", "format": "int64" }, - "required": true, - "examples": { - "GetTodolistOrGroup_example1": { - "summary": "Get a Todolist", - "description": "Returns a Todolist when ID refers to a todolist", - "value": 987654 - }, - "GetTodolistOrGroup_example2": { - "summary": "Get a TodolistGroup", - "description": "Returns a TodolistGroup when ID refers to a group", - "value": 111222 - } + "required": true + }, + { + "name": "status", + "in": "query", + "description": "active|archived|trashed", + "schema": { + "type": "string", + "description": "active|archived|trashed" + } + }, + { + "name": "completed", + "in": "query", + "schema": { + "type": "boolean" } } ], "responses": { "200": { - "description": "GetTodolistOrGroup 200 response", + "description": "ListTodos 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetTodolistOrGroupResponseContent" - }, - "examples": { - "GetTodolistOrGroup_example1": { - "summary": "Get a Todolist", - "description": "Returns a Todolist when ID refers to a todolist", - "value": { - "result": { - "todolist": { - "id": 987654, - "status": "active", - "name": "Launch Tasks", - "visible_to_clients": false, - "created_at": "2025-01-01T00:00:00Z", - "updated_at": "2025-01-01T00:00:00Z", - "title": "Launch Tasks", - "inherits_status": true, - "type": "Todolist", - "description_attachments": [], - "url": "https://3.basecampapi.com/999/buckets/12345678/todolists/987654.json", - "app_url": "https://3.basecamp.com/999/buckets/12345678/todolists/987654", - "creator": { - "id": 1, - "name": "Someone", - "created_at": "2025-01-01T00:00:00Z", - "updated_at": "2025-01-01T00:00:00Z" - }, - "bucket": { - "id": 12345678, - "name": "My Project", - "type": "Project" - }, - "parent": { - "id": 99999, - "title": "To-dos", - "type": "Todoset", - "url": "https://3.basecampapi.com/999/buckets/12345678/todosets/99999.json", - "app_url": "https://3.basecamp.com/999/buckets/12345678/todosets/99999" - } - } - } - } - }, - "GetTodolistOrGroup_example2": { - "summary": "Get a TodolistGroup", - "description": "Returns a TodolistGroup when ID refers to a group", - "value": { - "result": { - "group": { - "id": 111222, - "status": "active", - "name": "Q1 Milestones", - "visible_to_clients": false, - "created_at": "2025-01-01T00:00:00Z", - "updated_at": "2025-01-01T00:00:00Z", - "title": "Q1 Milestones", - "inherits_status": true, - "type": "TodolistGroup", - "url": "https://3.basecampapi.com/999/buckets/12345678/todolists/111222.json", - "app_url": "https://3.basecamp.com/999/buckets/12345678/todolists/111222", - "creator": { - "id": 1, - "name": "Someone", - "created_at": "2025-01-01T00:00:00Z", - "updated_at": "2025-01-01T00:00:00Z" - }, - "bucket": { - "id": 12345678, - "name": "My Project", - "type": "Project" - }, - "parent": { - "id": 99999, - "title": "To-dos", - "type": "Todoset", - "url": "https://3.basecampapi.com/999/buckets/12345678/todosets/99999.json", - "app_url": "https://3.basecamp.com/999/buckets/12345678/todosets/99999" - } - } - } - } - } + "$ref": "#/components/schemas/ListTodosResponseContent" } } } @@ -16489,12 +17252,12 @@ } } }, - "404": { - "description": "NotFoundError 404 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -16513,6 +17276,11 @@ "tags": [ "Todos" ], + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -16523,21 +17291,22 @@ ] } }, - "put": { - "description": "Update an existing todolist or todolist group\nThe endpoint is polymorphic - updates either a Todolist or TodolistGroup", - "operationId": "UpdateTodolistOrGroup", + "post": { + "description": "Create a new todo in a todolist", + "operationId": "CreateTodo", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateTodolistOrGroupRequestContent" + "$ref": "#/components/schemas/CreateTodoRequestContent" } } - } + }, + "required": true }, "parameters": [ { - "name": "id", + "name": "todolistId", "in": "path", "schema": { "type": "integer", @@ -16547,12 +17316,12 @@ } ], "responses": { - "200": { - "description": "UpdateTodolistOrGroup 200 response", + "201": { + "description": "CreateTodo 201 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateTodolistOrGroupResponseContent" + "$ref": "#/components/schemas/CreateTodoResponseContent" } } } @@ -16577,22 +17346,22 @@ } } }, - "404": { - "description": "NotFoundError 404 response", + "422": { + "description": "ValidationError 422 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" + "$ref": "#/components/schemas/ValidationErrorResponseContent" } } } }, - "422": { - "description": "ValidationError 422 response", + "429": { + "description": "RateLimitError 429 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" + "$ref": "#/components/schemas/RateLimitErrorResponseContent" } } } @@ -16611,9 +17380,6 @@ "tags": [ "Todos" ], - "x-basecamp-idempotent": { - "natural": true - }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -16625,28 +17391,18 @@ } } }, - "/todolists/{todolistId}/groups.json": { + "/todos/completed.json": { "get": { - "description": "List groups in a todolist\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", - "operationId": "ListTodolistGroups", - "parameters": [ - { - "name": "todolistId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true - } - ], + "description": "Get completed to-dos across all accessible projects, grouped by project\n(paginated).", + "operationId": "GetEverythingCompletedTodos", + "parameters": [], "responses": { "200": { - "description": "ListTodolistGroups 200 response", + "description": "GetEverythingCompletedTodos 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListTodolistGroupsResponseContent" + "$ref": "#/components/schemas/GetEverythingCompletedTodosResponseContent" } } } @@ -16693,7 +17449,7 @@ } }, "tags": [ - "Todos" + "Everything" ], "x-basecamp-pagination": { "style": "link", @@ -16709,38 +17465,20 @@ 503 ] } - }, - "post": { - "description": "Create a new group in a todolist", - "operationId": "CreateTodolistGroup", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateTodolistGroupRequestContent" - } - } - }, - "required": true - }, - "parameters": [ - { - "name": "todolistId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true - } - ], + } + }, + "/todos/no_due_date.json": { + "get": { + "description": "Get open to-dos with no due date across all accessible projects, grouped by\nproject (paginated).", + "operationId": "GetEverythingNoDueDateTodos", + "parameters": [], "responses": { - "201": { - "description": "CreateTodolistGroup 201 response", + "200": { + "description": "GetEverythingNoDueDateTodos 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateTodolistGroupResponseContent" + "$ref": "#/components/schemas/GetEverythingNoDueDateTodosResponseContent" } } } @@ -16765,16 +17503,6 @@ } } }, - "422": { - "description": "ValidationError 422 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" - } - } - } - }, "429": { "description": "RateLimitError 429 response", "content": { @@ -16797,10 +17525,15 @@ } }, "tags": [ - "Todos" + "Everything" ], + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + }, "x-basecamp-retry": { - "maxAttempts": 2, + "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ @@ -16810,44 +17543,18 @@ } } }, - "/todolists/{todolistId}/todos.json": { + "/todos/open.json": { "get": { - "description": "List todos in a todolist\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", - "operationId": "ListTodos", - "parameters": [ - { - "name": "todolistId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true - }, - { - "name": "status", - "in": "query", - "description": "active|archived|trashed", - "schema": { - "type": "string", - "description": "active|archived|trashed" - } - }, - { - "name": "completed", - "in": "query", - "schema": { - "type": "boolean" - } - } - ], + "description": "Get active, incomplete to-dos across all accessible projects, grouped by\nproject (paginated). Each bucket entry carries the matching to-dos and their\nsteps.", + "operationId": "GetEverythingOpenTodos", + "parameters": [], "responses": { "200": { - "description": "ListTodos 200 response", + "description": "GetEverythingOpenTodos 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListTodosResponseContent" + "$ref": "#/components/schemas/GetEverythingOpenTodosResponseContent" } } } @@ -16894,7 +17601,7 @@ } }, "tags": [ - "Todos" + "Everything" ], "x-basecamp-pagination": { "style": "link", @@ -16910,38 +17617,20 @@ 503 ] } - }, - "post": { - "description": "Create a new todo in a todolist", - "operationId": "CreateTodo", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateTodoRequestContent" - } - } - }, - "required": true - }, - "parameters": [ - { - "name": "todolistId", - "in": "path", - "schema": { - "type": "integer", - "format": "int64" - }, - "required": true - } - ], + } + }, + "/todos/overdue.json": { + "get": { + "description": "Get every overdue to-do across all accessible projects — a complete,\noldest-due-date-first array (unpaginated). Each item embeds its `bucket`.", + "operationId": "GetEverythingOverdueTodos", + "parameters": [], "responses": { - "201": { - "description": "CreateTodo 201 response", + "200": { + "description": "GetEverythingOverdueTodos 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateTodoResponseContent" + "$ref": "#/components/schemas/GetEverythingOverdueTodosResponseContent" } } } @@ -16966,26 +17655,6 @@ } } }, - "422": { - "description": "ValidationError 422 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ValidationErrorResponseContent" - } - } - } - }, - "429": { - "description": "RateLimitError 429 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/RateLimitErrorResponseContent" - } - } - } - }, "500": { "description": "InternalServerError 500 response", "content": { @@ -16998,7 +17667,7 @@ } }, "tags": [ - "Todos" + "Everything" ], "x-basecamp-retry": { "maxAttempts": 3, @@ -17011,18 +17680,18 @@ } } }, - "/todos/overdue.json": { + "/todos/unassigned.json": { "get": { - "description": "Get every overdue to-do across all accessible projects — a complete,\noldest-due-date-first array (unpaginated). Each item embeds its `bucket`.", - "operationId": "GetEverythingOverdueTodos", + "description": "Get open, unassigned to-dos across all accessible projects, grouped by\nproject (paginated).", + "operationId": "GetEverythingUnassignedTodos", "parameters": [], "responses": { "200": { - "description": "GetEverythingOverdueTodos 200 response", + "description": "GetEverythingUnassignedTodos 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetEverythingOverdueTodosResponseContent" + "$ref": "#/components/schemas/GetEverythingUnassignedTodosResponseContent" } } } @@ -17047,6 +17716,16 @@ } } }, + "429": { + "description": "RateLimitError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RateLimitErrorResponseContent" + } + } + } + }, "500": { "description": "InternalServerError 500 response", "content": { @@ -17061,6 +17740,11 @@ "tags": [ "Everything" ], + "x-basecamp-pagination": { + "style": "link", + "totalCountHeader": "X-Total-Count", + "maxPageSize": 50 + }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, @@ -19655,6 +20339,36 @@ "id" ] }, + "BucketCardsGroup": { + "type": "object", + "description": "One project's slice of a filtered card listing: the parent project and the\nmatching cards (each carrying its steps).", + "properties": { + "bucket": { + "$ref": "#/components/schemas/RecordingBucket" + }, + "cards": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Card" + } + } + } + }, + "BucketTodosGroup": { + "type": "object", + "description": "One project's slice of a filtered to-do listing: the parent project and the\nmatching to-dos (each carrying its steps).", + "properties": { + "bucket": { + "$ref": "#/components/schemas/RecordingBucket" + }, + "todos": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Todo" + } + } + } + }, "Campfire": { "type": "object", "properties": { @@ -22503,6 +23217,18 @@ "$ref": "#/components/schemas/Recording" } }, + "GetEverythingCompletedCardsResponseContent": { + "type": "array", + "items": { + "$ref": "#/components/schemas/BucketCardsGroup" + } + }, + "GetEverythingCompletedTodosResponseContent": { + "type": "array", + "items": { + "$ref": "#/components/schemas/BucketTodosGroup" + } + }, "GetEverythingFilesResponseContent": { "type": "array", "items": { @@ -22521,6 +23247,36 @@ "$ref": "#/components/schemas/Recording" } }, + "GetEverythingNoDueDateCardsResponseContent": { + "type": "array", + "items": { + "$ref": "#/components/schemas/BucketCardsGroup" + } + }, + "GetEverythingNoDueDateTodosResponseContent": { + "type": "array", + "items": { + "$ref": "#/components/schemas/BucketTodosGroup" + } + }, + "GetEverythingNotNowCardsResponseContent": { + "type": "array", + "items": { + "$ref": "#/components/schemas/BucketCardsGroup" + } + }, + "GetEverythingOpenCardsResponseContent": { + "type": "array", + "items": { + "$ref": "#/components/schemas/BucketCardsGroup" + } + }, + "GetEverythingOpenTodosResponseContent": { + "type": "array", + "items": { + "$ref": "#/components/schemas/BucketTodosGroup" + } + }, "GetEverythingOverdueCardsResponseContent": { "type": "array", "items": { @@ -22533,6 +23289,18 @@ "$ref": "#/components/schemas/Todo" } }, + "GetEverythingUnassignedCardsResponseContent": { + "type": "array", + "items": { + "$ref": "#/components/schemas/BucketCardsGroup" + } + }, + "GetEverythingUnassignedTodosResponseContent": { + "type": "array", + "items": { + "$ref": "#/components/schemas/BucketTodosGroup" + } + }, "GetForwardReplyResponseContent": { "$ref": "#/components/schemas/ForwardReply" }, diff --git a/typescript/src/generated/path-mapping.ts b/typescript/src/generated/path-mapping.ts index d0acd93e..ca3855f2 100644 --- a/typescript/src/generated/path-mapping.ts +++ b/typescript/src/generated/path-mapping.ts @@ -37,7 +37,12 @@ export const PATH_TO_OPERATION: Record = { "GET:/{accountId}/card_tables/steps/{stepId}": "GetCardStep", "PUT:/{accountId}/card_tables/steps/{stepId}": "UpdateCardStep", "PUT:/{accountId}/card_tables/steps/{stepId}/completions.json": "SetCardStepCompletion", + "GET:/{accountId}/cards/completed.json": "GetEverythingCompletedCards", + "GET:/{accountId}/cards/no_due_date.json": "GetEverythingNoDueDateCards", + "GET:/{accountId}/cards/not_now.json": "GetEverythingNotNowCards", + "GET:/{accountId}/cards/open.json": "GetEverythingOpenCards", "GET:/{accountId}/cards/overdue.json": "GetEverythingOverdueCards", + "GET:/{accountId}/cards/unassigned.json": "GetEverythingUnassignedCards", "GET:/{accountId}/categories.json": "ListMessageTypes", "POST:/{accountId}/categories.json": "CreateMessageType", "DELETE:/{accountId}/categories/{typeId}": "DeleteMessageType", @@ -157,7 +162,11 @@ export const PATH_TO_OPERATION: Record = { "DELETE:/{accountId}/todos/{todoId}/completion.json": "UncompleteTodo", "POST:/{accountId}/todos/{todoId}/completion.json": "CompleteTodo", "PUT:/{accountId}/todos/{todoId}/position.json": "RepositionTodo", + "GET:/{accountId}/todos/completed.json": "GetEverythingCompletedTodos", + "GET:/{accountId}/todos/no_due_date.json": "GetEverythingNoDueDateTodos", + "GET:/{accountId}/todos/open.json": "GetEverythingOpenTodos", "GET:/{accountId}/todos/overdue.json": "GetEverythingOverdueTodos", + "GET:/{accountId}/todos/unassigned.json": "GetEverythingUnassignedTodos", "GET:/{accountId}/todosets/{todosetId}": "GetTodoset", "GET:/{accountId}/todosets/{todosetId}/hill.json": "GetHillChart", "PUT:/{accountId}/todosets/{todosetId}/hills/settings.json": "UpdateHillChartSettings", diff --git a/typescript/src/generated/schema.d.ts b/typescript/src/generated/schema.d.ts index 012d8f46..151f462a 100644 --- a/typescript/src/generated/schema.d.ts +++ b/typescript/src/generated/schema.d.ts @@ -404,6 +404,87 @@ export interface paths { patch?: never; trace?: never; }; + "/cards/completed.json": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * @description Get completed cards across all accessible projects, grouped by project + * (paginated). + */ + get: operations["GetEverythingCompletedCards"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/cards/no_due_date.json": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * @description Get open cards with no due date across all accessible projects, grouped by + * project (paginated). + */ + get: operations["GetEverythingNoDueDateCards"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/cards/not_now.json": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * @description Get cards parked in a project's "Not now" column across all accessible + * projects, grouped by project (paginated). + */ + get: operations["GetEverythingNotNowCards"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/cards/open.json": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * @description Get incomplete cards in active columns across all accessible projects, + * grouped by project (paginated). Each bucket entry carries the matching cards + * and their steps. + */ + get: operations["GetEverythingOpenCards"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; "/cards/overdue.json": { parameters: { query?: never; @@ -424,6 +505,26 @@ export interface paths { patch?: never; trace?: never; }; + "/cards/unassigned.json": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * @description Get open, unassigned cards across all accessible projects, grouped by + * project (paginated). + */ + get: operations["GetEverythingUnassignedCards"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; "/categories.json": { parameters: { query?: never; @@ -2420,6 +2521,67 @@ export interface paths { patch?: never; trace?: never; }; + "/todos/completed.json": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * @description Get completed to-dos across all accessible projects, grouped by project + * (paginated). + */ + get: operations["GetEverythingCompletedTodos"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/todos/no_due_date.json": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * @description Get open to-dos with no due date across all accessible projects, grouped by + * project (paginated). + */ + get: operations["GetEverythingNoDueDateTodos"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/todos/open.json": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * @description Get active, incomplete to-dos across all accessible projects, grouped by + * project (paginated). Each bucket entry carries the matching to-dos and their + * steps. + */ + get: operations["GetEverythingOpenTodos"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; "/todos/overdue.json": { parameters: { query?: never; @@ -2440,6 +2602,26 @@ export interface paths { patch?: never; trace?: never; }; + "/todos/unassigned.json": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * @description Get open, unassigned to-dos across all accessible projects, grouped by + * project (paginated). + */ + get: operations["GetEverythingUnassignedTodos"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; "/todos/{todoId}": { parameters: { query?: never; @@ -2817,6 +2999,22 @@ export interface components { booster?: components["schemas"]["Person"]; recording?: components["schemas"]["RecordingParent"]; }; + /** + * @description One project's slice of a filtered card listing: the parent project and the + * matching cards (each carrying its steps). + */ + BucketCardsGroup: { + bucket?: components["schemas"]["RecordingBucket"]; + cards?: components["schemas"]["Card"][]; + }; + /** + * @description One project's slice of a filtered to-do listing: the parent project and the + * matching to-dos (each carrying its steps). + */ + BucketTodosGroup: { + bucket?: components["schemas"]["RecordingBucket"]; + todos?: components["schemas"]["Todo"][]; + }; Campfire: { /** Format: int64 */ id: number; @@ -3609,11 +3807,20 @@ export interface components { GetEverythingBoostsResponseContent: components["schemas"]["Boost"][]; GetEverythingCheckinsResponseContent: components["schemas"]["Recording"][]; GetEverythingCommentsResponseContent: components["schemas"]["Recording"][]; + GetEverythingCompletedCardsResponseContent: components["schemas"]["BucketCardsGroup"][]; + GetEverythingCompletedTodosResponseContent: components["schemas"]["BucketTodosGroup"][]; GetEverythingFilesResponseContent: components["schemas"]["EverythingFile"][]; GetEverythingForwardsResponseContent: components["schemas"]["Recording"][]; GetEverythingMessagesResponseContent: components["schemas"]["Recording"][]; + GetEverythingNoDueDateCardsResponseContent: components["schemas"]["BucketCardsGroup"][]; + GetEverythingNoDueDateTodosResponseContent: components["schemas"]["BucketTodosGroup"][]; + GetEverythingNotNowCardsResponseContent: components["schemas"]["BucketCardsGroup"][]; + GetEverythingOpenCardsResponseContent: components["schemas"]["BucketCardsGroup"][]; + GetEverythingOpenTodosResponseContent: components["schemas"]["BucketTodosGroup"][]; GetEverythingOverdueCardsResponseContent: components["schemas"]["Card"][]; GetEverythingOverdueTodosResponseContent: components["schemas"]["Todo"][]; + GetEverythingUnassignedCardsResponseContent: components["schemas"]["BucketCardsGroup"][]; + GetEverythingUnassignedTodosResponseContent: components["schemas"]["BucketTodosGroup"][]; GetForwardReplyResponseContent: components["schemas"]["ForwardReply"]; GetForwardResponseContent: components["schemas"]["Forward"]; GetGaugeNeedleResponseContent: components["schemas"]["GaugeNeedle"]; @@ -7128,18 +7335,307 @@ export interface operations { }; cookie?: never; }; - requestBody: { - content: { - "application/json": components["schemas"]["MoveCardColumnRequestContent"]; - }; - }; + requestBody: { + content: { + "application/json": components["schemas"]["MoveCardColumnRequestContent"]; + }; + }; + responses: { + /** @description MoveCardColumn 204 response */ + 204: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description UnauthorizedError 401 response */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["UnauthorizedErrorResponseContent"]; + }; + }; + /** @description ForbiddenError 403 response */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ForbiddenErrorResponseContent"]; + }; + }; + /** @description ValidationError 422 response */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ValidationErrorResponseContent"]; + }; + }; + /** @description RateLimitError 429 response */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["RateLimitErrorResponseContent"]; + }; + }; + /** @description InternalServerError 500 response */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["InternalServerErrorResponseContent"]; + }; + }; + }; + }; + GetEverythingCompletedCards: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description GetEverythingCompletedCards 200 response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["GetEverythingCompletedCardsResponseContent"]; + }; + }; + /** @description UnauthorizedError 401 response */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["UnauthorizedErrorResponseContent"]; + }; + }; + /** @description ForbiddenError 403 response */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ForbiddenErrorResponseContent"]; + }; + }; + /** @description RateLimitError 429 response */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["RateLimitErrorResponseContent"]; + }; + }; + /** @description InternalServerError 500 response */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["InternalServerErrorResponseContent"]; + }; + }; + }; + }; + GetEverythingNoDueDateCards: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description GetEverythingNoDueDateCards 200 response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["GetEverythingNoDueDateCardsResponseContent"]; + }; + }; + /** @description UnauthorizedError 401 response */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["UnauthorizedErrorResponseContent"]; + }; + }; + /** @description ForbiddenError 403 response */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ForbiddenErrorResponseContent"]; + }; + }; + /** @description RateLimitError 429 response */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["RateLimitErrorResponseContent"]; + }; + }; + /** @description InternalServerError 500 response */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["InternalServerErrorResponseContent"]; + }; + }; + }; + }; + GetEverythingNotNowCards: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description GetEverythingNotNowCards 200 response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["GetEverythingNotNowCardsResponseContent"]; + }; + }; + /** @description UnauthorizedError 401 response */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["UnauthorizedErrorResponseContent"]; + }; + }; + /** @description ForbiddenError 403 response */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ForbiddenErrorResponseContent"]; + }; + }; + /** @description RateLimitError 429 response */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["RateLimitErrorResponseContent"]; + }; + }; + /** @description InternalServerError 500 response */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["InternalServerErrorResponseContent"]; + }; + }; + }; + }; + GetEverythingOpenCards: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description GetEverythingOpenCards 200 response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["GetEverythingOpenCardsResponseContent"]; + }; + }; + /** @description UnauthorizedError 401 response */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["UnauthorizedErrorResponseContent"]; + }; + }; + /** @description ForbiddenError 403 response */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ForbiddenErrorResponseContent"]; + }; + }; + /** @description RateLimitError 429 response */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["RateLimitErrorResponseContent"]; + }; + }; + /** @description InternalServerError 500 response */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["InternalServerErrorResponseContent"]; + }; + }; + }; + }; + GetEverythingOverdueCards: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; responses: { - /** @description MoveCardColumn 204 response */ - 204: { + /** @description GetEverythingOverdueCards 200 response */ + 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + "application/json": components["schemas"]["GetEverythingOverdueCardsResponseContent"]; + }; }; /** @description UnauthorizedError 401 response */ 401: { @@ -7159,24 +7655,6 @@ export interface operations { "application/json": components["schemas"]["ForbiddenErrorResponseContent"]; }; }; - /** @description ValidationError 422 response */ - 422: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["ValidationErrorResponseContent"]; - }; - }; - /** @description RateLimitError 429 response */ - 429: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["RateLimitErrorResponseContent"]; - }; - }; /** @description InternalServerError 500 response */ 500: { headers: { @@ -7188,7 +7666,7 @@ export interface operations { }; }; }; - GetEverythingOverdueCards: { + GetEverythingUnassignedCards: { parameters: { query?: never; header?: never; @@ -7197,13 +7675,13 @@ export interface operations { }; requestBody?: never; responses: { - /** @description GetEverythingOverdueCards 200 response */ + /** @description GetEverythingUnassignedCards 200 response */ 200: { headers: { [name: string]: unknown; }; content: { - "application/json": components["schemas"]["GetEverythingOverdueCardsResponseContent"]; + "application/json": components["schemas"]["GetEverythingUnassignedCardsResponseContent"]; }; }; /** @description UnauthorizedError 401 response */ @@ -7224,6 +7702,15 @@ export interface operations { "application/json": components["schemas"]["ForbiddenErrorResponseContent"]; }; }; + /** @description RateLimitError 429 response */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["RateLimitErrorResponseContent"]; + }; + }; /** @description InternalServerError 500 response */ 500: { headers: { @@ -16965,6 +17452,174 @@ export interface operations { }; }; }; + GetEverythingCompletedTodos: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description GetEverythingCompletedTodos 200 response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["GetEverythingCompletedTodosResponseContent"]; + }; + }; + /** @description UnauthorizedError 401 response */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["UnauthorizedErrorResponseContent"]; + }; + }; + /** @description ForbiddenError 403 response */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ForbiddenErrorResponseContent"]; + }; + }; + /** @description RateLimitError 429 response */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["RateLimitErrorResponseContent"]; + }; + }; + /** @description InternalServerError 500 response */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["InternalServerErrorResponseContent"]; + }; + }; + }; + }; + GetEverythingNoDueDateTodos: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description GetEverythingNoDueDateTodos 200 response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["GetEverythingNoDueDateTodosResponseContent"]; + }; + }; + /** @description UnauthorizedError 401 response */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["UnauthorizedErrorResponseContent"]; + }; + }; + /** @description ForbiddenError 403 response */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ForbiddenErrorResponseContent"]; + }; + }; + /** @description RateLimitError 429 response */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["RateLimitErrorResponseContent"]; + }; + }; + /** @description InternalServerError 500 response */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["InternalServerErrorResponseContent"]; + }; + }; + }; + }; + GetEverythingOpenTodos: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description GetEverythingOpenTodos 200 response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["GetEverythingOpenTodosResponseContent"]; + }; + }; + /** @description UnauthorizedError 401 response */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["UnauthorizedErrorResponseContent"]; + }; + }; + /** @description ForbiddenError 403 response */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ForbiddenErrorResponseContent"]; + }; + }; + /** @description RateLimitError 429 response */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["RateLimitErrorResponseContent"]; + }; + }; + /** @description InternalServerError 500 response */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["InternalServerErrorResponseContent"]; + }; + }; + }; + }; GetEverythingOverdueTodos: { parameters: { query?: never; @@ -17012,6 +17667,62 @@ export interface operations { }; }; }; + GetEverythingUnassignedTodos: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description GetEverythingUnassignedTodos 200 response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["GetEverythingUnassignedTodosResponseContent"]; + }; + }; + /** @description UnauthorizedError 401 response */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["UnauthorizedErrorResponseContent"]; + }; + }; + /** @description ForbiddenError 403 response */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ForbiddenErrorResponseContent"]; + }; + }; + /** @description RateLimitError 429 response */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["RateLimitErrorResponseContent"]; + }; + }; + /** @description InternalServerError 500 response */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["InternalServerErrorResponseContent"]; + }; + }; + }; + }; GetTodo: { parameters: { query?: never; diff --git a/typescript/src/generated/services/everything.ts b/typescript/src/generated/services/everything.ts index 82340240..25c2f405 100644 --- a/typescript/src/generated/services/everything.ts +++ b/typescript/src/generated/services/everything.ts @@ -26,6 +26,36 @@ export type Todo = components["schemas"]["Todo"]; export interface EverythingBoostsEverythingOptions extends PaginationOptions { } +/** + * Options for everythingCompletedCards. + */ +export interface EverythingCompletedCardsEverythingOptions extends PaginationOptions { +} + +/** + * Options for everythingNoDueDateCards. + */ +export interface EverythingNoDueDateCardsEverythingOptions extends PaginationOptions { +} + +/** + * Options for everythingNotNowCards. + */ +export interface EverythingNotNowCardsEverythingOptions extends PaginationOptions { +} + +/** + * Options for everythingOpenCards. + */ +export interface EverythingOpenCardsEverythingOptions extends PaginationOptions { +} + +/** + * Options for everythingUnassignedCards. + */ +export interface EverythingUnassignedCardsEverythingOptions extends PaginationOptions { +} + /** * Options for everythingCheckins. */ @@ -60,6 +90,30 @@ export interface EverythingForwardsEverythingOptions extends PaginationOptions { export interface EverythingMessagesEverythingOptions extends PaginationOptions { } +/** + * Options for everythingCompletedTodos. + */ +export interface EverythingCompletedTodosEverythingOptions extends PaginationOptions { +} + +/** + * Options for everythingNoDueDateTodos. + */ +export interface EverythingNoDueDateTodosEverythingOptions extends PaginationOptions { +} + +/** + * Options for everythingOpenTodos. + */ +export interface EverythingOpenTodosEverythingOptions extends PaginationOptions { +} + +/** + * Options for everythingUnassignedTodos. + */ +export interface EverythingUnassignedTodosEverythingOptions extends PaginationOptions { +} + // ============================================================================= // Service @@ -95,6 +149,106 @@ export class EverythingService extends BaseService { ); } + /** + * Get completed cards across all accessible projects, grouped by project + * @param options - Optional query parameters + * @returns All results across all pages, with .meta.totalCount + * + * @example + * ```ts + * const result = await client.everything.everythingCompletedCards(); + * ``` + */ + async everythingCompletedCards(options?: EverythingCompletedCardsEverythingOptions): Promise { + return this.requestPaginated( + { + service: "Everything", + operation: "GetEverythingCompletedCards", + resourceType: "everything_completed_card", + isMutation: false, + }, + () => + this.client.GET("/cards/completed.json", { + }) + , options + ); + } + + /** + * Get open cards with no due date across all accessible projects, grouped by + * @param options - Optional query parameters + * @returns All results across all pages, with .meta.totalCount + * + * @example + * ```ts + * const result = await client.everything.everythingNoDueDateCards(); + * ``` + */ + async everythingNoDueDateCards(options?: EverythingNoDueDateCardsEverythingOptions): Promise { + return this.requestPaginated( + { + service: "Everything", + operation: "GetEverythingNoDueDateCards", + resourceType: "everything_no_due_date_card", + isMutation: false, + }, + () => + this.client.GET("/cards/no_due_date.json", { + }) + , options + ); + } + + /** + * Get cards parked in a project's "Not now" column across all accessible + * @param options - Optional query parameters + * @returns All results across all pages, with .meta.totalCount + * + * @example + * ```ts + * const result = await client.everything.everythingNotNowCards(); + * ``` + */ + async everythingNotNowCards(options?: EverythingNotNowCardsEverythingOptions): Promise { + return this.requestPaginated( + { + service: "Everything", + operation: "GetEverythingNotNowCards", + resourceType: "everything_not_now_card", + isMutation: false, + }, + () => + this.client.GET("/cards/not_now.json", { + }) + , options + ); + } + + /** + * Get incomplete cards in active columns across all accessible projects, + * @param options - Optional query parameters + * @returns All results across all pages, with .meta.totalCount + * + * @example + * ```ts + * const result = await client.everything.everythingOpenCards(); + * ``` + */ + async everythingOpenCards(options?: EverythingOpenCardsEverythingOptions): Promise { + return this.requestPaginated( + { + service: "Everything", + operation: "GetEverythingOpenCards", + resourceType: "everything_open_card", + isMutation: false, + }, + () => + this.client.GET("/cards/open.json", { + }) + , options + ); + } + /** * Get every overdue card across all accessible projects — a complete, * @returns Array of Card @@ -119,6 +273,31 @@ export class EverythingService extends BaseService { return response ?? []; } + /** + * Get open, unassigned cards across all accessible projects, grouped by + * @param options - Optional query parameters + * @returns All results across all pages, with .meta.totalCount + * + * @example + * ```ts + * const result = await client.everything.everythingUnassignedCards(); + * ``` + */ + async everythingUnassignedCards(options?: EverythingUnassignedCardsEverythingOptions): Promise { + return this.requestPaginated( + { + service: "Everything", + operation: "GetEverythingUnassignedCards", + resourceType: "everything_unassigned_card", + isMutation: false, + }, + () => + this.client.GET("/cards/unassigned.json", { + }) + , options + ); + } + /** * Get every automatic check-in answer across all accessible projects, * @param options - Optional query parameters @@ -247,6 +426,81 @@ export class EverythingService extends BaseService { ); } + /** + * Get completed to-dos across all accessible projects, grouped by project + * @param options - Optional query parameters + * @returns All results across all pages, with .meta.totalCount + * + * @example + * ```ts + * const result = await client.everything.everythingCompletedTodos(); + * ``` + */ + async everythingCompletedTodos(options?: EverythingCompletedTodosEverythingOptions): Promise { + return this.requestPaginated( + { + service: "Everything", + operation: "GetEverythingCompletedTodos", + resourceType: "everything_completed_todo", + isMutation: false, + }, + () => + this.client.GET("/todos/completed.json", { + }) + , options + ); + } + + /** + * Get open to-dos with no due date across all accessible projects, grouped by + * @param options - Optional query parameters + * @returns All results across all pages, with .meta.totalCount + * + * @example + * ```ts + * const result = await client.everything.everythingNoDueDateTodos(); + * ``` + */ + async everythingNoDueDateTodos(options?: EverythingNoDueDateTodosEverythingOptions): Promise { + return this.requestPaginated( + { + service: "Everything", + operation: "GetEverythingNoDueDateTodos", + resourceType: "everything_no_due_date_todo", + isMutation: false, + }, + () => + this.client.GET("/todos/no_due_date.json", { + }) + , options + ); + } + + /** + * Get active, incomplete to-dos across all accessible projects, grouped by + * @param options - Optional query parameters + * @returns All results across all pages, with .meta.totalCount + * + * @example + * ```ts + * const result = await client.everything.everythingOpenTodos(); + * ``` + */ + async everythingOpenTodos(options?: EverythingOpenTodosEverythingOptions): Promise { + return this.requestPaginated( + { + service: "Everything", + operation: "GetEverythingOpenTodos", + resourceType: "everything_open_todo", + isMutation: false, + }, + () => + this.client.GET("/todos/open.json", { + }) + , options + ); + } + /** * Get every overdue to-do across all accessible projects — a complete, * @returns Array of Todo @@ -270,4 +524,29 @@ export class EverythingService extends BaseService { ); return response ?? []; } + + /** + * Get open, unassigned to-dos across all accessible projects, grouped by + * @param options - Optional query parameters + * @returns All results across all pages, with .meta.totalCount + * + * @example + * ```ts + * const result = await client.everything.everythingUnassignedTodos(); + * ``` + */ + async everythingUnassignedTodos(options?: EverythingUnassignedTodosEverythingOptions): Promise { + return this.requestPaginated( + { + service: "Everything", + operation: "GetEverythingUnassignedTodos", + resourceType: "everything_unassigned_todo", + isMutation: false, + }, + () => + this.client.GET("/todos/unassigned.json", { + }) + , options + ); + } } \ No newline at end of file