# Basecamp

Basecamp is a project management and team collaboration platform by 37signals. The Sling Basecamp connector extracts data from the Basecamp 4 API, supporting projects, people, todos, messages, comments, documents, schedule entries, and kanban cards.

{% hint style="success" %}
**CLI Pro Required**: APIs require a [CLI Pro token](https://docs.slingdata.io/sling-cli/cli-pro) or [Platform Plan](https://docs.slingdata.io/sling-platform/platform).
{% endhint %}

## Setup

The following credentials and inputs are accepted:

**Secrets:**

* `client_id` **(required)** -> Your Basecamp OAuth2 client ID
* `client_secret` **(required)** -> Your Basecamp OAuth2 client secret
* `access_token` **(required)** -> Your OAuth2 access token (obtained via authorization flow)
* `refresh_token` **(required)** -> Your OAuth2 refresh token

**Inputs:**

* `account_id` **(required)** -> Your Basecamp account ID (numeric, found in your Basecamp URL)
* `anchor_date` (optional) -> The starting date for historical data extraction (default: 1 year ago). Format: `YYYY-MM-DDTHH:MM:SSZ`

### Getting Your OAuth2 Credentials

1. Go to [37signals Launchpad Integrations](https://launchpad.37signals.com/integrations)
2. Click "Register another application"
3. Fill in your application details:
   * **Name**: Your integration name (e.g., "Sling Integration")
   * **Company**: Your company name
   * **Website URL**: Your website
   * **Redirect URI**: `http://localhost:8080/callback`
4. After creating the app, note the **Client ID** and **Client Secret**
5. Use `sling conns set` with the client credentials — Sling will handle the OAuth2 authorization flow automatically to obtain access and refresh tokens

### Using `sling conns`

Here are examples of setting a connection named `BASECAMP`. We must provide the `type=api` property:

{% code overflow="wrap" %}

```bash
sling conns set BASECAMP type=api spec=basecamp \
  secrets='{ client_id: your_client_id, client_secret: your_client_secret }' \
  inputs='{ account_id: "1234567" }'
```

{% endcode %}

After setting the connection, test it to trigger the OAuth2 authorization flow:

```bash
sling conns test BASECAMP
```

This will open a browser window for you to authorize the application. The access and refresh tokens will be saved automatically.

### Environment Variable

See [here](https://docs.slingdata.io/sling-cli/environment#dot-env-file-.env.sling) to learn more about the `.env.sling` file.

{% code overflow="wrap" %}

```bash
export BASECAMP='{ type: api, spec: basecamp, secrets: { client_id: "your_client_id", client_secret: "your_client_secret", access_token: "your_access_token", refresh_token: "your_refresh_token" }, inputs: { account_id: "1234567" } }'
```

{% endcode %}

### Sling Env File YAML

See [here](https://docs.slingdata.io/sling-cli/environment#sling-env-file-env.yaml) to learn more about the sling `env.yaml` file.

```yaml
connections:
  BASECAMP:
    type: api
    spec: basecamp
    secrets:
      client_id: "your_client_id"
      client_secret: "your_client_secret"
      access_token: "your_access_token"
      refresh_token: "your_refresh_token"
    inputs:
      account_id: "1234567"
```

**With anchor date for historical data:**

```yaml
connections:
  BASECAMP:
    type: api
    spec: basecamp
    secrets:
      client_id: "your_client_id"
      client_secret: "your_client_secret"
      access_token: "your_access_token"
      refresh_token: "your_refresh_token"
    inputs:
      account_id: "1234567"
      anchor_date: "2023-01-01T00:00:00Z"
```

## Replication

Here's an example replication configuration to sync Basecamp data to a PostgreSQL database:

```yaml
source: BASECAMP
target: MY_POSTGRES

defaults:
  mode: incremental
  object: basecamp.{stream_name}

streams:
  # sync all endpoints
  '*':

  # Full refresh for core reference data
  projects:
    mode: full-refresh
  people:
    mode: full-refresh
```

**Full refresh example:**

```yaml
source: BASECAMP
target: MY_POSTGRES

defaults:
  mode: full-refresh
  object: basecamp.{stream_name}

streams:
  projects:
  people:
  todos:
  todolists:
  messages:
  comments:
  documents:
  schedule_entries:
  kanban_cards:
  vaults:
```

## Endpoints

| Endpoint           | Description                                       | Incremental |
| ------------------ | ------------------------------------------------- | ----------- |
| `projects`         | All projects in the account                       | No          |
| `people`           | All people visible to the authenticated user      | No          |
| `todos`            | All to-do items across all projects               | Yes         |
| `todolists`        | All to-do lists across all projects               | Yes         |
| `messages`         | All messages across all projects                  | Yes         |
| `comments`         | All comments across all projects                  | Yes         |
| `documents`        | All documents across all projects                 | Yes         |
| `uploads`          | All file uploads across all projects              | Yes         |
| `schedule_entries` | All schedule entries across all projects          | Yes         |
| `question_answers` | All check-in question answers across all projects | Yes         |
| `kanban_cards`     | All kanban board cards across all projects        | Yes         |
| `vaults`           | All vaults (folders) across all projects          | Yes         |

To discover available endpoints:

```bash
sling conns discover BASECAMP
```

## Rate Limiting

The Basecamp API has the following rate limits:

* **50 requests per 10 seconds** per access token
* Responses include `429 Too Many Requests` when exceeded

The connector automatically:

* Uses conservative rate limiting (4 requests/second)
* Retries with exponential backoff on 429 responses (up to 5 attempts)
* Retries on 500+ server errors (up to 3 attempts)

## Common Use Cases

### Sync Project Management Data

```yaml
source: BASECAMP
target: MY_POSTGRES

defaults:
  mode: incremental
  object: basecamp.{stream_name}

streams:
  projects:
    mode: full-refresh
  todos:
  todolists:
  messages:
  comments:
```

### Sync Kanban and Schedule Data

```yaml
source: BASECAMP
target: MY_POSTGRES

defaults:
  mode: incremental
  object: basecamp.{stream_name}

streams:
  kanban_cards:
  schedule_entries:
```

If you are facing issues connecting, please reach out to us at <support@slingdata.io>, on [discord](https://discord.gg/q5xtaSNDvp) or open a Github Issue [here](https://github.com/slingdata-io/sling-cli/issues).
