Basecamp API
The Basecamp API is a REST API providing programmatic access to Basecamp's project management platform. Manage projects, to-do lists, messages, documents, schedules, and team members. Uses OAuth 2.0 for authentication and returns JSON.
The Basecamp API is a REST API providing programmatic access to Basecamp's project management platform. Manage projects, to-do lists, messages, documents, schedules, and team members. Uses OAuth 2.0 for authentication and returns JSON.
openapi: 3.1.0
info:
title: Basecamp API
description: >-
The Basecamp API is a REST API that provides programmatic access to
Basecamp's project management and team communication platform. It enables
developers to manage projects, to-do lists, messages, documents, schedules,
campfires, uploads, card tables, templates, and team members across Basecamp
accounts. The API uses OAuth 2.0 for authentication and returns JSON
responses, with all requests scoped to an account ID in the base URL path.
Resources include projects, people, to-dos, message boards, documents, card
tables, campfires, questionnaires, and webhooks, covering the full breadth
of Basecamp's collaboration toolset.
version: '1.0'
contact:
name: Basecamp Developer Support
url: https://github.com/basecamp/bc3-api
termsOfService: https://basecamp.com/terms
externalDocs:
description: Basecamp API Documentation
url: https://github.com/basecamp/bc3-api
servers:
- url: https://3.basecampapi.com/{accountId}
description: Production Server
variables:
accountId:
description: Your Basecamp account ID
default: '999999999'
tags:
- name: Campfires
description: Manage project campfire chat rooms and lines
- name: Card Tables
description: Manage kanban-style card tables and card movements
- name: Comments
description: Manage comments on any commentable recording
- name: Documents
description: Manage documents stored in vaults
- name: Messages
description: Manage messages on message boards
- name: People
description: Manage people, profiles, and project access
- name: Projects
description: Manage Basecamp projects (buckets)
- name: Recordings
description: Common actions for all recordable resources (archive, trash, restore)
- name: Schedule Entries
description: Manage individual schedule events and recurring entries
- name: Schedules
description: Manage project schedules
- name: Subscriptions
description: Manage per-recording notification subscriptions
- name: Templates
description: Manage project templates and construct projects from them
- name: To-Do Lists
description: Manage to-do lists within a to-do set
- name: To-Dos
description: Manage individual to-do items
- name: Uploads
description: Manage file uploads stored in vaults
- name: Webhooks
description: Manage webhook subscriptions for a project
security:
- bearerAuth: []
paths:
/projects.json:
get:
operationId: listProjects
summary: List projects
description: >-
Returns a paginated list of active projects visible to the authenticated
user. Use the optional status parameter to retrieve archived or trashed
projects instead.
tags:
- Projects
parameters:
- name: status
in: query
description: Filter projects by status. Omit for active projects.
required: false
schema:
type: string
enum: [archived, trashed]
responses:
'200':
description: Paginated list of projects
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Project'
'401':
$ref: '#/components/responses/Unauthorized'
'429':
$ref: '#/components/responses/TooManyRequests'
post:
operationId: createProject
summary: Create a project
description: >-
Creates a new Basecamp project with the given name and optional
description. Returns the new project with a 201 Created status.
tags:
- Projects
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ProjectCreateRequest'
responses:
'201':
description: Project created successfully
content:
application/json:
schema:
$ref: '#/components/schemas/Project'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
/projects/{projectId}.json:
get:
operationId: getProject
summary: Get a project
description: >-
Returns the project with the given ID including its dock, which lists
the tools enabled for that project.
tags:
- Projects
parameters:
- $ref: '#/components/parameters/ProjectId'
responses:
'200':
description: Project details
content:
application/json:
schema:
$ref: '#/components/schemas/Project'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
put:
operationId: updateProject
summary: Update a project
description: >-
Updates the name, description, schedule dates, or admissions settings
for an existing project. Returns the updated project.
tags:
- Projects
parameters:
- $ref: '#/components/parameters/ProjectId'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ProjectUpdateRequest'
responses:
'200':
description: Updated project
content:
application/json:
schema:
$ref: '#/components/schemas/Project'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
delete:
operationId: deleteProject
summary: Delete a project
description: >-
Moves the project with the given ID to trash. Trashed projects can be
permanently deleted from the Basecamp web interface.
tags:
- Projects
parameters:
- $ref: '#/components/parameters/ProjectId'
responses:
'204':
description: Project moved to trash
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/people.json:
get:
operationId: listPeople
summary: List all people
description: >-
Returns a paginated list of all people visible to the authenticated user
across the account.
tags:
- People
responses:
'200':
description: Paginated list of people
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Person'
'401':
$ref: '#/components/responses/Unauthorized'
/projects/{projectId}/people.json:
get:
operationId: listProjectPeople
summary: List people on a project
description: >-
Returns a paginated list of all people with access to the specified
project.
tags:
- People
parameters:
- $ref: '#/components/parameters/ProjectId'
responses:
'200':
description: List of people on the project
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Person'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/projects/{projectId}/people/users.json:
put:
operationId: updateProjectAccess
summary: Update project access
description: >-
Grants or revokes access to the project for specific people. Accepts
arrays of person IDs to grant or revoke, or new person objects to
create and invite.
tags:
- People
parameters:
- $ref: '#/components/parameters/ProjectId'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ProjectAccessRequest'
responses:
'200':
description: Updated access list
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/circles/people.json:
get:
operationId: listPingablePeople
summary: List pingable people
description: >-
Returns a paginated list of all people the authenticated user can ping
(direct message) within the account.
tags:
- People
responses:
'200':
description: List of pingable people
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Person'
'401':
$ref: '#/components/responses/Unauthorized'
/people/{personId}.json:
get:
operationId: getPerson
summary: Get a person
description: >-
Returns the profile of the person with the given ID.
tags:
- People
parameters:
- $ref: '#/components/parameters/PersonId'
responses:
'200':
description: Person profile
content:
application/json:
schema:
$ref: '#/components/schemas/Person'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/my/profile.json:
get:
operationId: getMyProfile
summary: Get my profile
description: >-
Returns the profile of the currently authenticated user.
tags:
- People
responses:
'200':
description: Authenticated user profile
content:
application/json:
schema:
$ref: '#/components/schemas/Person'
'401':
$ref: '#/components/responses/Unauthorized'
put:
operationId: updateMyProfile
summary: Update my profile
description: >-
Updates profile fields for the currently authenticated user including
name, email address, title, bio, location, and time zone.
tags:
- People
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ProfileUpdateRequest'
responses:
'200':
description: Updated profile
content:
application/json:
schema:
$ref: '#/components/schemas/Person'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
/templates.json:
get:
operationId: listTemplates
summary: List templates
description: >-
Returns a paginated list of active project templates visible to the
authenticated user. Optionally filter by status.
tags:
- Templates
parameters:
- name: status
in: query
description: Filter templates by status.
required: false
schema:
type: string
enum: [archived, trashed]
responses:
'200':
description: List of templates
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Template'
'401':
$ref: '#/components/responses/Unauthorized'
post:
operationId: createTemplate
summary: Create a template
description: >-
Creates a new project template with the given name and optional
description. Returns the template with a 201 Created status.
tags:
- Templates
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/TemplateCreateRequest'
responses:
'201':
description: Template created
content:
application/json:
schema:
$ref: '#/components/schemas/Template'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
/templates/{templateId}.json:
get:
operationId: getTemplate
summary: Get a template
description: >-
Returns the project template with the given ID.
tags:
- Templates
parameters:
- $ref: '#/components/parameters/TemplateId'
responses:
'200':
description: Template details
content:
application/json:
schema:
$ref: '#/components/schemas/Template'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
put:
operationId: updateTemplate
summary: Update a template
description: >-
Updates the name and description of an existing project template.
tags:
- Templates
parameters:
- $ref: '#/components/parameters/TemplateId'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/TemplateCreateRequest'
responses:
'200':
description: Updated template
content:
application/json:
schema:
$ref: '#/components/schemas/Template'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
delete:
operationId: deleteTemplate
summary: Delete a template
description: >-
Moves the template with the given ID to trash.
tags:
- Templates
parameters:
- $ref: '#/components/parameters/TemplateId'
responses:
'204':
description: Template trashed
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/templates/{templateId}/project_constructions.json:
post:
operationId: createProjectFromTemplate
summary: Create project from template
description: >-
Starts the construction of a new project based on the given template.
Returns a project construction object whose status can be polled until
it transitions from "pending" to "completed".
tags:
- Templates
parameters:
- $ref: '#/components/parameters/TemplateId'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ProjectConstructionRequest'
responses:
'201':
description: Project construction initiated
content:
application/json:
schema:
$ref: '#/components/schemas/ProjectConstruction'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/templates/{templateId}/project_constructions/{constructionId}.json:
get:
operationId: getProjectConstruction
summary: Get project construction status
description: >-
Returns the current status of a project construction job. Poll this
endpoint until status changes from "pending" to "completed".
tags:
- Templates
parameters:
- $ref: '#/components/parameters/TemplateId'
- $ref: '#/components/parameters/ConstructionId'
responses:
'200':
description: Project construction status
content:
application/json:
schema:
$ref: '#/components/schemas/ProjectConstruction'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/projects/recordings.json:
get:
operationId: listRecordings
summary: List recordings
description: >-
Returns a paginated list of recordings of the specified type across all
projects. Use the type parameter to specify the resource type (Comment,
Document, Message, Todo, Upload, etc.).
tags:
- Recordings
parameters:
- name: type
in: query
description: The recording type to list.
required: true
schema:
type: string
enum:
- Comment
- Document
- Message
- Todo
- TodoList
- Schedule::Entry
- Upload
- Vault
- name: bucket
in: query
description: Filter to a specific project (bucket) ID.
required: false
schema:
type: integer
- name: status
in: query
description: Filter by recording status.
required: false
schema:
type: string
enum: [active, archived, trashed]
- name: sort
in: query
description: Sort field.
required: false
schema:
type: string
enum: [created_at, updated_at]
- name: direction
in: query
description: Sort direction.
required: false
schema:
type: string
enum: [asc, desc]
responses:
'200':
description: List of recordings
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Recording'
'401':
$ref: '#/components/responses/Unauthorized'
/recordings/{recordingId}/status/trashed.json:
put:
operationId: trashRecording
summary: Trash a recording
description: >-
Moves the recording with the given ID to trash. Works for any
recordable resource type including messages, to-dos, documents, and
comments.
tags:
- Recordings
parameters:
- $ref: '#/components/parameters/RecordingId'
responses:
'204':
description: Recording trashed
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/recordings/{recordingId}/status/archived.json:
put:
operationId: archiveRecording
summary: Archive a recording
description: >-
Archives the recording with the given ID. Archived recordings are
hidden from default views but remain accessible.
tags:
- Recordings
parameters:
- $ref: '#/components/parameters/RecordingId'
responses:
'204':
description: Recording archived
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/recordings/{recordingId}/status/active.json:
put:
operationId: unarchiveRecording
summary: Unarchive a recording
description: >-
Restores an archived recording to active status, making it visible in
default views again.
tags:
- Recordings
parameters:
- $ref: '#/components/parameters/RecordingId'
responses:
'204':
description: Recording restored to active
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/message_boards/{messageBoardId}/messages.json:
get:
operationId: listMessages
summary: List messages
description: >-
Returns a paginated list of active messages in the specified message
board. Messages can be sorted by created_at or updated_at.
tags:
- Messages
parameters:
- $ref: '#/components/parameters/MessageBoardId'
- name: sort
in: query
description: Sort field.
required: false
schema:
type: string
enum: [created_at, updated_at]
- name: direction
in: query
description: Sort direction.
required: false
schema:
type: string
enum: [asc, desc]
responses:
'200':
description: List of messages
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Message'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
post:
operationId: createMessage
summary: Create a message
description: >-
Creates a new message in the specified message board. Set status to
"active" to publish immediately; otherwise the message is saved as a
draft.
tags:
- Messages
parameters:
- $ref: '#/components/parameters/MessageBoardId'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/MessageCreateRequest'
responses:
'201':
description: Message created
content:
application/json:
schema:
$ref: '#/components/schemas/Message'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
/messages/{messageId}.json:
get:
operationId: getMessage
summary: Get a message
description: >-
Returns the message with the given ID.
tags:
- Messages
parameters:
- $ref: '#/components/parameters/MessageId'
responses:
'200':
description: Message details
content:
application/json:
schema:
$ref: '#/components/schemas/Message'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
put:
operationId: updateMessage
summary: Update a message
description: >-
Updates the subject, content, or category of the specified message.
tags:
- Messages
parameters:
- $ref: '#/components/parameters/MessageId'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/MessageUpdateRequest'
responses:
'200':
description: Updated message
content:
application/json:
schema:
$ref: '#/components/schemas/Message'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/recordings/{recordingId}/comments.json:
get:
operationId: listComments
summary: List comments
description: >-
Returns a paginated list of active comments on the specified recording.
Any resource that exposes a comments_url can have its comments listed
via this endpoint.
tags:
- Comments
parameters:
- $ref: '#/components/parameters/RecordingId'
responses:
'200':
description: List of comments
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Comment'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
post:
operationId: createComment
summary: Create a comment
description: >-
Creates a new comment on the specified recording. All subscribers to
the recording will be notified. Supports HTML-formatted content.
tags:
- Comments
parameters:
- $ref: '#/components/parameters/RecordingId'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CommentCreateRequest'
responses:
'201':
description: Comment created
content:
application/json:
schema:
$ref: '#/components/schemas/Comment'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
/comments/{commentId}.json:
get:
operationId: getComment
summary: Get a comment
description: >-
Returns the comment with the given ID.
tags:
- Comments
parameters:
- $ref: '#/components/parameters/CommentId'
responses:
'200':
description: Comment details
content:
application/json:
schema:
$ref: '#/components/schemas/Comment'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
put:
operationId: updateComment
summary: Update a comment
description: >-
Updates the content of the specified comment.
tags:
- Comments
parameters:
- $ref: '#/components/parameters/CommentId'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CommentCreateRequest'
responses:
'200':
description: Updated comment
content:
application/json:
schema:
$ref: '#/components/schemas/Comment'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/todosets/{todosetId}/todolists.json:
get:
operationId: listTodoLists
summary: List to-do lists
description: >-
Returns a paginated list of active to-do lists within the specified
to-do set.
tags:
- To-Do Lists
parameters:
- $ref: '#/components/parameters/TodosetId'
- name: status
in: query
required: false
description: Filter by status.
schema:
type: string
enum: [archived, trashed]
responses:
'200':
description: List of to-do lists
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/TodoList'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
post:
operationId: createTodoList
summary: Create a to-do list
description: >-
Creates a new to-do list in the specified to-do set with the given name
and optional description.
tags:
- To-Do Lists
parameters:
- $ref: '#/components/parameters/TodosetId'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/TodoListCreateRequest'
responses:
'201':
description: To-do list created
content:
application/json:
schema:
$ref: '#/components/schemas/TodoList'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
/todolists/{todolistId}.json:
get:
operationId: getTodoList
summary: Get a to-do list
description: >-
Returns the to-do list with the given ID.
tags:
- To-Do Lists
parameters:
- $ref: '#/components/parameters/TodolistId'
responses:
'200':
description: To-do list details
content:
application/json:
schema:
$ref: '#/components/schemas/TodoList'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
put:
operationId: updateTodoList
summary: Update a to-do list
description: >-
Updates the name and description of the specified to-do list.
tags:
- To-Do Lists
parameters:
- $ref: '#/components/parameters/TodolistId'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/TodoListCreateRequest'
responses:
'200':
description: Updated to-do list
content:
application/json:
schema:
$ref: '#/components/schemas/TodoList'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/todolists/{todolistId}/todos.json:
get:
operationId: listTodos
summary: List to-dos
description: >-
Returns a paginated list of active to-dos in the specified to-do list.
Set completed=true to retrieve completed items instead.
tags:
- To-Dos
parameters:
- $ref: '#/components/parameters/TodolistId'
- name: status
in: query
required: false
description: Filter by status.
schema:
type: string
enum: [archived, trashed]
- name: completed
in: query
required: false
description: Set to true to return completed to-dos.
schema:
type: boolean
responses:
'200':
description: List of to-dos
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Todo'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
post:
operationId: createTodo
summary: Create a to-do
description: >-
Creates a new to-do in the specified to-do list. Supports assignees,
due dates, start dates, and completion subscriber notifications.
tags:
- To-Dos
parameters:
- $ref: '#/components/parameters/TodolistId'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/TodoCreateRequest'
responses:
'201':
description: To-do created
content:
application/json:
schema:
$ref: '#/components/schemas/Todo'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
/todos/{todoId}.json:
get:
operationId: getTodo
summary: Get a to-do
description: >-
Returns the to-do with the given ID.
tags:
- To-Dos
parameters:
- $ref: '#/components/parameters/TodoId'
responses:
'200':
description: To-do details
content:
application/json:
schema:
$ref: '#/components/schemas/Todo'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
put:
operationId: updateTodo
summary: Update a to-do
description: >-
Updates the content, description, assignees, due date, or other fields
of the specified to-do.
tags:
- To-Dos
parameters:
- $ref: '#/components/parameters/TodoId'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/TodoCreateRequest'
responses:
'200':
description: Updated to-do
content:
application/json:
schema:
$ref: '#/components/schemas/Todo'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFo
# --- truncated at 32 KB (90 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/basecamp/refs/heads/main/openapi/basecamp-api-openapi.yml