Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsCommunityBlog
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Authors
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

ProTermsPrivacyRefunds
Back to skills

Basecamp Project Management

BSecurity

Basecamp API integration with managed OAuth. Manage projects, to-dos, messages, schedules, documents, and team collaboration. Use this skill when users want to create and manage projects, to-do lists, schedule events, or collaborate with teams in Basecamp. For other third party…

19 stars
0 votes
0 copies
1 views
Added 9/19/2026
ai-agentsjavascriptpythongojavashellbashgitapidocumentation

Works with

api

Security Analysis

B75/100
criticalExfiltrates credentials via HTTP — exact pattern from Snyk ToxicSkills study

Scanned 9/19/2026

Install to Claude Code

$npx -y skills add rondoflow/rondoflow --skill basecamp-project-management --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Basecamp Project Management?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Basecamp Project Management
[![Security: B — Skills Directory](https://www.skillsdirectory.com/api/skills/rondoflow-basecamp-project-management/badge)](https://www.skillsdirectory.com/skills/rondoflow-basecamp-project-management)

More formats (shields.io, HTML) on the badges page.

Download with Pro
Files
SKILL.md
---
name: basecamp-project-management
description: "Basecamp API integration with managed OAuth. Manage projects, to-dos, messages, schedules, documents, and team collaboration. Use this skill when users want to create and manage projects, to-do lists, schedule events, or collaborate with teams in Basecamp. For other third party…"
category: "Integrations"
author: community
version: "1.0.2"
icon: plug
---

# Basecamp

Access the Basecamp 4 API with managed OAuth authentication. Manage projects, to-dos, messages, schedules, documents, and team collaboration.

## Quick Start

```bash
# List all projects
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/basecamp/projects.json')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
```

## Base URL

```
https://gateway.maton.ai/basecamp/{resource}.json
```

The gateway proxies requests to `3.basecampapi.com/{account_id}/` and automatically injects your OAuth token and account ID.

**Important:** All Basecamp API URLs must end with `.json`.

## Authentication

All requests require the Maton API key in the Authorization header:

```
Authorization: Bearer $MATON_API_KEY
```

**Environment Variable:** Set your API key as `MATON_API_KEY`:

```bash
export MATON_API_KEY="YOUR_API_KEY"
```

### Getting Your API Key

1. Sign in or create an account at [maton.ai](https://maton.ai)
2. Go to [maton.ai/settings](https://maton.ai/settings)
3. Copy your API key

## Connection Management

Manage your Basecamp OAuth connections at `https://ctrl.maton.ai`.

### List Connections

```bash
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections?app=basecamp&status=ACTIVE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
```

### Create Connection

```bash
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'app': 'basecamp'}).encode()
req = urllib.request.Request('https://ctrl.maton.ai/connections', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
```

### Get Connection

```bash
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
```

**Response:**
```json
{
  "connection": {
    "connection_id": "71e313c8-9100-48c6-8ea1-6323f6fafd04",
    "status": "ACTIVE",
    "creation_time": "2026-02-08T03:12:39.815086Z",
    "last_updated_time": "2026-02-08T03:12:59.259878Z",
    "url": "https://connect.maton.ai/?session_token=...",
    "app": "basecamp",
    "metadata": {}
  }
}
```

Open the returned `url` in a browser to complete OAuth authorization.

### Delete Connection

```bash
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}', method='DELETE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
```

### Specifying Connection

If you have multiple Basecamp connections, specify which one to use with the `Maton-Connection` header:

```bash
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/basecamp/projects.json')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Maton-Connection', '71e313c8-9100-48c6-8ea1-6323f6fafd04')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
```

If omitted, the gateway uses the default (oldest) active connection.

## API Reference

### User Info

#### Get Current User

```bash
GET /basecamp/my/profile.json
```

**Response:**
```json
{
  "id": 51197030,
  "name": "Chris Kim",
  "email_address": "chris@example.com",
  "admin": true,
  "owner": true,
  "time_zone": "America/Los_Angeles",
  "avatar_url": "https://..."
}
```

### People Operations

#### List People

```bash
GET /basecamp/people.json
```

**Response:**
```json
[
  {
    "id": 51197030,
    "name": "Chris Kim",
    "email_address": "chris@example.com",
    "admin": true,
    "owner": true,
    "employee": true,
    "time_zone": "America/Los_Angeles"
  }
]
```

#### Get Person

```bash
GET /basecamp/people/{person_id}.json
```

#### List Project Members

```bash
GET /basecamp/projects/{project_id}/people.json
```

### Project Operations

#### List Projects

```bash
GET /basecamp/projects.json
```

**Response:**
```json
[
  {
    "id": 46005636,
    "status": "active",
    "name": "Getting Started",
    "description": "Quickly get up to speed with everything Basecamp",
    "created_at": "2026-02-05T22:59:26.087Z",
    "url": "https://3.basecampapi.com/6153810/projects/46005636.json",
    "dock": [...]
  }
]
```

#### Get Project

```bash
GET /basecamp/projects/{project_id}.json
```

The project response includes a `dock` array with available tools (message_board, todoset, vault, chat, schedule, etc.). Each dock item has:
- `id`: The tool's ID
- `name`: Tool type (e.g., "todoset", "message_board")
- `enabled`: Whether the tool is active
- `url`: Direct URL to access the tool

#### Create Project

```bash
POST /basecamp/projects.json
Content-Type: application/json

{
  "name": "New Project",
  "description": "Project description"
}
```

#### Update Project

```bash
PUT /basecamp/projects/{project_id}.json
Content-Type: application/json

{
  "name": "Updated Project Name",
  "description": "Updated description"
}
```

#### Delete (Trash) Project

```bash
DELETE /basecamp/projects/{project_id}.json
```

### To-Do Operations

#### Get Todoset

First, get the todoset ID from the project's dock:

```bash
GET /basecamp/buckets/{project_id}/todosets/{todoset_id}.json
```

#### List Todolists

```bash
GET /basecamp/buckets/{project_id}/todosets/{todoset_id}/todolists.json
```

**Response:**
```json
[
  {
    "id": 9550474442,
    "title": "Basecamp essentials",
    "description": "",
    "completed": false,
    "completed_ratio": "0/5",
    "url": "https://..."
  }
]
```

#### Create Todolist

```bash
POST /basecamp/buckets/{project_id}/todosets/{todoset_id}/todolists.json
Content-Type: application/json

{
  "name": "New Todo List",
  "description": "List description"
}
```

#### Get Todolist

```bash
GET /basecamp/buckets/{project_id}/todolists/{todolist_id}.json
```

#### List Todos

```bash
GET /basecamp/buckets/{project_id}/todolists/{todolist_id}/todos.json
```

**Response:**
```json
[
  {
    "id": 9550474446,
    "content": "Start here",
    "description": "",
    "completed": false,
    "due_on": null,
    "assignees": []
  }
]
```

#### Create Todo

```bash
POST /basecamp/buckets/{project_id}/todolists/{todolist_id}/todos.json
Content-Type: application/json

{
  "content": "New todo item",
  "description": "Todo description",
  "due_on": "2026-02-15",
  "assignee_ids": [51197030]
}
```

**Response:**
```json
{
  "id": 9555973289,
  "content": "New todo item",
  "completed": false
}
```

#### Update Todo

```bash
PUT /basecamp/buckets/{project_id}/todos/{todo_id}.json
Content-Type: application/json

{
  "content": "Updated todo",
  "description": "Updated description"
}
```

#### Complete Todo

```bash
POST /basecamp/buckets/{project_id}/todos/{todo_id}/completion.json
```

Returns 204 on success.

#### Uncomplete Todo

```bash
DELETE /basecamp/buckets/{project_id}/todos/{todo_id}/completion.json
```

### Message Board Operations

#### Get Message Board

```bash
GET /basecamp/buckets/{project_id}/message_boards/{message_board_id}.json
```

#### List Messages

```bash
GET /basecamp/buckets/{project_id}/message_boards/{message_board_id}/messages.json
```

#### Create Message

```bash
POST /basecamp/buckets/{project_id}/message_boards/{message_board_id}/messages.json
Content-Type: application/json

{
  "subject": "Message Subject",
  "content": "<p>Message body with HTML</p>",
  "category_id": 123
}
```

#### Get Message

```bash
GET /basecamp/buckets/{project_id}/messages/{message_id}.json
```

#### Update Message

```bash
PUT /basecamp/buckets/{project_id}/messages/{message_id}.json
Content-Type: application/json

{
  "subject": "Updated Subject",
  "content": "<p>Updated content</p>"
}
```

### Schedule Operations

#### Get Schedule

```bash
GET /basecamp/buckets/{project_id}/schedules/{schedule_id}.json
```

#### List Schedule Entries

```bash
GET /basecamp/buckets/{project_id}/schedules/{schedule_id}/entries.json
```

#### Create Schedule Entry

```bash
POST /basecamp/buckets/{project_id}/schedules/{schedule_id}/entries.json
Content-Type: application/json

{
  "summary": "Team Meeting",
  "description": "Weekly sync",
  "starts_at": "2026-02-15T14:00:00Z",
  "ends_at": "2026-02-15T15:00:00Z",
  "all_day": false,
  "participant_ids": [51197030]
}
```

#### Update Schedule Entry

```bash
PUT /basecamp/buckets/{project_id}/schedule_entries/{entry_id}.json
Content-Type: application/json

{
  "summary": "Updated Meeting",
  "starts_at": "2026-02-15T15:00:00Z",
  "ends_at": "2026-02-15T16:00:00Z"
}
```

### Vault (Documents & Files) Operations

#### Get Vault

```bash
GET /basecamp/buckets/{project_id}/vaults/{vault_id}.json
```

#### List Documents in Vault

```bash
GET /basecamp/buckets/{project_id}/vaults/{vault_id}/documents.json
```

#### Create Document

```bash
POST /basecamp/buckets/{project_id}/vaults/{vault_id}/documents.json
Content-Type: application/json

{
  "title": "Document Title",
  "content": "<p>Document content with HTML</p>"
}
```

#### List Uploads in Vault

```bash
GET /basecamp/buckets/{project_id}/vaults/{vault_id}/uploads.json
```

### Campfire (Chat) Operations

#### List All Campfires

```bash
GET /basecamp/chats.json
```

#### Get Campfire

```bash
GET /basecamp/buckets/{project_id}/chats/{chat_id}.json
```

#### List Campfire Lines (Messages)

```bash
GET /basecamp/buckets/{project_id}/chats/{chat_id}/lines.json
```

#### Create Campfire Line

```bash
POST /basecamp/buckets/{project_id}/chats/{chat_id}/lines.json
Content-Type: application/json

{
  "content": "Hello from the API!"
}
```

### Comments Operations

#### List Comments on Recording

```bash
GET /basecamp/buckets/{project_id}/recordings/{recording_id}/comments.json
```

#### Create Comment

```bash
POST /basecamp/buckets/{project_id}/recordings/{recording_id}/comments.json
Content-Type: application/json

{
  "content": "<p>Comment text</p>"
}
```

### Recording Status Operations

All content items (todos, messages, documents, etc.) are "recordings" that can be archived or trashed.

#### Trash Recording

```bash
PUT /basecamp/buckets/{project_id}/recordings/{recording_id}/status/trashed.json
```

#### Archive Recording

```bash
PUT /basecamp/buckets/{project_id}/recordings/{recording_id}/status/archived.json
```

#### Unarchive Recording

```bash
PUT /basecamp/buckets/{project_id}/recordings/{recording_id}/status/active.json
```

### Templates Operations

#### List Templates

```bash
GET /basecamp/templates.json
```

#### Create Project from Template

```bash
POST /basecamp/templates/{template_id}/project_constructions.json
Content-Type: application/json

{
  "name": "New Project from Template",
  "description": "Description"
}
```

## Pagination

Basecamp uses Link header pagination with `rel="next"`:

**Response Headers:**
```
Link: <https://3.basecampapi.com/.../page=2>; rel="next"
X-Total-Count: 150
```

Follow the `Link` header URL for the next page. When `next` is absent, you've reached the last page.

**Important:** Do not construct pagination URLs manually. Always use the URL provided in the `Link` header.

## Key Concepts

### Buckets and Projects

A "bucket" is a project's content container. The bucket ID is the same as the project ID in URLs:

```
/buckets/{project_id}/todosets/{todoset_id}.json
```

### Dock

Each project has a "dock" containing available tools. Always check that a tool is `enabled: true` before using it:

```json
{
  "dock": [
    {"name": "todoset", "id": 123, "enabled": true},
    {"name": "message_board", "id": 456, "enabled": false}
  ]
}
```

### Recordings

All content items (todos, messages, documents, comments, etc.) are "recordings" with:
- `status`: "active", "archived", or "trashed"
- `parent`: navigation to container
- Unique IDs that can be used across endpoints

## Code Examples

### JavaScript

```javascript
const response = await fetch(
  'https://gateway.maton.ai/basecamp/projects.json',
  {
    headers: {
      'Authorization': `Bearer ${process.env.MATON_API_KEY}`
    }
  }
);
const projects = await response.json();
```

### Python

```python
import os
import requests

response = requests.get(
    'https://gateway.maton.ai/basecamp/projects.json',
    headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'}
)
projects = response.json()
```

## Notes

- All API paths must end with `.json`
- The gateway automatically injects the account ID
- Uses Basecamp 4 API (bc3-api)
- Timestamps are in ISO 8601 format
- HTML content uses `<div>`, `<p>`, `<strong>`, `<em>`, `<a>`, `<ul>`, `<ol>`, `<li>` tags
- Rate limit: ~50 requests per 10 seconds per IP
- IMPORTANT: When piping curl output to `jq` or other commands, environment variables like `$MATON_API_KEY` may not expand correctly in some shell environments

## Error Handling

| Status | Meaning |
|--------|---------|
| 400 | Missing Basecamp connection or bad request |
| 401 | Invalid or missing Maton API key |
| 404 | Resource not found, deleted, or no access |
| 429 | Rate limited (check Retry-After header) |
| 507 | Account limit reached (e.g., project limit) |
| 5xx | Server error (retry with exponential backoff) |

### Troubleshooting: API Key Issues

1. Check that the `MATON_API_KEY` environment variable is set:

```bash
echo $MATON_API_KEY
```

2. Verify the API key is valid by listing connections:

```bash
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
```

### Troubleshooting: Invalid App Name

1. Ensure your URL path starts with `basecamp`. For example:

- Correct: `https://gateway.maton.ai/basecamp/projects.json`
- Incorrect: `https://gateway.maton.ai/projects.json`

## Resources

- [Basecamp 4 API Documentation](https://github.com/basecamp/bc3-api)
- [Authentication Guide](https://github.com/basecamp/bc3-api/blob/master/sections/authentication.md)
- [API Reference](https://github.com/basecamp/bc3-api#endpoints)
- [Maton Community](https://discord.com/invite/dBfFAcefs2)
- [Maton Support](mailto:support@maton.ai)

Attribution

rondoflowrondoflow
View sourceMore from rondoflow →
SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Related Skills

Caveman

Ultra-compressed communication mode that cuts output tokens while keeping technical accuracy. Levels: lite, full, ultra and the wenyan variants. Use for /caveman, "caveman mode", "talk like caveman", "be brief" or "less tokens".

1074701 votes

Hyperplan

Adversarial multi-agent planning skill. Self-orchestrates 5 hostile category members (unspecified-low, unspecified-high, deep, ultrabrain, artistry) via team-mode for ruthless cross-critique debate, distills only the defensible insights, then MANDATORILY hands the distilled insight bundle to the `plan` agent for executable plan formalization. Use when planning needs maximum rigor and surfacing of weak assumptions, blind spots, and over-engineering. Triggers: 'hyperplan', 'hpp', '/hyperplan', ...

693621 votes

Mcp Code Execution

Routes multi-tool workflows through MCP servers for large datasets and pipelines. Use when Bash tool overhead is limiting throughput on data-heavy tasks.

3351 votes

catchup

Recovers the conversation and failed tool calls of a previous Codex, Claude Code, Antigravity, Cline, Copilot CLI, Cursor, DeepSeek Harness, Kimi, OpenCode, Pi Agent, or ZCode session. Use when the user says "catch up", "what did the last session do", "get me up to speed", "I switched agents", asks to recover/summarize a previous session before continuing, or asks to diagnose or report a catchup failure. Do NOT use for the current conversation, git history, or any non-agent log.

691 votes

math-skill

A comprehensive mathematical reasoning skill for AI assistants — handles arithmetic to research-level problems with rigorous step-by-step reasoning, systematic verification, and transparent uncertainty handling

381 votes
View all in ai-agents →