{ "openapi": "3.1.0", "info": { "title": "Basecamp", "version": "2026-08-11", "description": "Basecamp API", "contact": { "name": "Basecamp", "url": "https://github.com/basecamp/basecamp-sdk" }, "license": { "name": "MIT", "url": "https://github.com/basecamp/basecamp-sdk/blob/main/LICENSE" } }, "paths": { "/{accountId}/account.json": { "get": { "description": "Get the account for the current access token", "operationId": "GetAccount", "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": "GetAccount 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetAccountResponseContent" } } } }, "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" } } } }, "500": { "description": "InternalServerError 500 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/InternalServerErrorResponseContent" } } } } }, "tags": [ "Account" ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/account/logo.json": { "delete": { "description": "Remove the account logo. Only administrators and account owners can use this endpoint.", "operationId": "RemoveAccountLogo", "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": { "204": { "description": "RemoveAccountLogo 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" } } } }, "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": [ "Account" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } }, "put": { "description": "Upload or replace the account logo.\nAccepted formats: PNG, JPEG, GIF, WebP, AVIF, HEIC. Maximum 5 MB.\nOwners and admins only.", "operationId": "UpdateAccountLogo", "requestBody": { "required": true, "content": { "multipart/form-data": { "schema": { "type": "object", "properties": { "logo": { "type": "string", "format": "binary" } }, "required": [ "logo" ] } } } }, "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": { "204": { "description": "UpdateAccountLogo 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" } } } } }, "tags": [ "Account" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-multipart": { "field": "logo" }, "x-basecamp-retry": { "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/account/name.json": { "put": { "description": "Rename the current account. Only account owners can use this endpoint.", "operationId": "UpdateAccountName", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateAccountNameRequestContent" } } }, "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 } ], "responses": { "200": { "description": "UpdateAccountName 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateAccountNameResponseContent" } } } }, "400": { "description": "BadRequestError 400 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BadRequestErrorResponseContent" } } } }, "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": [ "Account" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/attachments.json": { "post": { "description": "Create an attachment (upload a file for embedding)", "operationId": "CreateAttachment", "requestBody": { "content": { "application/octet-stream": { "schema": { "$ref": "#/components/schemas/CreateAttachmentInputPayload" } } }, "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": "name", "in": "query", "schema": { "type": "string" }, "required": true } ], "responses": { "201": { "description": "CreateAttachment 201 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateAttachmentResponseContent" } } } }, "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" } } } }, "507": { "description": "StorageLimitError 507 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/StorageLimitErrorResponseContent" } } } } }, "tags": [ "Files" ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 2000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/boosts/{boostId}": { "delete": { "description": "Delete a boost", "operationId": "DeleteBoost", "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": "boostId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "204": { "description": "DeleteBoost 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": [ "Boosts" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } }, "get": { "description": "Get a single boost", "operationId": "GetBoost", "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": "boostId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "GetBoost 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetBoostResponseContent" } } } }, "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": [ "Boosts" ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/buckets/{bucketId}/card_tables/columns/{columnId}/color.json": { "put": { "description": "Set the color of a column", "operationId": "SetCardColumnColor", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SetCardColumnColorRequestContent" } } }, "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": "bucketId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true }, { "name": "columnId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "SetCardColumnColor 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SetCardColumnColorResponseContent" } } } }, "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" } } } }, "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": [ "Card Tables" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/buckets/{bucketId}/card_tables/columns/{columnId}/on_hold.json": { "delete": { "description": "Disable on-hold section in a column", "operationId": "DisableCardColumnOnHold", "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": "bucketId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true }, { "name": "columnId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "DisableCardColumnOnHold 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DisableCardColumnOnHoldResponseContent" } } } }, "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" } } } } }, "tags": [ "Card Tables" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } }, "post": { "description": "Enable on-hold section in a column", "operationId": "EnableCardColumnOnHold", "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": "bucketId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true }, { "name": "columnId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "EnableCardColumnOnHold 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EnableCardColumnOnHoldResponseContent" } } } }, "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": [ "Card Tables" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/buckets/{bucketId}/card_tables/wormholes/{wormholeId}": { "delete": { "description": "Delete a wormhole", "operationId": "DeleteWormhole", "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": "bucketId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true }, { "name": "wormholeId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "204": { "description": "DeleteWormhole 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" } } } }, "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": [ "Card Tables" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } }, "put": { "description": "Update a wormhole's destination column", "operationId": "UpdateWormhole", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateWormholeRequestContent" } } }, "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": "bucketId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true }, { "name": "wormholeId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "UpdateWormhole 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateWormholeResponseContent" } } } }, "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": [ "Card Tables" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/buckets/{bucketId}/card_tables/{cardTableId}/wormholes.json": { "post": { "description": "Create a wormhole linking this card table to a column on another card table.\n\nA wormhole is the only mechanism for moving a card to a different project: its\nid is a valid `column_id` for MoveCard, teleporting the card across projects.\n`destinationRecordingId` is the id of a column on another accessible card table.", "operationId": "CreateWormhole", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateWormholeRequestContent" } } }, "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": "bucketId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true }, { "name": "cardTableId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "201": { "description": "CreateWormhole 201 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateWormholeResponseContent" } } } }, "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" } } } }, "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": [ "Card Tables" ], "x-basecamp-retry": { "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/buckets/{bucketId}/categories.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", "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": "bucketId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "ListMessageTypes 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListMessageTypesResponseContent" } } } }, "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 message type in a project", "operationId": "CreateMessageType", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateMessageTypeRequestContent" } } }, "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": "bucketId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "201": { "description": "CreateMessageType 201 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateMessageTypeResponseContent" } } } }, "400": { "description": "BareFieldBadRequestError 400 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BareFieldBadRequestErrorResponseContent" } } } }, "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-retry": { "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/buckets/{bucketId}/categories/{typeId}": { "delete": { "description": "Delete a message type", "operationId": "DeleteMessageType", "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": "bucketId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true }, { "name": "typeId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "204": { "description": "DeleteMessageType 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": [ "Messages" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } }, "get": { "description": "Get a single message type by id", "operationId": "GetMessageType", "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": "bucketId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true }, { "name": "typeId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "GetMessageType 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetMessageTypeResponseContent" } } } }, "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": [ "Messages" ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } }, "put": { "description": "Update an existing message type", "operationId": "UpdateMessageType", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateMessageTypeRequestContent" } } } }, "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": "bucketId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true }, { "name": "typeId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "UpdateMessageType 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateMessageTypeResponseContent" } } } }, "400": { "description": "BareFieldBadRequestError 400 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BareFieldBadRequestErrorResponseContent" } } } }, "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": [ "Messages" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/buckets/{bucketId}/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", "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": "bucketId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true }, { "name": "campfireId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "ListChatbots 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListChatbotsResponseContent" } } } }, "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": [ "Campfire" ], "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 chatbot for a campfire", "operationId": "CreateChatbot", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateChatbotRequestContent" } } }, "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": "bucketId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true }, { "name": "campfireId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "201": { "description": "CreateChatbot 201 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateChatbotResponseContent" } } } }, "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": [ "Campfire" ], "x-basecamp-retry": { "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/buckets/{bucketId}/chats/{campfireId}/integrations/{chatbotId}": { "delete": { "description": "Delete a chatbot", "operationId": "DeleteChatbot", "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": "bucketId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "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": { "204": { "description": "DeleteChatbot 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": [ "Campfire" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } }, "get": { "description": "Get a chatbot by ID", "operationId": "GetChatbot", "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": "bucketId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "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", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetChatbotResponseContent" } } } }, "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": [ "Campfire" ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } }, "put": { "description": "Update an existing chatbot", "operationId": "UpdateChatbot", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateChatbotRequestContent" } } }, "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": "bucketId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "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": "UpdateChatbot 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateChatbotResponseContent" } } } }, "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": [ "Campfire" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/buckets/{bucketId}/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", "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": "bucketId", "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" } }, { "name": "page", "in": "query", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "responses": { "200": { "description": "ListClientApprovals 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListClientApprovalsResponseContent" } } } }, "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": [ "ClientFeatures" ], "x-basecamp-pagination": { "style": "link", "totalCountHeader": "X-Total-Count", "maxPageSize": 50 }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/buckets/{bucketId}/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", "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": "bucketId", "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" } }, { "name": "page", "in": "query", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "responses": { "200": { "description": "ListClientCorrespondences 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListClientCorrespondencesResponseContent" } } } }, "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": [ "ClientFeatures" ], "x-basecamp-pagination": { "style": "link", "totalCountHeader": "X-Total-Count", "maxPageSize": 50 }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/buckets/{bucketId}/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", "in": "path", "description": "Basecamp account ID (numeric string)", "schema": { "type": "string", "pattern": "^[0-9]+$", "description": "Basecamp account ID (numeric string)" }, "required": true }, { "name": "bucketId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true }, { "name": "recordingId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true }, { "name": "page", "in": "query", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "responses": { "200": { "description": "ListClientReplies 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListClientRepliesResponseContent" } } } }, "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": [ "ClientFeatures" ], "x-basecamp-pagination": { "style": "link", "totalCountHeader": "X-Total-Count", "maxPageSize": 50 }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/buckets/{bucketId}/client/recordings/{recordingId}/replies/{replyId}": { "get": { "description": "Get a single client reply by id", "operationId": "GetClientReply", "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": "bucketId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true }, { "name": "recordingId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true }, { "name": "replyId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "GetClientReply 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetClientReplyResponseContent" } } } }, "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": [ "ClientFeatures" ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/buckets/{bucketId}/dock/tools.json": { "post": { "description": "Create a tool in a project dock", "operationId": "CreateTool", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateToolRequestContent" } } }, "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": "bucketId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "201": { "description": "CreateTool 201 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateToolResponseContent" } } } }, "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 ] } } }, "/{accountId}/buckets/{bucketId}/todosets/{todosetId}/todos.json": { "post": { "description": "Create a to-do directly under a project's to-do set, outside any to-do list.\nThis form exists only project-scoped (no account-scoped variant); parameters\nand response match the to-do-list create. Find a project's to-do set id via\nGetTodoset.", "operationId": "CreateTodosetTodo", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateTodosetTodoRequestContent" } } }, "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": "bucketId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true }, { "name": "todosetId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "201": { "description": "CreateTodosetTodo 201 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateTodosetTodoResponseContent" } } } }, "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": [ "Todos" ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/buckets/{bucketId}/vaults/{vaultId}/cloud_files.json": { "post": { "description": "Create a new cloud file in a vault.\n`url` is validated against the selected service's patterns, so it must be a\nreal link for that service; use service \"other\" for anything that matches no\nrecognized service. Omitting `title` is allowed and reads back as\n\"Untitled\".", "operationId": "CreateCloudFile", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateCloudFileRequestContent" } } }, "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": "bucketId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true }, { "name": "vaultId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "201": { "description": "CreateCloudFile 201 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateCloudFileResponseContent" } } } }, "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": "FieldValidationError 422 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FieldValidationErrorResponseContent" } } } }, "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": [ "Files" ], "x-basecamp-retry": { "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/buckets/{bucketId}/vaults/{vaultId}/google_documents.json": { "post": { "description": "Create a new Google document in a vault.\nAn unrecognized `document_type` is rejected before validation with the\nfield-keyed 422 {\"errors\": {\"document_type\": [\"is not a valid document\ntype\"]}} — the enum would otherwise raise rather than add an error.\nOmitting `title` is allowed and reads back as \"Untitled\".", "operationId": "CreateGoogleDocument", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateGoogleDocumentRequestContent" } } }, "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": "bucketId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true }, { "name": "vaultId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "201": { "description": "CreateGoogleDocument 201 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateGoogleDocumentResponseContent" } } } }, "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": "FieldValidationError 422 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FieldValidationErrorResponseContent" } } } }, "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": [ "Files" ], "x-basecamp-retry": { "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/buckets/{bucketId}/webhooks.json": { "get": { "description": "List all webhooks for 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": "ListWebhooks", "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": "bucketId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "ListWebhooks 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListWebhooksResponseContent" } } } }, "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 webhook for a project", "operationId": "CreateWebhook", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateWebhookRequestContent" } } }, "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": "bucketId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "201": { "description": "CreateWebhook 201 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateWebhookResponseContent" } } } }, "400": { "description": "BareFieldBadRequestError 400 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BareFieldBadRequestErrorResponseContent" } } } }, "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" } } } }, "507": { "description": "WebhookLimitError 507 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/WebhookLimitErrorResponseContent" } } } } }, "tags": [ "Automation" ], "x-basecamp-retry": { "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/calendars/{calendarId}": { "get": { "description": "Get a calendar by its bucket id. A Calendar is a top-level BC5 bucketable\n(distinct from a project) exposing display metadata and a link to its\nunderlying schedule resource. Shipped scope is show + update only.", "operationId": "GetCalendar", "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": "calendarId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "GetCalendar 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetCalendarResponseContent" } } } }, "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" } } } } }, "tags": [ "Calendars" ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } }, "put": { "description": "Update a calendar's display color. An unknown color returns 422 with a JSON\nerrors payload keyed by field ({\"errors\": {\"color\": [\"is not a valid\ncolor\"]}}) — the controller rejects invalid enum values up front.", "operationId": "UpdateCalendar", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateCalendarRequestContent" } } }, "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": "calendarId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "UpdateCalendar 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateCalendarResponseContent" } } } }, "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": "FieldValidationError 422 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FieldValidationErrorResponseContent" } } } }, "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": [ "Calendars" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/card_tables/cards/{cardId}": { "get": { "description": "Get a card by ID", "operationId": "GetCard", "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": "cardId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "GetCard 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetCardResponseContent" } } } }, "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": [ "Card Tables" ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } }, "put": { "description": "Update an existing card", "operationId": "UpdateCard", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateCardRequestContent" } } } }, "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": "cardId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "UpdateCard 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateCardResponseContent" } } } }, "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": [ "Card Tables" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/card_tables/cards/{cardId}/moves.json": { "post": { "description": "Move a card to a different column", "operationId": "MoveCard", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MoveCardRequestContent" } } }, "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": "cardId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "204": { "description": "MoveCard 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" } } } } }, "tags": [ "Card Tables" ], "x-basecamp-retry": { "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/card_tables/cards/{cardId}/positions.json": { "post": { "description": "Reposition a step within a card", "operationId": "RepositionCardStep", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RepositionCardStepRequestContent" } } }, "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": "cardId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "RepositionCardStep 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" } } } }, "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": [ "Card Tables" ], "x-basecamp-retry": { "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/card_tables/cards/{cardId}/steps.json": { "post": { "description": "Create a step on a card", "operationId": "CreateCardStep", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateCardStepRequestContent" } } }, "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": "cardId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "201": { "description": "CreateCardStep 201 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateCardStepResponseContent" } } } }, "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": [ "Card Tables" ], "x-basecamp-retry": { "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/card_tables/columns/{columnId}": { "get": { "description": "Get a card column by ID", "operationId": "GetCardColumn", "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": "columnId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "GetCardColumn 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetCardColumnResponseContent" } } } }, "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": [ "Card Tables" ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } }, "put": { "description": "Update an existing column", "operationId": "UpdateCardColumn", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateCardColumnRequestContent" } } } }, "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": "columnId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "UpdateCardColumn 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateCardColumnResponseContent" } } } }, "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": [ "Card Tables" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/card_tables/lists/{columnId}/cards.json": { "get": { "description": "List cards in a column\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", "operationId": "ListCards", "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": "columnId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true }, { "name": "page", "in": "query", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "responses": { "200": { "description": "ListCards 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListCardsResponseContent" } } } }, "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": [ "Card Tables" ], "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 card in a column", "operationId": "CreateCard", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateCardRequestContent" } } }, "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": "columnId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "201": { "description": "CreateCard 201 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateCardResponseContent" } } } }, "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": [ "Card Tables" ], "x-basecamp-retry": { "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/card_tables/lists/{columnId}/subscription.json": { "delete": { "description": "Unsubscribe from a card column (stop watching for changes)", "operationId": "UnsubscribeFromCardColumn", "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": "columnId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "204": { "description": "UnsubscribeFromCardColumn 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" } } } } }, "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } }, "post": { "description": "Subscribe to a card column (watch for changes)", "operationId": "SubscribeToCardColumn", "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": "columnId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "204": { "description": "SubscribeToCardColumn 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" } } } }, "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-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/card_tables/steps/{stepId}": { "get": { "description": "Get a step by ID", "operationId": "GetCardStep", "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": "stepId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "GetCardStep 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetCardStepResponseContent" } } } }, "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": [ "Card Tables" ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } }, "put": { "description": "Update an existing step", "operationId": "UpdateCardStep", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateCardStepRequestContent" } } } }, "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": "stepId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "UpdateCardStep 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateCardStepResponseContent" } } } }, "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": [ "Card Tables" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/card_tables/steps/{stepId}/completions.json": { "put": { "description": "Set card step completion status (PUT with completion: \"on\" to complete, \"\" to uncomplete)", "operationId": "SetCardStepCompletion", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SetCardStepCompletionRequestContent" } } }, "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": "stepId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "SetCardStepCompletion 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SetCardStepCompletionResponseContent" } } } }, "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": [ "Card Tables" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/card_tables/{cardTableId}": { "get": { "description": "Get a card table by ID", "operationId": "GetCardTable", "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": "cardTableId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "GetCardTable 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetCardTableResponseContent" } } } }, "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": [ "Card Tables" ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/card_tables/{cardTableId}/columns.json": { "post": { "description": "Create a column in a card table", "operationId": "CreateCardColumn", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateCardColumnRequestContent" } } }, "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": "cardTableId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "201": { "description": "CreateCardColumn 201 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateCardColumnResponseContent" } } } }, "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": [ "Card Tables" ], "x-basecamp-retry": { "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/card_tables/{cardTableId}/moves.json": { "post": { "description": "Move a column within a card table", "operationId": "MoveCardColumn", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MoveCardColumnRequestContent" } } }, "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": "cardTableId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "204": { "description": "MoveCardColumn 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" } } } } }, "tags": [ "Card Tables" ], "x-basecamp-retry": { "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/cards/completed.json": { "get": { "description": "Completed cards across all accessible projects, grouped by project (paginated).", "operationId": "GetEverythingCompletedCards", "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": "assignee_ids[]", "in": "query", "description": "Restrict to tasks assigned to at least one of the given people (repeatable).\nAssignees on nested steps are not considered.", "style": "form", "schema": { "type": "array", "items": { "type": "integer", "format": "int64" }, "description": "Restrict to tasks assigned to at least one of the given people (repeatable).\nAssignees on nested steps are not considered." }, "explode": true }, { "name": "due", "in": "query", "description": "Filter by due date: with, without, or overdue. Unrecognized values are ignored.", "schema": { "type": "string", "description": "Filter by due date: with, without, or overdue. Unrecognized values are ignored." } }, { "name": "page", "in": "query", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "responses": { "200": { "description": "GetEverythingCompletedCards 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetEverythingCompletedCardsResponseContent" } } } }, "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": [ "Everything" ], "x-basecamp-pagination": { "style": "link", "totalCountHeader": "X-Total-Count", "maxPageSize": 5 }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/cards/no_due_date.json": { "get": { "description": "Open cards with no due date across all accessible projects, grouped by project (paginated).", "operationId": "GetEverythingNoDueDateCards", "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": "assignee_ids[]", "in": "query", "description": "Restrict to tasks assigned to at least one of the given people (repeatable).\nAssignees on nested steps are not considered.", "style": "form", "schema": { "type": "array", "items": { "type": "integer", "format": "int64" }, "description": "Restrict to tasks assigned to at least one of the given people (repeatable).\nAssignees on nested steps are not considered." }, "explode": true }, { "name": "due", "in": "query", "description": "Filter by due date: with, without, or overdue. Unrecognized values are ignored.", "schema": { "type": "string", "description": "Filter by due date: with, without, or overdue. Unrecognized values are ignored." } }, { "name": "page", "in": "query", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "responses": { "200": { "description": "GetEverythingNoDueDateCards 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetEverythingNoDueDateCardsResponseContent" } } } }, "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": [ "Everything" ], "x-basecamp-pagination": { "style": "link", "totalCountHeader": "X-Total-Count", "maxPageSize": 5 }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/cards/not_now.json": { "get": { "description": "Cards parked in a project's \"Not now\" column across all accessible projects, grouped by project (paginated).", "operationId": "GetEverythingNotNowCards", "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": "assignee_ids[]", "in": "query", "description": "Restrict to tasks assigned to at least one of the given people (repeatable).\nAssignees on nested steps are not considered.", "style": "form", "schema": { "type": "array", "items": { "type": "integer", "format": "int64" }, "description": "Restrict to tasks assigned to at least one of the given people (repeatable).\nAssignees on nested steps are not considered." }, "explode": true }, { "name": "due", "in": "query", "description": "Filter by due date: with, without, or overdue. Unrecognized values are ignored.", "schema": { "type": "string", "description": "Filter by due date: with, without, or overdue. Unrecognized values are ignored." } }, { "name": "page", "in": "query", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "responses": { "200": { "description": "GetEverythingNotNowCards 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetEverythingNotNowCardsResponseContent" } } } }, "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": [ "Everything" ], "x-basecamp-pagination": { "style": "link", "totalCountHeader": "X-Total-Count", "maxPageSize": 5 }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/cards/open.json": { "get": { "description": "Incomplete cards in active columns across all accessible projects, grouped by project (paginated).\nEach bucket entry carries the matching cards and their steps.", "operationId": "GetEverythingOpenCards", "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": "assignee_ids[]", "in": "query", "description": "Restrict to tasks assigned to at least one of the given people (repeatable).\nAssignees on nested steps are not considered.", "style": "form", "schema": { "type": "array", "items": { "type": "integer", "format": "int64" }, "description": "Restrict to tasks assigned to at least one of the given people (repeatable).\nAssignees on nested steps are not considered." }, "explode": true }, { "name": "due", "in": "query", "description": "Filter by due date: with, without, or overdue. Unrecognized values are ignored.", "schema": { "type": "string", "description": "Filter by due date: with, without, or overdue. Unrecognized values are ignored." } }, { "name": "page", "in": "query", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "responses": { "200": { "description": "GetEverythingOpenCards 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetEverythingOpenCardsResponseContent" } } } }, "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": [ "Everything" ], "x-basecamp-pagination": { "style": "link", "totalCountHeader": "X-Total-Count", "maxPageSize": 5 }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/cards/overdue.json": { "get": { "description": "Get every overdue card across all accessible projects, oldest-due-date-first.\nA complete, unpaginated array; each item embeds its `bucket`.", "operationId": "GetEverythingOverdueCards", "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": "assignee_ids[]", "in": "query", "description": "Restrict to tasks assigned to at least one of the given people (repeatable).\nAssignees on nested steps are not considered.", "style": "form", "schema": { "type": "array", "items": { "type": "integer", "format": "int64" }, "description": "Restrict to tasks assigned to at least one of the given people (repeatable).\nAssignees on nested steps are not considered." }, "explode": true }, { "name": "due", "in": "query", "description": "Filter by due date: with, without, or overdue. Unrecognized values are ignored.", "schema": { "type": "string", "description": "Filter by due date: with, without, or overdue. Unrecognized values are ignored." } } ], "responses": { "200": { "description": "GetEverythingOverdueCards 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetEverythingOverdueCardsResponseContent" } } } }, "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": [ "Everything" ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/cards/unassigned.json": { "get": { "description": "Open, unassigned cards across all accessible projects, grouped by project (paginated).", "operationId": "GetEverythingUnassignedCards", "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": "assignee_ids[]", "in": "query", "description": "Restrict to tasks assigned to at least one of the given people (repeatable).\nAssignees on nested steps are not considered.", "style": "form", "schema": { "type": "array", "items": { "type": "integer", "format": "int64" }, "description": "Restrict to tasks assigned to at least one of the given people (repeatable).\nAssignees on nested steps are not considered." }, "explode": true }, { "name": "due", "in": "query", "description": "Filter by due date: with, without, or overdue. Unrecognized values are ignored.", "schema": { "type": "string", "description": "Filter by due date: with, without, or overdue. Unrecognized values are ignored." } }, { "name": "page", "in": "query", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "responses": { "200": { "description": "GetEverythingUnassignedCards 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetEverythingUnassignedCardsResponseContent" } } } }, "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": [ "Everything" ], "x-basecamp-pagination": { "style": "link", "totalCountHeader": "X-Total-Count", "maxPageSize": 5 }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/chats.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", "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": "page", "in": "query", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "responses": { "200": { "description": "ListCampfires 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListCampfiresResponseContent" } } } }, "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": [ "Campfire" ], "x-basecamp-pagination": { "style": "link", "totalCountHeader": "X-Total-Count", "maxPageSize": 50 }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/chats/{campfireId}": { "get": { "description": "Get a campfire by ID", "operationId": "GetCampfire", "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": "campfireId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "GetCampfire 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetCampfireResponseContent" } } } }, "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": [ "Campfire" ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/chats/{campfireId}/lines.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", "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": "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" } }, { "name": "page", "in": "query", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "responses": { "200": { "description": "ListCampfireLines 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListCampfireLinesResponseContent" } } } }, "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": [ "Campfire" ], "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 line (message) in a campfire", "operationId": "CreateCampfireLine", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateCampfireLineRequestContent" } } }, "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": "campfireId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "201": { "description": "CreateCampfireLine 201 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateCampfireLineResponseContent" } } } }, "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": [ "Campfire" ], "x-basecamp-retry": { "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{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", "in": "path", "description": "Basecamp account ID (numeric string)", "schema": { "type": "string", "pattern": "^[0-9]+$", "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": { "204": { "description": "DeleteCampfireLine 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": [ "Campfire" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } }, "get": { "description": "Get a campfire line by ID", "operationId": "GetCampfireLine", "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": "campfireId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true }, { "name": "lineId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "GetCampfireLine 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetCampfireLineResponseContent" } } } }, "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": [ "Campfire" ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } }, "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", "in": "path", "description": "Basecamp account ID (numeric string)", "schema": { "type": "string", "pattern": "^[0-9]+$", "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": { "204": { "description": "UpdateCampfireLine 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" } } } }, "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": [ "Campfire" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/chats/{campfireId}/uploads.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", "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": "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" } }, { "name": "page", "in": "query", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "responses": { "200": { "description": "ListCampfireUploads 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListCampfireUploadsResponseContent" } } } }, "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": [ "Campfire" ], "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": "Upload a file to a campfire", "operationId": "CreateCampfireUpload", "requestBody": { "content": { "application/octet-stream": { "schema": { "$ref": "#/components/schemas/CreateCampfireUploadInputPayload" } } }, "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": "campfireId", "in": "path", "schema": { "type": "integer", "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", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateCampfireUploadResponseContent" } } } }, "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" } } } }, "507": { "description": "StorageLimitError 507 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/StorageLimitErrorResponseContent" } } } } }, "tags": [ "Campfire" ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 2000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/checkins.json": { "get": { "description": "Get every automatic check-in answer across all accessible projects, newest-first.\nPaginated; each item embeds its `bucket`.", "operationId": "GetEverythingCheckins", "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": "page", "in": "query", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "responses": { "200": { "description": "GetEverythingCheckins 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetEverythingCheckinsResponseContent" } } } }, "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": [ "Everything" ], "x-basecamp-pagination": { "style": "link", "totalCountHeader": "X-Total-Count", "maxPageSize": 50 }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 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", "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": "ListPingablePeople 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListPingablePeopleResponseContent" } } } }, "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": [ "People" ], "x-basecamp-pagination": { "style": "link", "totalCountHeader": "X-Total-Count", "maxPageSize": 50 }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/client/approvals/{approvalId}": { "get": { "description": "Get a single client approval by id", "operationId": "GetClientApproval", "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": "approvalId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "GetClientApproval 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetClientApprovalResponseContent" } } } }, "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": [ "ClientFeatures" ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/client/correspondences/{correspondenceId}": { "get": { "description": "Get a single client correspondence by id", "operationId": "GetClientCorrespondence", "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": "correspondenceId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "GetClientCorrespondence 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetClientCorrespondenceResponseContent" } } } }, "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": [ "ClientFeatures" ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/cloud_files/{cloudFileId}": { "get": { "description": "Get a single cloud file by id", "operationId": "GetCloudFile", "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": "cloudFileId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "GetCloudFile 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetCloudFileResponseContent" } } } }, "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": [ "Files" ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } }, "put": { "description": "Replace a cloud file with a new complete representation.\nBC3 builds a brand-new CloudFile from the permitted params and swaps the\nrecordable wholesale, so the request body is the full writable state:\nomitting `title` clears it (and the cloud file then reads back as\n\"Untitled\"), and omitting `description` clears it. `url` and `service` carry\npresence/format validations, so they are required here rather than\nclearable — a request without them is a 422, not a silent wipe.\nUpdating a drafted cloud file also publishes it.\nSubscribers are the exception to omission-clears: a drafted cloud file keeps\nits current subscribers when the request addresses neither `subscriptions`\nnor `notify`. The creator is always on the list.\nThe legacy bucket-scoped path PUT /buckets/{bucketId}/cloud_files/{id}.json\nis also accepted by BC3; this flat spelling is the documented one.", "operationId": "UpdateCloudFile", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateCloudFileRequestContent" } } }, "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": "cloudFileId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "UpdateCloudFile 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateCloudFileResponseContent" } } } }, "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": "FieldValidationError 422 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FieldValidationErrorResponseContent" } } } }, "500": { "description": "InternalServerError 500 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/InternalServerErrorResponseContent" } } } } }, "tags": [ "Files" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] }, "x-basecamp-write-semantics": { "mode": "replace", "clearsOmitted": 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", "in": "path", "description": "Basecamp account ID (numeric string)", "schema": { "type": "string", "pattern": "^[0-9]+$", "description": "Basecamp account ID (numeric string)" }, "required": true }, { "name": "page", "in": "query", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "responses": { "200": { "description": "GetEverythingComments 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetEverythingCommentsResponseContent" } } } }, "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": [ "Everything" ], "x-basecamp-pagination": { "style": "link", "totalCountHeader": "X-Total-Count", "maxPageSize": 50 }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/comments/{commentId}": { "get": { "description": "Get a single comment by id", "operationId": "GetComment", "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": "commentId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "GetComment 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetCommentResponseContent" } } } }, "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": [ "Messages" ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } }, "put": { "description": "Update an existing comment", "operationId": "UpdateComment", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateCommentRequestContent" } } }, "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": "commentId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "UpdateComment 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateCommentResponseContent" } } } }, "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": [ "Messages" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/dock/tools/{toolId}": { "delete": { "description": "Delete a tool (trash it)", "operationId": "DeleteTool", "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": "DeleteTool 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 ] } }, "get": { "description": "Get a dock tool by id", "operationId": "GetTool", "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": "GetTool 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetToolResponseContent" } } } }, "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 ] } }, "put": { "description": "Update (rename) an existing tool", "operationId": "UpdateTool", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateToolRequestContent" } } }, "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": "UpdateTool 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateToolResponseContent" } } } }, "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}/documents/{documentId}": { "get": { "description": "Get a single document by id", "operationId": "GetDocument", "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": "documentId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "GetDocument 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetDocumentResponseContent" } } } }, "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": [ "Files" ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } }, "put": { "description": "Replace a document with a new complete representation.\nThe request body is the document's full writable state: any writable field\nomitted from the request is cleared server-side. Omitting content clears it;\nomitting title clears it too, and the document then reads back as\n\"Untitled\" (Document#title falls back when blank).\nNeither field is required. BC3 builds a brand-new Document from the\npermitted params and swaps the recordable wholesale, and neither attribute\ncarries a presence validation — so an omission is a 200 that clears, not a\n422. What BC3 does require is the wrapping document object, which Rails\nsynthesizes from a flat body, so a request naming neither field is a 400.\nPublishing a draft (status: \"active\") is not modeled: the SDK sends only\ntitle and content, and BC3 rejects a status-only update for the same\nreason it 400s an empty body.\nSubscribers are the one exception to omission-clears. A drafted document\nkeeps its current subscribers when the request addresses neither\nsubscriptions nor notify, so a full-representation PUT that mentions\nneither is safe on a draft.\nTo set some fields while preserving the rest, use the SDK's merge-safe\nupdate or edit methods, which GET the current document and PUT the full\nrepresentation back. Those read-modify-write helpers are not atomic:\na concurrent write between the GET and PUT is overwritten (last write\nwins for the whole representation; the window is one round-trip).", "operationId": "ReplaceDocument", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ReplaceDocumentRequestContent" } } } }, "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": "documentId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "ReplaceDocument 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ReplaceDocumentResponseContent" } } } }, "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": [ "Files" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] }, "x-basecamp-write-semantics": { "mode": "replace", "clearsOmitted": true } } }, "/{accountId}/files.json": { "get": { "description": "Get every file recording across all accessible projects, newest-first (paginated).\nHeterogeneous: 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", "in": "path", "description": "Basecamp account ID (numeric string)", "schema": { "type": "string", "pattern": "^[0-9]+$", "description": "Basecamp account ID (numeric string)" }, "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", "schema": { "type": "array", "items": { "type": "integer", "format": "int64" }, "description": "Restrict to files created by the given people (repeatable)." }, "explode": true }, { "name": "page", "in": "query", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "responses": { "200": { "description": "GetEverythingFiles 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetEverythingFilesResponseContent" } } } }, "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": [ "Everything" ], "x-basecamp-pagination": { "style": "link", "totalCountHeader": "X-Total-Count", "maxPageSize": 50 }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/forwards.json": { "get": { "description": "Get every inbox forward across all accessible projects, newest-first (paginated).\nEach item embeds its `bucket`.", "operationId": "GetEverythingForwards", "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": "page", "in": "query", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "responses": { "200": { "description": "GetEverythingForwards 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetEverythingForwardsResponseContent" } } } }, "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": [ "Everything" ], "x-basecamp-pagination": { "style": "link", "totalCountHeader": "X-Total-Count", "maxPageSize": 50 }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/gauge_needles/{needleId}": { "delete": { "description": "Destroy a gauge needle", "operationId": "DestroyGaugeNeedle", "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": "needleId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "204": { "description": "DestroyGaugeNeedle 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" } } } }, "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-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } }, "get": { "description": "Get a gauge needle by ID", "operationId": "GetGaugeNeedle", "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": "needleId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "GetGaugeNeedle 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetGaugeNeedleResponseContent" } } } }, "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" ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } }, "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", "in": "path", "description": "Basecamp account ID (numeric string)", "schema": { "type": "string", "pattern": "^[0-9]+$", "description": "Basecamp account ID (numeric string)" }, "required": true }, { "name": "needleId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "UpdateGaugeNeedle 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateGaugeNeedleResponseContent" } } } }, "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" } } } }, "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-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/google_documents/{googleDocumentId}": { "get": { "description": "Get a single Google document by id", "operationId": "GetGoogleDocument", "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": "googleDocumentId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "GetGoogleDocument 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetGoogleDocumentResponseContent" } } } }, "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": [ "Files" ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } }, "put": { "description": "Replace a Google document with a new complete representation.\nBC3 builds a brand-new GoogleDocument from the permitted params and swaps\nthe recordable wholesale, so the request body is the full writable state:\nomitting `title` clears it (and the document then reads back as \"Untitled\"),\nand omitting `description` clears it. `url` and `document_type` are required\nhere — `document_type` because an absent or unrecognized value is a 422, and\n`url` because it carries a presence validation.\nSubscribers are the exception to omission-clears: a drafted document keeps\nits current subscribers when the request addresses neither `subscriptions`\nnor `notify`. The creator is always on the list.\nThe legacy bucket-scoped path\nPUT /buckets/{bucketId}/google_documents/{id}.json is also accepted by BC3;\nthis flat spelling is the documented one.", "operationId": "UpdateGoogleDocument", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateGoogleDocumentRequestContent" } } }, "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": "googleDocumentId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "UpdateGoogleDocument 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateGoogleDocumentResponseContent" } } } }, "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": "FieldValidationError 422 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FieldValidationErrorResponseContent" } } } }, "500": { "description": "InternalServerError 500 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/InternalServerErrorResponseContent" } } } } }, "tags": [ "Files" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] }, "x-basecamp-write-semantics": { "mode": "replace", "clearsOmitted": true } } }, "/{accountId}/inbox_forwards/{forwardId}": { "get": { "description": "Get a forward by ID", "operationId": "GetForward", "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": "forwardId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "GetForward 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetForwardResponseContent" } } } }, "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": [ "Forwards" ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/inbox_forwards/{forwardId}/replies.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": "accountId", "in": "path", "description": "Basecamp account ID (numeric string)", "schema": { "type": "string", "pattern": "^[0-9]+$", "description": "Basecamp account ID (numeric string)" }, "required": true }, { "name": "forwardId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true }, { "name": "page", "in": "query", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "responses": { "200": { "description": "ListForwardReplies 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListForwardRepliesResponseContent" } } } }, "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": [ "Forwards" ], "x-basecamp-pagination": { "style": "link", "totalCountHeader": "X-Total-Count", "maxPageSize": 50 }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/inbox_forwards/{forwardId}/replies/{replyId}": { "get": { "description": "Get a forward reply by ID", "operationId": "GetForwardReply", "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": "forwardId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true }, { "name": "replyId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "GetForwardReply 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetForwardReplyResponseContent" } } } }, "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": [ "Forwards" ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/inboxes/{inboxId}": { "get": { "description": "Get an inbox by ID", "operationId": "GetInbox", "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": "inboxId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "GetInbox 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetInboxResponseContent" } } } }, "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": [ "Forwards" ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/inboxes/{inboxId}/inbox_forwards.json": { "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", "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": "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" } }, { "name": "page", "in": "query", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "responses": { "200": { "description": "ListForwards 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListForwardsResponseContent" } } } }, "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": [ "Forwards" ], "x-basecamp-pagination": { "style": "link", "totalCountHeader": "X-Total-Count", "maxPageSize": 50 }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/lineup/markers.json": { "get": { "description": "List all lineup markers for the account", "operationId": "ListLineupMarkers", "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": "ListLineupMarkers 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListLineupMarkersResponseContent" } } } }, "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-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } }, "post": { "description": "Create a new lineup marker", "operationId": "CreateLineupMarker", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateLineupMarkerRequestContent" } } }, "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 } ], "responses": { "201": { "description": "CreateLineupMarker 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": "BareFieldValidationError 422 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BareFieldValidationErrorResponseContent" } } } }, "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}/lineup/markers/{markerId}": { "delete": { "description": "Delete a lineup marker", "operationId": "DeleteLineupMarker", "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": "markerId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "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", "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 ] } }, "put": { "description": "Update an existing lineup marker", "operationId": "UpdateLineupMarker", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateLineupMarkerRequestContent" } } } }, "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": "markerId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "UpdateLineupMarker 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": "BareFieldValidationError 422 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BareFieldValidationErrorResponseContent" } } } }, "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}/message_boards/{boardId}": { "get": { "description": "Get a message board", "operationId": "GetMessageBoard", "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": "boardId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "GetMessageBoard 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetMessageBoardResponseContent" } } } }, "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": [ "Messages" ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/message_boards/{boardId}/messages.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", "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": "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" } }, { "name": "page", "in": "query", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "responses": { "200": { "description": "ListMessages 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListMessagesResponseContent" } } } }, "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 message on a message board", "operationId": "CreateMessage", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateMessageRequestContent" } } }, "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": "boardId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "201": { "description": "CreateMessage 201 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateMessageResponseContent" } } } }, "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": [ "Messages" ], "x-basecamp-retry": { "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{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", "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": "page", "in": "query", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "responses": { "200": { "description": "GetEverythingMessages 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetEverythingMessagesResponseContent" } } } }, "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": [ "Everything" ], "x-basecamp-pagination": { "style": "link", "totalCountHeader": "X-Total-Count", "maxPageSize": 50 }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/messages/{messageId}": { "get": { "description": "Get a single message by id", "operationId": "GetMessage", "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": "messageId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "GetMessage 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetMessageResponseContent" } } } }, "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": [ "Messages" ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } }, "put": { "description": "Update an existing message", "operationId": "UpdateMessage", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateMessageRequestContent" } } } }, "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": "messageId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "UpdateMessage 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateMessageResponseContent" } } } }, "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": [ "Messages" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/my/assignments.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", "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": "GetMyAssignments 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetMyAssignmentsResponseContent" } } } }, "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" } } } }, "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 ] } } }, "/{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", "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": "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", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ForbiddenErrorResponseContent" } } } }, "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 ] } } }, "/{accountId}/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": "accountId", "in": "path", "description": "Basecamp account ID (numeric string)", "schema": { "type": "string", "pattern": "^[0-9]+$", "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", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetMyDueAssignmentsResponseContent" } } } }, "400": { "description": "BadRequestError 400 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BadRequestErrorResponseContent" } } } }, "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" } } } }, "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 ] } } }, "/{accountId}/my/bookmarks.json": { "get": { "description": "List the current user's bookmarks, most recently bookmarked first (paginated).\nA bookmark is a personal link between the current user and a single recording,\nvisible only to its creator; each entry wraps the shared recording projection.", "operationId": "ListMyBookmarks", "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": "page", "in": "query", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "responses": { "200": { "description": "ListMyBookmarks 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListMyBookmarksResponseContent" } } } }, "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": [ "Bookmarks" ], "x-basecamp-pagination": { "style": "link", "totalCountHeader": "X-Total-Count", "maxPageSize": 50 }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/my/drafts.json": { "get": { "description": "List the current user's drafts across their active projects, most recently\nupdated first (paginated, capped at 250 like /my/assignments). Five draft\nkinds are returned: messages, documents, uploads, client approvals, and\nclient correspondences. Drafts under archived or trashed projects are\nexcluded.", "operationId": "ListMyDrafts", "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": "page", "in": "query", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "responses": { "200": { "description": "ListMyDrafts 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListMyDraftsResponseContent" } } } }, "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": [ "Drafts" ], "x-basecamp-pagination": { "style": "link", "totalCountHeader": "X-Total-Count", "maxPageSize": 50 }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/my/notes.json": { "get": { "description": "Get the authenticated user's note — a per-person notebook singleton at\n/my/notes.json. If the user has not yet written anything, the shape is the\nsame with empty content and null id/created_at/updated_at; the record is\ncreated on first update.", "operationId": "GetMyNote", "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": "GetMyNote 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetMyNoteResponseContent" } } } }, "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": [ "MyNotes" ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } }, "put": { "description": "Replace the note's content, recording a new revision server-side.\nThe first update also creates the underlying notebook if the user did not\nhave one yet. Returns the updated note. Rejections arrive as a field-keyed\n422 ({\"errors\": {\"content\": [\"can't be blank\"]}}), not the flat {error}\nbody.", "operationId": "UpdateMyNote", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateMyNoteRequestContent" } } }, "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 } ], "responses": { "200": { "description": "UpdateMyNote 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateMyNoteResponseContent" } } } }, "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": "FieldValidationError 422 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FieldValidationErrorResponseContent" } } } }, "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": [ "MyNotes" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/my/preferences.json": { "get": { "description": "Get the current user's preferences", "operationId": "GetMyPreferences", "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": "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", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ForbiddenErrorResponseContent" } } } }, "500": { "description": "InternalServerError 500 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/InternalServerErrorResponseContent" } } } } }, "tags": [ "People" ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } }, "put": { "description": "Update the current user's preferences.\nRejections arrive as a field-keyed 422\n({\"errors\": {\"time_zone_name\": [\"is not included in the list\"]}}), not the\nflat {error} body.", "operationId": "UpdateMyPreferences", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateMyPreferencesRequestContent" } } }, "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 } ], "responses": { "200": { "description": "UpdateMyPreferences 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateMyPreferencesResponseContent" } } } }, "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": "FieldValidationError 422 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FieldValidationErrorResponseContent" } } } }, "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": [ "People" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/my/priorities.json": { "post": { "description": "Add a recording to Up Next — the current user's ordered list of prioritized\nassignments (the priorities returned by GetMyAssignments). Identify the item\nby the recording id that carries the priority; for a card table step\nsurfaced under its parent card, that is the entry's priority_recording_id.\nIdempotent: re-prioritizing an already-prioritized recording is a no-op.", "operationId": "PrioritizeAssignment", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PrioritizeAssignmentRequestContent" } } }, "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 } ], "responses": { "204": { "description": "PrioritizeAssignment 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" } } } }, "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": [ "MyAssignments" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/my/priorities/{recordingId}": { "delete": { "description": "Remove a recording from Up Next (returns 204 No Content). Exact-target:\nonly the priority carried by the identified recording is cleared, and\ndeleting an absent priority is a no-op 204 — so the DELETE is idempotent\nand safe to retry (BC3 #12483). Address a surfaced card table step by its\npriority_recording_id, not its parent card's id.", "operationId": "DeprioritizeAssignment", "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": { "204": { "description": "DeprioritizeAssignment 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" } } } }, "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": [ "MyAssignments" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/my/priority_moves.json": { "post": { "description": "Move an already-prioritized recording to a new 1-based position in Up Next\n(returns 204 No Content). NOT idempotent: a positional move's meaning\nshifts as the list changes, so a retry can land the item somewhere else —\nno retry gating is declared. Errors: 400 for a missing or non-integer\nposition, 422 (flat {error} body) for an out-of-range position or an\nunprioritized recording, and a bare bodyless 404 for an inaccessible\nrecording.", "operationId": "ReorderUpNext", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ReorderUpNextRequestContent" } } }, "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 } ], "responses": { "204": { "description": "ReorderUpNext 204 response" }, "400": { "description": "BadRequestError 400 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BadRequestErrorResponseContent" } } } }, "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": "BareNotFoundError 404 response" }, "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": [ "MyAssignments" ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/my/profile.json": { "get": { "description": "Get the current authenticated user's profile", "operationId": "GetMyProfile", "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": "GetMyProfile 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetMyProfileResponseContent" } } } }, "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": [ "People" ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 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" } } } }, "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": { "204": { "description": "UpdateMyProfile 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" } } } }, "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}/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": [ { "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": "page", "in": "query", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "responses": { "200": { "description": "GetQuestionReminders 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetQuestionRemindersResponseContent" } } } }, "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", "maxPageSize": 50 }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{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", "in": "path", "description": "Basecamp account ID (numeric string)", "schema": { "type": "string", "pattern": "^[0-9]+$", "description": "Basecamp account ID (numeric string)" }, "required": true }, { "name": "page", "in": "query", "description": "Page number for paginating through read items. Defaults to 1. This\noperation is not auto-paginated in any SDK, so a page is returned as\nasked for and later pages are not followed.", "schema": { "type": "integer", "description": "Page number for paginating through read items. Defaults to 1. This\noperation is not auto-paginated in any SDK, so a page is returned as\nasked for and later pages are not followed.", "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", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetMyNotificationsResponseContent" } } } }, "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" } } } }, "500": { "description": "InternalServerError 500 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/InternalServerErrorResponseContent" } } } } }, "tags": [ "MyNotifications" ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/my/readings/bubble_ups.json": { "get": { "description": "Get the current user's current and scheduled bubble-ups (paginated, 50 per page).\nCurrent bubble-ups are returned first, ordered by most recently bubbled up;\nscheduled bubble-ups follow, ordered by scheduled bubble-up time. Each item\nuses the same notification object shape as GetMyNotifications.", "operationId": "GetBubbleUps", "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": "page", "in": "query", "description": "Page number. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "responses": { "200": { "description": "GetBubbleUps 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetBubbleUpsResponseContent" } } } }, "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": [ "MyNotifications" ], "x-basecamp-pagination": { "style": "link", "totalCountHeader": "X-Total-Count", "maxPageSize": 50 }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/my/unreads.json": { "put": { "description": "Mark specified items as read", "operationId": "MarkAsRead", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MarkAsReadRequestContent" } } }, "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 } ], "responses": { "200": { "description": "MarkAsRead 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" } } } }, "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": [ "MyNotifications" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 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", "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": "page", "in": "query", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "responses": { "200": { "description": "ListPeople 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListPeopleResponseContent" } } } }, "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": [ "People" ], "x-basecamp-pagination": { "style": "link", "totalCountHeader": "X-Total-Count", "maxPageSize": 50 }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/people/{personId}": { "get": { "description": "Get a person by ID", "operationId": "GetPerson", "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": "personId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "GetPerson 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetPersonResponseContent" } } } }, "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": [ "People" ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{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", "in": "path", "description": "Basecamp account ID (numeric string)", "schema": { "type": "string", "pattern": "^[0-9]+$", "description": "Basecamp account ID (numeric string)" }, "required": true }, { "name": "personId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "204": { "description": "DisableOutOfOffice 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" } } } }, "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": [ "People" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } }, "get": { "description": "Get the out of office status for a person", "operationId": "GetOutOfOffice", "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": "personId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "GetOutOfOffice 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetOutOfOfficeResponseContent" } } } }, "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": [ "People" ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 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": "accountId", "in": "path", "description": "Basecamp account ID (numeric string)", "schema": { "type": "string", "pattern": "^[0-9]+$", "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" } } } }, "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": [ "People" ], "x-basecamp-retry": { "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{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", "in": "path", "description": "Basecamp account ID (numeric string)", "schema": { "type": "string", "pattern": "^[0-9]+$", "description": "Basecamp account ID (numeric string)" }, "required": true }, { "name": "status", "in": "query", "description": "active|archived|trashed", "schema": { "type": "string", "description": "active|archived|trashed" } }, { "name": "page", "in": "query", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "responses": { "200": { "description": "ListProjects 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListProjectsResponseContent" } } } }, "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": [ "Projects" ], "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 project", "operationId": "CreateProject", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateProjectRequestContent" } } }, "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 } ], "responses": { "201": { "description": "CreateProject 201 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateProjectResponseContent" } } } }, "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" } } } }, "507": { "description": "ProjectLimitError 507 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProjectLimitErrorResponseContent" } } } } }, "tags": [ "Projects" ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{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", "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": { "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": "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" } } }, { "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" } }, { "name": "page", "in": "query", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "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": [ { "id": 1069479523, "status": "active", "visible_to_clients": false, "created_at": "2025-01-01T00:00:00Z", "updated_at": "2025-01-02T00:00:00Z", "title": "Ship the hardware", "inherits_status": true, "type": "Todo", "url": "https://3.basecampapi.com/999/buckets/12345678/todos/1069479523.json", "app_url": "https://3.basecamp.com/999/buckets/12345678/todos/1069479523", "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": 987654, "title": "Launch Tasks", "type": "Todolist", "url": "https://3.basecampapi.com/999/buckets/12345678/todolists/987654.json", "app_url": "https://3.basecamp.com/999/buckets/12345678/todolists/987654" } } ] }, "ListRecordings_example2": { "summary": "List Kanban Card recordings", "description": "Use double-colon notation for nested types", "value": [ { "id": 1069479524, "status": "active", "visible_to_clients": false, "created_at": "2025-01-01T00:00:00Z", "updated_at": "2025-01-02T00:00:00Z", "title": "Design the enclosure", "inherits_status": true, "type": "Kanban::Card", "url": "https://3.basecampapi.com/999/buckets/12345678/card_tables/cards/1069479524.json", "app_url": "https://3.basecamp.com/999/buckets/12345678/card_tables/cards/1069479524", "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": 1069479519, "title": "In Progress", "type": "Kanban::Column", "url": "https://3.basecampapi.com/999/buckets/12345678/card_tables/lists/1069479519.json", "app_url": "https://3.basecamp.com/999/buckets/12345678/card_tables/columns/1069479519" } } ] }, "ListRecordings_example3": { "summary": "List Question Answer recordings", "description": "Another nested type example", "value": [ { "id": 1069479525, "status": "active", "visible_to_clients": false, "created_at": "2025-01-01T00:00:00Z", "updated_at": "2025-01-02T00:00:00Z", "title": "How did the week go?", "inherits_status": true, "type": "Question::Answer", "url": "https://3.basecampapi.com/999/buckets/12345678/question_answers/1069479525.json", "app_url": "https://3.basecamp.com/999/buckets/12345678/question_answers/1069479525", "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": 1069479518, "title": "How did the week go?", "type": "Question", "url": "https://3.basecampapi.com/999/buckets/12345678/questions/1069479518.json", "app_url": "https://3.basecamp.com/999/buckets/12345678/questions/1069479518" } } ] } } } } }, "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 ] } } }, "/{accountId}/projects/{projectId}": { "delete": { "description": "Trash a project (returns 204 No Content)", "operationId": "TrashProject", "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": "projectId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "204": { "description": "TrashProject 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": [ "Projects" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } }, "get": { "description": "Get a single project by id", "operationId": "GetProject", "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": "projectId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "GetProject 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetProjectResponseContent" } } } }, "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": [ "Projects" ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } }, "put": { "description": "Update an existing project", "operationId": "UpdateProject", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateProjectRequestContent" } } }, "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": "projectId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "UpdateProject 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateProjectResponseContent" } } } }, "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": [ "Projects" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{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", "in": "path", "description": "Basecamp account ID (numeric string)", "schema": { "type": "string", "pattern": "^[0-9]+$", "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" }, "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-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/projects/{projectId}/gauge/needles.json": { "get": { "description": "List gauge needles for a project, ordered newest first.", "operationId": "ListGaugeNeedles", "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": "projectId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true }, { "name": "page", "in": "query", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "responses": { "200": { "description": "ListGaugeNeedles 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListGaugeNeedlesResponseContent" } } } }, "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" } } } } }, "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 ] } }, "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", "in": "path", "description": "Basecamp account ID (numeric string)", "schema": { "type": "string", "pattern": "^[0-9]+$", "description": "Basecamp account ID (numeric string)" }, "required": true }, { "name": "projectId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "201": { "description": "CreateGaugeNeedle 201 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateGaugeNeedleResponseContent" } } } }, "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": [ "Gauges" ], "x-basecamp-retry": { "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 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", "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": "projectId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true }, { "name": "page", "in": "query", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "responses": { "200": { "description": "ListProjectPeople 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListProjectPeopleResponseContent" } } } }, "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": [ "People" ], "x-basecamp-pagination": { "style": "link", "totalCountHeader": "X-Total-Count", "maxPageSize": 50 }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{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", "in": "path", "description": "Basecamp account ID (numeric string)", "schema": { "type": "string", "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" } } }, { "name": "projectId", "in": "path", "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 } } } ], "responses": { "200": { "description": "UpdateProjectAccess 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": { "granted": [ { "id": 111, "name": "Jane Doe" }, { "id": 222, "name": "John Roe" } ], "revoked": [] } }, "UpdateProjectAccess_example2": { "summary": "Revoke access", "description": "Use revoke array to remove users", "value": { "granted": [], "revoked": [ { "id": 333, "name": "Sam Ray" } ] } }, "UpdateProjectAccess_example3": { "summary": "Invite new users", "description": "Use create array for new users without accounts", "value": { "granted": [ { "id": 444, "name": "Jane", "email_address": "jane@example.com" } ], "revoked": [] } } } } } }, "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" } } } }, "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": [ "People" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/projects/{projectId}/status/active.json": { "put": { "description": "Restore a project to active status from trash as well as from the archive (returns 204 No Content).\nThis is the inverse of both ArchiveProject and TrashProject. Restoring counts against\nthe account's project limit, so it answers 507 when that limit is already reached.", "operationId": "UnarchiveProject", "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": "projectId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "204": { "description": "UnarchiveProject 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" } } } }, "507": { "description": "ProjectLimitError 507 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProjectLimitErrorResponseContent" } } } } }, "tags": [ "Projects" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/projects/{projectId}/status/archived.json": { "put": { "description": "Archive a project, removing it from the active project list (returns 204 No Content).\nAccounts on the admin pro pack may restrict archiving to admins and the project's\ncreator, which answers 403.", "operationId": "ArchiveProject", "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": "projectId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "204": { "description": "ArchiveProject 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": [ "Projects" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/projects/{projectId}/timeline.json": { "get": { "description": "Get project timeline", "operationId": "GetProjectTimeline", "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": "projectId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true }, { "name": "page", "in": "query", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "responses": { "200": { "description": "GetProjectTimeline 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetProjectTimelineResponseContent" } } } }, "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 }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/projects/{projectId}/timesheet.json": { "get": { "description": "Get timesheet for a specific project", "operationId": "GetProjectTimesheet", "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": "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" } }, { "name": "page", "in": "query", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "responses": { "200": { "description": "GetProjectTimesheet 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetProjectTimesheetResponseContent" } } } }, "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}/question_answers/{answerId}": { "get": { "description": "Get a single answer by id", "operationId": "GetAnswer", "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": "answerId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "GetAnswer 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetAnswerResponseContent" } } } }, "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 ] } }, "put": { "description": "Update an existing answer", "operationId": "UpdateAnswer", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/QuestionAnswerUpdatePayload" } } }, "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": "answerId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "204": { "description": "UpdateAnswer 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" } } } }, "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}/questionnaires/{questionnaireId}": { "get": { "description": "Get a questionnaire (automatic check-ins container) by id", "operationId": "GetQuestionnaire", "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": "questionnaireId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "GetQuestionnaire 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetQuestionnaireResponseContent" } } } }, "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 ] } } }, "/{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", "in": "path", "description": "Basecamp account ID (numeric string)", "schema": { "type": "string", "pattern": "^[0-9]+$", "description": "Basecamp account ID (numeric string)" }, "required": true }, { "name": "questionnaireId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true }, { "name": "page", "in": "query", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "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": { "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 question in a questionnaire", "operationId": "CreateQuestion", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateQuestionRequestContent" } } }, "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": "questionnaireId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "201": { "description": "CreateQuestion 201 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateQuestionResponseContent" } } } }, "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 ] } } }, "/{accountId}/questions/{questionId}": { "get": { "description": "Get a single question by id", "operationId": "GetQuestion", "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", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "GetQuestion 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetQuestionResponseContent" } } } }, "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 ] } }, "put": { "description": "Update an existing question", "operationId": "UpdateQuestion", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateQuestionRequestContent" } } } }, "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", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "UpdateQuestion 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateQuestionResponseContent" } } } }, "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}/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", "in": "path", "description": "Basecamp account ID (numeric string)", "schema": { "type": "string", "pattern": "^[0-9]+$", "description": "Basecamp account ID (numeric string)" }, "required": true }, { "name": "questionId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true }, { "name": "page", "in": "query", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "responses": { "200": { "description": "ListAnswers 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListAnswersResponseContent" } } } }, "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 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", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "201": { "description": "CreateAnswer 201 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateAnswerResponseContent" } } } }, "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 ] } } }, "/{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", "in": "path", "description": "Basecamp account ID (numeric string)", "schema": { "type": "string", "pattern": "^[0-9]+$", "description": "Basecamp account ID (numeric string)" }, "required": true }, { "name": "questionId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "ListQuestionAnswerers 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListQuestionAnswerersResponseContent" } } } }, "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", "maxPageSize": 50 }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{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", "in": "path", "description": "Basecamp account ID (numeric string)", "schema": { "type": "string", "pattern": "^[0-9]+$", "description": "Basecamp account ID (numeric string)" }, "required": true }, { "name": "questionId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true }, { "name": "personId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true }, { "name": "page", "in": "query", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "responses": { "200": { "description": "GetAnswersByPerson 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetAnswersByPersonResponseContent" } } } }, "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", "maxPageSize": 50 }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{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", "in": "path", "description": "Basecamp account ID (numeric string)", "schema": { "type": "string", "pattern": "^[0-9]+$", "description": "Basecamp account ID (numeric string)" }, "required": true }, { "name": "questionId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "UpdateQuestionNotificationSettings 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateQuestionNotificationSettingsResponseContent" } } } }, "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" } } } } }, "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/questions/{questionId}/pause.json": { "delete": { "description": "Resume a paused check-in question (resumes sending reminders)", "operationId": "ResumeQuestion", "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", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "ResumeQuestion 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResumeQuestionResponseContent" } } } }, "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" } } } } }, "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } }, "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 }, { "name": "questionId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "PauseQuestion 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PauseQuestionResponseContent" } } } }, "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-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/recordings/{messageId}/pin.json": { "delete": { "description": "Unpin a message from the message board", "operationId": "UnpinMessage", "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": "messageId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "204": { "description": "UnpinMessage 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": [ "Messages" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } }, "post": { "description": "Pin a message to the top of the message board", "operationId": "PinMessage", "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": "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" } } } } }, "tags": [ "Messages" ], "x-basecamp-retry": { "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/recordings/{recordingId}/bookmark.json": { "delete": { "description": "Remove the current user's bookmark from a recording (returns 204 No Content).\nIdempotent: deleting an absent bookmark also returns 204.", "operationId": "DeleteBookmark", "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": { "204": { "description": "DeleteBookmark 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" } } } }, "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": [ "Bookmarks" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } }, "get": { "description": "Report whether the current user has bookmarked the recording.", "operationId": "GetBookmark", "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": "GetBookmark 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetBookmarkResponseContent" } } } }, "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" } } } } }, "tags": [ "Bookmarks" ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } }, "post": { "description": "Bookmark a recording for the current user.\nIdempotent: re-bookmarking returns the existing bookmark, never a duplicate.", "operationId": "CreateBookmark", "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": "CreateBookmark 201 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateBookmarkResponseContent" } } } }, "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" } } } } }, "tags": [ "Bookmarks" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/recordings/{recordingId}/boosts.json": { "get": { "description": "List boosts on a recording", "operationId": "ListRecordingBoosts", "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": "page", "in": "query", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "responses": { "200": { "description": "ListRecordingBoosts 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListRecordingBoostsResponseContent" } } } }, "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": [ "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": "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": "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": { "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": [ "Boosts" ], "x-basecamp-retry": { "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{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 }, "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": "SetClientVisibility 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SetClientVisibilityResponseContent" } } } }, "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": [ "ClientFeatures" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 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 }, { "name": "page", "in": "query", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "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 }, "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": "CreateComment 201 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateCommentResponseContent" } } } }, "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": [ "Messages" ], "x-basecamp-retry": { "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{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", "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": "page", "in": "query", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "responses": { "200": { "description": "ListEvents 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListEventsResponseContent" } } } }, "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 ] } } }, "/{accountId}/recordings/{recordingId}/events/{eventId}/boosts.json": { "get": { "description": "List boosts on a specific event within a recording", "operationId": "ListEventBoosts", "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": "eventId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true }, { "name": "page", "in": "query", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "responses": { "200": { "description": "ListEventBoosts 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListEventBoostsResponseContent" } } } }, "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": [ "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 specific event within a recording", "operationId": "CreateEventBoost", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateEventBoostRequestContent" } } }, "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 }, { "name": "eventId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "201": { "description": "CreateEventBoost 201 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateEventBoostResponseContent" } } } }, "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": [ "Boosts" ], "x-basecamp-retry": { "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/recordings/{recordingId}/status/active.json": { "put": { "description": "Unarchive a recording (restore to active status)", "operationId": "UnarchiveRecording", "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": { "204": { "description": "UnarchiveRecording 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" } } } }, "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}/recordings/{recordingId}/status/archived.json": { "put": { "description": "Archive a recording", "operationId": "ArchiveRecording", "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": { "204": { "description": "ArchiveRecording 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" } } } }, "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}/recordings/{recordingId}/status/trashed.json": { "put": { "description": "Trash a recording", "operationId": "TrashRecording", "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": { "TrashRecording_example1": { "summary": "Trash any recording type", "description": "Works on comments, messages, documents, cards - any recording", "value": "999" } } }, { "name": "recordingId", "in": "path", "schema": { "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 } } } ], "responses": { "204": { "description": "TrashRecording 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" } } } }, "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}/recordings/{recordingId}/subscription.json": { "delete": { "description": "Unsubscribe the current user from a recording", "operationId": "Unsubscribe", "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": { "204": { "description": "Unsubscribe 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": [ "People" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } }, "get": { "description": "Get subscription information for a recording", "operationId": "GetSubscription", "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": "GetSubscription 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetSubscriptionResponseContent" } } } }, "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": [ "People" ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } }, "post": { "description": "Subscribe the current user to a recording", "operationId": "Subscribe", "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": "Subscribe 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SubscribeResponseContent" } } } }, "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": [ "People" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 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 ] } } } } } }, "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": { "subscribed": true, "count": 2, "url": "https://3.basecampapi.com/999/buckets/12345678/recordings/987654/subscription.json", "subscribers": [ { "id": 111, "name": "Jane Doe" }, { "id": 222, "name": "John Roe" } ] } }, "UpdateSubscription_example2": { "summary": "Remove subscribers", "description": "", "value": { "subscribed": false, "count": 0, "url": "https://3.basecampapi.com/999/buckets/12345678/recordings/987654/subscription.json", "subscribers": [] } } } } } }, "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" } }, { "name": "page", "in": "query", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "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." } }, { "name": "page", "in": "query", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "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 }, { "name": "page", "in": "query", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "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.\n\nThe three arrays carry the report's own reduced projections —\nUpcomingScheduleEntry and UpcomingAssignable — not the shared ScheduleEntry\nand Todo/Card shapes. BC3 renders this report through\n`app/views/api/schedules/calendar/_entry.json.jbuilder` and\n`_assignable.json.jbuilder`, which emit a narrower key set than the\nper-resource partials, plus keys those partials never emit. See\nUpcomingScheduleEntry for the full accounting.", "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": "window_starts_on", "in": "query", "description": "Inclusive first day of the window, `YYYY-MM-DD`. Required — BC3 answers 400 without it.", "schema": { "type": "string", "description": "Inclusive first day of the window, `YYYY-MM-DD`. Required — BC3 answers 400 without it." }, "required": true }, { "name": "window_ends_on", "in": "query", "description": "Inclusive last day of the window, `YYYY-MM-DD`. Required — BC3 answers 400 without it.", "schema": { "type": "string", "description": "Inclusive last day of the window, `YYYY-MM-DD`. Required — BC3 answers 400 without it." }, "required": true } ], "responses": { "200": { "description": "GetUpcomingSchedule 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetUpcomingScheduleResponseContent" } } } }, "400": { "description": "BadRequestError 400 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BadRequestErrorResponseContent" } } } }, "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 ] } } }, "/{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": [ "Schedule" ], "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, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/reports/todos/assigned/{personId}": { "get": { "description": "Get todos assigned to a specific person", "operationId": "GetAssignedTodos", "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": "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": "GetAssignedTodos 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetAssignedTodosResponseContent" } } } }, "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-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/reports/todos/overdue.json": { "get": { "description": "Get overdue todos grouped by lateness", "operationId": "GetOverdueTodos", "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": "GetOverdueTodos 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetOverdueTodosResponseContent" } } } }, "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 ] } } }, "/{accountId}/reports/users/progress/{personId}.json": { "get": { "description": "Get a person's activity timeline", "operationId": "GetPersonProgress", "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": "personId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true }, { "name": "page", "in": "query", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "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 ] } } }, "/{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", "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": "entryId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "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": "Replace a schedule entry with a new complete representation.\nThe request body is the entry's full writable state: a writable field\nomitted from the request is cleared server-side, because BC3 builds a\nbrand-new Schedule::Entry from the permitted params and swaps the recordable\nwholesale.\nThree writable fields are carved out of that swap and preserved when the\nrequest does not address them — participant_ids, url and highlighted, as\ndeclared by preservedOnOmission. Each is a field a caller could not safely\nresend from a read-back, which is why the guard is server-side: the response\ncarries participants (objects, not ids) and join_url (the entry's own url\nkey is its Basecamp API URL, a different value under a colliding name).\nAddressing one applies it normally, so participant_ids: [] clears the\nparticipants, url: \"\" clears the join link and highlighted: false removes\nthe highlight.\nstarts_at and ends_at are required: Schedule::Entry validates their presence\nand Recording validates the associated recordable on update, so omitting\neither is a 422 rather than a clear. summary carries no validation — omit it\nand the entry reads back as \"Untitled\" (Schedule::Entry#summary falls back\nwhen blank).\nRecurring entries are unreachable here. ensure_non_recurring_event redirects\nboth show and update to the entry's occurrence, so this operation serves\nnon-recurring entries only; read a recurring entry through\nGetScheduleEntryOccurrence.\ntime_zone_name, recurs_until and recurrence_schedule are not modeled: BC3\nforces all three to nil for a non-recurring entry, which is the only kind\nthis route serves.\nSubscribers follow the same carve-out logic one level up. A drafted entry\nkeeps its current subscribers when the request addresses neither\nsubscriptions, notify, nor the participant parameters.\nTo set some fields while preserving the rest, use the SDK's merge-safe\nupdate or edit methods, which GET the current entry and PUT the full\nrepresentation back. Those read-modify-write helpers are not atomic:\na concurrent write between the GET and PUT is overwritten (last write\nwins for the whole representation; the window is one round-trip).", "operationId": "ReplaceScheduleEntry", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ReplaceScheduleEntryRequestContent" } } }, "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": "entryId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "ReplaceScheduleEntry 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ReplaceScheduleEntryResponseContent" } } } }, "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 ] }, "x-basecamp-write-semantics": { "mode": "replace", "clearsOmitted": true, "preservedOnOmission": [ "participant_ids", "url", "highlighted" ] } } }, "/{accountId}/schedule_entries/{entryId}/occurrences/{date}": { "get": { "description": "Get a specific occurrence of a recurring schedule entry", "operationId": "GetScheduleEntryOccurrence", "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": "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 ] } } }, "/{accountId}/schedules/{scheduleId}": { "get": { "description": "Get a schedule", "operationId": "GetSchedule", "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": "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": "accountId", "in": "path", "description": "Basecamp account ID (numeric string)", "schema": { "type": "string", "pattern": "^[0-9]+$", "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", "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 ] } } }, "/{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", "in": "path", "description": "Basecamp account ID (numeric string)", "schema": { "type": "string", "pattern": "^[0-9]+$", "description": "Basecamp account ID (numeric string)" }, "required": true }, { "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" } }, { "name": "page", "in": "query", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "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": "accountId", "in": "path", "description": "Basecamp account ID (numeric string)", "schema": { "type": "string", "pattern": "^[0-9]+$", "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", "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 ] } } }, "/{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." }, "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." }, "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." }, "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" }, "deprecated": true, "x-deprecated-reason": "prefer creator_ids[]." }, { "name": "page", "in": "query", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "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 ] } } }, "/{accountId}/searches/metadata.json": { "get": { "description": "Get search metadata (available filter options)", "operationId": "GetSearchMetadata", "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": "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 ] } } }, "/{accountId}/stacks.json": { "get": { "description": "List the authenticated user's folders in home-screen order.\n\nReturns a bare array with no pagination envelope. Items are the base folder\nshape: they carry `bucket_ids` but **not** the expanded `projects`, which\nonly the single-folder operations return.", "operationId": "ListFolders", "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": "ListFolders 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListFoldersResponseContent" } } } }, "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": [ "Folders" ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } }, "post": { "description": "Create a folder for the authenticated user and file the given projects into it.\n\nReturns 201 with the new folder and its expanded `projects`, placed at the\ntop of the home screen. Filing an all-access project the user has not joined\n**grants** them access to it. Every id is preflighted: if any is archived,\ntrashed, or an invitation-only project the user is not on, the whole request\nfails with 404 and nothing is created — there is no partial success.", "operationId": "CreateFolder", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateFolderRequestContent" } } } }, "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": { "201": { "description": "CreateFolder 201 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateFolderResponseContent" } } } }, "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": "FieldValidationError 422 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FieldValidationErrorResponseContent" } } } }, "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": [ "Folders" ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/stacks/{folderId}": { "delete": { "description": "Delete a folder and unpin its projects from the home screen (returns 204 No Content).\n\nThe projects themselves are not deleted and are not moved back out onto the\nhome screen; they simply stop appearing there until pinned again.", "operationId": "DeleteFolder", "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": "folderId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "204": { "description": "DeleteFolder 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": [ "Folders" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } }, "get": { "description": "Get one folder, with the projects grouped inside it expanded under `projects`.", "operationId": "GetFolder", "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": "folderId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "GetFolder 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetFolderResponseContent" } } } }, "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" } } } } }, "tags": [ "Folders" ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } }, "put": { "description": "Rename a folder.\n\n`name` is the only writable attribute; a folder's projects, ordering, and\nimage are managed elsewhere and an image parameter sent here is ignored.", "operationId": "UpdateFolder", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateFolderRequestContent" } } }, "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": "folderId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "UpdateFolder 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateFolderResponseContent" } } } }, "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": "FieldValidationError 422 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FieldValidationErrorResponseContent" } } } }, "500": { "description": "InternalServerError 500 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/InternalServerErrorResponseContent" } } } } }, "tags": [ "Folders" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 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", "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": "status", "in": "query", "description": "active|archived|trashed", "schema": { "type": "string", "description": "active|archived|trashed" } }, { "name": "page", "in": "query", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "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": [ { "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": { "201": { "description": "CreateTemplate 201 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateTemplateResponseContent" } } } }, "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 ] } } }, "/{accountId}/templates/{templateId}": { "delete": { "description": "Delete a template (trash it)", "operationId": "DeleteTemplate", "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": "templateId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "204": { "description": "DeleteTemplate 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 ] } }, "get": { "description": "Get a single template by id", "operationId": "GetTemplate", "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": "templateId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "GetTemplate 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetTemplateResponseContent" } } } }, "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 ] } }, "put": { "description": "Update an existing template", "operationId": "UpdateTemplate", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateTemplateRequestContent" } } } }, "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": "templateId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "UpdateTemplate 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateTemplateResponseContent" } } } }, "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}/templates/{templateId}/project_constructions.json": { "post": { "description": "Create a project from a template (asynchronous)", "operationId": "CreateProjectFromTemplate", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateProjectFromTemplateRequestContent" } } }, "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": "templateId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "201": { "description": "CreateProjectFromTemplate 201 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateProjectFromTemplateResponseContent" } } } }, "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 ] } } }, "/{accountId}/templates/{templateId}/project_constructions/{constructionId}": { "get": { "description": "Get the status of a project construction", "operationId": "GetProjectConstruction", "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": "templateId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true }, { "name": "constructionId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "GetProjectConstruction 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetProjectConstructionResponseContent" } } } }, "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 ] } } }, "/{accountId}/timesheet_entries/{entryId}": { "delete": { "description": "Permanently delete a timesheet entry; answers 403 when the caller may not archive or trash it.", "operationId": "DestroyTimesheetEntry", "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": "entryId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "204": { "description": "DestroyTimesheetEntry 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" } } } }, "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-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } }, "get": { "description": "Get a single timesheet entry", "operationId": "GetTimesheetEntry", "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": "entryId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "GetTimesheetEntry 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetTimesheetEntryResponseContent" } } } }, "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 a timesheet entry", "operationId": "UpdateTimesheetEntry", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateTimesheetEntryRequestContent" } } } }, "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": "entryId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "UpdateTimesheetEntry 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateTimesheetEntryResponseContent" } } } }, "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 ] } } }, "/{accountId}/todolists/groups/{groupId}/position.json": { "put": { "description": "Reposition a todolist group", "operationId": "RepositionTodolistGroup", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RepositionTodolistGroupRequestContent" } } }, "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": "groupId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "RepositionTodolistGroup 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": [ "Todos" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/todolists/{id}": { "get": { "description": "Get a single todolist or todolist group by id\nThe endpoint is polymorphic, but it answers with one shape: BC3 has no group\nmodel, so both variants come back as a flat Todolist (see the Todolist shape).", "operationId": "GetTodolistOrGroup", "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": { "GetTodolistOrGroup_example1": { "summary": "Get a to-do list", "description": "A to-do list: parent is a Todoset, and groups_url is present", "value": "999" }, "GetTodolistOrGroup_example2": { "summary": "Get a group", "description": "A group: parent is a Todolist, and group_position_url replaces groups_url", "value": "999" } } }, { "name": "id", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true, "examples": { "GetTodolistOrGroup_example1": { "summary": "Get a to-do list", "description": "A to-do list: parent is a Todoset, and groups_url is present", "value": 987654 }, "GetTodolistOrGroup_example2": { "summary": "Get a group", "description": "A group: parent is a Todolist, and group_position_url replaces groups_url", "value": 111222 } } } ], "responses": { "200": { "description": "GetTodolistOrGroup 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetTodolistOrGroupResponseContent" }, "examples": { "GetTodolistOrGroup_example1": { "summary": "Get a to-do list", "description": "A to-do list: parent is a Todoset, and groups_url is present", "value": { "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": "", "description_attachments": [], "url": "https://3.basecampapi.com/999/buckets/12345678/todolists/987654.json", "app_url": "https://3.basecamp.com/999/buckets/12345678/todolists/987654", "bubble_up_url": "https://3.basecampapi.com/999/buckets/12345678/recordings/987654/bubble_up.json", "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" }, "comments_app_url": "https://3.basecamp.com/999/buckets/12345678/recordings/987654/comments", "groups_url": "https://3.basecampapi.com/999/buckets/12345678/todolists/987654/groups.json", "color": "blue" } }, "GetTodolistOrGroup_example2": { "summary": "Get a group", "description": "A group: parent is a Todolist, and group_position_url replaces groups_url", "value": { "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": "Todolist", "description": "", "description_attachments": [], "url": "https://3.basecampapi.com/999/buckets/12345678/todolists/111222.json", "app_url": "https://3.basecamp.com/999/buckets/12345678/todolists/111222", "bubble_up_url": "https://3.basecampapi.com/999/buckets/12345678/recordings/111222/bubble_up.json", "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": 987654, "title": "Launch Tasks", "type": "Todolist", "url": "https://3.basecampapi.com/999/buckets/12345678/todolists/987654.json", "app_url": "https://3.basecamp.com/999/buckets/12345678/todolists/987654" }, "comments_app_url": "https://3.basecamp.com/999/buckets/12345678/recordings/111222/comments", "group_position_url": "https://3.basecampapi.com/999/buckets/12345678/todolists/groups/111222/position.json", "color": null } } } } } }, "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": [ "Todos" ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } }, "put": { "description": "Replace a todolist (or todolist group) with a new complete representation.\nThe endpoint is polymorphic - it addresses a to-do list or a group, and answers\nwith the same flat Todolist shape either way.\nThe request body is the recordable's full writable state: TodolistsController#update\nbuilds a brand-new Todolist from the permitted params and swaps it in, so any\nwritable field omitted from the request is cleared server-side (a request that\nomits description erases the description). name is required - it is\npresence-validated on the model, so a request without it is rejected.\nTo set some fields while preserving the rest, use the SDK's merge-safe\nupdate or edit methods, which GET the current list and PUT the full\nrepresentation back. Those read-modify-write helpers are not atomic:\na concurrent write between the GET and PUT is overwritten (last write\nwins for the whole representation; the window is one round-trip).", "operationId": "UpdateTodolistOrGroup", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateTodolistOrGroupRequestContent" } } }, "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": "id", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "UpdateTodolistOrGroup 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateTodolistOrGroupResponseContent" } } } }, "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": [ "Todos" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] }, "x-basecamp-write-semantics": { "mode": "replace", "clearsOmitted": true } } }, "/{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", "in": "path", "description": "Basecamp account ID (numeric string)", "schema": { "type": "string", "pattern": "^[0-9]+$", "description": "Basecamp account ID (numeric string)" }, "required": true }, { "name": "todolistId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true }, { "name": "page", "in": "query", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "responses": { "200": { "description": "ListTodolistGroups 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListTodolistGroupsResponseContent" } } } }, "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": [ "Todos" ], "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 group in a todolist", "operationId": "CreateTodolistGroup", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateTodolistGroupRequestContent" } } }, "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": "todolistId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "201": { "description": "CreateTodolistGroup 201 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateTodolistGroupResponseContent" } } } }, "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": [ "Todos" ], "x-basecamp-retry": { "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/todolists/{todolistId}/todos.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": "accountId", "in": "path", "description": "Basecamp account ID (numeric string)", "schema": { "type": "string", "pattern": "^[0-9]+$", "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" } }, { "name": "page", "in": "query", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "responses": { "200": { "description": "ListTodos 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListTodosResponseContent" } } } }, "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": [ "Todos" ], "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 todo in a todolist", "operationId": "CreateTodo", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateTodoRequestContent" } } }, "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": "todolistId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "201": { "description": "CreateTodo 201 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateTodoResponseContent" } } } }, "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": [ "Todos" ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/todos/completed.json": { "get": { "description": "Completed to-dos across all accessible projects, grouped by project (paginated).", "operationId": "GetEverythingCompletedTodos", "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": "assignee_ids[]", "in": "query", "description": "Restrict to tasks assigned to at least one of the given people (repeatable).\nAssignees on nested steps are not considered.", "style": "form", "schema": { "type": "array", "items": { "type": "integer", "format": "int64" }, "description": "Restrict to tasks assigned to at least one of the given people (repeatable).\nAssignees on nested steps are not considered." }, "explode": true }, { "name": "due", "in": "query", "description": "Filter by due date: with, without, or overdue. Unrecognized values are ignored.", "schema": { "type": "string", "description": "Filter by due date: with, without, or overdue. Unrecognized values are ignored." } }, { "name": "page", "in": "query", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "responses": { "200": { "description": "GetEverythingCompletedTodos 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetEverythingCompletedTodosResponseContent" } } } }, "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": [ "Everything" ], "x-basecamp-pagination": { "style": "link", "totalCountHeader": "X-Total-Count", "maxPageSize": 5 }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/todos/no_due_date.json": { "get": { "description": "Open to-dos with no due date across all accessible projects, grouped by project (paginated).", "operationId": "GetEverythingNoDueDateTodos", "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": "assignee_ids[]", "in": "query", "description": "Restrict to tasks assigned to at least one of the given people (repeatable).\nAssignees on nested steps are not considered.", "style": "form", "schema": { "type": "array", "items": { "type": "integer", "format": "int64" }, "description": "Restrict to tasks assigned to at least one of the given people (repeatable).\nAssignees on nested steps are not considered." }, "explode": true }, { "name": "due", "in": "query", "description": "Filter by due date: with, without, or overdue. Unrecognized values are ignored.", "schema": { "type": "string", "description": "Filter by due date: with, without, or overdue. Unrecognized values are ignored." } }, { "name": "page", "in": "query", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "responses": { "200": { "description": "GetEverythingNoDueDateTodos 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetEverythingNoDueDateTodosResponseContent" } } } }, "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": [ "Everything" ], "x-basecamp-pagination": { "style": "link", "totalCountHeader": "X-Total-Count", "maxPageSize": 5 }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/todos/open.json": { "get": { "description": "Active, incomplete to-dos across all accessible projects, grouped by project (paginated).\nEach bucket entry carries the matching to-dos and their steps.", "operationId": "GetEverythingOpenTodos", "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": "assignee_ids[]", "in": "query", "description": "Restrict to tasks assigned to at least one of the given people (repeatable).\nAssignees on nested steps are not considered.", "style": "form", "schema": { "type": "array", "items": { "type": "integer", "format": "int64" }, "description": "Restrict to tasks assigned to at least one of the given people (repeatable).\nAssignees on nested steps are not considered." }, "explode": true }, { "name": "due", "in": "query", "description": "Filter by due date: with, without, or overdue. Unrecognized values are ignored.", "schema": { "type": "string", "description": "Filter by due date: with, without, or overdue. Unrecognized values are ignored." } }, { "name": "page", "in": "query", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "responses": { "200": { "description": "GetEverythingOpenTodos 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetEverythingOpenTodosResponseContent" } } } }, "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": [ "Everything" ], "x-basecamp-pagination": { "style": "link", "totalCountHeader": "X-Total-Count", "maxPageSize": 5 }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/todos/overdue.json": { "get": { "description": "Get every overdue to-do across all accessible projects, oldest-due-date-first.\nA complete, unpaginated array; each item embeds its `bucket`.", "operationId": "GetEverythingOverdueTodos", "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": "assignee_ids[]", "in": "query", "description": "Restrict to tasks assigned to at least one of the given people (repeatable).\nAssignees on nested steps are not considered.", "style": "form", "schema": { "type": "array", "items": { "type": "integer", "format": "int64" }, "description": "Restrict to tasks assigned to at least one of the given people (repeatable).\nAssignees on nested steps are not considered." }, "explode": true }, { "name": "due", "in": "query", "description": "Filter by due date: with, without, or overdue. Unrecognized values are ignored.", "schema": { "type": "string", "description": "Filter by due date: with, without, or overdue. Unrecognized values are ignored." } } ], "responses": { "200": { "description": "GetEverythingOverdueTodos 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetEverythingOverdueTodosResponseContent" } } } }, "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": [ "Everything" ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/todos/unassigned.json": { "get": { "description": "Open, unassigned to-dos across all accessible projects, grouped by project (paginated).", "operationId": "GetEverythingUnassignedTodos", "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": "assignee_ids[]", "in": "query", "description": "Restrict to tasks assigned to at least one of the given people (repeatable).\nAssignees on nested steps are not considered.", "style": "form", "schema": { "type": "array", "items": { "type": "integer", "format": "int64" }, "description": "Restrict to tasks assigned to at least one of the given people (repeatable).\nAssignees on nested steps are not considered." }, "explode": true }, { "name": "due", "in": "query", "description": "Filter by due date: with, without, or overdue. Unrecognized values are ignored.", "schema": { "type": "string", "description": "Filter by due date: with, without, or overdue. Unrecognized values are ignored." } }, { "name": "page", "in": "query", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "responses": { "200": { "description": "GetEverythingUnassignedTodos 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetEverythingUnassignedTodosResponseContent" } } } }, "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": [ "Everything" ], "x-basecamp-pagination": { "style": "link", "totalCountHeader": "X-Total-Count", "maxPageSize": 5 }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/todos/{todoId}": { "get": { "description": "Get a single todo by id", "operationId": "GetTodo", "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": "todoId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "GetTodo 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetTodoResponseContent" } } } }, "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": [ "Todos" ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } }, "put": { "description": "Replace a todo with a new complete representation.\nThe request body is the todo's full writable state: any writable field\nomitted from the request is cleared server-side (empty/missing\nassignee_ids clears assignees, missing description clears it, and so\non). content is required — a request without it is rejected.\nTo set some fields while preserving the rest, use the SDK's merge-safe\nupdate or edit methods, which GET the current todo and PUT the full\nrepresentation back. Those read-modify-write helpers are not atomic:\na concurrent write between the GET and PUT is overwritten (last write\nwins for the whole representation; the window is one round-trip).", "operationId": "ReplaceTodo", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ReplaceTodoRequestContent" } } }, "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": "todoId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "ReplaceTodo 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ReplaceTodoResponseContent" } } } }, "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": [ "Todos" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] }, "x-basecamp-write-semantics": { "mode": "replace", "clearsOmitted": true } } }, "/{accountId}/todos/{todoId}/completion.json": { "delete": { "description": "Mark a todo as incomplete", "operationId": "UncompleteTodo", "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": "todoId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "204": { "description": "UncompleteTodo 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": [ "Todos" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } }, "post": { "description": "Mark a todo as complete", "operationId": "CompleteTodo", "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": "todoId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "204": { "description": "CompleteTodo 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" } } } } }, "tags": [ "Todos" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/todos/{todoId}/position.json": { "put": { "description": "Reposition a todo within its todolist", "operationId": "RepositionTodo", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RepositionTodoRequestContent" } } }, "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": "todoId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "RepositionTodo 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" } } } } }, "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/todosets/todolists/{todolistId}/position.json": { "put": { "description": "Reposition a to-do list within its to-do set.\nposition is the 1-based index among the to-do lists the caller can see; the server\ntranslates it relative to loose to-dos and hidden completed lists. Shifts siblings.", "operationId": "RepositionTodolist", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RepositionTodolistRequestContent" } } }, "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": "todolistId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "204": { "description": "RepositionTodolist 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" } } } }, "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": [ "Todos" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/todosets/{todosetId}": { "get": { "description": "Get a todoset (container for todolists in a project)", "operationId": "GetTodoset", "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": "todosetId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "GetTodoset 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetTodosetResponseContent" } } } }, "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": [ "Todos" ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/todosets/{todosetId}/hill.json": { "get": { "description": "Get the hill chart for a todoset", "operationId": "GetHillChart", "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": "todosetId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "GetHillChart 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetHillChartResponseContent" } } } }, "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": [ "Todos" ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/todosets/{todosetId}/hills/settings.json": { "put": { "description": "Track or untrack todolists on a hill chart", "operationId": "UpdateHillChartSettings", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateHillChartSettingsRequestContent" } } } }, "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": "todosetId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "UpdateHillChartSettings 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateHillChartSettingsResponseContent" } } } }, "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": [ "Todos" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/todosets/{todosetId}/todolists.json": { "get": { "description": "List todolists in a todoset\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", "operationId": "ListTodolists", "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": "todosetId", "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": "page", "in": "query", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "responses": { "200": { "description": "ListTodolists 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListTodolistsResponseContent" } } } }, "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": [ "Todos" ], "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 todolist in a todoset", "operationId": "CreateTodolist", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateTodolistRequestContent" } } }, "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": "todosetId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "201": { "description": "CreateTodolist 201 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateTodolistResponseContent" } } } }, "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": [ "Todos" ], "x-basecamp-retry": { "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/uploads/{uploadId}": { "get": { "description": "Get a single upload by id", "operationId": "GetUpload", "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": "uploadId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "GetUpload 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetUploadResponseContent" } } } }, "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": [ "Files" ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } }, "put": { "description": "Update an existing upload", "operationId": "UpdateUpload", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateUploadRequestContent" } } } }, "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": "uploadId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "UpdateUpload 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateUploadResponseContent" } } } }, "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": [ "Files" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/uploads/{uploadId}/versions.json": { "get": { "description": "List versions of an upload\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", "operationId": "ListUploadVersions", "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": "uploadId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "ListUploadVersions 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListUploadVersionsResponseContent" } } } }, "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": [ "Files" ], "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": "Replace an upload's file with a new version\n\nThe recording keeps its id, its URL and its comments; the previous file becomes a\npast version. Use this instead of CreateUpload when publishing a new release of the\nsame file, so its published link keeps working.", "operationId": "CreateUploadVersion", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateUploadVersionRequestContent" } } }, "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": "uploadId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "201": { "description": "CreateUploadVersion 201 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateUploadVersionResponseContent" } } } }, "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" } } } }, "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" } } } }, "507": { "description": "StorageLimitError 507 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/StorageLimitErrorResponseContent" } } } } }, "tags": [ "Files" ], "x-basecamp-retry": { "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/vaults/{vaultId}": { "get": { "description": "Get a single vault by id", "operationId": "GetVault", "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": "vaultId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "GetVault 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetVaultResponseContent" } } } }, "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": [ "Files" ], "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } }, "put": { "description": "Update an existing vault", "operationId": "UpdateVault", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateVaultRequestContent" } } } }, "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": "vaultId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "UpdateVault 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateVaultResponseContent" } } } }, "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": [ "Files" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/vaults/{vaultId}/documents.json": { "get": { "description": "List documents in a vault\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", "operationId": "ListDocuments", "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": "vaultId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true }, { "name": "page", "in": "query", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "responses": { "200": { "description": "ListDocuments 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListDocumentsResponseContent" } } } }, "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": [ "Files" ], "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 document in a vault", "operationId": "CreateDocument", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateDocumentRequestContent" } } }, "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": "vaultId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "201": { "description": "CreateDocument 201 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateDocumentResponseContent" } } } }, "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": [ "Files" ], "x-basecamp-retry": { "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/vaults/{vaultId}/uploads.json": { "get": { "description": "List uploads in a vault\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", "operationId": "ListUploads", "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": "vaultId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true }, { "name": "page", "in": "query", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "responses": { "200": { "description": "ListUploads 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListUploadsResponseContent" } } } }, "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": [ "Files" ], "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 upload in a vault", "operationId": "CreateUpload", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateUploadRequestContent" } } }, "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": "vaultId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "201": { "description": "CreateUpload 201 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateUploadResponseContent" } } } }, "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" } } } }, "507": { "description": "StorageLimitError 507 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/StorageLimitErrorResponseContent" } } } } }, "tags": [ "Files" ], "x-basecamp-retry": { "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/vaults/{vaultId}/vaults.json": { "get": { "description": "List vaults (subfolders) in a vault\n\n**Pagination**: Uses Link header (RFC5988). Follow the `next` rel URL\nto fetch additional pages. X-Total-Count header provides total count.", "operationId": "ListVaults", "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": "vaultId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true }, { "name": "page", "in": "query", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "schema": { "type": "integer", "description": "Page number for paginating through results. Defaults to 1. A positive value selects exactly that page, not a starting offset; see SPEC section 8.", "format": "int32" } } ], "responses": { "200": { "description": "ListVaults 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListVaultsResponseContent" } } } }, "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": [ "Files" ], "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 vault (subfolder) in a vault", "operationId": "CreateVault", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateVaultRequestContent" } } }, "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": "vaultId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "201": { "description": "CreateVault 201 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateVaultResponseContent" } } } }, "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": [ "Files" ], "x-basecamp-retry": { "maxAttempts": 2, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } }, "/{accountId}/webhooks/{webhookId}": { "delete": { "description": "Delete a webhook", "operationId": "DeleteWebhook", "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": "webhookId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "204": { "description": "DeleteWebhook 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 ] } }, "get": { "description": "Get a single webhook by id", "operationId": "GetWebhook", "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": "webhookId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "GetWebhook 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetWebhookResponseContent" } } } }, "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 ] } }, "put": { "description": "Update an existing webhook", "operationId": "UpdateWebhook", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateWebhookRequestContent" } } } }, "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": "webhookId", "in": "path", "schema": { "type": "integer", "format": "int64" }, "required": true } ], "responses": { "200": { "description": "UpdateWebhook 200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateWebhookResponseContent" } } } }, "400": { "description": "BareFieldBadRequestError 400 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BareFieldBadRequestErrorResponseContent" } } } }, "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" } } } }, "507": { "description": "WebhookLimitError 507 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/WebhookLimitErrorResponseContent" } } } } }, "tags": [ "Automation" ], "x-basecamp-idempotent": { "natural": true }, "x-basecamp-retry": { "maxAttempts": 3, "baseDelayMs": 1000, "backoff": "exponential", "retryOn": [ 429, 503 ] } } } }, "components": { "schemas": { "Account": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "name": { "type": "string" }, "owner_name": { "type": "string" }, "active": { "type": "boolean" }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "updated_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "trial": { "type": "boolean" }, "trial_ends_on": { "type": "string", "x-go-type": "types.Date", "x-go-type-import": { "path": "github.com/basecamp/basecamp-sdk/go/pkg/types" } }, "frozen": { "type": "boolean" }, "paused": { "type": "boolean" }, "limits": { "$ref": "#/components/schemas/AccountLimits" }, "subscription": { "$ref": "#/components/schemas/AccountSubscription" }, "settings": { "$ref": "#/components/schemas/AccountSettings" }, "logo": { "$ref": "#/components/schemas/AccountLogo" } }, "required": [ "created_at", "id", "name", "updated_at" ] }, "AccountLimits": { "type": "object", "properties": { "can_create_projects": { "type": "boolean" }, "can_pin_projects": { "type": "boolean" }, "can_create_users": { "type": "boolean" }, "can_upload_files": { "type": "boolean" } } }, "AccountLogo": { "type": "object", "properties": { "url": { "type": "string" } } }, "AccountSettings": { "type": "object", "properties": { "company_hq_enabled": { "type": "boolean" }, "teams_enabled": { "type": "boolean" }, "projects_enabled": { "type": "boolean" } } }, "AccountSubscription": { "type": "object", "properties": { "short_name": { "type": "string" }, "proper_name": { "type": "string" }, "project_limit": { "type": "integer", "format": "int32" }, "teams": { "type": "boolean" }, "clients": { "type": "boolean" }, "templates": { "type": "boolean" }, "logo": { "type": "boolean" }, "timesheet": { "type": "boolean" } } }, "BadRequestErrorResponseContent": { "type": "object", "properties": { "error": { "type": "string" }, "message": { "type": "string" } }, "required": [ "error" ] }, "BareFieldBadRequestErrorResponseContent": { "$ref": "#/components/schemas/FieldErrorMap" }, "BareFieldValidationErrorResponseContent": { "$ref": "#/components/schemas/FieldErrorMap" }, "Bookmark": { "type": "object", "description": "A personal bookmark: the current user's link to a single recording.\nThe wrapped recording is the shared recording projection, whose `parent`\nis optional (docked recordings and doors omit it).", "properties": { "id": { "type": "integer", "format": "int64" }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "updated_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "recording": { "$ref": "#/components/schemas/Recording" } }, "required": [ "created_at", "id", "recording", "updated_at" ] }, "BookmarkStatus": { "type": "object", "description": "The current user's bookmark state for one recording.", "properties": { "bookmarked": { "type": "boolean" } }, "required": [ "bookmarked" ] }, "Boost": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "content": { "type": "string" }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "booster": { "$ref": "#/components/schemas/Person" }, "recording": { "$ref": "#/components/schemas/RecordingParent" } }, "required": [ "created_at", "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" } } }, "required": [ "bucket", "cards" ] }, "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" } } }, "required": [ "bucket", "todos" ] }, "Calendar": { "type": "object", "description": "A per-account calendar (wire type Calendar), keyed by its own bucket id.", "properties": { "id": { "type": "integer", "format": "int64" }, "type": { "type": "string" }, "name": { "type": "string" }, "color": { "type": "string", "description": "One of: white, red, orange, yellow, green, blue, aqua, purple, gray,\npink, brown." }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "updated_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "url": { "type": "string" }, "app_url": { "type": "string" }, "schedule_url": { "type": "string", "description": "API URL of the calendar's underlying schedule resource." } }, "required": [ "app_url", "color", "created_at", "id", "name", "schedule_url", "type", "updated_at", "url" ] }, "CalendarAttributes": { "type": "object", "description": "The writable calendar payload — the wire body is the nested\n{calendar: {color}} envelope.", "properties": { "color": { "type": "string", "description": "One of: white, red, orange, yellow, green, blue, aqua, purple, gray,\npink, brown." } }, "required": [ "color" ] }, "Campfire": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "status": { "type": "string" }, "visible_to_clients": { "type": "boolean" }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "updated_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "title": { "type": "string" }, "inherits_status": { "type": "boolean" }, "type": { "type": "string" }, "url": { "type": "string" }, "app_url": { "type": "string" }, "bookmark_url": { "type": "string" }, "subscription_url": { "type": "string" }, "position": { "type": "integer", "format": "int32" }, "bucket": { "$ref": "#/components/schemas/TodoBucket" }, "creator": { "$ref": "#/components/schemas/Person" }, "topic": { "type": "string" }, "lines_url": { "type": "string" }, "files_url": { "type": "string" } }, "required": [ "app_url", "bucket", "created_at", "creator", "id", "inherits_status", "status", "title", "type", "updated_at", "url", "visible_to_clients" ] }, "CampfireLine": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "status": { "type": "string" }, "visible_to_clients": { "type": "boolean" }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "updated_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "title": { "type": "string" }, "inherits_status": { "type": "boolean" }, "type": { "type": "string" }, "url": { "type": "string" }, "app_url": { "type": "string" }, "bookmark_url": { "type": "string" }, "content": { "type": "string" }, "attachments": { "type": "array", "items": { "$ref": "#/components/schemas/CampfireLineAttachment" }, "x-go-type-skip-optional-pointer": true }, "parent": { "$ref": "#/components/schemas/RecordingParent" }, "bucket": { "$ref": "#/components/schemas/TodoBucket" }, "creator": { "$ref": "#/components/schemas/Person" }, "boosts_count": { "type": "integer", "format": "int32" }, "boosts_url": { "type": "string" } }, "required": [ "app_url", "bucket", "created_at", "creator", "id", "inherits_status", "parent", "status", "title", "type", "updated_at", "url", "visible_to_clients" ] }, "CampfireLineAttachment": { "type": "object", "properties": { "title": { "type": "string" }, "url": { "type": "string" }, "filename": { "type": "string" }, "content_type": { "type": "string" }, "byte_size": { "type": "integer", "format": "int64" }, "download_url": { "type": "string", "x-basecamp-auth-routable-url": {} } } }, "Card": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "status": { "type": "string" }, "visible_to_clients": { "type": "boolean" }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "updated_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "title": { "type": "string" }, "inherits_status": { "type": "boolean" }, "type": { "type": "string" }, "url": { "type": "string" }, "app_url": { "type": "string" }, "bookmark_url": { "type": "string" }, "subscription_url": { "type": "string" }, "position": { "type": "integer", "format": "int32" }, "content": { "type": "string" }, "description": { "type": "string" }, "description_attachments": { "type": "array", "items": { "$ref": "#/components/schemas/RichTextAttachment" } }, "due_on": { "type": "string", "x-go-type": "types.Date", "x-go-type-import": { "path": "github.com/basecamp/basecamp-sdk/go/pkg/types" }, "nullable": true }, "completed": { "type": "boolean" }, "completed_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "comments_count": { "type": "integer", "format": "int32" }, "comments_url": { "type": "string" }, "completion_url": { "type": "string" }, "parent": { "$ref": "#/components/schemas/RecordingParent" }, "bucket": { "$ref": "#/components/schemas/TodoBucket" }, "creator": { "$ref": "#/components/schemas/Person" }, "completer": { "$ref": "#/components/schemas/Person" }, "assignees": { "type": "array", "items": { "$ref": "#/components/schemas/Person" }, "x-go-type-skip-optional-pointer": true }, "completion_subscribers": { "type": "array", "items": { "$ref": "#/components/schemas/Person" }, "x-go-type-skip-optional-pointer": true }, "steps": { "type": "array", "items": { "$ref": "#/components/schemas/CardStep" }, "x-go-type-skip-optional-pointer": true }, "boosts_count": { "type": "integer", "format": "int32" }, "boosts_url": { "type": "string" } }, "required": [ "app_url", "bucket", "created_at", "creator", "description_attachments", "id", "inherits_status", "parent", "status", "title", "type", "updated_at", "url", "visible_to_clients" ] }, "CardColumn": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "status": { "type": "string" }, "visible_to_clients": { "type": "boolean" }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "updated_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "title": { "type": "string" }, "inherits_status": { "type": "boolean" }, "type": { "type": "string" }, "url": { "type": "string" }, "app_url": { "type": "string" }, "bookmark_url": { "type": "string" }, "position": { "type": "integer", "format": "int32" }, "color": { "type": "string" }, "description": { "type": "string" }, "cards_count": { "type": "integer", "format": "int32" }, "comments_count": { "type": "integer", "format": "int32" }, "cards_url": { "type": "string" }, "parent": { "$ref": "#/components/schemas/RecordingParent" }, "bucket": { "$ref": "#/components/schemas/TodoBucket" }, "creator": { "$ref": "#/components/schemas/Person" }, "subscribers": { "type": "array", "items": { "$ref": "#/components/schemas/Person" }, "x-go-type-skip-optional-pointer": true }, "on_hold": { "$ref": "#/components/schemas/CardColumnOnHold" } }, "required": [ "app_url", "bucket", "created_at", "creator", "id", "inherits_status", "parent", "status", "title", "type", "updated_at", "url", "visible_to_clients" ] }, "CardColumnOnHold": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "status": { "type": "string" }, "inherits_status": { "type": "boolean" }, "title": { "type": "string" }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "updated_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "cards_count": { "type": "integer", "format": "int32" }, "cards_url": { "type": "string" } }, "required": [ "cards_count", "cards_url", "created_at", "id", "inherits_status", "status", "title", "updated_at" ] }, "CardStep": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "status": { "type": "string" }, "visible_to_clients": { "type": "boolean" }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "updated_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "title": { "type": "string" }, "inherits_status": { "type": "boolean" }, "type": { "type": "string" }, "url": { "type": "string" }, "app_url": { "type": "string" }, "bookmark_url": { "type": "string" }, "position": { "type": "integer", "format": "int32" }, "due_on": { "type": "string", "x-go-type": "types.Date", "x-go-type-import": { "path": "github.com/basecamp/basecamp-sdk/go/pkg/types" } }, "completed": { "type": "boolean" }, "completed_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "parent": { "$ref": "#/components/schemas/RecordingParent" }, "bucket": { "$ref": "#/components/schemas/TodoBucket" }, "creator": { "$ref": "#/components/schemas/Person" }, "completer": { "$ref": "#/components/schemas/Person" }, "assignees": { "type": "array", "items": { "$ref": "#/components/schemas/Person" }, "x-go-type-skip-optional-pointer": true }, "completion_url": { "type": "string" } }, "required": [ "app_url", "bucket", "created_at", "creator", "id", "inherits_status", "parent", "status", "title", "type", "updated_at", "url", "visible_to_clients" ] }, "CardTable": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "status": { "type": "string" }, "visible_to_clients": { "type": "boolean" }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "updated_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "title": { "type": "string" }, "inherits_status": { "type": "boolean" }, "type": { "type": "string" }, "url": { "type": "string" }, "app_url": { "type": "string" }, "bookmark_url": { "type": "string" }, "subscription_url": { "type": "string" }, "bucket": { "$ref": "#/components/schemas/TodoBucket" }, "creator": { "$ref": "#/components/schemas/Person" }, "subscribers": { "type": "array", "items": { "$ref": "#/components/schemas/Person" }, "x-go-type-skip-optional-pointer": true }, "lists": { "type": "array", "items": { "$ref": "#/components/schemas/CardColumn" }, "x-go-type-skip-optional-pointer": true }, "wormholes": { "type": "array", "items": { "$ref": "#/components/schemas/Wormhole" }, "x-go-type-skip-optional-pointer": true } }, "required": [ "app_url", "bucket", "created_at", "creator", "id", "inherits_status", "status", "title", "type", "updated_at", "url", "visible_to_clients" ] }, "Chatbot": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "updated_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "service_name": { "type": "string" }, "command_url": { "type": "string", "description": "Only present when the requester is an account administrator; possession of this URL is enough to command the bot." }, "url": { "type": "string" }, "app_url": { "type": "string" }, "lines_url": { "type": "string", "description": "Only present when the requester is an account administrator; possession of this URL is enough to post lines as the bot." } }, "required": [ "created_at", "id", "service_name", "updated_at" ] }, "ClientApproval": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "status": { "type": "string" }, "visible_to_clients": { "type": "boolean" }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "updated_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "title": { "type": "string" }, "inherits_status": { "type": "boolean" }, "type": { "type": "string" }, "url": { "type": "string" }, "app_url": { "type": "string" }, "bookmark_url": { "type": "string" }, "subscription_url": { "type": "string" }, "parent": { "$ref": "#/components/schemas/RecordingParent" }, "bucket": { "$ref": "#/components/schemas/RecordingBucket" }, "creator": { "$ref": "#/components/schemas/Person" }, "content": { "type": "string" }, "content_attachments": { "type": "array", "items": { "$ref": "#/components/schemas/RichTextAttachment" } }, "subject": { "type": "string" }, "due_on": { "type": "string", "x-go-type": "types.Date", "x-go-type-import": { "path": "github.com/basecamp/basecamp-sdk/go/pkg/types" } }, "replies_count": { "type": "integer", "format": "int32" }, "replies_url": { "type": "string" }, "approval_status": { "type": "string" }, "approver": { "$ref": "#/components/schemas/Person" }, "responses": { "type": "array", "items": { "$ref": "#/components/schemas/ClientApprovalResponse" }, "x-go-type-skip-optional-pointer": true } }, "required": [ "app_url", "bucket", "content_attachments", "created_at", "creator", "id", "inherits_status", "parent", "status", "title", "type", "updated_at", "url", "visible_to_clients" ] }, "ClientApprovalResponse": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "status": { "type": "string" }, "visible_to_clients": { "type": "boolean" }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "updated_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "title": { "type": "string" }, "inherits_status": { "type": "boolean" }, "type": { "type": "string" }, "app_url": { "type": "string" }, "bookmark_url": { "type": "string" }, "parent": { "$ref": "#/components/schemas/RecordingParent" }, "bucket": { "$ref": "#/components/schemas/RecordingBucket" }, "creator": { "$ref": "#/components/schemas/Person" }, "content": { "type": "string" }, "approved": { "type": "boolean" } } }, "ClientCompany": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "name": { "type": "string" } }, "required": [ "id", "name" ] }, "ClientCorrespondence": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "status": { "type": "string" }, "visible_to_clients": { "type": "boolean" }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "updated_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "title": { "type": "string" }, "inherits_status": { "type": "boolean" }, "type": { "type": "string" }, "url": { "type": "string" }, "app_url": { "type": "string" }, "bookmark_url": { "type": "string" }, "subscription_url": { "type": "string" }, "parent": { "$ref": "#/components/schemas/RecordingParent" }, "bucket": { "$ref": "#/components/schemas/RecordingBucket" }, "creator": { "$ref": "#/components/schemas/Person" }, "content": { "type": "string" }, "content_attachments": { "type": "array", "items": { "$ref": "#/components/schemas/RichTextAttachment" } }, "subject": { "type": "string" }, "replies_count": { "type": "integer", "format": "int32" }, "replies_url": { "type": "string" } }, "required": [ "app_url", "bucket", "content_attachments", "created_at", "creator", "id", "inherits_status", "parent", "status", "subject", "title", "type", "updated_at", "url", "visible_to_clients" ] }, "ClientReply": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "status": { "type": "string" }, "visible_to_clients": { "type": "boolean" }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "updated_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "title": { "type": "string" }, "inherits_status": { "type": "boolean" }, "type": { "type": "string" }, "url": { "type": "string" }, "app_url": { "type": "string" }, "bookmark_url": { "type": "string" }, "parent": { "$ref": "#/components/schemas/RecordingParent" }, "bucket": { "$ref": "#/components/schemas/RecordingBucket" }, "creator": { "$ref": "#/components/schemas/Person" }, "content": { "type": "string" }, "content_attachments": { "type": "array", "items": { "$ref": "#/components/schemas/RichTextAttachment" } } }, "required": [ "app_url", "bucket", "content", "content_attachments", "created_at", "creator", "id", "inherits_status", "parent", "status", "title", "type", "updated_at", "url", "visible_to_clients" ] }, "ClientSide": { "type": "object", "deprecated": true, "description": "This shape is deprecated since 2024-01: Use Client Visibility feature instead", "properties": { "url": { "type": "string" }, "app_url": { "type": "string" } }, "x-deprecated-reason": "This shape is deprecated since 2024-01: Use Client Visibility feature instead" }, "CloudFile": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "status": { "type": "string" }, "visible_to_clients": { "type": "boolean" }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "updated_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "title": { "type": "string" }, "inherits_status": { "type": "boolean" }, "type": { "type": "string" }, "url": { "type": "string", "description": "The link on the external service — NOT this record's API URL. The\ncloud_files jbuilder renders the shared recording partial first and then\n`json.(recording.recordable, :url, :service)`, which overwrites the\nrecording's `url` key with the recordable's. `app_url` is still this\nrecord's Basecamp URL." }, "app_url": { "type": "string" }, "bookmark_url": { "type": "string" }, "subscription_url": { "type": "string" }, "comments_count": { "type": "integer", "format": "int32" }, "comments_url": { "type": "string" }, "position": { "type": "integer", "format": "int32" }, "parent": { "$ref": "#/components/schemas/RecordingParent" }, "bucket": { "$ref": "#/components/schemas/TodoBucket" }, "creator": { "$ref": "#/components/schemas/Person" }, "description": { "type": "string" }, "description_attachments": { "type": "array", "items": { "$ref": "#/components/schemas/RichTextAttachment" } }, "service": { "$ref": "#/components/schemas/CloudFileService" }, "boosts_count": { "type": "integer", "format": "int32" }, "boosts_url": { "type": "string" } }, "required": [ "app_url", "bucket", "created_at", "creator", "description_attachments", "id", "inherits_status", "parent", "service", "status", "title", "type", "updated_at", "url", "visible_to_clients" ] }, "CloudFileService": { "type": "object", "description": "The external service a cloud file points at, embedded in every cloud file\nresponse so clients can render the service's name, supporting text, and\nexample URL without shipping a hard-coded catalogue. Serialized by\nCloudFile::Service#as_json.", "properties": { "name": { "type": "string" }, "example_url": { "type": "string", "description": "A representative URL for the service, suitable as an input placeholder." }, "code": { "type": "string", "description": "Short identifier for the external service — \"dropbox\", \"google_doc\",\n\"figma\", \"other\", … Derived from the CloudFile::Service subclass name, so it\nis always present. `other` accepts any well-formed HTTPS URL." }, "valid_patterns": { "type": "array", "items": { "type": "string" }, "description": "Regular expressions the cloud file's `url` is validated against. Sending a\n`url` that matches none of the selected service's patterns is a 422." }, "supporting_text": { "type": "string", "description": "Human-readable hint (\"a file or folder on Dropbox\"). Absent for services\nthat declare none — CloudFile::Service::Services::Other, for one." } }, "required": [ "code", "example_url", "name", "valid_patterns" ] }, "Comment": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "status": { "type": "string" }, "visible_to_clients": { "type": "boolean" }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "updated_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "title": { "type": "string" }, "inherits_status": { "type": "boolean" }, "type": { "type": "string" }, "url": { "type": "string" }, "app_url": { "type": "string" }, "bookmark_url": { "type": "string" }, "parent": { "$ref": "#/components/schemas/RecordingParent" }, "bucket": { "$ref": "#/components/schemas/TodoBucket" }, "creator": { "$ref": "#/components/schemas/Person" }, "content": { "type": "string" }, "content_attachments": { "type": "array", "items": { "$ref": "#/components/schemas/RichTextAttachment" } }, "boosts_count": { "type": "integer", "format": "int32" }, "boosts_url": { "type": "string" } }, "required": [ "app_url", "bucket", "content", "content_attachments", "created_at", "creator", "id", "inherits_status", "parent", "status", "title", "type", "updated_at", "url", "visible_to_clients" ] }, "CreateAnswerResponseContent": { "$ref": "#/components/schemas/QuestionAnswer" }, "CreateAttachmentInputPayload": { "type": "string", "contentEncoding": "byte" }, "CreateAttachmentResponseContent": { "type": "object", "properties": { "attachable_sgid": { "type": "string" } } }, "CreateBookmarkResponseContent": { "$ref": "#/components/schemas/Bookmark" }, "CreateCampfireLineRequestContent": { "type": "object", "properties": { "content": { "type": "string" }, "content_type": { "type": "string" } }, "required": [ "content" ] }, "CreateCampfireLineResponseContent": { "$ref": "#/components/schemas/CampfireLine" }, "CreateCampfireUploadInputPayload": { "type": "string", "description": "Raw binary content of the file. Set the Content-Type header to match\nthe file's media type (e.g. \"image/png\", \"application/pdf\").", "contentEncoding": "byte" }, "CreateCampfireUploadResponseContent": { "$ref": "#/components/schemas/CampfireLine" }, "CreateCardColumnRequestContent": { "type": "object", "properties": { "title": { "type": "string" }, "description": { "type": "string" } }, "required": [ "title" ] }, "CreateCardColumnResponseContent": { "$ref": "#/components/schemas/CardColumn" }, "CreateCardRequestContent": { "type": "object", "properties": { "title": { "type": "string" }, "content": { "type": "string" }, "due_on": { "type": "string", "x-go-type": "types.Date", "x-go-type-import": { "path": "github.com/basecamp/basecamp-sdk/go/pkg/types" } }, "notify": { "type": "boolean" } }, "required": [ "title" ] }, "CreateCardResponseContent": { "$ref": "#/components/schemas/Card" }, "CreateCardStepRequestContent": { "type": "object", "properties": { "title": { "type": "string" }, "due_on": { "type": "string", "x-go-type": "types.Date", "x-go-type-import": { "path": "github.com/basecamp/basecamp-sdk/go/pkg/types" } }, "assignee_ids": { "type": "array", "items": { "type": "integer", "format": "int64" } } }, "required": [ "title" ] }, "CreateCardStepResponseContent": { "$ref": "#/components/schemas/CardStep" }, "CreateChatbotRequestContent": { "type": "object", "properties": { "service_name": { "type": "string" }, "command_url": { "type": "string" } }, "required": [ "service_name" ] }, "CreateChatbotResponseContent": { "$ref": "#/components/schemas/Chatbot" }, "CreateCloudFileRequestContent": { "type": "object", "properties": { "url": { "type": "string" }, "service": { "type": "string", "description": "Short identifier for the external service — \"dropbox\", \"google_doc\",\n\"figma\", \"other\", … Derived from the CloudFile::Service subclass name, so it\nis always present. `other` accepts any well-formed HTTPS URL." }, "title": { "type": "string" }, "description": { "type": "string" }, "subscriptions": { "type": "array", "items": { "type": "integer", "format": "int64" } }, "visible_to_clients": { "type": "boolean", "description": "Whether the cloud file is visible to the project's clients. Applies only\nwhen creating directly in the tool's vault — an item created inside a\nfolder inherits the folder's visibility and ignores this. A client caller\nalways creates client-visible records regardless of what is sent." } }, "required": [ "service", "url" ] }, "CreateCloudFileResponseContent": { "$ref": "#/components/schemas/CloudFile" }, "CreateCommentRequestContent": { "type": "object", "properties": { "content": { "type": "string" } }, "required": [ "content" ] }, "CreateCommentResponseContent": { "$ref": "#/components/schemas/Comment" }, "CreateDocumentRequestContent": { "type": "object", "properties": { "title": { "type": "string" }, "content": { "type": "string" }, "status": { "type": "string", "description": "active|drafted" }, "subscriptions": { "type": "array", "items": { "type": "integer", "format": "int64" } }, "visible_to_clients": { "type": "boolean" } }, "required": [ "title" ] }, "CreateDocumentResponseContent": { "$ref": "#/components/schemas/Document" }, "CreateEventBoostRequestContent": { "type": "object", "properties": { "content": { "type": "string", "maxLength": 16 } }, "required": [ "content" ] }, "CreateEventBoostResponseContent": { "$ref": "#/components/schemas/Boost" }, "CreateFolderRequestContent": { "type": "object", "properties": { "name": { "type": "string", "description": "The folder's name. Defaults to `New folder` when blank, null, or omitted." }, "project_ids": { "type": "array", "items": { "type": "integer", "format": "int64" }, "description": "IDs of the projects to file into the folder — the same ids the folder\nreports back as `bucket_ids` and expands as `projects`. This does not\nround-trip under its own name. Omit it, or send null or an empty array,\nfor an empty folder." } } }, "CreateFolderResponseContent": { "$ref": "#/components/schemas/FolderWithProjects" }, "CreateGaugeNeedleRequestContent": { "type": "object", "properties": { "gauge_needle": { "$ref": "#/components/schemas/GaugeNeedlePayload" }, "notify": { "type": "string", "description": "Who to notify: \"everyone\", \"working_on\", \"custom\", or omit for nobody" }, "subscriptions": { "type": "array", "items": { "type": "integer", "format": "int64" }, "description": "Array of people IDs to notify (only used when notify is \"custom\")" } }, "required": [ "gauge_needle" ] }, "CreateGaugeNeedleResponseContent": { "$ref": "#/components/schemas/GaugeNeedle" }, "CreateGoogleDocumentRequestContent": { "type": "object", "properties": { "url": { "type": "string" }, "document_type": { "type": "string", "description": "One of \"doc\", \"sheet\", \"slide\", \"other\". Backed by a Rails enum, so an\nunrecognized value is rejected up front with a field-keyed 422\n({\"errors\": {\"document_type\": [\"is not a valid document type\"]}}) rather\nthan reaching validation." }, "title": { "type": "string" }, "description": { "type": "string" }, "status": { "type": "string", "description": "active|drafted — defaults to drafted" }, "subscriptions": { "type": "array", "items": { "type": "integer", "format": "int64" } }, "visible_to_clients": { "type": "boolean", "description": "Whether the document is visible to the project's clients. Applies only\nwhen creating directly in the tool's vault — an item created inside a\nfolder inherits the folder's visibility and ignores this. A client caller\nalways creates client-visible records regardless of what is sent." } }, "required": [ "document_type", "url" ] }, "CreateGoogleDocumentResponseContent": { "$ref": "#/components/schemas/GoogleDocument" }, "CreateLineupMarkerRequestContent": { "type": "object", "properties": { "name": { "type": "string" }, "date": { "type": "string" } }, "required": [ "date", "name" ] }, "CreateMessageRequestContent": { "type": "object", "properties": { "subject": { "type": "string" }, "content": { "type": "string" }, "status": { "type": "string", "description": "active|drafted" }, "category_id": { "type": "integer", "format": "int64" }, "subscriptions": { "type": "array", "items": { "type": "integer", "format": "int64" } }, "visible_to_clients": { "type": "boolean" } }, "required": [ "subject" ] }, "CreateMessageResponseContent": { "$ref": "#/components/schemas/Message" }, "CreateMessageTypeRequestContent": { "type": "object", "properties": { "name": { "type": "string" }, "icon": { "type": "string" } }, "required": [ "icon", "name" ] }, "CreateMessageTypeResponseContent": { "$ref": "#/components/schemas/MessageType" }, "CreatePersonRequest": { "type": "object", "properties": { "name": { "type": "string", "format": "password" }, "email_address": { "type": "string", "format": "password" }, "title": { "type": "string", "format": "password" }, "company_name": { "type": "string", "format": "password" } }, "required": [ "email_address", "name" ] }, "CreateProjectFromTemplateRequestContent": { "type": "object", "properties": { "project": { "$ref": "#/components/schemas/ProjectConstructionAttributes" } }, "required": [ "project" ] }, "CreateProjectFromTemplateResponseContent": { "$ref": "#/components/schemas/ProjectConstruction" }, "CreateProjectRequestContent": { "type": "object", "properties": { "name": { "type": "string" }, "description": { "type": "string" } }, "required": [ "name" ] }, "CreateProjectResponseContent": { "$ref": "#/components/schemas/Project" }, "CreateQuestionRequestContent": { "type": "object", "properties": { "title": { "type": "string" }, "schedule": { "$ref": "#/components/schemas/QuestionSchedule" }, "visible_to_clients": { "type": "boolean" } }, "required": [ "schedule", "title" ] }, "CreateQuestionResponseContent": { "$ref": "#/components/schemas/Question" }, "CreateRecordingBoostRequestContent": { "type": "object", "properties": { "content": { "type": "string", "maxLength": 16 } }, "required": [ "content" ] }, "CreateRecordingBoostResponseContent": { "$ref": "#/components/schemas/Boost" }, "CreateScheduleEntryRequestContent": { "type": "object", "properties": { "summary": { "type": "string" }, "starts_at": { "type": "string", "description": "The entry's start, as a bare date (\"2026-06-01\") for an all-day entry or a\nfull timestamp (\"2026-06-01T09:00:00Z\") otherwise — the same two forms the\nresponse renders, and the same two ReplaceScheduleEntry accepts.\n\nCreate and replace share one permit list:\n`Schedules::Entries::BaseController#base_schedule_entry_params` is what\nboth `new_schedule_entry_params` and `update_schedule_entry_params` call,\nand Schedule::Entry does no format-specific parsing of either bound, so\nwhatever one operation takes the other takes too.\n\nTreat the value as opaque and send it verbatim. Parsing it into a\ndate-time type and re-rendering rewrites an all-day entry's bounds into\nmidnight timestamps, which is why every SDK models it as a string." }, "ends_at": { "type": "string", "description": "The entry's end. See starts_at for the date-vs-timestamp rule." }, "description": { "type": "string" }, "participant_ids": { "type": "array", "items": { "type": "integer", "format": "int64" } }, "all_day": { "type": "boolean" }, "notify": { "type": "boolean" }, "url": { "type": "string", "description": "The entry's join link — a video-call URL or similar, up to 2500\ncharacters, validated as a URL when present. A scheme-less value is\nnormalized to `https://`.\n\nSpell it `url` on the way in and read it back as `join_url`: the response\nkey `url` is the entry's own Basecamp API URL, written by a partial that\nrenders before this field, so BC3 emits the join link under a\nnon-colliding name. Sending `join_url` instead is silently dropped by\nstrong parameters — the create succeeds with no join link.\n\nAccepted on create since long before it was documented:\n`Schedules::Entries::BaseController#base_schedule_entry_params` permits it\nand `new_schedule_entry_params` passes it through unchanged for API\nrequests. Modeling it only on ReplaceScheduleEntry forced callers into a\nthree-request read-modify-write for a field the create already took — and\ncreate is the notifying write, so participants learned about a video call\nbefore its link existed." }, "highlighted": { "type": "boolean", "description": "Whether the entry is highlighted on the schedule. Defaults to false.\n\nDo not send an explicit null: `schedule_entries.highlighted` is NOT NULL,\nso BC3 raises rather than falling back to the default. Omit it instead —\nevery SDK's request compactor already drops unset members." }, "status": { "type": "string", "description": "Publication state at creation — `active|drafted`, defaulting to `active`\nfor an API create.\n\nA top-level parameter, not part of the entry's attributes: `status` is a\nRecording column, so `wrap_parameters` leaves it outside the\n`schedule_entry` envelope and `Recording::StatusParam#status_param` reads\nit directly. On create it accepts `drafted`, `active`, `archived` or\n`trashed` and raises `ActionController::BadRequest` — a 400, not a 422 —\nfor anything else; the two documented values are the two worth sending.\n\nUnlike messages and documents, schedule-entry drafts are not listed by\nGetMyDrafts." }, "subscriptions": { "type": "array", "items": { "type": "integer", "format": "int64" } }, "visible_to_clients": { "type": "boolean" } }, "required": [ "ends_at", "starts_at", "summary" ] }, "CreateScheduleEntryResponseContent": { "$ref": "#/components/schemas/ScheduleEntry" }, "CreateTemplateRequestContent": { "type": "object", "properties": { "name": { "type": "string" }, "description": { "type": "string" } }, "required": [ "name" ] }, "CreateTemplateResponseContent": { "$ref": "#/components/schemas/Template" }, "CreateTimesheetEntryRequestContent": { "type": "object", "properties": { "date": { "type": "string" }, "hours": { "type": "string" }, "description": { "type": "string" }, "person_id": { "type": "integer", "format": "int64" } }, "required": [ "date", "hours" ] }, "CreateTimesheetEntryResponseContent": { "$ref": "#/components/schemas/TimesheetEntry" }, "CreateTodoRequestContent": { "type": "object", "properties": { "content": { "type": "string" }, "description": { "type": "string" }, "assignee_ids": { "type": "array", "items": { "type": "integer", "format": "int64" } }, "completion_subscriber_ids": { "type": "array", "items": { "type": "integer", "format": "int64" } }, "notify": { "type": "boolean" }, "due_on": { "type": "string", "x-go-type": "types.Date", "x-go-type-import": { "path": "github.com/basecamp/basecamp-sdk/go/pkg/types" } }, "starts_on": { "type": "string", "x-go-type": "types.Date", "x-go-type-import": { "path": "github.com/basecamp/basecamp-sdk/go/pkg/types" } } }, "required": [ "content" ] }, "CreateTodoResponseContent": { "$ref": "#/components/schemas/Todo" }, "CreateTodolistGroupRequestContent": { "type": "object", "properties": { "name": { "type": "string" } }, "required": [ "name" ] }, "CreateTodolistGroupResponseContent": { "$ref": "#/components/schemas/Todolist" }, "CreateTodolistRequestContent": { "type": "object", "properties": { "name": { "type": "string" }, "description": { "type": "string" }, "visible_to_clients": { "type": "boolean" } }, "required": [ "name" ] }, "CreateTodolistResponseContent": { "$ref": "#/components/schemas/Todolist" }, "CreateTodosetTodoRequestContent": { "type": "object", "properties": { "content": { "type": "string" }, "description": { "type": "string" }, "assignee_ids": { "type": "array", "items": { "type": "integer", "format": "int64" } }, "completion_subscriber_ids": { "type": "array", "items": { "type": "integer", "format": "int64" } }, "notify": { "type": "boolean" }, "due_on": { "type": "string", "x-go-type": "types.Date", "x-go-type-import": { "path": "github.com/basecamp/basecamp-sdk/go/pkg/types" } }, "starts_on": { "type": "string", "x-go-type": "types.Date", "x-go-type-import": { "path": "github.com/basecamp/basecamp-sdk/go/pkg/types" } } }, "required": [ "content" ] }, "CreateTodosetTodoResponseContent": { "$ref": "#/components/schemas/Todo" }, "CreateToolRequestContent": { "type": "object", "properties": { "tool_type": { "type": "string", "description": "Tool type to add to the project dock. Values: Chat::Transcript|Inbox|Kanban::Board|Message::Board|Questionnaire|Schedule|Todoset|Vault." }, "title": { "type": "string", "description": "Title for the new tool. When omitted, Basecamp assigns the next available default title for the tool type." }, "visible_to_clients": { "type": "boolean", "description": "Create the tool already visible to clients. Honored only for tool types that manage their own client visibility (Chat::Transcript, Kanban::Board), which otherwise start hidden; every other tool type ignores it and inherits the project default." } }, "required": [ "tool_type" ] }, "CreateToolResponseContent": { "$ref": "#/components/schemas/Tool" }, "CreateUploadRequestContent": { "type": "object", "properties": { "attachable_sgid": { "type": "string" }, "description": { "type": "string" }, "base_name": { "type": "string" }, "subscriptions": { "type": "array", "items": { "type": "integer", "format": "int64" } }, "visible_to_clients": { "type": "boolean" } }, "required": [ "attachable_sgid" ] }, "CreateUploadResponseContent": { "$ref": "#/components/schemas/Upload" }, "CreateUploadVersionRequestContent": { "type": "object", "properties": { "attachable_sgid": { "type": "string" }, "base_name": { "type": "string", "description": "Omit to keep the uploaded file's own name. Sending \"\" also keeps it." }, "description": { "type": "string", "description": "Presence-aware: omit to carry the previous version's description forward,\nsend \"\" to clear it, send a value to set it." }, "notify": { "type": "string", "description": "Who to notify: \"default\", \"everyone\", or \"custom\" (the people in subscriptions).\n\nOmit both this and subscriptions to notify nobody. A subscriptions array sent\nwithout notify is read as \"custom\"." }, "subscriptions": { "type": "array", "items": { "type": "integer", "format": "int64" }, "description": "People to notify about the replacement and subscribe to the upload." } }, "required": [ "attachable_sgid" ] }, "CreateUploadVersionResponseContent": { "$ref": "#/components/schemas/Upload" }, "CreateVaultRequestContent": { "type": "object", "properties": { "title": { "type": "string" } }, "required": [ "title" ] }, "CreateVaultResponseContent": { "$ref": "#/components/schemas/Vault" }, "CreateWebhookRequestContent": { "type": "object", "properties": { "payload_url": { "type": "string" }, "types": { "type": "array", "items": { "type": "string" } }, "active": { "type": "boolean" } }, "required": [ "payload_url", "types" ] }, "CreateWebhookResponseContent": { "$ref": "#/components/schemas/Webhook" }, "CreateWormholeRequestContent": { "type": "object", "properties": { "destination_recording_id": { "type": "integer", "description": "Id of the destination column (on another accessible card table) to link to.", "format": "int64" } }, "required": [ "destination_recording_id" ] }, "CreateWormholeResponseContent": { "$ref": "#/components/schemas/Wormhole" }, "DisableCardColumnOnHoldResponseContent": { "$ref": "#/components/schemas/CardColumn" }, "DockItem": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "title": { "type": "string" }, "name": { "type": "string" }, "enabled": { "type": "boolean" }, "position": { "type": "integer", "format": "int32" }, "url": { "type": "string" }, "app_url": { "type": "string" } }, "required": [ "app_url", "enabled", "id", "name", "title", "url" ] }, "Document": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "status": { "type": "string" }, "visible_to_clients": { "type": "boolean" }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "updated_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "title": { "type": "string" }, "inherits_status": { "type": "boolean" }, "type": { "type": "string" }, "url": { "type": "string" }, "app_url": { "type": "string" }, "bookmark_url": { "type": "string" }, "subscription_url": { "type": "string" }, "comments_count": { "type": "integer", "format": "int32" }, "comments_url": { "type": "string" }, "position": { "type": "integer", "format": "int32" }, "parent": { "$ref": "#/components/schemas/RecordingParent" }, "bucket": { "$ref": "#/components/schemas/TodoBucket" }, "creator": { "$ref": "#/components/schemas/Person" }, "content": { "type": "string" }, "content_attachments": { "type": "array", "items": { "$ref": "#/components/schemas/RichTextAttachment" } }, "boosts_count": { "type": "integer", "format": "int32" }, "boosts_url": { "type": "string" } }, "required": [ "app_url", "bucket", "content_attachments", "created_at", "creator", "id", "inherits_status", "parent", "status", "title", "type", "updated_at", "url", "visible_to_clients" ] }, "DoorService": { "type": "object", "description": "Metadata describing the recognized external service backing an external link\n(`Door` recording): its display name, a canonical example URL, a short code,\nthe URL patterns Basecamp recognizes for it, and human supporting text. `code`\nis `other` for a generic link.", "properties": { "name": { "type": "string" }, "example_url": { "type": "string" }, "code": { "type": "string" }, "valid_patterns": { "type": "array", "items": { "type": "string" }, "x-go-type-skip-optional-pointer": true }, "supporting_text": { "type": "string" } } }, "Draft": { "type": "object", "description": "A draft envelope: a message, document, upload, or client approval/\ncorrespondence saved but not yet published. Flat and purpose-built —\nNOT the shared recording projection.", "properties": { "id": { "type": "integer", "format": "int64" }, "app_url": { "type": "string" }, "title": { "type": "string" }, "type": { "type": "string", "description": "Short recordable name: message, document, upload, client_approval,\nor client_correspondence." }, "bucket": { "$ref": "#/components/schemas/DraftBucket" }, "parent": { "anyOf": [ { "$ref": "#/components/schemas/DraftParent" }, { "type": "null" } ], "x-go-type": "DraftParent" }, "excerpt": { "type": "string", "description": "Up to 300 characters of plain text; empty string when the draft has no body." }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "updated_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "scheduled_posting_at": { "type": [ "string", "null" ], "description": "Always present; `null` unless the draft is scheduled to publish later.\nRequired-presence with nullable value, like `parent`.", "x-go-type": "time.Time" } }, "required": [ "app_url", "bucket", "created_at", "excerpt", "id", "parent", "scheduled_posting_at", "title", "type", "updated_at" ] }, "DraftBucket": { "type": "object", "description": "The project a draft lives in (drafts-specific projection: id, name, app_url).", "properties": { "id": { "type": "integer", "format": "int64" }, "name": { "type": "string" }, "app_url": { "type": "string" } }, "required": [ "app_url", "id", "name" ] }, "DraftParent": { "type": "object", "description": "The parent recording a draft is filed under (id, title, app_url).", "properties": { "id": { "type": "integer", "format": "int64" }, "title": { "type": "string" }, "app_url": { "type": "string" } }, "required": [ "app_url", "id", "title" ] }, "EnableCardColumnOnHoldResponseContent": { "$ref": "#/components/schemas/CardColumn" }, "EnableOutOfOfficeRequestContent": { "type": "object", "properties": { "out_of_office": { "$ref": "#/components/schemas/OutOfOfficePayload" } }, "required": [ "out_of_office" ] }, "EnableOutOfOfficeResponseContent": { "$ref": "#/components/schemas/OutOfOffice" }, "Event": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "recording_id": { "type": "integer", "format": "int64" }, "action": { "type": "string" }, "details": { "$ref": "#/components/schemas/EventDetails" }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "creator": { "$ref": "#/components/schemas/Person" }, "boosts_count": { "type": "integer", "format": "int32" }, "boosts_url": { "type": "string" } }, "required": [ "action", "created_at", "creator", "id", "recording_id" ] }, "EventDetails": { "type": "object", "properties": { "added_person_ids": { "type": "array", "items": { "type": "integer", "format": "int64" }, "x-go-type-skip-optional-pointer": true }, "removed_person_ids": { "type": "array", "items": { "type": "integer", "format": "int64" }, "x-go-type-skip-optional-pointer": true }, "notified_recipient_ids": { "type": "array", "items": { "type": "integer", "format": "int64" }, "x-go-type-skip-optional-pointer": true } } }, "EverythingFile": { "type": "object", "description": "A single item in the /files.json feed. An optional-field superset over three\nwire variants — a full Upload recording, a Basecamp Document recording, and a\nrich-text attachment wrapped in a recording envelope (distinguished by\n`attachable_sgid` and blob metadata). Every field is optional; a given\ninstance populates only the fields of the variant it represents. Unknown\nfields are ignored by every SDK decoder, so the superset need not enumerate\nevery field of the Upload/Document recordings.", "properties": { "id": { "type": "integer", "description": "Recording (Upload/Document) or attachment id.", "format": "int64" }, "status": { "type": "string" }, "visible_to_clients": { "type": "boolean" }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "updated_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "title": { "type": "string" }, "inherits_status": { "type": "boolean" }, "type": { "type": "string", "description": "\"Upload\", \"Document\", or \"Attachment\"." }, "url": { "type": "string" }, "app_url": { "type": "string" }, "bookmark_url": { "type": "string" }, "subscription_url": { "type": "string" }, "comments_count": { "type": "integer", "format": "int32" }, "comments_url": { "type": "string" }, "boosts_count": { "type": "integer", "format": "int32" }, "boosts_url": { "type": "string" }, "position": { "type": "integer", "format": "int32" }, "parent": { "$ref": "#/components/schemas/RecordingParent" }, "bucket": { "$ref": "#/components/schemas/RecordingBucket" }, "creator": { "$ref": "#/components/schemas/Person" }, "attachable_sgid": { "type": "string", "description": "Present on the rich-text attachment variant: signed global id of the\nattachment (uploads/documents omit it)." }, "content_type": { "type": "string" }, "byte_size": { "type": "integer", "format": "int64" }, "filename": { "type": "string" }, "download_url": { "type": "string", "x-basecamp-auth-routable-url": {} }, "app_download_url": { "type": "string" }, "width": { "type": "integer", "description": "Pixel width; null for non-image blobs and may be float-spelled (1024.0).", "format": "int32", "nullable": true, "x-go-type": "types.FlexInt", "x-go-type-import": { "path": "github.com/basecamp/basecamp-sdk/go/pkg/types" } }, "height": { "type": "integer", "description": "Pixel height; null for non-image blobs and may be float-spelled (1024.0).", "format": "int32", "nullable": true, "x-go-type": "types.FlexInt", "x-go-type-import": { "path": "github.com/basecamp/basecamp-sdk/go/pkg/types" } }, "description": { "type": "string", "description": "Rich-text description (upload/document variants)." }, "description_attachments": { "type": "array", "items": { "$ref": "#/components/schemas/RichTextAttachment" }, "x-go-type-skip-optional-pointer": true }, "content": { "type": "string", "description": "Rich-text body of the Document variant (uploads/attachments omit it)." }, "content_attachments": { "type": "array", "items": { "$ref": "#/components/schemas/RichTextAttachment" }, "x-go-type-skip-optional-pointer": true } } }, "FieldErrorMap": { "type": "object", "additionalProperties": { "type": "array", "items": { "type": "string" } }, "propertyNames": { "type": "string" } }, "FieldKeyedErrors": { "type": "object", "description": "The field-keyed 422 body: {\"errors\": {\"color\": [\"is not a valid color\"]}}.", "properties": { "errors": { "$ref": "#/components/schemas/FieldErrorMap" } }, "required": [ "errors" ] }, "FieldValidationErrorResponseContent": { "$ref": "#/components/schemas/FieldKeyedErrors" }, "FirstWeekDay": { "type": "string", "enum": [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ] }, "Folder": { "type": "object", "description": "A folder as the list returns it: the base shape, without expanded projects.\n\nDeliberately distinct from FolderWithProjects. A single shape with an\noptional `projects` member would make every list item declare a field the\nlist response never populates.", "properties": { "id": { "type": "integer", "format": "int64" }, "name": { "type": "string" }, "type": { "type": "string", "description": "Always the string `Stack` — the wire type kept its pre-rename name." }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "updated_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "bucket_ids": { "type": "array", "items": { "type": "integer", "format": "int64" }, "description": "IDs of the projects filed into this folder. Same ids as `project_ids` on\ncreate, and the ids FolderWithProjects expands under `projects`." }, "is_emoji_only_name": { "type": "boolean" }, "star_url": { "type": "string" }, "gauges_url": { "type": [ "string", "null" ], "description": "Gauges URL covering this folder's projects; always emitted, `null` when\nnone of them is gauged. `@required` models the presence — the nullability\nis layered on in the OpenAPI (smithy-build.json jsonAdd -> type:\n[\"string\",\"null\"]), so Go types it *string because the value is nullable,\nnot because the key is optional.", "x-go-type": "string" }, "color": { "type": [ "string", "null" ], "description": "The viewer's colour customization for this folder; always emitted, `null`\nwhen unset. Required-and-nullable, like gauges_url.", "x-go-type": "string" }, "image_url": { "type": [ "string", "null" ], "description": "The viewer's folder image; always emitted, `null` when unset. Read-only:\nthere is no image create or update in v1. Required-and-nullable, like\ngauges_url.", "x-go-type": "string" }, "url": { "type": "string" } }, "required": [ "bucket_ids", "color", "created_at", "gauges_url", "id", "image_url", "is_emoji_only_name", "name", "star_url", "type", "updated_at", "url" ] }, "FolderWithProjects": { "type": "object", "description": "One folder plus the projects grouped inside it, as get/create/update return it.\n\nThe `projects` entries are the shared project projection, minus the\n`bookmarked` flag that only the projects index adds.", "properties": { "id": { "type": "integer", "format": "int64" }, "name": { "type": "string" }, "type": { "type": "string", "description": "Always the string `Stack` — the wire type kept its pre-rename name." }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "updated_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "bucket_ids": { "type": "array", "items": { "type": "integer", "format": "int64" }, "description": "IDs of the projects filed into this folder — the same set `projects`\nexpands." }, "is_emoji_only_name": { "type": "boolean" }, "star_url": { "type": "string" }, "gauges_url": { "type": [ "string", "null" ], "description": "Gauges URL covering this folder's projects; always emitted, `null` when\nnone of them is gauged. Required-and-nullable (see Folder.gauges_url).", "x-go-type": "string" }, "color": { "type": [ "string", "null" ], "description": "The viewer's colour customization for this folder; always emitted, `null`\nwhen unset. Required-and-nullable.", "x-go-type": "string" }, "image_url": { "type": [ "string", "null" ], "description": "The viewer's folder image; always emitted, `null` when unset. Read-only.\nRequired-and-nullable.", "x-go-type": "string" }, "url": { "type": "string" }, "projects": { "type": "array", "items": { "$ref": "#/components/schemas/Project" }, "description": "The projects filed into this folder, expanded. Always emitted; empty for\nan empty folder." } }, "required": [ "bucket_ids", "color", "created_at", "gauges_url", "id", "image_url", "is_emoji_only_name", "name", "projects", "star_url", "type", "updated_at", "url" ] }, "ForbiddenErrorResponseContent": { "type": "object", "properties": { "error": { "type": "string" }, "message": { "type": "string" } }, "required": [ "error" ] }, "Forward": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "status": { "type": "string" }, "visible_to_clients": { "type": "boolean" }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "updated_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "title": { "type": "string" }, "inherits_status": { "type": "boolean" }, "type": { "type": "string" }, "url": { "type": "string" }, "app_url": { "type": "string" }, "bookmark_url": { "type": "string" }, "subscription_url": { "type": "string" }, "parent": { "$ref": "#/components/schemas/RecordingParent" }, "bucket": { "$ref": "#/components/schemas/TodoBucket" }, "creator": { "$ref": "#/components/schemas/Person" }, "content": { "type": "string" }, "content_attachments": { "type": "array", "items": { "$ref": "#/components/schemas/RichTextAttachment" } }, "subject": { "type": "string" }, "from": { "type": "string" }, "replies_count": { "type": "integer", "format": "int32" }, "replies_url": { "type": "string" } }, "required": [ "app_url", "bucket", "content_attachments", "created_at", "creator", "id", "inherits_status", "parent", "status", "subject", "title", "type", "updated_at", "url", "visible_to_clients" ] }, "ForwardReply": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "status": { "type": "string" }, "visible_to_clients": { "type": "boolean" }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "updated_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "title": { "type": "string" }, "inherits_status": { "type": "boolean" }, "type": { "type": "string" }, "url": { "type": "string" }, "app_url": { "type": "string" }, "bookmark_url": { "type": "string" }, "parent": { "$ref": "#/components/schemas/RecordingParent" }, "bucket": { "$ref": "#/components/schemas/TodoBucket" }, "creator": { "$ref": "#/components/schemas/Person" }, "content": { "type": "string" }, "content_attachments": { "type": "array", "items": { "$ref": "#/components/schemas/RichTextAttachment" } }, "boosts_count": { "type": "integer", "format": "int32" }, "boosts_url": { "type": "string" } }, "required": [ "app_url", "bucket", "content", "content_attachments", "created_at", "creator", "id", "inherits_status", "parent", "status", "title", "type", "updated_at", "url", "visible_to_clients" ] }, "Gauge": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "status": { "type": "string" }, "visible_to_clients": { "type": "boolean" }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "updated_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "title": { "type": "string" }, "inherits_status": { "type": "boolean" }, "type": { "type": "string" }, "url": { "type": "string" }, "app_url": { "type": "string" }, "bookmark_url": { "type": "string" }, "bucket": { "$ref": "#/components/schemas/RecordingBucket" }, "creator": { "$ref": "#/components/schemas/Person" }, "description": { "type": "string" }, "description_attachments": { "type": "array", "items": { "$ref": "#/components/schemas/RichTextAttachment" }, "description": "Optional (no `@required`): the type-specific partial renders the\ncompanion array only when the gauge has needles (bc3 `if\ngauge.any_needles?`), so a needle-less gauge omits the key entirely.\nNon-nullable — never served as JSON `null`.", "x-go-type-skip-optional-pointer": true }, "enabled": { "type": "boolean" }, "last_needle_color": { "type": "string" }, "last_needle_position": { "type": "integer", "format": "int32" }, "previous_needle_position": { "type": "integer", "format": "int32" } }, "required": [ "created_at", "id", "updated_at" ] }, "GaugeNeedle": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "status": { "type": "string" }, "visible_to_clients": { "type": "boolean" }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "updated_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "title": { "type": "string" }, "inherits_status": { "type": "boolean" }, "type": { "type": "string" }, "url": { "type": "string" }, "app_url": { "type": "string" }, "bookmark_url": { "type": "string" }, "subscription_url": { "type": "string" }, "comments_count": { "type": "integer", "format": "int32" }, "comments_url": { "type": "string" }, "boosts_count": { "type": "integer", "format": "int32" }, "boosts_url": { "type": "string" }, "parent": { "$ref": "#/components/schemas/RecordingParent" }, "bucket": { "$ref": "#/components/schemas/RecordingBucket" }, "creator": { "$ref": "#/components/schemas/Person" }, "description": { "type": "string" }, "description_attachments": { "type": "array", "items": { "$ref": "#/components/schemas/RichTextAttachment" } }, "color": { "type": "string" }, "position": { "type": "integer", "format": "int32" } }, "required": [ "created_at", "description_attachments", "id", "updated_at" ] }, "GaugeNeedlePayload": { "type": "object", "properties": { "position": { "type": "integer", "description": "Position of the needle (0-100)", "format": "int32" }, "color": { "type": "string", "description": "Status color: green (default), yellow, or red" }, "description": { "type": "string", "description": "Rich text (HTML) description of the progress update" } }, "required": [ "position" ] }, "GaugeNeedleUpdatePayload": { "type": "object", "properties": { "description": { "type": "string", "description": "Rich text (HTML) description" } } }, "GaugeTogglePayload": { "type": "object", "properties": { "enabled": { "type": "boolean" } }, "required": [ "enabled" ] }, "GetAccountResponseContent": { "$ref": "#/components/schemas/Account" }, "GetAnswerResponseContent": { "$ref": "#/components/schemas/QuestionAnswer" }, "GetAnswersByPersonResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/QuestionAnswer" } }, "GetAssignedTodosResponseContent": { "type": "object", "properties": { "person": { "$ref": "#/components/schemas/Person" }, "grouped_by": { "type": "string" }, "todos": { "type": "array", "items": { "$ref": "#/components/schemas/Todo" }, "x-go-type-skip-optional-pointer": true } } }, "GetBookmarkResponseContent": { "$ref": "#/components/schemas/BookmarkStatus" }, "GetBoostResponseContent": { "$ref": "#/components/schemas/Boost" }, "GetBubbleUpsResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/Notification" } }, "GetCalendarResponseContent": { "$ref": "#/components/schemas/Calendar" }, "GetCampfireLineResponseContent": { "$ref": "#/components/schemas/CampfireLine" }, "GetCampfireResponseContent": { "$ref": "#/components/schemas/Campfire" }, "GetCardColumnResponseContent": { "$ref": "#/components/schemas/CardColumn" }, "GetCardResponseContent": { "$ref": "#/components/schemas/Card" }, "GetCardStepResponseContent": { "$ref": "#/components/schemas/CardStep" }, "GetCardTableResponseContent": { "$ref": "#/components/schemas/CardTable" }, "GetChatbotResponseContent": { "$ref": "#/components/schemas/Chatbot" }, "GetClientApprovalResponseContent": { "$ref": "#/components/schemas/ClientApproval" }, "GetClientCorrespondenceResponseContent": { "$ref": "#/components/schemas/ClientCorrespondence" }, "GetClientReplyResponseContent": { "$ref": "#/components/schemas/ClientReply" }, "GetCloudFileResponseContent": { "$ref": "#/components/schemas/CloudFile" }, "GetCommentResponseContent": { "$ref": "#/components/schemas/Comment" }, "GetDocumentResponseContent": { "$ref": "#/components/schemas/Document" }, "GetEverythingCheckinsResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/Recording" } }, "GetEverythingCommentsResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/Recording" } }, "GetEverythingCompletedCardsResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/BucketCardsGroup" } }, "GetEverythingCompletedTodosResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/BucketTodosGroup" } }, "GetEverythingFilesResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/EverythingFile" } }, "GetEverythingForwardsResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/Recording" } }, "GetEverythingMessagesResponseContent": { "type": "array", "items": { "$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": { "$ref": "#/components/schemas/Card" } }, "GetEverythingOverdueTodosResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/Todo" } }, "GetEverythingUnassignedCardsResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/BucketCardsGroup" } }, "GetEverythingUnassignedTodosResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/BucketTodosGroup" } }, "GetFolderResponseContent": { "$ref": "#/components/schemas/FolderWithProjects" }, "GetForwardReplyResponseContent": { "$ref": "#/components/schemas/ForwardReply" }, "GetForwardResponseContent": { "$ref": "#/components/schemas/Forward" }, "GetGaugeNeedleResponseContent": { "$ref": "#/components/schemas/GaugeNeedle" }, "GetGoogleDocumentResponseContent": { "$ref": "#/components/schemas/GoogleDocument" }, "GetHillChartResponseContent": { "$ref": "#/components/schemas/HillChart" }, "GetInboxResponseContent": { "$ref": "#/components/schemas/Inbox" }, "GetMessageBoardResponseContent": { "$ref": "#/components/schemas/MessageBoard" }, "GetMessageResponseContent": { "$ref": "#/components/schemas/Message" }, "GetMessageTypeResponseContent": { "$ref": "#/components/schemas/MessageType" }, "GetMyAssignmentsResponseContent": { "type": "object", "properties": { "priorities": { "type": "array", "items": { "$ref": "#/components/schemas/MyAssignment" }, "x-go-type-skip-optional-pointer": true }, "non_priorities": { "type": "array", "items": { "$ref": "#/components/schemas/MyAssignment" }, "x-go-type-skip-optional-pointer": true } } }, "GetMyCompletedAssignmentsResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/MyAssignment" } }, "GetMyDueAssignmentsResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/MyAssignment" } }, "GetMyNoteResponseContent": { "$ref": "#/components/schemas/MyNote" }, "GetMyNotificationsResponseContent": { "type": "object", "properties": { "unreads": { "type": "array", "items": { "$ref": "#/components/schemas/Notification" }, "x-go-type-skip-optional-pointer": true }, "reads": { "type": "array", "items": { "$ref": "#/components/schemas/Notification" }, "x-go-type-skip-optional-pointer": true }, "bubble_ups_count": { "type": "integer", "description": "Total number of current bubble-ups, for notification UI counts\n(independent of the `limit_bubble_ups` cap on the `bubble_ups` array).", "format": "int32" }, "scheduled_bubble_ups_count": { "type": "integer", "description": "Total number of scheduled bubble-ups, for notification UI counts\n(present even when `limit_bubble_ups` omits the `scheduled_bubble_ups`\narray).", "format": "int32" }, "memories": { "type": "array", "items": { "$ref": "#/components/schemas/Notification" }, "description": "Legacy \"save forever\" collection. Permanently `[]` on BC5 by documented\ncontract (`doc/api/sections/my_notifications.md`, codified by BC3 #11628):\nan always-empty placeholder superseded by `bubble_ups`. BC4 (the `four`\nbranch) still populates it — an accepted BC4→BC5 subtractive delta\nrecorded in `spec/api-gaps/memories-emptied-regression.md`. New\nintegrations should use `bubble_ups` / `scheduled_bubble_ups` and must\nnot rely on `memories` on BC5.", "x-go-type-skip-optional-pointer": true }, "bubble_ups": { "type": "array", "items": { "$ref": "#/components/schemas/Notification" }, "description": "Items the user has saved with Bubble Up (BC5 addition). Roughly the\nsuccessor to `memories` but with optional scheduling — see\n`scheduled_bubble_ups` for the time-deferred subset.", "x-go-type-skip-optional-pointer": true }, "scheduled_bubble_ups": { "type": "array", "items": { "$ref": "#/components/schemas/Notification" }, "description": "Bubble Ups scheduled to resurface in the future (BC5 addition).", "x-go-type-skip-optional-pointer": true } }, "required": [ "bubble_ups_count", "scheduled_bubble_ups_count" ] }, "GetMyPreferencesResponseContent": { "$ref": "#/components/schemas/Preferences" }, "GetMyProfileResponseContent": { "$ref": "#/components/schemas/Person" }, "GetOutOfOfficeResponseContent": { "$ref": "#/components/schemas/OutOfOffice" }, "GetOverdueTodosResponseContent": { "type": "object", "properties": { "under_a_week_late": { "type": "array", "items": { "$ref": "#/components/schemas/Todo" }, "x-go-type-skip-optional-pointer": true }, "over_a_week_late": { "type": "array", "items": { "$ref": "#/components/schemas/Todo" }, "x-go-type-skip-optional-pointer": true }, "over_a_month_late": { "type": "array", "items": { "$ref": "#/components/schemas/Todo" }, "x-go-type-skip-optional-pointer": true }, "over_three_months_late": { "type": "array", "items": { "$ref": "#/components/schemas/Todo" }, "x-go-type-skip-optional-pointer": true } } }, "GetPersonProgressResponseContent": { "type": "object", "properties": { "person": { "$ref": "#/components/schemas/Person" }, "events": { "type": "array", "items": { "$ref": "#/components/schemas/TimelineEvent" } } }, "required": [ "events", "person" ] }, "GetPersonResponseContent": { "$ref": "#/components/schemas/Person" }, "GetProgressReportResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/TimelineEvent" } }, "GetProjectConstructionResponseContent": { "$ref": "#/components/schemas/ProjectConstruction" }, "GetProjectResponseContent": { "$ref": "#/components/schemas/Project" }, "GetProjectTimelineResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/TimelineEvent" } }, "GetProjectTimesheetResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/TimesheetEntry" } }, "GetQuestionRemindersResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/QuestionReminder" } }, "GetQuestionResponseContent": { "$ref": "#/components/schemas/Question" }, "GetQuestionnaireResponseContent": { "$ref": "#/components/schemas/Questionnaire" }, "GetRecordingTimesheetResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/TimesheetEntry" } }, "GetScheduleEntryOccurrenceResponseContent": { "$ref": "#/components/schemas/ScheduleEntry" }, "GetScheduleEntryResponseContent": { "$ref": "#/components/schemas/ScheduleEntry" }, "GetScheduleResponseContent": { "$ref": "#/components/schemas/Schedule" }, "GetSearchMetadataResponseContent": { "$ref": "#/components/schemas/SearchMetadata" }, "GetSubscriptionResponseContent": { "$ref": "#/components/schemas/Subscription" }, "GetTemplateResponseContent": { "$ref": "#/components/schemas/Template" }, "GetTimesheetEntryResponseContent": { "$ref": "#/components/schemas/TimesheetEntry" }, "GetTimesheetReportResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/TimesheetEntry" } }, "GetTodoResponseContent": { "$ref": "#/components/schemas/Todo" }, "GetTodolistOrGroupResponseContent": { "$ref": "#/components/schemas/Todolist" }, "GetTodosetResponseContent": { "$ref": "#/components/schemas/Todoset" }, "GetToolResponseContent": { "$ref": "#/components/schemas/Tool" }, "GetUpcomingScheduleResponseContent": { "type": "object", "properties": { "schedule_entries": { "type": "array", "items": { "$ref": "#/components/schemas/UpcomingScheduleEntry" }, "description": "Non-recurring entries starting in the window, chronological. Always\npresent — `reports/schedules/upcoming/index.json.jbuilder` writes all\nthree keys unconditionally, so an empty window is three empty arrays\nrather than a missing key." }, "recurring_schedule_entry_occurrences": { "type": "array", "items": { "$ref": "#/components/schemas/UpcomingScheduleEntry" }, "description": "Realized occurrences of recurring entries falling in the window. Rendered\nthrough the same calendar entry partial as schedule_entries, so the two\narrays carry the same shape; an occurrence is distinguished only by its\n`recurring` flag being true. Always present." }, "assignables": { "type": "array", "items": { "$ref": "#/components/schemas/UpcomingAssignable" }, "description": "Dated to-dos, cards and steps falling in the window. Always present." } }, "required": [ "assignables", "recurring_schedule_entry_occurrences", "schedule_entries" ] }, "GetUploadResponseContent": { "$ref": "#/components/schemas/Upload" }, "GetVaultResponseContent": { "$ref": "#/components/schemas/Vault" }, "GetWebhookResponseContent": { "$ref": "#/components/schemas/Webhook" }, "GoogleDocument": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "status": { "type": "string" }, "visible_to_clients": { "type": "boolean" }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "updated_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "title": { "type": "string" }, "inherits_status": { "type": "boolean" }, "type": { "type": "string" }, "url": { "type": "string", "description": "The Google Workspace document link — NOT this record's API URL. Same\nrecordable-overwrites-recording rendering as CloudFile#url." }, "app_url": { "type": "string" }, "bookmark_url": { "type": "string" }, "subscription_url": { "type": "string" }, "comments_count": { "type": "integer", "format": "int32" }, "comments_url": { "type": "string" }, "position": { "type": "integer", "format": "int32" }, "parent": { "$ref": "#/components/schemas/RecordingParent" }, "bucket": { "$ref": "#/components/schemas/TodoBucket" }, "creator": { "$ref": "#/components/schemas/Person" }, "description": { "type": "string" }, "description_attachments": { "type": "array", "items": { "$ref": "#/components/schemas/RichTextAttachment" } }, "document_type": { "type": "string", "description": "One of \"doc\", \"sheet\", \"slide\", \"other\". Backed by a Rails enum, so an\nunrecognized value is rejected up front with a field-keyed 422\n({\"errors\": {\"document_type\": [\"is not a valid document type\"]}}) rather\nthan reaching validation." }, "boosts_count": { "type": "integer", "format": "int32" }, "boosts_url": { "type": "string" } }, "required": [ "app_url", "bucket", "created_at", "creator", "description_attachments", "document_type", "id", "inherits_status", "parent", "status", "title", "type", "updated_at", "url", "visible_to_clients" ] }, "HillChart": { "type": "object", "properties": { "enabled": { "type": "boolean" }, "stale": { "type": "boolean" }, "updated_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "app_update_url": { "type": "string" }, "app_versions_url": { "type": "string" }, "dots": { "type": "array", "items": { "$ref": "#/components/schemas/HillChartDot" }, "x-go-type-skip-optional-pointer": true } }, "required": [ "enabled", "stale" ] }, "HillChartDot": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "label": { "type": "string" }, "color": { "type": "string" }, "position": { "type": "integer", "format": "int32" }, "url": { "type": "string" }, "app_url": { "type": "string" } }, "required": [ "color", "id", "label", "position" ] }, "Inbox": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "status": { "type": "string" }, "visible_to_clients": { "type": "boolean" }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "updated_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "title": { "type": "string" }, "inherits_status": { "type": "boolean" }, "type": { "type": "string" }, "url": { "type": "string" }, "app_url": { "type": "string" }, "bookmark_url": { "type": "string" }, "position": { "type": "integer", "format": "int32" }, "bucket": { "$ref": "#/components/schemas/TodoBucket" }, "creator": { "$ref": "#/components/schemas/Person" }, "forwards_count": { "type": "integer", "format": "int32" }, "forwards_url": { "type": "string" } }, "required": [ "app_url", "bucket", "created_at", "creator", "id", "inherits_status", "status", "title", "type", "updated_at", "url", "visible_to_clients" ] }, "InternalServerErrorResponseContent": { "type": "object", "properties": { "error": { "type": "string" }, "message": { "type": "string" } }, "required": [ "error" ] }, "LineupMarker": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "name": { "type": "string" }, "date": { "type": "string" }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "updated_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } } }, "required": [ "created_at", "date", "id", "name", "updated_at" ] }, "ListAnswersResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/QuestionAnswer" } }, "ListAssignablePeopleResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/Person" } }, "ListCampfireLinesResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/CampfireLine" } }, "ListCampfireUploadsResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/CampfireLine" } }, "ListCampfiresResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/Campfire" } }, "ListCardsResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/Card" } }, "ListChatbotsResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/Chatbot" } }, "ListClientApprovalsResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/ClientApproval" } }, "ListClientCorrespondencesResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/ClientCorrespondence" } }, "ListClientRepliesResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/ClientReply" } }, "ListCommentsResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/Comment" } }, "ListDocumentsResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/Document" } }, "ListEventBoostsResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/Boost" } }, "ListEventsResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/Event" } }, "ListFoldersResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/Folder" } }, "ListForwardRepliesResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/ForwardReply" } }, "ListForwardsResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/Forward" } }, "ListGaugeNeedlesResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/GaugeNeedle" } }, "ListGaugesResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/Gauge" } }, "ListLineupMarkersResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/LineupMarker" } }, "ListMessageTypesResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/MessageType" } }, "ListMessagesResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/Message" } }, "ListMyBookmarksResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/Bookmark" } }, "ListMyDraftsResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/Draft" } }, "ListPeopleResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/Person" } }, "ListPingablePeopleResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/Person" } }, "ListProjectPeopleResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/Person" } }, "ListProjectsResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/Project" } }, "ListQuestionAnswerersResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/Person" } }, "ListQuestionsResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/Question" } }, "ListRecordingBoostsResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/Boost" } }, "ListRecordingsResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/Recording" } }, "ListScheduleEntriesResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/ScheduleEntry" } }, "ListTemplatesResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/Template" } }, "ListTodolistGroupsResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/Todolist" } }, "ListTodolistsResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/Todolist" } }, "ListTodosResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/Todo" } }, "ListUploadVersionsResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/UploadVersion" } }, "ListUploadsResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/Upload" } }, "ListVaultsResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/Vault" } }, "ListWebhooksResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/Webhook" } }, "MarkAsReadRequestContent": { "type": "object", "properties": { "readables": { "type": "array", "items": { "type": "string" }, "description": "Array of readable_sgid values identifying the items to mark as read" } }, "required": [ "readables" ] }, "Message": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "status": { "type": "string" }, "visible_to_clients": { "type": "boolean" }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "updated_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "title": { "type": "string" }, "inherits_status": { "type": "boolean" }, "type": { "type": "string" }, "url": { "type": "string" }, "app_url": { "type": "string" }, "bookmark_url": { "type": "string" }, "subscription_url": { "type": "string" }, "comments_count": { "type": "integer", "format": "int32" }, "comments_url": { "type": "string" }, "parent": { "$ref": "#/components/schemas/RecordingParent" }, "bucket": { "$ref": "#/components/schemas/TodoBucket" }, "creator": { "$ref": "#/components/schemas/Person" }, "subject": { "type": "string" }, "content": { "type": "string" }, "content_attachments": { "type": "array", "items": { "$ref": "#/components/schemas/RichTextAttachment" } }, "category": { "$ref": "#/components/schemas/MessageType" }, "boosts_count": { "type": "integer", "format": "int32" }, "boosts_url": { "type": "string" } }, "required": [ "app_url", "bucket", "content", "content_attachments", "created_at", "creator", "id", "inherits_status", "parent", "status", "subject", "title", "type", "updated_at", "url", "visible_to_clients" ] }, "MessageBoard": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "status": { "type": "string" }, "visible_to_clients": { "type": "boolean" }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "updated_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "title": { "type": "string" }, "inherits_status": { "type": "boolean" }, "type": { "type": "string" }, "url": { "type": "string" }, "app_url": { "type": "string" }, "bookmark_url": { "type": "string" }, "position": { "type": "integer", "format": "int32" }, "bucket": { "$ref": "#/components/schemas/TodoBucket" }, "creator": { "$ref": "#/components/schemas/Person" }, "messages_count": { "type": "integer", "format": "int32" }, "messages_url": { "type": "string" }, "app_messages_url": { "type": "string" } }, "required": [ "app_url", "bucket", "created_at", "creator", "id", "inherits_status", "status", "title", "type", "updated_at", "url", "visible_to_clients" ] }, "MessageType": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "name": { "type": "string" }, "icon": { "type": "string" }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "updated_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } } }, "required": [ "created_at", "icon", "id", "name", "updated_at" ] }, "MoveCardColumnRequestContent": { "type": "object", "properties": { "source_id": { "type": "integer", "format": "int64" }, "target_id": { "type": "integer", "format": "int64" }, "position": { "type": "integer", "format": "int32" } }, "required": [ "source_id", "target_id" ] }, "MoveCardRequestContent": { "type": "object", "properties": { "column_id": { "type": "integer", "format": "int64" }, "position": { "type": "integer", "description": "1-indexed position within the destination column. Defaults to 1 (top).", "format": "int32" } }, "required": [ "column_id" ] }, "MyAssignment": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "app_url": { "type": "string" }, "content": { "type": "string" }, "starts_on": { "type": "string", "x-go-type": "types.Date", "x-go-type-import": { "path": "github.com/basecamp/basecamp-sdk/go/pkg/types" } }, "due_on": { "type": "string", "x-go-type": "types.Date", "x-go-type-import": { "path": "github.com/basecamp/basecamp-sdk/go/pkg/types" } }, "bucket": { "$ref": "#/components/schemas/MyAssignmentBucket" }, "completed": { "type": "boolean" }, "type": { "type": "string" }, "assignees": { "type": "array", "items": { "$ref": "#/components/schemas/MyAssignmentAssignee" }, "x-go-type-skip-optional-pointer": true }, "comments_count": { "type": "integer", "format": "int32" }, "has_description": { "type": "boolean" }, "priority_recording_id": { "type": "integer", "description": "Present on priority items", "format": "int64" }, "parent": { "$ref": "#/components/schemas/MyAssignmentParent" }, "children": { "type": "array", "items": { "$ref": "#/components/schemas/MyAssignment" }, "x-go-type-skip-optional-pointer": true } }, "required": [ "id" ] }, "MyAssignmentAssignee": { "type": "object", "description": "A person as bc3's `people/_person_minimal.json.jbuilder` renders them —\nthe same three-key partial behind UpcomingSchedulePerson and\nOutOfOfficePerson. All three keys are emitted unconditionally, so all\nthree are required.", "properties": { "id": { "type": "integer", "format": "int64" }, "name": { "type": "string", "format": "password" }, "avatar_url": { "type": "string", "format": "password" } }, "required": [ "avatar_url", "id", "name" ] }, "MyAssignmentBucket": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "name": { "type": "string" }, "app_url": { "type": "string" } }, "required": [ "id" ] }, "MyAssignmentParent": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "title": { "type": "string" }, "app_url": { "type": "string" } }, "required": [ "id" ] }, "MyNote": { "type": "object", "description": "The per-user notebook note (wire type Notebook::Note). Before the first\nwrite, id/created_at/updated_at are present-but-null (required-nullable,\nlayered in the OpenAPI via jsonAdd) and content is empty.", "properties": { "id": { "type": [ "integer", "null" ], "description": "Null until the note is first written.", "format": "int64", "x-go-type": "int64" }, "type": { "type": "string" }, "created_at": { "type": [ "string", "null" ], "description": "Null until the note is first written.", "x-go-type": "time.Time" }, "updated_at": { "type": [ "string", "null" ], "description": "Null until the note is first written.", "x-go-type": "time.Time" }, "content": { "type": "string" }, "content_attachments": { "type": "array", "items": { "$ref": "#/components/schemas/RichTextAttachment" } }, "url": { "type": "string" }, "app_url": { "type": "string" } }, "required": [ "app_url", "content", "content_attachments", "created_at", "id", "type", "updated_at", "url" ] }, "MyNoteAttributes": { "type": "object", "description": "The writable note payload — the wire body is the nested {note: {content}}\nenvelope, the ProjectConstructionAttributes treatment.", "properties": { "content": { "type": "string", "description": "The note's rich-text body (HTML)." } }, "required": [ "content" ] }, "NotFoundErrorResponseContent": { "type": "object", "properties": { "error": { "type": "string" }, "message": { "type": "string" } }, "required": [ "error" ] }, "Notification": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "updated_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "section": { "type": "string", "description": "The notification category: `inbox`, `chats`, `pings`, `bubbles`,\nor `mentions`." }, "unread_count": { "type": "integer", "format": "int32" }, "unread_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "read_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "readable_sgid": { "type": "string" }, "readable_identifier": { "type": "string" }, "title": { "type": "string" }, "type": { "type": "string" }, "bucket_name": { "type": "string" }, "creator": { "$ref": "#/components/schemas/Person" }, "content_excerpt": { "type": "string" }, "app_url": { "type": "string" }, "unread_url": { "type": "string" }, "bookmark_url": { "type": "string" }, "memory_url": { "type": "string" }, "bubble_up_url": { "type": "string", "description": "URL for the Bubble Up record covering this notification (BC5 addition).\nEligibility-gated — only present on items the current user can bubble up." }, "bubble_up_at": { "type": "string", "description": "Scheduled resurfacing time when this item is queued as a scheduled\nBubble Up (BC5 addition). Absent when there is no scheduled time.", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "subscription_url": { "type": "string" }, "subscribed": { "type": "boolean" }, "previewable_attachments": { "type": "array", "items": { "$ref": "#/components/schemas/PreviewableAttachment" }, "x-go-type-skip-optional-pointer": true }, "participants": { "type": "array", "items": { "$ref": "#/components/schemas/Person" }, "description": "Present on ping notifications", "x-go-type-skip-optional-pointer": true }, "named": { "type": "boolean", "description": "Whether the ping has a custom name (pings only)" }, "image_url": { "type": "string", "description": "Custom image URL (pings only)" } }, "required": [ "created_at", "id", "updated_at" ] }, "OutOfOffice": { "type": "object", "description": "When out of office is not enabled, `enabled` is `false` and\n`start_date`, `end_date`, and `back_on_date` are omitted.", "properties": { "person": { "$ref": "#/components/schemas/OutOfOfficePerson" }, "enabled": { "type": "boolean" }, "ongoing": { "type": "boolean" }, "start_date": { "type": "string" }, "end_date": { "type": "string" }, "back_on_date": { "type": "string", "description": "First working day after the out-of-office window ends.\nOmitted when out of office is not enabled." } } }, "OutOfOfficePayload": { "type": "object", "properties": { "start_date": { "type": "string", "description": "Start date in ISO 8601 format (YYYY-MM-DD)" }, "end_date": { "type": "string", "description": "End date in ISO 8601 format (YYYY-MM-DD)" } }, "required": [ "end_date", "start_date" ] }, "OutOfOfficePerson": { "type": "object", "description": "A person as bc3's `people/_person_minimal.json.jbuilder` renders them —\nthe same three-key partial behind UpcomingSchedulePerson and\nMyAssignmentAssignee. All three keys are emitted unconditionally, so all\nthree are required.", "properties": { "id": { "type": "integer", "format": "int64" }, "name": { "type": "string", "format": "password" }, "avatar_url": { "type": "string", "format": "password" } }, "required": [ "avatar_url", "id", "name" ] }, "PauseQuestionResponseContent": { "type": "object", "properties": { "paused": { "type": "boolean" } } }, "Person": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64", "x-go-type": "types.FlexibleInt64", "x-go-type-import": { "path": "github.com/basecamp/basecamp-sdk/go/pkg/types" } }, "attachable_sgid": { "type": "string" }, "name": { "type": "string", "format": "password", "x-basecamp-sensitive": { "category": "pii", "redact": true } }, "email_address": { "type": "string", "format": "password", "x-basecamp-sensitive": { "category": "pii", "redact": true } }, "personable_type": { "type": "string" }, "title": { "type": "string", "format": "password", "x-basecamp-sensitive": { "category": "pii", "redact": false } }, "bio": { "type": "string", "format": "password", "x-basecamp-sensitive": { "category": "pii", "redact": false } }, "tagline": { "type": "string", "description": "Alias of `bio` introduced in BC5. BC3 emits both keys with identical content;\nolder BC4 responses may omit `tagline`. Prefer `bio` for cross-version reads.", "format": "password", "x-basecamp-sensitive": { "category": "pii", "redact": false } }, "location": { "type": "string", "format": "password", "x-basecamp-sensitive": { "category": "pii", "redact": false } }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "updated_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "admin": { "type": "boolean" }, "owner": { "type": "boolean" }, "client": { "type": "boolean" }, "employee": { "type": "boolean" }, "time_zone": { "type": "string" }, "avatar_url": { "type": "string", "format": "password", "x-basecamp-sensitive": { "category": "pii", "redact": true } }, "company": { "$ref": "#/components/schemas/PersonCompany" }, "can_manage_projects": { "type": "boolean" }, "can_manage_people": { "type": "boolean" }, "can_ping": { "type": "boolean" }, "can_access_timesheet": { "type": "boolean" }, "can_access_hill_charts": { "type": "boolean" } }, "required": [ "id", "name" ] }, "PersonCompany": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "name": { "type": "string", "format": "password" } }, "required": [ "id", "name" ] }, "Preferences": { "type": "object", "properties": { "url": { "type": "string" }, "app_url": { "type": "string" }, "time_zone_name": { "type": "string", "description": "Returned as a Rails-style name (e.g. \"Central Time (US & Canada)\")." }, "first_week_day": { "type": "string" }, "time_format": { "type": "string" } } }, "PreferencesPayload": { "type": "object", "properties": { "time_zone_name": { "type": "string", "description": "Time zone name. Accepts any valid Rails time zone name (e.g.\n\"London\", \"UTC\") as well as IANA identifiers (e.g.\n\"America/Chicago\"), which are normalized to the matching\nRails-style name before saving." }, "first_week_day": { "type": "string", "description": "First day of the week: Sunday, Monday, Tuesday, etc." }, "time_format": { "type": "string", "description": "Time display format: twelve_hour or twenty_four_hour" } } }, "PreviewableAttachment": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "url": { "type": "string" }, "app_url": { "type": "string" }, "content_type": { "type": "string" }, "filename": { "type": "string" }, "filesize": { "type": "integer", "format": "int64" }, "width": { "type": "integer", "format": "int32" }, "height": { "type": "integer", "format": "int32" } } }, "PrioritizeAssignmentRequestContent": { "type": "object", "properties": { "id": { "type": "integer", "description": "The recording id to prioritize.", "format": "int64" } }, "required": [ "id" ] }, "Project": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "status": { "type": "string", "description": "active|archived|trashed" }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "updated_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "name": { "type": "string" }, "description": { "type": "string" }, "purpose": { "type": "string" }, "start_date": { "type": "string" }, "end_date": { "type": "string" }, "clients_enabled": { "type": "boolean" }, "bookmark_url": { "type": "string" }, "url": { "type": "string" }, "app_url": { "type": "string" }, "dock": { "type": "array", "items": { "$ref": "#/components/schemas/DockItem" }, "x-go-type-skip-optional-pointer": true }, "bookmarked": { "type": "boolean" }, "client_company": { "$ref": "#/components/schemas/ClientCompany" }, "clientside": { "$ref": "#/components/schemas/ClientSide", "deprecated": true, "x-deprecated-reason": "This shape is deprecated since 2024-01: Use Client Visibility feature instead" } }, "required": [ "app_url", "created_at", "id", "name", "status", "updated_at", "url" ] }, "ProjectAccessResult": { "type": "object", "properties": { "granted": { "type": "array", "items": { "$ref": "#/components/schemas/Person" }, "x-go-type-skip-optional-pointer": true }, "revoked": { "type": "array", "items": { "$ref": "#/components/schemas/Person" }, "x-go-type-skip-optional-pointer": true } } }, "ProjectConstruction": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "status": { "type": "string" }, "url": { "type": "string" }, "project": { "$ref": "#/components/schemas/Project" } }, "required": [ "id", "status" ] }, "ProjectConstructionAttributes": { "type": "object", "properties": { "name": { "type": "string" }, "description": { "type": "string" } }, "required": [ "name" ] }, "ProjectLimitErrorResponseContent": { "type": "object", "description": "The account has reached its project limit. Raised by CreateProject and by\nUnarchiveProject, both of which add to the active project count.", "properties": { "error": { "type": "string" }, "message": { "type": "string" } }, "required": [ "error" ] }, "Question": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "status": { "type": "string" }, "visible_to_clients": { "type": "boolean" }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "updated_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "title": { "type": "string" }, "inherits_status": { "type": "boolean" }, "type": { "type": "string" }, "url": { "type": "string" }, "app_url": { "type": "string" }, "bookmark_url": { "type": "string" }, "subscription_url": { "type": "string" }, "parent": { "$ref": "#/components/schemas/RecordingParent" }, "bucket": { "$ref": "#/components/schemas/RecordingBucket" }, "creator": { "$ref": "#/components/schemas/Person" }, "paused": { "type": "boolean" }, "schedule": { "$ref": "#/components/schemas/QuestionSchedule" }, "answers_count": { "type": "integer", "format": "int32" }, "answers_url": { "type": "string" } }, "required": [ "app_url", "bucket", "created_at", "creator", "id", "inherits_status", "parent", "status", "title", "type", "updated_at", "url", "visible_to_clients" ] }, "QuestionAnswer": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "status": { "type": "string" }, "visible_to_clients": { "type": "boolean" }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "updated_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "title": { "type": "string" }, "inherits_status": { "type": "boolean" }, "type": { "type": "string" }, "url": { "type": "string" }, "app_url": { "type": "string" }, "bookmark_url": { "type": "string" }, "subscription_url": { "type": "string" }, "comments_count": { "type": "integer", "format": "int32" }, "comments_url": { "type": "string" }, "content": { "type": "string" }, "content_attachments": { "type": "array", "items": { "$ref": "#/components/schemas/RichTextAttachment" } }, "group_on": { "type": "string", "x-go-type": "types.Date", "x-go-type-import": { "path": "github.com/basecamp/basecamp-sdk/go/pkg/types" } }, "parent": { "$ref": "#/components/schemas/RecordingParent" }, "bucket": { "$ref": "#/components/schemas/RecordingBucket" }, "creator": { "$ref": "#/components/schemas/Person" }, "boosts_count": { "type": "integer", "format": "int32" }, "boosts_url": { "type": "string" } }, "required": [ "app_url", "bucket", "content", "content_attachments", "created_at", "creator", "id", "inherits_status", "parent", "status", "title", "type", "updated_at", "url", "visible_to_clients" ] }, "QuestionAnswerPayload": { "type": "object", "properties": { "content": { "type": "string" }, "group_on": { "type": "string", "x-go-type": "types.Date", "x-go-type-import": { "path": "github.com/basecamp/basecamp-sdk/go/pkg/types" } } }, "required": [ "content" ] }, "QuestionAnswerUpdatePayload": { "type": "object", "properties": { "content": { "type": "string" }, "group_on": { "type": "string", "x-go-type": "types.Date", "x-go-type-import": { "path": "github.com/basecamp/basecamp-sdk/go/pkg/types" } } }, "required": [ "content" ] }, "QuestionReminder": { "type": "object", "properties": { "reminder_id": { "type": "integer", "format": "int64" }, "remind_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "group_on": { "type": "string", "x-go-type": "types.Date", "x-go-type-import": { "path": "github.com/basecamp/basecamp-sdk/go/pkg/types" } }, "question": { "$ref": "#/components/schemas/Question" } } }, "QuestionSchedule": { "type": "object", "properties": { "frequency": { "type": "string" }, "days": { "type": "array", "items": { "type": "integer", "format": "int32" } }, "hour": { "type": "integer", "format": "int32" }, "minute": { "type": "integer", "format": "int32" }, "week_instance": { "type": "integer", "format": "int32" }, "week_interval": { "type": "integer", "format": "int32" }, "month_interval": { "type": "integer", "format": "int32" }, "start_date": { "type": "string" }, "end_date": { "type": "string" } } }, "Questionnaire": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "status": { "type": "string" }, "visible_to_clients": { "type": "boolean" }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "updated_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "title": { "type": "string" }, "inherits_status": { "type": "boolean" }, "type": { "type": "string" }, "url": { "type": "string" }, "app_url": { "type": "string" }, "bookmark_url": { "type": "string" }, "questions_url": { "type": "string" }, "questions_count": { "type": "integer", "format": "int32" }, "name": { "type": "string" }, "bucket": { "$ref": "#/components/schemas/RecordingBucket" }, "creator": { "$ref": "#/components/schemas/Person" } }, "required": [ "app_url", "bucket", "created_at", "creator", "id", "inherits_status", "name", "status", "title", "type", "updated_at", "url", "visible_to_clients" ] }, "RateLimitErrorResponseContent": { "type": "object", "properties": { "error": { "type": "string" }, "message": { "type": "string" }, "retry_after": { "type": "integer", "format": "int32" } }, "required": [ "error" ] }, "Recording": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "status": { "type": "string" }, "visible_to_clients": { "type": "boolean" }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "updated_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "title": { "type": "string" }, "inherits_status": { "type": "boolean" }, "type": { "type": "string" }, "url": { "type": "string", "description": "API URL of the recording. Exception: in the `type=Door` (external-link)\nprojection, `url` is the door's **external destination address** (e.g. the\nFigma/Dropbox URL) and `app_url` is the Basecamp redirector — see the\ndoor-specific `service`/`description` fields below." }, "app_url": { "type": "string" }, "bookmark_url": { "type": "string" }, "bubble_up_url": { "type": "string", "description": "URL of the Bubble Up record for this recording (BC5 addition). Optional\nhere because this is a polymorphic projection:\n`recordings/_recording.json.jbuilder` emits the key only when the caller\npasses `local_assigns[:bubbleupable]`, and `todolists/_todolist` is the\nonly partial that does. So a Todolist-shaped instance carries it and the\nother recording types do not." }, "content": { "type": "string" }, "content_attachments": { "type": "array", "items": { "$ref": "#/components/schemas/RichTextAttachment" }, "description": "Rich-text companion arrays carried through the generic recording\nprojection (`to_recordable_partial_path` renders the full type-specific\npartial). A given recording is one type, so it carries only the array\nmatching its rich-text attribute (`content_attachments` for a\nComment/Message, `description_attachments` for a Todo/Card); a\nwebhook-sourced recording (base partial) carries neither. Optional (no\n`@required`), non-nullable.", "x-go-type-skip-optional-pointer": true }, "description_attachments": { "type": "array", "items": { "$ref": "#/components/schemas/RichTextAttachment" }, "description": "See `content_attachments` — the description-attribute companion array.", "x-go-type-skip-optional-pointer": true }, "comments_count": { "type": "integer", "format": "int32" }, "comments_url": { "type": "string" }, "subscription_url": { "type": "string" }, "boosts_count": { "type": "integer", "description": "Boost count/URL. Carried on boostable recordings — notably the account-wide\naggregate feeds (`/messages.json`, `/comments.json`), whose type-specific\npartials render with `boostable: true`. Optional (absent on non-boostable\nrecordings and on the base/webhook partial).", "format": "int32" }, "boosts_url": { "type": "string" }, "subject": { "type": "string", "description": "Message subject. Present on `Message` recordings — notably the account-wide\n`/messages.json` aggregate feed, whose message partial renders `subject`." }, "category": { "$ref": "#/components/schemas/RecordingCategory" }, "group_on": { "type": "string", "description": "Check-in grouping date (YYYY-MM-DD). Present on automatic check-in answer\n(`Question::Answer`) recordings — notably the `/checkins.json` aggregate\nfeed, whose answer partial renders `group_on`.", "x-go-type": "types.Date", "x-go-type-import": { "path": "github.com/basecamp/basecamp-sdk/go/pkg/types" } }, "from": { "type": "string", "description": "Sender of an inbox forward. Present on `Inbox::Forward` recordings — notably\nthe `/forwards.json` aggregate feed, whose forward partial renders `from`." }, "replies_count": { "type": "integer", "description": "Reply count/URL for an inbox forward. Present on `Inbox::Forward`\nrecordings — notably the `/forwards.json` aggregate feed.", "format": "int32" }, "replies_url": { "type": "string" }, "position": { "type": "integer", "description": "Ordinal position within the project's External links section. Present on\n`Door` (external-link) recordings.", "format": "int32" }, "description": { "type": "string", "description": "Rich-text (HTML) description shown beneath an external link. Present only\non `Door` recordings returned by the `type=Door` recordings query (the only\nendpoint that returns the full door shape). The external destination\naddress is `url` (not this field); `app_url` is the Basecamp redirector.\nSee `spec/api-gaps/external-links-doors.md`." }, "service": { "$ref": "#/components/schemas/DoorService" }, "parent": { "$ref": "#/components/schemas/RecordingParent" }, "bucket": { "$ref": "#/components/schemas/RecordingBucket" }, "creator": { "$ref": "#/components/schemas/Person" } }, "required": [ "app_url", "bucket", "created_at", "creator", "id", "inherits_status", "status", "title", "type", "updated_at", "url", "visible_to_clients" ] }, "RecordingBucket": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "name": { "type": "string" }, "type": { "type": "string" } }, "required": [ "id", "name", "type" ] }, "RecordingCategory": { "type": "object", "description": "A message category (type) as rendered by the shared recordings/_category\npartial: id, display name, and icon. Present on categorized Message\nrecordings.", "properties": { "id": { "type": "integer", "format": "int64" }, "name": { "type": "string" }, "icon": { "type": "string" } }, "required": [ "id", "name" ] }, "RecordingParent": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "title": { "type": "string" }, "type": { "type": "string" }, "url": { "type": "string" }, "app_url": { "type": "string" }, "bucket": { "$ref": "#/components/schemas/RecordingBucket" } }, "required": [ "app_url", "id", "title", "type", "url" ] }, "ReorderUpNextRequestContent": { "type": "object", "properties": { "source_id": { "type": "integer", "description": "The recording id to move, chosen the same way as when prioritizing.", "format": "int64" }, "position": { "type": "integer", "description": "The 1-based position to move it to.", "format": "int32" } }, "required": [ "position", "source_id" ] }, "ReplaceDocumentRequestContent": { "type": "object", "properties": { "title": { "type": "string" }, "content": { "type": "string" } } }, "ReplaceDocumentResponseContent": { "$ref": "#/components/schemas/Document" }, "ReplaceScheduleEntryRequestContent": { "type": "object", "properties": { "summary": { "type": "string" }, "starts_at": { "type": "string", "description": "The entry's start, as a bare date (\"2026-06-01\") for an all-day entry or a\nfull timestamp otherwise. Same rule as CreateScheduleEntry: send it\nverbatim, never parsed and re-rendered." }, "ends_at": { "type": "string", "description": "The entry's end. See starts_at for the date-vs-timestamp rule." }, "description": { "type": "string" }, "participant_ids": { "type": "array", "items": { "type": "integer", "format": "int64" }, "description": "Replaces the entry's participants.\n\nOmitting this member preserves the current participants; sending an empty\narray clears them. That guarantee is BC3-side and recent: until\nbasecamp/bc3#12425, `Schedules::EntriesController#update` called\n`replace_participants` unconditionally, so any update omitting the key —\nincluding the shape in BC3's own \"Update a schedule entry\" doc example —\nsilently removed every participant and notified each one. The controller\nnow guards on the request actually addressing participants." }, "all_day": { "type": "boolean", "description": "Whether the entry occupies whole days rather than a time range.\n\nNot carved out, and the carve-out list is what makes that dangerous to\nforget: `schedule_entries.all_day` is NOT NULL with a `false` default, so\nomitting this member on a replace resets it — silently converting an\nall-day entry into a midnight-to-midnight timed one. The SDK's merge-safe\nupdate and edit resend it from the read-back for exactly this reason.\n\nSending an explicit null is worse than omitting it: the column rejects\nNULL, so BC3 raises rather than falling back to the default. The same is\ntrue of highlighted." }, "notify": { "type": "boolean" }, "url": { "type": "string", "description": "The entry's join link — a video-call URL or similar, up to 2500\ncharacters, validated as a URL when present.\n\nOmitting this member preserves the current join link; sending an empty\nstring clears it. Read it back as `join_url`, never as `url`: the entry's\n`url` is its own Basecamp API URL, written by a partial that renders\nbefore this one, so BC3 emits the join link under a non-colliding key.\nEchoing the response's `url` into this member would write the API URL into\nthe join link." }, "highlighted": { "type": "boolean", "description": "Whether the entry is highlighted on the schedule.\n\nOmitting this member preserves the current highlight; sending false\nremoves it. Preserved on omission because until basecamp/bc3#12502 the\nfield was writable but never returned, so no caller could resend it." } }, "required": [ "ends_at", "starts_at" ] }, "ReplaceScheduleEntryResponseContent": { "$ref": "#/components/schemas/ScheduleEntry" }, "ReplaceTodoRequestContent": { "type": "object", "properties": { "content": { "type": "string" }, "description": { "type": "string" }, "assignee_ids": { "type": "array", "items": { "type": "integer", "format": "int64" } }, "completion_subscriber_ids": { "type": "array", "items": { "type": "integer", "format": "int64" } }, "notify": { "type": "boolean" }, "due_on": { "type": "string", "x-go-type": "types.Date", "x-go-type-import": { "path": "github.com/basecamp/basecamp-sdk/go/pkg/types" } }, "starts_on": { "type": "string", "x-go-type": "types.Date", "x-go-type-import": { "path": "github.com/basecamp/basecamp-sdk/go/pkg/types" } } }, "required": [ "content" ] }, "ReplaceTodoResponseContent": { "$ref": "#/components/schemas/Todo" }, "RepositionCardStepRequestContent": { "type": "object", "properties": { "source_id": { "type": "integer", "format": "int64" }, "position": { "type": "integer", "description": "0-indexed position", "format": "int32" } }, "required": [ "position", "source_id" ] }, "RepositionTodoRequestContent": { "type": "object", "properties": { "position": { "type": "integer", "format": "int32" }, "parent_id": { "type": "integer", "description": "Optional todolist ID to move the todo to a different parent", "format": "int64" } }, "required": [ "position" ] }, "RepositionTodolistGroupRequestContent": { "type": "object", "properties": { "position": { "type": "integer", "format": "int32" } }, "required": [ "position" ] }, "RepositionTodolistRequestContent": { "type": "object", "properties": { "position": { "type": "integer", "format": "int32" } }, "required": [ "position" ] }, "RepositionToolRequestContent": { "type": "object", "properties": { "position": { "type": "integer", "format": "int32" } }, "required": [ "position" ] }, "ResumeQuestionResponseContent": { "type": "object", "properties": { "paused": { "type": "boolean" } } }, "RichTextAttachment": { "type": "object", "description": "Structured metadata for a downloadable file attachment embedded in a\nrich text attribute. Every rich text attribute in an API response is\naccompanied by a corresponding `*_attachments` array named after the\nattribute (a Todo's `description_attachments` for its `description`).\nMentions, remote images, and opengraph embeds are excluded — only\ndownloadable file attachments appear.", "properties": { "id": { "type": "integer", "format": "int64" }, "sgid": { "type": "string" }, "filename": { "type": "string" }, "content_type": { "type": "string" }, "byte_size": { "type": "integer", "format": "int64" }, "download_url": { "type": "string", "x-basecamp-auth-routable-url": {} }, "width": { "type": "integer", "description": "Pixel dimensions, present as keys on every attachment but null for\nnon-image blobs, and the BC3 API may serialize them float-spelled\n(`1024.0`) — hence optional/nullable rather than `@required` (the enhance\npass marks them `nullable: true` in the OpenAPI). All SDKs decode both\nforms faithfully and type the nullable value statically: Go `types.FlexInt`\n→ `*int32`, Kotlin `Int?` via `FlexibleIntSerializer`, Swift `Int32?`,\nTypeScript `number | null`, Python `Optional[int | float]` (raw JSON keeps\nthe float), Ruby nilable. See SPEC.md §10 Type Fidelity.", "format": "int32", "nullable": true, "x-go-type": "types.FlexInt", "x-go-type-import": { "path": "github.com/basecamp/basecamp-sdk/go/pkg/types" } }, "height": { "type": "integer", "description": "See `width` — same nullable/float-spelled behavior and cross-SDK note.", "format": "int32", "nullable": true, "x-go-type": "types.FlexInt", "x-go-type-import": { "path": "github.com/basecamp/basecamp-sdk/go/pkg/types" } }, "previewable": { "type": "boolean" }, "preview_url": { "type": "string" }, "thumbnail_url": { "type": "string" } }, "required": [ "byte_size", "content_type", "download_url", "filename", "id", "preview_url", "previewable", "sgid", "thumbnail_url" ] }, "Schedule": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "status": { "type": "string" }, "visible_to_clients": { "type": "boolean" }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "updated_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "title": { "type": "string" }, "inherits_status": { "type": "boolean" }, "type": { "type": "string" }, "url": { "type": "string" }, "app_url": { "type": "string" }, "bookmark_url": { "type": "string" }, "position": { "type": "integer", "format": "int32" }, "bucket": { "$ref": "#/components/schemas/TodoBucket" }, "creator": { "$ref": "#/components/schemas/Person" }, "include_due_assignments": { "type": "boolean" }, "entries_count": { "type": "integer", "format": "int32" }, "entries_url": { "type": "string" } }, "required": [ "app_url", "bucket", "created_at", "creator", "id", "inherits_status", "status", "title", "type", "updated_at", "url", "visible_to_clients" ] }, "ScheduleAttributes": { "type": "object", "properties": { "start_date": { "type": "string" }, "end_date": { "type": "string" } } }, "ScheduleEntry": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "status": { "type": "string" }, "visible_to_clients": { "type": "boolean" }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "updated_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "title": { "type": "string" }, "inherits_status": { "type": "boolean" }, "type": { "type": "string" }, "url": { "type": "string" }, "app_url": { "type": "string" }, "bookmark_url": { "type": "string" }, "subscription_url": { "type": "string" }, "comments_count": { "type": "integer", "format": "int32" }, "comments_url": { "type": "string" }, "parent": { "$ref": "#/components/schemas/RecordingParent" }, "bucket": { "$ref": "#/components/schemas/TodoBucket" }, "creator": { "$ref": "#/components/schemas/Person" }, "summary": { "type": "string" }, "description": { "type": "string" }, "description_attachments": { "type": "array", "items": { "$ref": "#/components/schemas/RichTextAttachment" } }, "all_day": { "type": "boolean", "description": "Always sent. schedule_entries.all_day is NOT NULL with a false default,\nand every partial that renders an entry emits it." }, "starts_at": { "type": "string", "description": "Always sent, and a date rather than a timestamp for an all-day entry:\nBC3 renders starts_at_date_or_time, which is `starts_at.to_date` unless\nthe entry is timed, so an all-day entry reads back as `2016-06-01` and a\ntimed one as a full timestamp. The sibling all_day field discriminates.\n\nISO8601Timestamp is a plain string in this model, so both shapes decode;\ntreat the value as opaque and round-trip it verbatim rather than parsing\nit into a date type and re-rendering, which would rewrite an all-day\nentry's bounds.", "x-go-type": "types.FlexibleTime", "x-go-type-import": { "path": "github.com/basecamp/basecamp-sdk/go/pkg/types" } }, "ends_at": { "type": "string", "description": "Always sent. See starts_at for the date-vs-timestamp rendering.", "x-go-type": "types.FlexibleTime", "x-go-type-import": { "path": "github.com/basecamp/basecamp-sdk/go/pkg/types" } }, "participants": { "type": "array", "items": { "$ref": "#/components/schemas/Person" }, "x-go-type-skip-optional-pointer": true }, "join_url": { "type": "string", "description": "The entry's join link, or null when it has none.\n\nSent under this key rather than `url`, which is the entry's own Basecamp\nAPI URL: recordings/_recording writes that key first and the entry partial\nrenders after it. Write it back through the `url` member of\nReplaceScheduleEntry — the two spellings are deliberate, not a typo.\n\nOptional is now UNDER-modelled, and deliberately left that way for one\nrelease. Every operation that still returns this structure —\nGetScheduleEntry, GetScheduleEntryOccurrence, ListScheduleEntries,\nCreateScheduleEntry, ReplaceScheduleEntry — renders\nschedules/entries/_entry, which emits this key unconditionally, so it is\nreally required-and-nullable.\n\nIt was optional because this structure used to cover two wire shapes: the\nreduced schedules/calendar/_entry, which omits it, reached here through\nGetUpcomingSchedule. That is no longer true — the report has its own\nUpcomingScheduleEntry projection (#635) — so the reason is retired and\nonly the cost of tightening remains. Promoting it is a separate contract\nchange: it forces every inline schedule-entry stub across six SDKs to\ncarry the key, and pairs with a required-and-nullable jsonAdd, so it\nbelongs in its own reviewable diff rather than riding this one." }, "highlighted": { "type": "boolean", "description": "Whether the entry is highlighted on the schedule.\n\nUnder-modelled for the same reason as join_url, and more plainly so: this\none is not even nullable (`schedule_entries.highlighted` is NOT NULL with\na false default), so the entry partial's unconditional emission makes it\nstraightforwardly @required. Tracked with join_url." }, "boosts_count": { "type": "integer", "format": "int32" }, "boosts_url": { "type": "string" } }, "required": [ "all_day", "app_url", "bucket", "created_at", "creator", "description_attachments", "ends_at", "id", "inherits_status", "parent", "starts_at", "status", "summary", "title", "type", "updated_at", "url", "visible_to_clients" ] }, "SearchMetadata": { "type": "object", "properties": { "recording_search_types": { "type": "array", "items": { "$ref": "#/components/schemas/SearchType" } }, "file_search_types": { "type": "array", "items": { "$ref": "#/components/schemas/SearchType" } }, "default_creator_label": { "type": "string" }, "default_bucket_label": { "type": "string" }, "default_circle_label": { "type": "string" }, "default_file_type_label": { "type": "string" }, "default_type_label": { "type": "string" } }, "required": [ "default_bucket_label", "default_circle_label", "default_creator_label", "default_file_type_label", "default_type_label", "file_search_types", "recording_search_types" ] }, "SearchResponseContent": { "type": "array", "items": { "$ref": "#/components/schemas/SearchResult" } }, "SearchResult": { "type": "object", "description": "One hit from account-wide search — a polymorphic projection over every\nsearchable recording type.\n\nMost result types render the common recording envelope\n(`recordings/_recording.json.jbuilder`) plus their own recordable partial,\nbut `api_search_result_template_path` special-cases four branches — chat\nlines, kanban (card table) lists, file attachments and gauge needles — and\nthe file-attachment branch writes its own projection from scratch instead\nof the envelope. Members are therefore optional unless every branch emits\nthem; the doc comments name the branches that carry each optional member.", "properties": { "id": { "type": "integer", "description": "The recording id. Optional only because the file-attachment branch\n(`searches/_attachment.json.jbuilder`) skips the recording envelope and\nemits none of the top-level id/title/type/url/app_url keys; every other\nbranch emits all five.", "format": "int64" }, "status": { "type": "string" }, "visible_to_clients": { "type": "boolean" }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "updated_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "title": { "type": "string", "description": "See `id` — omitted by the file-attachment branch, emitted by every other\nbranch." }, "inherits_status": { "type": "boolean" }, "type": { "type": "string", "description": "See `id` — omitted by the file-attachment branch, emitted by every other\nbranch. A file-attachment hit is therefore recognizable by the absence\nof this key (its file keys, `filename` through `app_download_url`, are\nthe positive signal)." }, "url": { "type": "string", "description": "See `id` — omitted by the file-attachment branch, emitted by every other\nbranch." }, "app_url": { "type": "string", "description": "See `id` — omitted by the file-attachment branch, emitted by every other\nbranch." }, "bookmark_url": { "type": "string" }, "subscription_url": { "type": "string", "description": "Subscription URL, emitted by the common recording envelope for any\nsubscribable result — kanban lists and gauge needles among the special\nbranches, plus subscribable generic-branch types (messages, todos, …)." }, "bubble_up_url": { "type": "string", "description": "URL of the Bubble Up record for this recording (BC5 addition). Optional\nhere because this is a polymorphic projection:\n`recordings/_recording.json.jbuilder` emits the key only when the caller\npasses `local_assigns[:bubbleupable]`, and `todolists/_todolist` is the\nonly partial that does. So a Todolist-shaped instance carries it and the\nother recording types do not." }, "parent": { "$ref": "#/components/schemas/RecordingParent" }, "bucket": { "$ref": "#/components/schemas/RecordingBucket" }, "creator": { "$ref": "#/components/schemas/Person" }, "content": { "type": [ "string", "null" ], "description": "Always present, always null. `api/searches/show.json.jbuilder` renders the\nrecording's own partial and then unconditionally overwrites `content` with\n`nil` to strip the large HTML body out of the search payload. The key is\ntherefore guaranteed present on every result — required — and its value is\nguaranteed null. Read `plain_text_content` instead.", "x-go-type": "string" }, "description": { "type": [ "string", "null" ], "description": "Always present, always null — the description-attribute counterpart to\n`content`. Read `plain_text_description` instead.", "x-go-type": "string" }, "plain_text_content": { "type": "string", "description": "A highlighted, truncated excerpt of the recording's content — **not** plain\ntext despite the name. `excerpt_and_highlight_matches` converts the rich\ntext with `to_plain_text`, escapes it with `html_escape_once`, then wraps\neach query match in `` and\ntruncates the result to 300 characters. Treat it as an HTML fragment.\n\nOptional and non-nullable: emitted only when the underlying recordable\nresponds to `content`, so a result whose type has no content attribute\nomits the key entirely rather than sending null." }, "plain_text_description": { "type": "string", "description": "The description-attribute counterpart to `plain_text_content`, with the\nsame highlighting, escaping, and 300-character truncation. Optional and\nnon-nullable — omitted when the recordable has no description attribute." }, "content_attachments": { "type": "array", "items": { "$ref": "#/components/schemas/RichTextAttachment" }, "description": "Rich-text companion arrays carried through the polymorphic search\nprojection. A given result is one recording type, so it carries only\nthe array matching its rich-text attribute (`content_attachments` for a\nComment/Message, `description_attachments` for a Todo); a webhook-sourced\nresult carries neither. Optional (no `@required`), non-nullable.", "x-go-type-skip-optional-pointer": true }, "description_attachments": { "type": "array", "items": { "$ref": "#/components/schemas/RichTextAttachment" }, "description": "See `content_attachments` — the description-attribute companion array.", "x-go-type-skip-optional-pointer": true }, "attachments": { "type": "array", "items": { "$ref": "#/components/schemas/SearchResultAttachment" }, "description": "File attachments on the result, in either of two wire shapes — see\n`SearchResultAttachment`.\n\nFor a result whose recordable carries downloadable rich-text\nattachments, `searches/show.json.jbuilder` emits this key through the\nsame `attachments/_attachment` partial that builds the rich-text\ncompanion array above, so it repeats that array's elements. For a chat\n*upload* line, `chats/lines/_upload.json.jbuilder` instead builds a\nbespoke six-key aggregate inline — and because upload lines have no\nrich-text attribute, the show template never overwrites it, so that\ndistinct shape survives to the wire.", "x-go-type-skip-optional-pointer": true }, "subject": { "type": "string" }, "boosts_count": { "type": "integer", "description": "Boost count, emitted by the recording envelope when the branch passes\n`boostable` — chat lines and gauge needles.", "format": "int32" }, "boosts_url": { "type": "string", "description": "See `boosts_count` — the companion URL." }, "language": { "type": "string", "description": "Language of a code chat line (`chats/lines/_code.json.jbuilder`);\nvalidated present on the model, so never null when the key is emitted." }, "image_url": { "type": "string", "description": "Image URL of a soundtracked (play-kind) chat line whose sound carries an\nimage; such a line emits `image_url` in place of `content`." }, "sound_url": { "type": "string", "description": "Sound URL of a play-kind chat line; always emitted for that kind." }, "subscribers": { "type": "array", "items": { "$ref": "#/components/schemas/Person" }, "description": "Everyone subscribed to the kanban list, as full Person projections.", "x-go-type-skip-optional-pointer": true }, "color": { "type": "string", "description": "Color of a kanban list or gauge needle. Emitted unconditionally by both\nbranches with a null value when unset, so it is nullable (the enhance\npass layers `nullable: true` onto the OpenAPI).", "nullable": true }, "cards_count": { "type": "integer", "description": "Number of cards in the kanban list.", "format": "int32" }, "comment_count": { "type": "integer", "description": "Comment count of a kanban list or gauge needle (branch-partial key,\nsingular `comment_count` — distinct from the envelope's\n`comments_count`, which a needle also carries).", "format": "int32" }, "cards_url": { "type": "string", "description": "API URL of the kanban list's cards." }, "on_hold": { "$ref": "#/components/schemas/CardColumnOnHold" }, "comments_count": { "type": "integer", "description": "Comment count, emitted by the recording envelope when the branch passes\n`commentable` — gauge needles among the special branches, plus\ncommentable generic-branch types.", "format": "int32" }, "comments_url": { "type": "string", "description": "See `comments_count` — the companion URL." }, "position": { "type": "integer", "description": "Position of the result. Two emitters share the key: the recording\nenvelope emits list position for positioned recordings (kanban lists\namong the special branches), and the gauge-needle branch overwrites it\nwith the needle's own 0–100 gauge position.", "format": "int32" }, "filename": { "type": "string", "description": "Filename of a file-attachment hit. This and the following file keys are\nemitted only by the file-attachment branch — the one branch that omits\nthe id/title/type/url/app_url envelope keys." }, "content_type": { "type": "string", "description": "MIME type of a file-attachment hit." }, "byte_size": { "type": "integer", "description": "Size in bytes of a file-attachment hit.", "format": "int64" }, "previewable": { "type": "boolean", "description": "Whether the file can be previewed." }, "width": { "type": "integer", "description": "Pixel width, emitted only when the file is previewable. May be\nfloat-spelled (`1024.0`) and nullable, like every other blob dimension —\nsee `RichTextAttachment.width` for the cross-SDK typing note.", "format": "int32", "nullable": true, "x-go-type": "types.FlexInt", "x-go-type-import": { "path": "github.com/basecamp/basecamp-sdk/go/pkg/types" } }, "height": { "type": "integer", "description": "See `width` — same conditional emission and nullable/float-spelled\nbehavior.", "format": "int32", "nullable": true, "x-go-type": "types.FlexInt", "x-go-type-import": { "path": "github.com/basecamp/basecamp-sdk/go/pkg/types" } }, "preview_url": { "type": "string", "description": "Full-size preview URL of a file-attachment hit." }, "thumbnail_url": { "type": "string", "description": "Thumbnail URL of a file-attachment hit." }, "download_url": { "type": "string", "description": "Authenticated download URL of a file-attachment hit.", "x-basecamp-auth-routable-url": {} }, "app_download_url": { "type": "string", "description": "Web (app-host) download URL of a file-attachment hit." } }, "required": [ "content", "description" ] }, "SearchResultAttachment": { "type": "object", "description": "A file attached to a search result, in either of two wire shapes.\n\nThis is an optional-field superset over the two variants the search\nprojection emits (the TimelineAttachment approach): the rich-text\nattachment/blob shape rendered through `attachments/_attachment` +\n`blobs/_blob` — the same emitters `RichTextAttachment` models — and the\nbespoke six-key aggregate a chat upload line builds inline in\n`chats/lines/_upload.json.jbuilder`. Only the four keys both variants\nalways emit are `@required`; the rest identify their variant.", "properties": { "filename": { "type": "string", "description": "Original filename (both variants)." }, "content_type": { "type": "string", "description": "MIME type of the file (both variants)." }, "byte_size": { "type": "integer", "description": "Size of the file in bytes (both variants).", "format": "int64" }, "download_url": { "type": "string", "description": "Authenticated download URL for the file (both variants).", "x-basecamp-auth-routable-url": {} }, "id": { "type": "integer", "description": "Attachment id (rich-text variant).", "format": "int64" }, "sgid": { "type": "string", "description": "Signed global id of the attachment (rich-text variant)." }, "previewable": { "type": "boolean", "description": "Whether the blob can be previewed (rich-text variant)." }, "preview_url": { "type": "string", "description": "Full-size preview URL (rich-text variant)." }, "thumbnail_url": { "type": "string", "description": "Thumbnail URL (rich-text variant)." }, "width": { "type": "integer", "description": "Pixel width (rich-text variant) — null for non-image blobs and may be\nfloat-spelled (`1024.0`); see `RichTextAttachment.width`.", "format": "int32", "nullable": true, "x-go-type": "types.FlexInt", "x-go-type-import": { "path": "github.com/basecamp/basecamp-sdk/go/pkg/types" } }, "height": { "type": "integer", "description": "See `width` (rich-text variant).", "format": "int32", "nullable": true, "x-go-type": "types.FlexInt", "x-go-type-import": { "path": "github.com/basecamp/basecamp-sdk/go/pkg/types" } }, "title": { "type": "string", "description": "Title of the attachment recording (chat upload-line variant)." }, "url": { "type": "string", "description": "Browser preview URL of the blob (chat upload-line variant)." } }, "required": [ "byte_size", "content_type", "download_url", "filename" ] }, "SearchType": { "type": "object", "description": "A selectable search filter option. `key` is the value passed back as a\nfilter parameter (null represents the default \"everything\" option); `value`\nis the human-readable label.", "properties": { "key": { "type": [ "string", "null" ], "description": "Always present on the wire; `null` for the default \"everything\" option.\n`@required` models the presence; nullability of the value is layered on in\nthe OpenAPI (smithy-build.json jsonAdd -> type: [\"string\", \"null\"]) since\nSmithy has no native required-and-nullable.", "x-go-type": "string" }, "value": { "type": "string" } }, "required": [ "key", "value" ] }, "SetCardColumnColorRequestContent": { "type": "object", "properties": { "color": { "type": "string", "description": "Valid colors: white, red, orange, yellow, green, blue, aqua, purple, gray, pink, brown" } }, "required": [ "color" ] }, "SetCardColumnColorResponseContent": { "$ref": "#/components/schemas/CardColumn" }, "SetCardStepCompletionRequestContent": { "type": "object", "properties": { "completion": { "type": "string", "description": "Set to \"on\" to complete the step, \"\" (empty) to uncomplete" } }, "required": [ "completion" ] }, "SetCardStepCompletionResponseContent": { "$ref": "#/components/schemas/CardStep" }, "SetClientVisibilityRequestContent": { "type": "object", "properties": { "visible_to_clients": { "type": "boolean" } }, "required": [ "visible_to_clients" ] }, "SetClientVisibilityResponseContent": { "$ref": "#/components/schemas/Recording" }, "StorageLimitErrorResponseContent": { "type": "object", "description": "The account has reached its file storage limit.\n\nRaised by ResourceLimits#ensure_account_can_upload_files ahead of any operation\nthat stores new bytes. No retry can satisfy it: the account needs more storage,\nso this maps to `limit_exceeded` rather than a retryable server error.", "properties": { "error": { "type": "string" }, "message": { "type": "string" } }, "required": [ "error" ] }, "SubscribeResponseContent": { "$ref": "#/components/schemas/Subscription" }, "Subscription": { "type": "object", "properties": { "subscribed": { "type": "boolean" }, "count": { "type": "integer", "format": "int32" }, "url": { "type": "string" }, "subscribers": { "type": "array", "items": { "$ref": "#/components/schemas/Person" }, "x-go-type-skip-optional-pointer": true } }, "required": [ "count", "subscribed", "url" ] }, "Template": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "status": { "type": "string" }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "updated_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "name": { "type": "string" }, "description": { "type": "string" }, "url": { "type": "string" }, "app_url": { "type": "string" }, "dock": { "type": "array", "items": { "$ref": "#/components/schemas/DockItem" }, "x-go-type-skip-optional-pointer": true } }, "required": [ "created_at", "id", "name", "updated_at" ] }, "TimelineAttachment": { "type": "object", "description": "A single timeline-event attachment. This is an optional-field superset over\ntwo wire variants — a full Upload recording (upload-kind recordings, rendered\nby BC3's uploads/_upload partial: the complete recording projection + rich-\ntext description + the upload body) and a rich-text attachment/blob partial\n(all other recordings) — so one element type decodes either. Every field is\noptional; a given instance populates only the fields of the variant it\nrepresents. The upload-recording variant enumerates the full documented\nprojection so no documented field is silently dropped on decode.", "properties": { "id": { "type": "integer", "description": "Attachment or upload-recording id.", "format": "int64" }, "content_type": { "type": "string", "description": "MIME type of the file." }, "byte_size": { "type": "integer", "description": "Size of the file in bytes.", "format": "int64" }, "filename": { "type": "string", "description": "Original filename." }, "download_url": { "type": "string", "description": "Authenticated download URL for the file.", "x-basecamp-auth-routable-url": {} }, "width": { "type": "integer", "description": "Pixel width; null for non-image blobs and may be float-spelled (1024.0).", "format": "int32", "nullable": true, "x-go-type": "types.FlexInt", "x-go-type-import": { "path": "github.com/basecamp/basecamp-sdk/go/pkg/types" } }, "height": { "type": "integer", "description": "Pixel height; null for non-image blobs and may be float-spelled (1024.0).", "format": "int32", "nullable": true, "x-go-type": "types.FlexInt", "x-go-type-import": { "path": "github.com/basecamp/basecamp-sdk/go/pkg/types" } }, "type": { "type": "string", "description": "Recording type, e.g. \"Upload\" (upload-recording variant)." }, "title": { "type": "string", "description": "Title of the upload recording." }, "status": { "type": "string", "description": "Publication status of the upload recording (e.g. \"active\")." }, "inherits_status": { "type": "boolean", "description": "Whether the recording inherits its status from its parent." }, "created_at": { "type": "string", "description": "When the upload recording was created.", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "updated_at": { "type": "string", "description": "When the upload recording was last updated.", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "url": { "type": "string", "description": "API URL of the upload recording." }, "app_url": { "type": "string", "description": "Web URL of the upload recording." }, "bookmark_url": { "type": "string", "description": "Personal bookmark toggle URL for the current user." }, "subscription_url": { "type": "string", "description": "Subscription URL; present only when the recording is subscribable." }, "comments_count": { "type": "integer", "description": "Number of comments on the recording.", "format": "int32" }, "comments_url": { "type": "string", "description": "API URL for the recording's comments." }, "boosts_count": { "type": "integer", "description": "Number of boosts on the recording.", "format": "int32" }, "boosts_url": { "type": "string", "description": "API URL for the recording's boosts." }, "position": { "type": "integer", "description": "Position within its parent; present only when the recording is positioned.", "format": "int32" }, "parent": { "$ref": "#/components/schemas/RecordingParent" }, "bucket": { "$ref": "#/components/schemas/TodoBucket" }, "creator": { "$ref": "#/components/schemas/Person" }, "description": { "type": "string", "description": "Rich-text description of the upload (HTML), when present." }, "description_attachments": { "type": "array", "items": { "$ref": "#/components/schemas/RichTextAttachment" }, "description": "Rich-text attachments referenced by the description.", "x-go-type-skip-optional-pointer": true }, "app_download_url": { "type": "string", "description": "Web download URL (upload-recording variant)." }, "visible_to_clients": { "type": "boolean", "description": "Whether the upload recording is visible to clients." }, "attachable_sgid": { "type": "string", "description": "Signed global id of the attachable (attachment variant)." }, "sgid": { "type": "string", "description": "Signed global id of the attachment (attachment variant)." }, "status_url": { "type": "string", "description": "URL to poll attachment processing status (attachment variant)." }, "caption": { "type": "string", "description": "Caption text, if any (attachment variant)." }, "key": { "type": "string", "description": "Storage key of the underlying blob (attachment variant)." }, "previewable": { "type": "boolean", "description": "Whether the blob can be previewed (attachment variant)." }, "preview_url": { "type": "string", "description": "Full-size preview URL (attachment variant)." }, "thumbnail_url": { "type": "string", "description": "Thumbnail preview URL (attachment variant)." } } }, "TimelineEvent": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "kind": { "type": "string", "description": "What kind of activity the event records. Open, non-exhaustive vocabulary —\nBC3 documents \"common values include\" and adds new kinds over time, so\ntreat unrecognized values as valid. Common values include message_created,\ncomment_created, todo_created, todo_completed, upload_created,\ndocument_created, google_document_created, schedule_entry_created,\nschedule_entry_rescheduled, question_created, question_answer_created,\nchat_transcript_rollup, kanban_card_created, kanban_card_completed,\ninbox_forward_created, client_correspondence_created, dock_created, and\nproject_access_changed." }, "parent_recording_id": { "type": "integer", "format": "int64" }, "url": { "type": "string" }, "app_url": { "type": "string" }, "creator": { "$ref": "#/components/schemas/Person" }, "action": { "type": "string" }, "target": { "type": "string" }, "title": { "type": "string" }, "summary_excerpt": { "type": "string" }, "avatars_sample": { "type": "array", "items": { "type": "string" }, "description": "Avatar URLs of participants — populated for chat_transcript_rollup events\n(the people summarized in the rollup); an empty array otherwise.", "x-go-type-skip-optional-pointer": true }, "bucket": { "$ref": "#/components/schemas/TodoBucket" }, "data": { "$ref": "#/components/schemas/TimelineEventData" }, "attachments": { "type": "array", "items": { "$ref": "#/components/schemas/TimelineAttachment" }, "description": "Files attached to the event's recording, when it has any. Heterogeneous:\nan upload-kind recording contributes its full Upload shape, while other\nrecordings contribute rich-text attachment/blob partials. Modeled as an\noptional-field superset so a single element type decodes either variant;\nconsumers should treat the per-variant fields as present-or-absent.", "x-go-type-skip-optional-pointer": true } } }, "TimelineEventData": { "type": "object", "description": "Schedule-entry timing carried on schedule_entry_* timeline events. starts_at\nand ends_at are date-or-timestamp: a full ISO 8601 timestamp for timed\nentries, or a bare date (YYYY-MM-DD) when all_day is true. Modeled as\nISO8601Timestamp (mirroring ScheduleEntry), with the Go enhancement pass\nmapping them to types.FlexibleTime so date-only values decode; the other\nSDKs type them as plain strings.", "properties": { "all_day": { "type": "boolean", "description": "Whether the entry is all-day. BC3 emits all three members unconditionally\nwhenever the data object is present (schedule_entry_* events), so they are\nrequired within this struct." }, "starts_at": { "type": [ "string", "null" ], "x-go-type": "types.FlexibleTime", "x-go-type-import": { "path": "github.com/basecamp/basecamp-sdk/go/pkg/types" } }, "ends_at": { "type": [ "string", "null" ], "x-go-type": "types.FlexibleTime", "x-go-type-import": { "path": "github.com/basecamp/basecamp-sdk/go/pkg/types" } } }, "required": [ "all_day", "ends_at", "starts_at" ] }, "TimesheetEntry": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "status": { "type": "string" }, "visible_to_clients": { "type": "boolean" }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "updated_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "title": { "type": "string" }, "inherits_status": { "type": "boolean" }, "type": { "type": "string" }, "url": { "type": "string" }, "app_url": { "type": "string" }, "bookmark_url": { "type": "string" }, "parent": { "$ref": "#/components/schemas/RecordingParent" }, "bucket": { "$ref": "#/components/schemas/TodoBucket" }, "creator": { "$ref": "#/components/schemas/Person" }, "date": { "type": "string" }, "description": { "type": "string" }, "hours": { "type": "string" }, "person": { "$ref": "#/components/schemas/Person" } }, "required": [ "app_url", "bucket", "created_at", "creator", "id", "inherits_status", "parent", "status", "title", "type", "updated_at", "url", "visible_to_clients" ] }, "Todo": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "status": { "type": "string", "description": "active|archived|trashed" }, "visible_to_clients": { "type": "boolean" }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "updated_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "title": { "type": "string" }, "inherits_status": { "type": "boolean" }, "type": { "type": "string" }, "url": { "type": "string" }, "app_url": { "type": "string" }, "bookmark_url": { "type": "string" }, "subscription_url": { "type": "string" }, "comments_count": { "type": "integer", "format": "int32" }, "comments_url": { "type": "string" }, "position": { "type": "integer", "format": "int32" }, "parent": { "$ref": "#/components/schemas/TodoParent" }, "bucket": { "$ref": "#/components/schemas/TodoBucket" }, "creator": { "$ref": "#/components/schemas/Person" }, "description": { "type": "string" }, "completed": { "type": "boolean" }, "content": { "type": "string" }, "description_attachments": { "type": "array", "items": { "$ref": "#/components/schemas/RichTextAttachment" } }, "starts_on": { "type": "string", "x-go-type": "types.Date", "x-go-type-import": { "path": "github.com/basecamp/basecamp-sdk/go/pkg/types" }, "nullable": true }, "due_on": { "type": "string", "x-go-type": "types.Date", "x-go-type-import": { "path": "github.com/basecamp/basecamp-sdk/go/pkg/types" }, "nullable": true }, "assignees": { "type": "array", "items": { "$ref": "#/components/schemas/Person" }, "x-go-type-skip-optional-pointer": true }, "completion_subscribers": { "type": "array", "items": { "$ref": "#/components/schemas/Person" }, "x-go-type-skip-optional-pointer": true }, "completion_url": { "type": "string" }, "boosts_count": { "type": "integer", "format": "int32" }, "boosts_url": { "type": "string" }, "steps": { "type": "array", "items": { "$ref": "#/components/schemas/CardStep" }, "description": "Steps embedded in the Todo response (BC5 addition). The shared\n`steps/step` jbuilder partial emits the same shape as `CardStep`,\nso the existing `CardStepList` is reused.", "x-go-type-skip-optional-pointer": true } }, "required": [ "app_url", "bucket", "content", "created_at", "creator", "description_attachments", "id", "inherits_status", "parent", "status", "title", "type", "updated_at", "url", "visible_to_clients" ] }, "TodoBucket": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "name": { "type": "string" }, "type": { "type": "string" } }, "required": [ "id", "name", "type" ] }, "TodoParent": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "title": { "type": "string" }, "type": { "type": "string" }, "url": { "type": "string" }, "app_url": { "type": "string" } }, "required": [ "app_url", "id", "title", "type", "url" ] }, "Todolist": { "type": "object", "description": "A to-do list, or a group inside one. There is only this shape.\n\nBC3 has no group model: a \"group\" is a `Todolist` whose parent is another\n`Todolist` (`Todolist.group?`), there is no `Todolist::Group` class, and\n`todolists/groups/index.json.jbuilder` and `show.json.jbuilder` both render\n`todolists/_todolist.json.jbuilder` — the same partial the list routes use.\nSo a group reports `\"type\": \"Todolist\"` (the shared recording partial emits\n`recordable_type`) and carries `description`/`description_attachments` like\nany other list. Every operation that returns a list or a group returns this\nstructure: the polymorphic GET/PUT, the todoset-scoped list, and the\ngroup list, group create and group get.\n\nDiscriminate STRUCTURALLY, never on `type` — which reads `\"Todolist\"` for\nboth variants. `_todolist.json.jbuilder` branches on `recording.parent.todoset?`\nand emits exactly one of:\n\n- `groups_url` — a to-do list; its `parent` is a Todoset.\n- `group_position_url` — a group; its `parent` is a Todolist.\n\nThe two are mutually exclusive and exactly one is always present.", "properties": { "id": { "type": "integer", "format": "int64" }, "status": { "type": "string", "description": "active|archived|trashed" }, "visible_to_clients": { "type": "boolean" }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "updated_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "title": { "type": "string" }, "inherits_status": { "type": "boolean" }, "type": { "type": "string" }, "url": { "type": "string" }, "app_url": { "type": "string" }, "bookmark_url": { "type": "string" }, "subscription_url": { "type": "string" }, "bubble_up_url": { "type": "string", "description": "URL of the Bubble Up record for this recording (BC5 addition). Required:\n`todolists/_todolist.json.jbuilder` renders the shared recording partial\nwith `bubbleupable: true` unconditionally, and every list, show, and group\npath renders that partial — so the key is present on every projection of\nthis shape." }, "comments_count": { "type": "integer", "format": "int32" }, "comments_url": { "type": "string" }, "position": { "type": "integer", "format": "int32" }, "parent": { "$ref": "#/components/schemas/TodoParent" }, "bucket": { "$ref": "#/components/schemas/TodoBucket" }, "creator": { "$ref": "#/components/schemas/Person" }, "description": { "type": "string", "description": "Rich text description (HTML). Required and never null: the shared rich-text\npartial emits the key unconditionally, and `format_api_content` funnels a\nblank or absent rich text through `call_pipeline`, which returns `\"\"` rather\nthan nil. A list with no description carries `\"\"`, not `null`, and a group\ncarries it too — `todolists/groups/{index,show}.json.jbuilder` render the\nsame partial." }, "description_attachments": { "type": "array", "items": { "$ref": "#/components/schemas/RichTextAttachment" }, "description": "Downloadable files embedded in `description`. Required and never null:\nthe partial emits `rich_text&.downloadable_attachments.to_a`, so the value\nis `[]` when there is no description and when there are no attachments." }, "completed": { "type": "boolean" }, "completed_ratio": { "type": "string" }, "name": { "type": "string" }, "todos_url": { "type": "string" }, "groups_url": { "type": "string", "description": "API URL for this list's groups. The to-do-list half of the structural\ndiscriminator: emitted only when `parent` is a Todoset, and mutually\nexclusive with `group_position_url`." }, "group_position_url": { "type": "string", "description": "API URL for repositioning this group within its parent list. The group half\nof the structural discriminator: emitted only when `parent` is a Todolist,\nand mutually exclusive with `groups_url`." }, "app_todos_url": { "type": "string", "description": "In-app (non-API) URL for this record's to-dos, alongside the API-host\n`todos_url`." }, "color": { "type": [ "string", "null" ], "description": "Color of the list or group, one of BC3's `Colored` enum values\n(`white red orange yellow green blue aqua purple gray pink brown`). For a\ntop-level list a hill-chart dot color takes precedence over the recording's\nown.\n\n**Required and nullable.** The key is always present and the value is often\n`null`. `_todolist.json.jbuilder` calls `json.color` in both branches of its\n`todolist_group?` conditional, so no projection of this shape omits it;\n`recordings.color` is a nullable integer column, so the value is JSON `null`\nwhenever it is unset — which, for a group, is the ordinary case.\n\nSmithy expresses neither half natively here, so both are layered onto the\nOpenAPI projection through `jsonAdd` in `spec/smithy-build.json`: the\n`[\"string\", \"null\"]` union for the value, the same treatment\n`SearchResult.content` and `SearchType.key` get, and an append to\n`Todolist.required` for the presence.\n\nThe member stays natively optional because `@required` collides with this\nshape's `@examples` (`GetTodolistOrGroup`): Smithy cannot express a `null`\nin an example for a `String` shape, so requiring the member would force the\ngroup example to advertise a color that uncolored groups do not have —\ntrading a faithful example for a type the projection can state anyway. The\nsibling shapes that carry the same field (`Wormhole`, `Folder`,\n`FolderWithProjects`) are natively `@required` because none of them carries\nexamples. Nullability is not the weaker claim about presence: absence and\n`null` are different wire facts, and BC3 only ever sends the second.", "x-go-type": "string" }, "comments_app_url": { "type": "string", "description": "In-app (non-API) URL for this recording's comments, alongside the API-host\n`comments_url`. Required and never null: `_todolist.json.jbuilder` emits\n`json.comments_app_url` unconditionally, from the\n`bucket_recording_comments_url` route helper — which returns a String or\nraises, and has no nil path. Native `@required` is enough here precisely\nbecause the value is never null, so it costs the examples a real URL rather\nthan a fiction." }, "boosts_count": { "type": "integer", "format": "int32" }, "boosts_url": { "type": "string" } }, "required": [ "app_url", "bubble_up_url", "bucket", "comments_app_url", "created_at", "creator", "description", "description_attachments", "id", "inherits_status", "name", "parent", "status", "title", "type", "updated_at", "url", "visible_to_clients", "color" ] }, "Todoset": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "status": { "type": "string" }, "visible_to_clients": { "type": "boolean" }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "updated_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "title": { "type": "string" }, "inherits_status": { "type": "boolean" }, "type": { "type": "string" }, "url": { "type": "string" }, "app_url": { "type": "string" }, "bookmark_url": { "type": "string" }, "position": { "type": "integer", "format": "int32" }, "bucket": { "$ref": "#/components/schemas/TodoBucket" }, "creator": { "$ref": "#/components/schemas/Person" }, "name": { "type": "string" }, "todolists_count": { "type": "integer", "format": "int32" }, "todolists_url": { "type": "string" }, "completed_ratio": { "type": "string" }, "completed": { "type": "boolean" }, "app_todolists_url": { "type": "string" }, "todos_count": { "type": "integer", "description": "Total count of todos across all todolists in this todoset (BC5 addition).", "format": "int32" }, "completed_loose_todos_count": { "type": "integer", "description": "Count of completed loose todos at the todoset level (BC5 addition).", "format": "int32" }, "todos_url": { "type": "string", "description": "API URL for listing todos directly under this todoset (BC5 addition)." }, "app_todos_url": { "type": "string", "description": "In-app URL for viewing the todoset's todos (BC5 addition)." } }, "required": [ "app_url", "bucket", "created_at", "creator", "id", "inherits_status", "name", "status", "title", "type", "updated_at", "url", "visible_to_clients" ] }, "ToggleGaugeRequestContent": { "type": "object", "properties": { "gauge": { "$ref": "#/components/schemas/GaugeTogglePayload" } }, "required": [ "gauge" ] }, "Tool": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "status": { "type": "string" }, "visible_to_clients": { "type": "boolean" }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "updated_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "title": { "type": "string" }, "inherits_status": { "type": "boolean" }, "type": { "type": "string", "description": "The tool's recordable type, e.g. `Chat::Transcript`, `Todoset`, `Vault`." }, "url": { "type": "string" }, "app_url": { "type": "string" }, "bookmark_url": { "type": "string" }, "subscription_url": { "type": "string", "description": "Absent for tool types that are not subscribable." }, "position": { "type": "integer", "description": "Emitted only for a positioned recording. For a docked tool that makes an\nabsent position the disabled signal — disabling removes the tool from the\ndock without deleting it. Positioning is independent of dockedness, so\nthis does not generalize: a nested vault is not docked and is positioned.", "format": "int32" }, "parent": { "$ref": "#/components/schemas/RecordingParent" }, "bucket": { "$ref": "#/components/schemas/RecordingBucket" }, "creator": { "$ref": "#/components/schemas/Person" }, "name": { "type": "string", "description": "Not emitted by this projection. The dock array on a project\n(`DockItem$name`) carries the tool's slug; this key is absent from every\nGetTool/CreateTool/UpdateTool response." }, "enabled": { "type": "boolean", "description": "Not emitted by this projection. The dock array on a project\n(`DockItem$enabled`) is the authoritative enabled flag; on a docked tool's\nown response, an absent `position` is the equivalent signal." } }, "required": [ "created_at", "creator", "id", "inherits_status", "title", "type", "updated_at", "visible_to_clients" ] }, "UnauthorizedErrorResponseContent": { "type": "object", "properties": { "error": { "type": "string" }, "message": { "type": "string" } }, "required": [ "error" ] }, "UpcomingAssignable": { "type": "object", "description": "A dated to-do, card or step as the upcoming-schedule report renders it.\n\nRendered by `app/views/api/schedules/calendar/_assignable.json.jbuilder`,\nwhich — like the calendar entry partial — writes its own keys instead of\nrendering `recordings/_recording`. Nothing else in the API returns this\nshape.\n\nThe member that bites: BC3 emits the item's text under `content`, not\n`title`. The previous model of this report declared `title`, so the field\ncallers most wanted was permanently absent while a key that was always\npresent went unmodelled.", "properties": { "id": { "type": "integer", "format": "int64" }, "status": { "type": "string" }, "visible_to_clients": { "type": "boolean" }, "url": { "type": "string", "description": "The item's own Basecamp API URL." }, "app_url": { "type": "string" }, "starts_on": { "type": "string", "description": "The item's start date, `null` unless this is a to-do that has one:\nKanban cards and steps both define `starts_on` as a literal nil to\nduck-type Todo, and the partial reads it unconditionally.\n\nThe key is in fact always present. It is modeled optional-and-nullable\nanyway, matching the deliberate treatment of `Todo.starts_on` and\n`Todo`/`Card.due_on` (see the fifth-g pass in\n`scripts/enhance-openapi-go-types.sh`): the static SDKs then type it\n`string | null | undefined`, which accepts the null this really sends and\nalso tolerates a partial payload. Nullability rides that same pass, which\nis what keeps the Go type `types.Date` rather than a bare string.", "x-go-type": "types.Date", "x-go-type-import": { "path": "github.com/basecamp/basecamp-sdk/go/pkg/types" }, "nullable": true }, "due_on": { "type": "string", "description": "The item's due date, `null` when it has none. Optional-and-nullable for\nthe same reason as starts_on.", "x-go-type": "types.Date", "x-go-type-import": { "path": "github.com/basecamp/basecamp-sdk/go/pkg/types" }, "nullable": true }, "type": { "type": "string", "description": "The item's kind, LOWERCASE and singular: \"todo\", \"card\" or \"step\".\n`short_recordable_name` demodulizes and downcases the recordable class,\nso this does not match the CamelCase `type` other recording projections\ncarry." }, "content": { "type": "string", "description": "The item's text — `recordable.title`. Spelled `content`, not `title`:\nthis partial names it after the Todo/Card content attribute rather than\nthe recording's title." }, "assignees": { "type": "array", "items": { "$ref": "#/components/schemas/UpcomingSchedulePerson" }, "description": "Present and possibly empty, never absent." }, "bucket": { "$ref": "#/components/schemas/UpcomingScheduleBucket" }, "parent": { "$ref": "#/components/schemas/UpcomingAssignableParent" }, "completion_url": { "type": "string", "description": "Where to POST/PUT the item's completion.\n\nOnly the to-do branch is an absolute URL: BC3 renders\n`completion_bucket_todo_url` for a to-do and\n`bucket_step_completions_path` for everything else, and a `_path` helper\nemits no host. Resolve this against the account base rather than assuming\nit is absolute." }, "completed": { "type": "boolean" }, "repeating": { "type": "boolean", "description": "Whether the item repeats." }, "completion": { "$ref": "#/components/schemas/UpcomingAssignableCompletion" }, "comments_count": { "type": "integer", "format": "int32" } }, "required": [ "app_url", "assignees", "bucket", "comments_count", "completed", "completion_url", "content", "id", "parent", "repeating", "status", "type", "url", "visible_to_clients" ] }, "UpcomingAssignableCompletion": { "type": "object", "description": "When an assignable was completed and by whom.", "properties": { "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "creator": { "$ref": "#/components/schemas/UpcomingSchedulePerson" } }, "required": [ "created_at", "creator" ] }, "UpcomingAssignableParent": { "type": "object", "description": "The to-do list, card column or parent to-do an assignable is filed under:\nid and title only, with no `type`, `url` or `app_url`.\n\nThe title is not always the parent's own: for a to-do inside a grouped\nlist, `todolist_or_group_title` folds in the grandparent list's title as\n\"List: Group\".", "properties": { "id": { "type": "integer", "format": "int64" }, "title": { "type": "string" } }, "required": [ "id", "title" ] }, "UpcomingScheduleBucket": { "type": "object", "description": "The project an upcoming-schedule item belongs to: id and name only.\n\nBoth calendar partials write `json.(recording.bucket, :id, :name)`, so this\nis TodoBucket minus `type`. That missing `type` is the first key a strict\ndecoder reaches on a populated response, ahead of any of the top-level\nmembers the calendar entry partial drops.", "properties": { "id": { "type": "integer", "format": "int64" }, "name": { "type": "string" } }, "required": [ "id", "name" ] }, "UpcomingScheduleEntry": { "type": "object", "description": "One schedule entry as the upcoming-schedule report renders it.\n\nThis is NOT the ScheduleEntry projection. BC3 renders this report through\n`app/views/api/schedules/calendar/_entry.json.jbuilder`, a purpose-built\ncalendar partial, while GetScheduleEntry, GetScheduleEntryOccurrence,\nListScheduleEntries, CreateScheduleEntry and ReplaceScheduleEntry all render\n`schedules/entries/_entry.json.jbuilder` on top of the shared recording\npartial. The calendar partial does not render `recordings/_recording` at\nall — it writes its own keys — so relative to ScheduleEntry it drops\n`created_at`, `updated_at`, `title`, `inherits_status`, `parent`,\n`description_attachments`, `description`, `bookmark_url`,\n`subscription_url`, `comments_url`, `join_url`, `highlighted`,\n`boosts_count` and `boosts_url`, narrows `bucket` to id + name, and adds\n`recurring`, which no other schedule-entry projection emits.\n\nEvery member here is @required because the partial emits every key\nunconditionally: there is no `if` in it.", "properties": { "id": { "type": "integer", "format": "int64" }, "status": { "type": "string" }, "visible_to_clients": { "type": "boolean" }, "url": { "type": "string", "description": "The entry's own Basecamp API URL. Unlike the ScheduleEntry projection,\nthis report never carries the entry's join link, so `url` here has no\n`join_url` sibling to be confused with." }, "app_url": { "type": "string" }, "type": { "type": "string", "description": "Always the literal string \"ScheduleEntry\" — the calendar partial hardcodes\nit rather than deriving it from the recordable, so an occurrence reads\nback as \"ScheduleEntry\" too, not \"Schedule::Entry::Occurrence\"." }, "summary": { "type": "string" }, "all_day": { "type": "boolean", "description": "Whether the entry occupies whole days rather than a time range.\nDiscriminates the two renderings of starts_at/ends_at below." }, "recurring": { "type": "boolean", "description": "Whether the entry repeats. Emitted only by this partial —\n`recording.schedule_entry.recurring?`, i.e. whether the entry carries a\nrecurrence schedule.\n\nIt also discriminates the two envelope arrays: BC3 selects\n`schedule_entries` with `recurrence_schedule: nil` and\n`recurring_schedule_entry_occurrences` with `recurrence_schedule` NOT\nNULL, so this reads false throughout the first array and true throughout\nthe second." }, "starts_at": { "type": "string", "description": "A date for an all-day entry and a full timestamp for a timed one —\n`starts_at_date_or_time`, the same rendering ScheduleEntry documents.\nTreat it as opaque and round-trip it verbatim; the all_day sibling\ndiscriminates.", "x-go-type": "types.FlexibleTime", "x-go-type-import": { "path": "github.com/basecamp/basecamp-sdk/go/pkg/types" } }, "ends_at": { "type": "string", "description": "See starts_at for the date-vs-timestamp rendering.", "x-go-type": "types.FlexibleTime", "x-go-type-import": { "path": "github.com/basecamp/basecamp-sdk/go/pkg/types" } }, "creator": { "$ref": "#/components/schemas/UpcomingSchedulePerson" }, "participants": { "type": "array", "items": { "$ref": "#/components/schemas/UpcomingSchedulePerson" }, "description": "Everyone attending. Present and possibly empty, never absent." }, "bucket": { "$ref": "#/components/schemas/UpcomingScheduleBucket" }, "comments_count": { "type": "integer", "description": "Comments on the entry — or, for an occurrence, on that occurrence.", "format": "int32" } }, "required": [ "all_day", "app_url", "bucket", "comments_count", "creator", "ends_at", "id", "participants", "recurring", "starts_at", "status", "summary", "type", "url", "visible_to_clients" ] }, "UpcomingSchedulePerson": { "type": "object", "description": "A person as the calendar partials render them: id, name and avatar only.\n\n`schedules/calendar/_person.json.jbuilder` delegates to\n`people/_person_minimal.json.jbuilder`, the same three-key partial that\nMyAssignmentAssignee and OutOfOfficePerson already model separately from the\nfull Person projection. Reusing Person here would decode — its only\n@required members are id and name — but would advertise two dozen members\nthis report never sends.", "properties": { "id": { "type": "integer", "format": "int64" }, "name": { "type": "string", "format": "password" }, "avatar_url": { "type": "string", "format": "password" } }, "required": [ "avatar_url", "id", "name" ] }, "UpdateAccountLogoInputPayload": { "type": "string", "contentEncoding": "byte" }, "UpdateAccountNameRequestContent": { "type": "object", "properties": { "name": { "type": "string" } }, "required": [ "name" ] }, "UpdateAccountNameResponseContent": { "$ref": "#/components/schemas/Account" }, "UpdateCalendarRequestContent": { "type": "object", "properties": { "calendar": { "$ref": "#/components/schemas/CalendarAttributes" } }, "required": [ "calendar" ] }, "UpdateCalendarResponseContent": { "$ref": "#/components/schemas/Calendar" }, "UpdateCampfireLineRequestContent": { "type": "object", "properties": { "content": { "type": "string", "description": "The new line content, interpreted as rich text (HTML)" } }, "required": [ "content" ] }, "UpdateCardColumnRequestContent": { "type": "object", "properties": { "title": { "type": "string" }, "description": { "type": "string" } } }, "UpdateCardColumnResponseContent": { "$ref": "#/components/schemas/CardColumn" }, "UpdateCardRequestContent": { "type": "object", "properties": { "title": { "type": "string" }, "content": { "type": "string" }, "due_on": { "type": "string", "x-go-type": "types.Date", "x-go-type-import": { "path": "github.com/basecamp/basecamp-sdk/go/pkg/types" } }, "assignee_ids": { "type": "array", "items": { "type": "integer", "format": "int64" } } } }, "UpdateCardResponseContent": { "$ref": "#/components/schemas/Card" }, "UpdateCardStepRequestContent": { "type": "object", "properties": { "title": { "type": "string" }, "due_on": { "type": "string", "x-go-type": "types.Date", "x-go-type-import": { "path": "github.com/basecamp/basecamp-sdk/go/pkg/types" } }, "assignee_ids": { "type": "array", "items": { "type": "integer", "format": "int64" } } } }, "UpdateCardStepResponseContent": { "$ref": "#/components/schemas/CardStep" }, "UpdateChatbotRequestContent": { "type": "object", "properties": { "service_name": { "type": "string" }, "command_url": { "type": "string" } }, "required": [ "service_name" ] }, "UpdateChatbotResponseContent": { "$ref": "#/components/schemas/Chatbot" }, "UpdateCloudFileRequestContent": { "type": "object", "properties": { "url": { "type": "string" }, "service": { "type": "string", "description": "Short identifier for the external service — \"dropbox\", \"google_doc\",\n\"figma\", \"other\", … Derived from the CloudFile::Service subclass name, so it\nis always present. `other` accepts any well-formed HTTPS URL." }, "title": { "type": "string" }, "description": { "type": "string" }, "subscriptions": { "type": "array", "items": { "type": "integer", "format": "int64" } } }, "required": [ "service", "url" ] }, "UpdateCloudFileResponseContent": { "$ref": "#/components/schemas/CloudFile" }, "UpdateCommentRequestContent": { "type": "object", "properties": { "content": { "type": "string" } }, "required": [ "content" ] }, "UpdateCommentResponseContent": { "$ref": "#/components/schemas/Comment" }, "UpdateFolderRequestContent": { "type": "object", "properties": { "name": { "type": "string", "description": "The folder's new name. Blank is rejected with 422 — unlike create, update\ndoes not fall back to a default name." } }, "required": [ "name" ] }, "UpdateFolderResponseContent": { "$ref": "#/components/schemas/FolderWithProjects" }, "UpdateGaugeNeedleRequestContent": { "type": "object", "properties": { "gauge_needle": { "$ref": "#/components/schemas/GaugeNeedleUpdatePayload" } } }, "UpdateGaugeNeedleResponseContent": { "$ref": "#/components/schemas/GaugeNeedle" }, "UpdateGoogleDocumentRequestContent": { "type": "object", "properties": { "url": { "type": "string" }, "document_type": { "type": "string", "description": "One of \"doc\", \"sheet\", \"slide\", \"other\". Backed by a Rails enum, so an\nunrecognized value is rejected up front with a field-keyed 422\n({\"errors\": {\"document_type\": [\"is not a valid document type\"]}}) rather\nthan reaching validation." }, "title": { "type": "string" }, "description": { "type": "string" }, "status": { "type": "string", "description": "active|drafted" }, "subscriptions": { "type": "array", "items": { "type": "integer", "format": "int64" } } }, "required": [ "document_type", "url" ] }, "UpdateGoogleDocumentResponseContent": { "$ref": "#/components/schemas/GoogleDocument" }, "UpdateHillChartSettingsRequestContent": { "type": "object", "properties": { "tracked": { "type": "array", "items": { "type": "integer", "format": "int64" } }, "untracked": { "type": "array", "items": { "type": "integer", "format": "int64" } } } }, "UpdateHillChartSettingsResponseContent": { "$ref": "#/components/schemas/HillChart" }, "UpdateLineupMarkerRequestContent": { "type": "object", "properties": { "name": { "type": "string" }, "date": { "type": "string" } } }, "UpdateMessageRequestContent": { "type": "object", "properties": { "subject": { "type": "string" }, "content": { "type": "string" }, "status": { "type": "string", "description": "active|drafted" }, "category_id": { "type": "integer", "format": "int64" } } }, "UpdateMessageResponseContent": { "$ref": "#/components/schemas/Message" }, "UpdateMessageTypeRequestContent": { "type": "object", "properties": { "name": { "type": "string" }, "icon": { "type": "string" } } }, "UpdateMessageTypeResponseContent": { "$ref": "#/components/schemas/MessageType" }, "UpdateMyNoteRequestContent": { "type": "object", "properties": { "note": { "$ref": "#/components/schemas/MyNoteAttributes" } }, "required": [ "note" ] }, "UpdateMyNoteResponseContent": { "$ref": "#/components/schemas/MyNote" }, "UpdateMyPreferencesRequestContent": { "type": "object", "properties": { "person": { "$ref": "#/components/schemas/PreferencesPayload" } }, "required": [ "person" ] }, "UpdateMyPreferencesResponseContent": { "$ref": "#/components/schemas/Preferences" }, "UpdateMyProfileRequestContent": { "type": "object", "properties": { "name": { "type": "string", "format": "password" }, "email_address": { "type": "string", "format": "password" }, "title": { "type": "string", "format": "password" }, "bio": { "type": "string", "format": "password" }, "location": { "type": "string", "format": "password" }, "time_zone_name": { "type": "string" }, "first_week_day": { "$ref": "#/components/schemas/FirstWeekDay" }, "time_format": { "type": "string" } } }, "UpdateProjectAccessRequestContent": { "type": "object", "properties": { "grant": { "type": "array", "items": { "type": "integer", "format": "int64" } }, "revoke": { "type": "array", "items": { "type": "integer", "format": "int64" } }, "create": { "type": "array", "items": { "$ref": "#/components/schemas/CreatePersonRequest" } } } }, "UpdateProjectAccessResponseContent": { "$ref": "#/components/schemas/ProjectAccessResult" }, "UpdateProjectRequestContent": { "type": "object", "properties": { "name": { "type": "string" }, "description": { "type": "string" }, "admissions": { "type": "string", "description": "invite|employee|team" }, "schedule_attributes": { "$ref": "#/components/schemas/ScheduleAttributes" } }, "required": [ "name" ] }, "UpdateProjectResponseContent": { "$ref": "#/components/schemas/Project" }, "UpdateQuestionNotificationSettingsRequestContent": { "type": "object", "properties": { "notify_on_answer": { "type": "boolean", "description": "Notify when someone answers" }, "digest_include_unanswered": { "type": "boolean", "description": "Include unanswered in digest" } } }, "UpdateQuestionNotificationSettingsResponseContent": { "type": "object", "properties": { "responding": { "type": "boolean" }, "subscribed": { "type": "boolean" } } }, "UpdateQuestionRequestContent": { "type": "object", "properties": { "title": { "type": "string" }, "schedule": { "$ref": "#/components/schemas/QuestionSchedule" }, "paused": { "type": "boolean" } } }, "UpdateQuestionResponseContent": { "$ref": "#/components/schemas/Question" }, "UpdateScheduleSettingsRequestContent": { "type": "object", "properties": { "include_due_assignments": { "type": "boolean" } }, "required": [ "include_due_assignments" ] }, "UpdateScheduleSettingsResponseContent": { "$ref": "#/components/schemas/Schedule" }, "UpdateSubscriptionRequestContent": { "type": "object", "properties": { "subscriptions": { "type": "array", "items": { "type": "integer", "format": "int64" } }, "unsubscriptions": { "type": "array", "items": { "type": "integer", "format": "int64" } } } }, "UpdateSubscriptionResponseContent": { "$ref": "#/components/schemas/Subscription" }, "UpdateTemplateRequestContent": { "type": "object", "properties": { "name": { "type": "string" }, "description": { "type": "string" } } }, "UpdateTemplateResponseContent": { "$ref": "#/components/schemas/Template" }, "UpdateTimesheetEntryRequestContent": { "type": "object", "properties": { "date": { "type": "string" }, "hours": { "type": "string" }, "description": { "type": "string" }, "person_id": { "type": "integer", "format": "int64" } } }, "UpdateTimesheetEntryResponseContent": { "$ref": "#/components/schemas/TimesheetEntry" }, "UpdateTodolistOrGroupRequestContent": { "type": "object", "properties": { "name": { "type": "string", "description": "Name (required for a to-do list and for a group alike) - presence-validated server-side, so omitting it is a 422, not a preserve" }, "description": { "type": "string", "description": "Description (rich text HTML) - writable for a todolist group as well as a todolist, and omitting it clears it either way" } }, "required": [ "name" ] }, "UpdateTodolistOrGroupResponseContent": { "$ref": "#/components/schemas/Todolist" }, "UpdateToolRequestContent": { "type": "object", "properties": { "title": { "type": "string" } }, "required": [ "title" ] }, "UpdateToolResponseContent": { "$ref": "#/components/schemas/Tool" }, "UpdateUploadRequestContent": { "type": "object", "properties": { "description": { "type": "string" }, "base_name": { "type": "string" } } }, "UpdateUploadResponseContent": { "$ref": "#/components/schemas/Upload" }, "UpdateVaultRequestContent": { "type": "object", "properties": { "title": { "type": "string" } } }, "UpdateVaultResponseContent": { "$ref": "#/components/schemas/Vault" }, "UpdateWebhookRequestContent": { "type": "object", "properties": { "payload_url": { "type": "string" }, "types": { "type": "array", "items": { "type": "string" } }, "active": { "type": "boolean" } } }, "UpdateWebhookResponseContent": { "$ref": "#/components/schemas/Webhook" }, "UpdateWormholeRequestContent": { "type": "object", "properties": { "destination_recording_id": { "type": "integer", "description": "Id of the new destination column (on another accessible card table).", "format": "int64" } }, "required": [ "destination_recording_id" ] }, "UpdateWormholeResponseContent": { "$ref": "#/components/schemas/Wormhole" }, "Upload": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "status": { "type": "string" }, "visible_to_clients": { "type": "boolean" }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "updated_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "title": { "type": "string" }, "inherits_status": { "type": "boolean" }, "type": { "type": "string" }, "url": { "type": "string" }, "app_url": { "type": "string" }, "bookmark_url": { "type": "string" }, "subscription_url": { "type": "string" }, "comments_count": { "type": "integer", "format": "int32" }, "comments_url": { "type": "string" }, "position": { "type": "integer", "format": "int32" }, "parent": { "$ref": "#/components/schemas/RecordingParent" }, "bucket": { "$ref": "#/components/schemas/TodoBucket" }, "creator": { "$ref": "#/components/schemas/Person" }, "description": { "type": "string" }, "description_attachments": { "type": "array", "items": { "$ref": "#/components/schemas/RichTextAttachment" } }, "content_type": { "type": "string" }, "byte_size": { "type": "integer", "format": "int64" }, "width": { "type": "integer", "format": "int32", "x-go-type": "types.FlexInt", "x-go-type-import": { "path": "github.com/basecamp/basecamp-sdk/go/pkg/types" } }, "height": { "type": "integer", "format": "int32", "x-go-type": "types.FlexInt", "x-go-type-import": { "path": "github.com/basecamp/basecamp-sdk/go/pkg/types" } }, "download_url": { "type": "string", "x-basecamp-auth-routable-url": {} }, "filename": { "type": "string" }, "boosts_count": { "type": "integer", "format": "int32" }, "boosts_url": { "type": "string" } }, "required": [ "app_url", "bucket", "created_at", "creator", "description_attachments", "id", "inherits_status", "parent", "status", "title", "type", "updated_at", "url", "visible_to_clients" ] }, "UploadVersion": { "type": "object", "description": "A version event for an upload, from GET /uploads/{id}/versions.json.\n\n`action` is one of `created`, `active` (the upload's publication) or `blob_changed`\n(a file replacement). To list the file's PAST versions, select entries that carry\nan `upload` whose `current` is false — the original file arrives as `created` or\n`active`, never `blob_changed`, so filtering on that action drops the original\nand keeps the current file instead. This is an Event plus the file it recorded, rendered by its own\npartial rather than the shared event one, so upload fields don't leak onto todo,\nmessage and card events.", "properties": { "id": { "type": "integer", "format": "int64" }, "recording_id": { "type": "integer", "format": "int64" }, "action": { "type": "string" }, "details": { "$ref": "#/components/schemas/EventDetails" }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "creator": { "$ref": "#/components/schemas/Person" }, "boosts_count": { "type": "integer", "format": "int32" }, "boosts_url": { "type": "string" }, "upload": { "$ref": "#/components/schemas/UploadVersionFile" } }, "required": [ "action", "created_at", "creator", "id", "recording_id" ] }, "UploadVersionFile": { "type": "object", "description": "The file a version event recorded — a reduced projection, not an Upload.", "properties": { "content_type": { "type": "string" }, "byte_size": { "type": "integer", "format": "int64" }, "filename": { "type": "string" }, "download_url": { "type": "string", "description": "Fetches THIS version's bytes. The upload's own download_url always serves the\nlatest, which is the whole point of the feature.", "x-basecamp-auth-routable-url": {} }, "app_download_url": { "type": "string" }, "current": { "type": "boolean", "description": "True for the newest version *event*, and for exactly one element of any\nnon-empty response. The renderer computes it positionally — `event ==\n@events.first` over a reverse-chronological list — so it is a property of\nordering, not of what the upload currently points at, and it cannot be\nzero or plural.\n\nThat distinction is the whole caveat: `current` does NOT mean \"this is the\nfile the upload's own download_url serves\". A metadata-only PUT swaps in a\nrecordable carrying the same blob and emits no event, so afterwards no\nevent references the upload's current recordable — and this flag still\nmarks exactly one element, the newest event. bc3 pins that case by name in\n\"exactly one version is current after a metadata-only update\"." } }, "required": [ "app_download_url", "current", "download_url", "filename" ] }, "ValidationErrorResponseContent": { "type": "object", "properties": { "error": { "type": "string" }, "message": { "type": "string" } }, "required": [ "error" ] }, "Vault": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "status": { "type": "string" }, "visible_to_clients": { "type": "boolean" }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "updated_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "title": { "type": "string" }, "inherits_status": { "type": "boolean" }, "type": { "type": "string" }, "url": { "type": "string" }, "app_url": { "type": "string" }, "bookmark_url": { "type": "string" }, "position": { "type": "integer", "format": "int32" }, "parent": { "$ref": "#/components/schemas/RecordingParent" }, "bucket": { "$ref": "#/components/schemas/TodoBucket" }, "creator": { "$ref": "#/components/schemas/Person" }, "documents_count": { "type": "integer", "format": "int32" }, "documents_url": { "type": "string" }, "uploads_count": { "type": "integer", "format": "int32" }, "uploads_url": { "type": "string" }, "vaults_count": { "type": "integer", "format": "int32" }, "vaults_url": { "type": "string" } }, "required": [ "app_url", "bucket", "created_at", "creator", "id", "inherits_status", "status", "title", "type", "updated_at", "url", "visible_to_clients" ] }, "Webhook": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "active": { "type": "boolean" }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "updated_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "payload_url": { "type": "string" }, "types": { "type": "array", "items": { "type": "string" }, "x-go-type-skip-optional-pointer": true }, "url": { "type": "string" }, "app_url": { "type": "string" }, "recent_deliveries": { "type": "array", "items": { "$ref": "#/components/schemas/WebhookDelivery" }, "description": "Up to the 25 most recent delivery exchanges, most recent first.\nEmpty when the webhook hasn't delivered anything yet.", "x-go-type-skip-optional-pointer": true } }, "required": [ "app_url", "created_at", "id", "payload_url", "updated_at", "url" ] }, "WebhookCopy": { "type": "object", "description": "Reference to a copied/moved recording in copy events.", "properties": { "id": { "type": "integer", "format": "int64" }, "url": { "type": "string" }, "app_url": { "type": "string" }, "bucket": { "$ref": "#/components/schemas/WebhookCopyBucket" } } }, "WebhookCopyBucket": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" } } }, "WebhookDelivery": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "request": { "$ref": "#/components/schemas/WebhookDeliveryRequest" }, "response": { "$ref": "#/components/schemas/WebhookDeliveryResponse" } } }, "WebhookDeliveryRequest": { "type": "object", "properties": { "headers": { "$ref": "#/components/schemas/WebhookHeadersMap" }, "body": { "$ref": "#/components/schemas/WebhookEvent" } } }, "WebhookDeliveryResponse": { "type": "object", "properties": { "headers": { "$ref": "#/components/schemas/WebhookHeadersMap" }, "code": { "type": "integer", "format": "int32" }, "message": { "type": "string" } } }, "WebhookEvent": { "type": "object", "description": "The event payload delivered to webhook URLs.\nThis is the body of an outbound webhook HTTP request.\nAlso appears as the body field in WebhookDelivery.request.", "properties": { "id": { "type": "integer", "format": "int64" }, "kind": { "type": "string" }, "details": {}, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "recording": { "$ref": "#/components/schemas/Recording" }, "creator": { "$ref": "#/components/schemas/Person" }, "copy": { "$ref": "#/components/schemas/WebhookCopy" } } }, "WebhookHeadersMap": { "type": "object", "additionalProperties": { "type": "string" }, "propertyNames": { "type": "string" } }, "WebhookLimitErrorResponseContent": { "type": "object", "properties": { "error": { "type": "string" }, "message": { "type": "string" } }, "required": [ "error" ] }, "Wormhole": { "type": "object", "description": "A wormhole links this card table to a column on another card table, enabling\ncards to move across projects. It carries the full recording representation\nplus the destination-linkage fields. The wormhole's own `url`/`app_url`/`parent`\npoint at the *source* board; `destination_url` is the only field identifying\nthe destination column.", "properties": { "id": { "type": "integer", "format": "int64" }, "status": { "type": "string" }, "visible_to_clients": { "type": "boolean" }, "created_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "updated_at": { "type": "string", "x-go-type": "time.Time", "x-go-type-import": { "path": "time" } }, "title": { "type": "string" }, "inherits_status": { "type": "boolean" }, "type": { "type": "string" }, "url": { "type": "string" }, "app_url": { "type": "string" }, "bookmark_url": { "type": "string" }, "parent": { "$ref": "#/components/schemas/RecordingParent" }, "bucket": { "$ref": "#/components/schemas/TodoBucket" }, "creator": { "$ref": "#/components/schemas/Person" }, "color": { "type": [ "string", "null" ], "description": "Wormhole color; always emitted on the wire (`json.color recording.color`),\n`null` when unset. Like destination_url, `@required` models the presence and\nthe nullability is layered on in the OpenAPI (smithy-build.json jsonAdd ->\ntype: [\"string\",\"null\"]). Go types it *string because the value is nullable,\nnot because it is optional — the field is @required and carries no omitempty.", "x-go-type": "string" }, "linked": { "type": "boolean", "description": "True only while the destination column, its board, and its bucket are all\nactive; false once the destination is unlinked. Always emitted." }, "destination_url": { "type": [ "string", "null" ], "description": "URL of the destination column; always present on the wire, `null` for an\nunlinked wormhole. `@required` models the presence; the nullability of the\nvalue is layered on in the OpenAPI (smithy-build.json jsonAdd -> type:\n[\"string\",\"null\"]) since Smithy has no native\nrequired-and-nullable — exactly the SearchType.key treatment. SDKs model it\nas required-but-nullable (`string | null`, not `string | null | undefined`).", "x-go-type": "string" } }, "required": [ "app_url", "bucket", "color", "created_at", "creator", "destination_url", "id", "inherits_status", "linked", "parent", "status", "title", "type", "updated_at", "url", "visible_to_clients" ] } } } }