# Basecamp API
This package allows simple interaction with [Basecamp API](https://github.com/basecamp/bc3-api) using Python.
## Table of contents
1. [Installation](https://github.com/mare011rs/basecampapi#1-installation)
2. [Initial authentication: Getting your refresh token](https://github.com/mare011rs/basecampapi#2-initial-authentication-getting-your-refresh-token)
3. [Authentication with Refresh token](https://github.com/mare011rs/basecampapi#3-authentication-with-refresh-token)
4. [Message Boards](https://github.com/mare011rs/basecampapi#4-message-boards)
5. [Campfires](https://github.com/mare011rs/basecampapi#5-campfires)
6. [Attachments](https://github.com/mare011rs/basecampapi#6-attachments)
7. [To-dos](https://github.com/mare011rs/basecampapi#7-to-dos)
8. [Comments](https://github.com/mare011rs/basecampapi#8-comments)
9. [Chatbots](https://github.com/mare011rs/basecampapi#9-chatbots)
10. [Custom Request Method](https://github.com/mare011rs/basecampapi#10-custom-request-method)
## 1. Installation
The package can be installed from your terminal by typing:
pip install basecampapi
You need to have python 3.7 or higher installed.
## 2. Initial authentication: Getting your refresh token
##### You only need to do this the first time. Once you get your Refresh token you should pass it with your credentials to gain access.
##### If you already have a Refresh token you should skip this step.
To be able to interact with Basecamp's API, we need to provide an access token upon each API request. Basecamp's access tokens are set to expire 2 weeks after being generated, which is why we need to generate a refresh token.
Refresh token allows us to automate the process of generating an access token. We only have to generate the refresh token once and after that we can use it to gain access to Basecamp each time we run our script.
To gain access you need a developer app on Basecamp. App can be created on https://launchpad.37signals.com/integrations, after which you need to use the generated Client ID, Client Secret and the Redirect URI which you provided for initial authentication. You can read more about the authentication process on [Basecamp API Authentication](https://github.com/basecamp/api/blob/master/sections/authentication.md) page.
To begin the authentication process, you need to create a dictionary with your app credentials and use it in the `Basecamp` object:
```python
from basecampapi import Basecamp
your_credentials = {
"account_id": "your-account-id",
"client_id": "your-client-id",
"client_secret": "your-client-secret",
"redirect_uri": "your-redirect-uri"
}
bc = Basecamp(credentials=your_credentials)
```
Your account ID can be found on your Basecamp home page, in the URL address:
> https:<SPAN></SPAN>//3.basecamp.com/<b>YOUR-ACCOUNT-ID</b>/projects
If your credentials dictionary does not contain a "refresh_token", an error will be raised which contains a link for the authorization of your app. You need to open that link on the browser where you are logged into your Basecamp account and click on "Yes, I'll allow access":

Clicking that button will redirect you to the link you provided as Redirect URI in your credentials, but it will have the verification code in the url address. Save that verification code:

Initiate the `Basecamp` object again, and provide the code you gathered via the `verification_code` parameter:
```python
# Verification code variable
your_verification_code = "17beb4cd"
bc = Basecamp(credentials=your_credentials, verification_code=your_verification_code)
```
This will generate your Refresh token and use that token right away to generate the Access token for your current session. You need to generate your Refresh token only once, but that Refresh token will be used to generate Access token each time you initialize the `Basecamp` object.
## 3. Authentication with Refresh token
To interact with objects on Basecamp you have to initialize the `Basecamp` object. This object will generate your access token and allow you to interact with other Basecamp objects.
```python
from basecampapi import Basecamp
your_credentials = {
"account_id": "your-account-id",
"client_id": "your-client-id",
"client_secret": "your-client-secret",
"redirect_uri": "your-redirect-uri",
"refresh_token": "your-refresh-token"
}
bc = Basecamp(credentials=your_credentials)
```
This generates the Access token which is then used in objects that interact with Basecamp.
## 4. Message Boards
Message Boards allow you to create, read, and update messages. They are useful for team announcements, discussions, and documentation. For working with comments on messages, use the dedicated Comments module (see section 8).
```python
# Create a MessageBoard resource
message_board = bc.message_board(project_id=123456, message_board_id=123456)
# Get all messages
messages = message_board.get_all_messages()
# Create a new message
new_message = message_board.create_message(
data={
"subject": "Team update",
"content": "<p>Important announcement</p>",
"status": "active"
}
)
# Get a specific message
message = message_board.get_message(message_id=new_message['id'])
```
## 5. Campfires
Campfires are Basecamp's chat rooms for quick, informal communication. You can read past messages and post new ones.
```python
# Create a Campfire resource
campfire = bc.campfire(project_id=123456, campfire_id=123456)
# Get all messages
messages = campfire.get_lines()
# Send a message
campfire.write(data={"content": "Hello from Python!"})
```
## 6. Attachments
Upload files to Basecamp and attach them to messages, comments, or other objects. Files are uploaded to Basecamp's server and given an `attachable_sgid` that can be used in rich text content.
```python
# Create an Attachments resource
attachments = bc.attachments()
# Upload a file
response = attachments.upload_file(file_path="folder/image.png", name="my_image")
# Create HTML for embedding an attachment
html = attachments.create_attachment_html(name="my_image", caption="My image")
# Use in a message
message_board = bc.message_board(project_id=123456, message_board_id=123456)
message_board.create_message(
data={
"subject": "Test message with attachment",
"content": f"Hello world! <br> {html} <br> This is an image.",
"status": "active"
}
)
```
## 7. To-dos
Manage to-do lists and to-dos in Basecamp projects. Access to-do sets, create and update to-do lists, and manage individual to-dos.
```python
# Access a to-do set
todoset = bc.todoset(project_id=123456, todoset_id=123456)
# Create a to-do list
todolist = todoset.create_todolist(
data={
"name": "Launch checklist",
"description": "What we need to do before launch"
}
)
# Access a to-do list directly
todolist = bc.todolist(project_id=123456, todolist_id=123456)
# Create a to-do
todo = todolist.create_todo(
data={
"content": "Design signup form",
"description": "Make it simple and clean",
"due_on": "2022-12-31"
}
)
# Complete a to-do
todolist.complete_todo(todo_id=todo['id'])
```
## 8. Comments
The Basecamp API wrapper provides a dedicated Comments module for working with comments on any commentable resource in Basecamp, such as messages, to-dos, documents, and more.
```python
# Create a Comments resource
comments = bc.comments(project_id=123456)
# Get all comments on any recording (message, to-do, etc.)
message_comments = comments.get_all_comments(recording_id=789012)
# Get a specific comment
comment = comments.get_comment(comment_id=345678)
# Create a comment on any recording
new_comment = comments.create_comment(
recording_id=789012, # This could be a message_id, todo_id, etc.
data={"content": "<p>This is a comment</p>"}
)
# Update a comment
updated_comment = comments.update_comment(
comment_id=new_comment['id'],
data={"content": "<p>Updated comment</p>"}
)
# Trash a comment
comments.trash_comment(comment_id=new_comment['id'])
```
### Benefits of the Comments Module
- **Universal compatibility**: Works with comments on any commentable resource in Basecamp
- **Consistent interface**: Provides a standardized way to interact with comments across different resource types
- **Complete functionality**: Includes all comment operations (get, create, update, trash)
- **Separation of concerns**: Keeps comment functionality separate from other resource-specific operations
## 9. Chatbots
Post messages to Campfire chats programmatically using chatbots. Useful for integrating Basecamp with other systems like CI/CD pipelines or monitoring tools.
```python
# Create a chatbot
new_chatbot = bc.request(
method='POST',
path=f'/buckets/{project_id}/chats/{campfire_id}/integrations.json',
data={
"service_name": "deploy",
"command_url": "https://example.com/webhook"
}
)
chatbot_key = new_chatbot['lines_url'].split('/integrations/')[1].split('/')[0]
# Create a Chatbot resource
chatbot = bc.chatbot(chatbot_key=chatbot_key)
# Post a message
chatbot.write(
project_id=123456,
campfire_id=789012,
data={"content": "Deployment completed successfully!"}
)
```
## 10. Custom Request Method
Access any Basecamp API endpoint directly, even those not yet implemented in the wrapper. Useful for new API features or custom integrations.
```python
# List all projects
projects = bc.request(
method='GET',
path='/projects.json'
)
# Create a to-do
new_todo = bc.request(
method='POST',
path=f'/buckets/{project_id}/todolists/{todolist_id}/todos.json',
data={
"content": "Research new API features",
"due_on": "2023-12-31"
}
)
```
Raw data
{
"_id": null,
"home_page": "https://github.com/mare011rs/basecampapi",
"name": "basecampapi",
"maintainer": null,
"docs_url": null,
"requires_python": "<4.0,>=3.7",
"maintainer_email": null,
"keywords": "basecamp, api, wrapper, basecamp3, client",
"author": "mare011rs",
"author_email": "mare011rs@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/e3/35/348c652189ac8706beaa265f4de64e8039118399aafd3f7348b0db83dca8/basecampapi-2.0.0.tar.gz",
"platform": null,
"description": "# Basecamp API\n\nThis package allows simple interaction with [Basecamp API](https://github.com/basecamp/bc3-api) using Python.\n\n## Table of contents\n\n1. [Installation](https://github.com/mare011rs/basecampapi#1-installation)\n2. [Initial authentication: Getting your refresh token](https://github.com/mare011rs/basecampapi#2-initial-authentication-getting-your-refresh-token)\n3. [Authentication with Refresh token](https://github.com/mare011rs/basecampapi#3-authentication-with-refresh-token)\n4. [Message Boards](https://github.com/mare011rs/basecampapi#4-message-boards)\n5. [Campfires](https://github.com/mare011rs/basecampapi#5-campfires)\n6. [Attachments](https://github.com/mare011rs/basecampapi#6-attachments)\n7. [To-dos](https://github.com/mare011rs/basecampapi#7-to-dos)\n8. [Comments](https://github.com/mare011rs/basecampapi#8-comments)\n9. [Chatbots](https://github.com/mare011rs/basecampapi#9-chatbots)\n10. [Custom Request Method](https://github.com/mare011rs/basecampapi#10-custom-request-method)\n\n## 1. Installation\nThe package can be installed from your terminal by typing:\n\n pip install basecampapi\n\nYou need to have python 3.7 or higher installed.\n\n\n## 2. Initial authentication: Getting your refresh token\n\n##### You only need to do this the first time. Once you get your Refresh token you should pass it with your credentials to gain access. \n##### If you already have a Refresh token you should skip this step.\n\nTo be able to interact with Basecamp's API, we need to provide an access token upon each API request. Basecamp's access tokens are set to expire 2 weeks after being generated, which is why we need to generate a refresh token.\n\nRefresh token allows us to automate the process of generating an access token. We only have to generate the refresh token once and after that we can use it to gain access to Basecamp each time we run our script.\n\nTo gain access you need a developer app on Basecamp. App can be created on https://launchpad.37signals.com/integrations, after which you need to use the generated Client ID, Client Secret and the Redirect URI which you provided for initial authentication. You can read more about the authentication process on [Basecamp API Authentication](https://github.com/basecamp/api/blob/master/sections/authentication.md) page.\n\nTo begin the authentication process, you need to create a dictionary with your app credentials and use it in the `Basecamp` object:\n\n```python\nfrom basecampapi import Basecamp\n\nyour_credentials = {\n\t\"account_id\": \"your-account-id\",\n\t\"client_id\": \"your-client-id\",\n\t\"client_secret\": \"your-client-secret\",\n\t\"redirect_uri\": \"your-redirect-uri\"\n}\n\nbc = Basecamp(credentials=your_credentials)\n```\nYour account ID can be found on your Basecamp home page, in the URL address:\n> https:<SPAN></SPAN>//3.basecamp.com/<b>YOUR-ACCOUNT-ID</b>/projects\n\nIf your credentials dictionary does not contain a \"refresh_token\", an error will be raised which contains a link for the authorization of your app. You need to open that link on the browser where you are logged into your Basecamp account and click on \"Yes, I'll allow access\":\n\n\n\nClicking that button will redirect you to the link you provided as Redirect URI in your credentials, but it will have the verification code in the url address. Save that verification code:\n\n\n\nInitiate the `Basecamp` object again, and provide the code you gathered via the `verification_code` parameter:\n\n```python\n# Verification code variable \nyour_verification_code = \"17beb4cd\"\n\nbc = Basecamp(credentials=your_credentials, verification_code=your_verification_code)\n```\n\nThis will generate your Refresh token and use that token right away to generate the Access token for your current session. You need to generate your Refresh token only once, but that Refresh token will be used to generate Access token each time you initialize the `Basecamp` object.\n\n\n## 3. Authentication with Refresh token\n\nTo interact with objects on Basecamp you have to initialize the `Basecamp` object. This object will generate your access token and allow you to interact with other Basecamp objects. \n\n```python\nfrom basecampapi import Basecamp\n\nyour_credentials = {\n\t\"account_id\": \"your-account-id\",\n\t\"client_id\": \"your-client-id\",\n\t\"client_secret\": \"your-client-secret\",\n\t\"redirect_uri\": \"your-redirect-uri\",\n\t\"refresh_token\": \"your-refresh-token\"\n}\n\nbc = Basecamp(credentials=your_credentials)\n```\nThis generates the Access token which is then used in objects that interact with Basecamp.\n\n## 4. Message Boards\n\nMessage Boards allow you to create, read, and update messages. They are useful for team announcements, discussions, and documentation. For working with comments on messages, use the dedicated Comments module (see section 8).\n\n```python\n# Create a MessageBoard resource\nmessage_board = bc.message_board(project_id=123456, message_board_id=123456)\n\n# Get all messages\nmessages = message_board.get_all_messages()\n\n# Create a new message\nnew_message = message_board.create_message(\n data={\n \"subject\": \"Team update\",\n \"content\": \"<p>Important announcement</p>\",\n \"status\": \"active\"\n }\n)\n\n# Get a specific message\nmessage = message_board.get_message(message_id=new_message['id'])\n```\n\n## 5. Campfires\n\nCampfires are Basecamp's chat rooms for quick, informal communication. You can read past messages and post new ones.\n\n```python\n# Create a Campfire resource\ncampfire = bc.campfire(project_id=123456, campfire_id=123456)\n\n# Get all messages\nmessages = campfire.get_lines()\n\n# Send a message\ncampfire.write(data={\"content\": \"Hello from Python!\"})\n```\n\n## 6. Attachments\n\nUpload files to Basecamp and attach them to messages, comments, or other objects. Files are uploaded to Basecamp's server and given an `attachable_sgid` that can be used in rich text content.\n\n```python\n# Create an Attachments resource\nattachments = bc.attachments()\n\n# Upload a file\nresponse = attachments.upload_file(file_path=\"folder/image.png\", name=\"my_image\")\n\n# Create HTML for embedding an attachment\nhtml = attachments.create_attachment_html(name=\"my_image\", caption=\"My image\")\n\n# Use in a message\nmessage_board = bc.message_board(project_id=123456, message_board_id=123456)\nmessage_board.create_message(\n data={\n \"subject\": \"Test message with attachment\",\n \"content\": f\"Hello world! <br> {html} <br> This is an image.\",\n \"status\": \"active\"\n }\n)\n```\n\n## 7. To-dos\n\nManage to-do lists and to-dos in Basecamp projects. Access to-do sets, create and update to-do lists, and manage individual to-dos.\n\n```python\n# Access a to-do set\ntodoset = bc.todoset(project_id=123456, todoset_id=123456)\n\n# Create a to-do list\ntodolist = todoset.create_todolist(\n data={\n \"name\": \"Launch checklist\",\n \"description\": \"What we need to do before launch\"\n }\n)\n\n# Access a to-do list directly\ntodolist = bc.todolist(project_id=123456, todolist_id=123456)\n\n# Create a to-do\ntodo = todolist.create_todo(\n data={\n \"content\": \"Design signup form\",\n \"description\": \"Make it simple and clean\",\n \"due_on\": \"2022-12-31\"\n }\n)\n\n# Complete a to-do\ntodolist.complete_todo(todo_id=todo['id'])\n```\n\n## 8. Comments\n\nThe Basecamp API wrapper provides a dedicated Comments module for working with comments on any commentable resource in Basecamp, such as messages, to-dos, documents, and more.\n\n```python\n# Create a Comments resource\ncomments = bc.comments(project_id=123456)\n\n# Get all comments on any recording (message, to-do, etc.)\nmessage_comments = comments.get_all_comments(recording_id=789012)\n\n# Get a specific comment\ncomment = comments.get_comment(comment_id=345678)\n\n# Create a comment on any recording\nnew_comment = comments.create_comment(\n recording_id=789012, # This could be a message_id, todo_id, etc.\n data={\"content\": \"<p>This is a comment</p>\"}\n)\n\n# Update a comment\nupdated_comment = comments.update_comment(\n comment_id=new_comment['id'],\n data={\"content\": \"<p>Updated comment</p>\"}\n)\n\n# Trash a comment\ncomments.trash_comment(comment_id=new_comment['id'])\n```\n\n### Benefits of the Comments Module\n\n- **Universal compatibility**: Works with comments on any commentable resource in Basecamp\n- **Consistent interface**: Provides a standardized way to interact with comments across different resource types\n- **Complete functionality**: Includes all comment operations (get, create, update, trash)\n- **Separation of concerns**: Keeps comment functionality separate from other resource-specific operations\n\n## 9. Chatbots\n\nPost messages to Campfire chats programmatically using chatbots. Useful for integrating Basecamp with other systems like CI/CD pipelines or monitoring tools.\n\n```python\n# Create a chatbot\nnew_chatbot = bc.request(\n method='POST',\n path=f'/buckets/{project_id}/chats/{campfire_id}/integrations.json',\n data={\n \"service_name\": \"deploy\",\n \"command_url\": \"https://example.com/webhook\"\n }\n)\nchatbot_key = new_chatbot['lines_url'].split('/integrations/')[1].split('/')[0]\n\n# Create a Chatbot resource\nchatbot = bc.chatbot(chatbot_key=chatbot_key)\n\n# Post a message\nchatbot.write(\n project_id=123456,\n campfire_id=789012,\n data={\"content\": \"Deployment completed successfully!\"}\n)\n```\n\n## 10. Custom Request Method\n\nAccess any Basecamp API endpoint directly, even those not yet implemented in the wrapper. Useful for new API features or custom integrations.\n\n```python\n# List all projects\nprojects = bc.request(\n method='GET',\n path='/projects.json'\n)\n\n# Create a to-do\nnew_todo = bc.request(\n method='POST',\n path=f'/buckets/{project_id}/todolists/{todolist_id}/todos.json',\n data={\n \"content\": \"Research new API features\",\n \"due_on\": \"2023-12-31\"\n }\n)\n```",
"bugtrack_url": null,
"license": "MIT",
"summary": "A Python wrapper for the Basecamp 3 API that provides a simple and intuitive interface for interacting with Basecamp resources.",
"version": "2.0.0",
"project_urls": {
"Homepage": "https://github.com/mare011rs/basecampapi",
"Repository": "https://github.com/mare011rs/basecampapi"
},
"split_keywords": [
"basecamp",
" api",
" wrapper",
" basecamp3",
" client"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "c2dfdbee3c64350b5ce509ce2b80c8448190f2fa6a1e016ba916273275312996",
"md5": "f734b49b485375b48cbdbb964aa9d050",
"sha256": "f0ad45cdad9495d48a3ac4e7767e436b5d47f476785b094e1faa73c6dee134c3"
},
"downloads": -1,
"filename": "basecampapi-2.0.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "f734b49b485375b48cbdbb964aa9d050",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<4.0,>=3.7",
"size": 18847,
"upload_time": "2025-08-04T09:18:31",
"upload_time_iso_8601": "2025-08-04T09:18:31.484394Z",
"url": "https://files.pythonhosted.org/packages/c2/df/dbee3c64350b5ce509ce2b80c8448190f2fa6a1e016ba916273275312996/basecampapi-2.0.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "e335348c652189ac8706beaa265f4de64e8039118399aafd3f7348b0db83dca8",
"md5": "d376a3d38c1e40a02fa28db8deb5f2fb",
"sha256": "8a76a777f34a6d941df6cc5cc6f6c2085f485b889d2c938e0ede32355f6bb9d0"
},
"downloads": -1,
"filename": "basecampapi-2.0.0.tar.gz",
"has_sig": false,
"md5_digest": "d376a3d38c1e40a02fa28db8deb5f2fb",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4.0,>=3.7",
"size": 15388,
"upload_time": "2025-08-04T09:18:32",
"upload_time_iso_8601": "2025-08-04T09:18:32.736777Z",
"url": "https://files.pythonhosted.org/packages/e3/35/348c652189ac8706beaa265f4de64e8039118399aafd3f7348b0db83dca8/basecampapi-2.0.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-04 09:18:32",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "mare011rs",
"github_project": "basecampapi",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "basecampapi"
}