Stitchflow
Basecamp logo

Basecamp User Management API Guide

API workflow

How to automate user lifecycle operations through APIs with caveats that matter in production.

UpdatedMar 4, 2026

Summary and recommendation

Basecamp 3 exposes a REST API authenticated via OAuth 2.0, with no named scopes - the token inherits all permissions of the authenticated user. The `account_id` required for every endpoint must be retrieved from `https://launchpad.37signals.com/authorization.json` post-OAuth; it is not available from the token response directly.

All user list endpoints paginate at a fixed page size of 15 records using RFC 5988 Link headers (`rel='next'`, `rel='prev'`). There is no `page` query parameter. Rate limiting is enforced at 50 requests per 10-second window per access token; HTTP 429 responses include a `Retry-After` header.

A descriptive `User-Agent` header is required on every request or calls may be blocked.

For teams operating an MCP server with ~100 deep IT/identity integrations, Basecamp's REST API covers read and write operations on people and project membership, but lacks bulk operations and user lifecycle webhooks - SCIM is the preferred path for provisioning workflows at scale.

API quick reference

Has user APIYes
Auth methodOAuth 2.0
Base URLOfficial docs
SCIM availableYes
SCIM plan requiredBusiness (Pro Unlimited, $299/month flat rate) with SSO enabled

Authentication

Auth method: OAuth 2.0

Setup steps

  1. Register your application at https://launchpad.37signals.com/integrations to obtain a client_id and client_secret.
  2. Redirect users to https://launchpad.37signals.com/authorization/new?type=web_server&client_id={client_id}&redirect_uri={redirect_uri} to obtain an authorization code.
  3. Exchange the authorization code for an access token via POST to https://launchpad.37signals.com/authorization/token?type=web_server&client_id={client_id}&redirect_uri={redirect_uri}&client_secret={client_secret}&code={code}.
  4. Use the returned access_token as a Bearer token in the Authorization header for all API requests.
  5. Include a descriptive User-Agent header identifying your application and contact email as required by Basecamp.

Required scopes

Scope Description Required for
N/A Basecamp 3 OAuth 2.0 does not use named scopes; access is granted to all resources the authenticated user can access. All API operations

User object / data model

Field Type Description On create On update Notes
id integer Unique person identifier system-assigned immutable
attachable_sgid string Signed global ID for use in rich text system-assigned immutable
name string Full name of the person required optional
email_address string Primary email address required optional Must be unique within the account
personable_type string Type of person (User or Client) system-assigned immutable
title string Job title optional optional
bio string Short biography optional optional
location string Location string optional optional
created_at datetime ISO 8601 timestamp of account creation system-assigned immutable
updated_at datetime ISO 8601 timestamp of last update system-assigned system-assigned
admin boolean Whether the person is an account admin optional optional
owner boolean Whether the person is the account owner system-assigned immutable
client boolean Whether the person is a client user optional optional
employee boolean Whether the person is an employee optional optional
time_zone string IANA time zone name optional optional
avatar_url string URL to the person's avatar image system-assigned immutable via API
company object Associated company object with id and name optional optional
can_manage_projects boolean Permission to manage projects optional optional
can_manage_people boolean Permission to manage people optional optional

Core endpoints

List all people on account

  • Method: GET
  • URL: https://3.basecampapi.com/{account_id}/people.json
  • Watch out for: Returns only active (non-trashed) people. Paginated at 15 per page via Link headers.

Request example

GET /people.json
Authorization: Bearer {token}
User-Agent: MyApp (contact@example.com)

Response example

[{"id":1234,"name":"Jane Doe","email_address":"jane@example.com","admin":true,"created_at":"2023-01-10T12:00:00.000Z"}]

Get a single person

  • Method: GET
  • URL: https://3.basecampapi.com/{account_id}/people/{person_id}.json
  • Watch out for: Returns 404 if the person is trashed or does not belong to the account.

Request example

GET /people/1234.json
Authorization: Bearer {token}

Response example

{"id":1234,"name":"Jane Doe","email_address":"jane@example.com","admin":true,"title":"Engineer"}

Get the authenticated person (me)

  • Method: GET
  • URL: https://3.basecampapi.com/{account_id}/my/profile.json
  • Watch out for: Returns the profile of the token owner only.

Request example

GET /my/profile.json
Authorization: Bearer {token}

Response example

{"id":5678,"name":"John Smith","email_address":"john@example.com","admin":false}

List people on a project

  • Method: GET
  • URL: https://3.basecampapi.com/{account_id}/projects/{project_id}/people.json
  • Watch out for: Only returns people currently active on the specified project.

Request example

GET /projects/9999/people.json
Authorization: Bearer {token}

Response example

[{"id":1234,"name":"Jane Doe","email_address":"jane@example.com"}]

Update project membership (grant/revoke access)

  • Method: PUT
  • URL: https://3.basecampapi.com/{account_id}/projects/{project_id}/people/users.json
  • Watch out for: This endpoint manages project-level access, not account-level user creation. Users must already exist on the account.

Request example

PUT /projects/9999/people/users.json
Content-Type: application/json
{"grant":[1234],"revoke":[5678]}

Response example

{"granted":[{"id":1234,"name":"Jane Doe"}],"revoked":[{"id":5678,"name":"John Smith"}]}

Invite people to account (create users)

  • Method: POST
  • URL: https://3.basecampapi.com/{account_id}/people/users.json
  • Watch out for: Sends an invitation email. The user is not active until they accept. Admin privileges required to call this endpoint.

Request example

POST /people/users.json
Content-Type: application/json
{"name":"New User","email_address":"new@example.com","title":"Designer"}

Response example

{"id":9012,"name":"New User","email_address":"new@example.com","created_at":"2024-01-01T00:00:00.000Z"}

Update a person

  • Method: PUT
  • URL: https://3.basecampapi.com/{account_id}/people/{person_id}.json
  • Watch out for: Only account admins can update other users. Limited fields are updatable via the REST API; SCIM is preferred for provisioning workflows.

Request example

PUT /people/1234.json
Content-Type: application/json
{"title":"Senior Engineer","admin":true}

Response example

{"id":1234,"name":"Jane Doe","title":"Senior Engineer","admin":true}

Trash (deactivate) a person

  • Method: DELETE
  • URL: https://3.basecampapi.com/{account_id}/people/{person_id}.json
  • Watch out for: This trashes (soft-deletes) the user, removing their access. It does not permanently delete the account. Requires admin privileges.

Request example

DELETE /people/1234.json
Authorization: Bearer {token}

Response example

HTTP 204 No Content

Rate limits, pagination, and events

  • Rate limits: Basecamp enforces a rate limit of 50 requests per 10-second window per access token. Exceeding this returns HTTP 429.
  • Rate-limit headers: Yes
  • Retry-After header: Yes
  • Rate-limit notes: When rate limited, Basecamp returns HTTP 429 with a Retry-After header indicating seconds to wait. The API also returns X-RateLimit-Limit and X-RateLimit-Remaining headers.
  • Pagination method: token
  • Default page size: 15
  • Max page size: 15
  • Pagination pointer: Link header (next/prev rel links); page param not directly exposed
Plan Limit Concurrent
All plans 50 requests per 10 seconds 0
  • Webhooks available: Yes
  • Webhook notes: Basecamp 3 supports webhooks that can be configured per project. They fire on events related to project resources. There is no dedicated user/people lifecycle webhook (e.g., user created/deactivated).
  • Alternative event strategy: Poll GET /people.json periodically to detect user changes, or use SCIM for provisioning lifecycle events via your IdP.
  • Webhook events: create (messages, todos, comments, etc.), update (messages, todos, etc.), trash (resource trashed), restore (resource restored), archive (project archived)

SCIM API status

  • SCIM available: Yes

  • SCIM version: 2.0

  • Plan required: Business (Pro Unlimited, $299/month flat rate) with SSO enabled

  • Endpoint: https://3.basecampapi.com/scim/v2/{account_id}

  • Supported operations: GET /Users (list users), GET /Users/{id} (get user), POST /Users (create/provision user), PUT /Users/{id} (replace user), PATCH /Users/{id} (update user attributes), DELETE /Users/{id} (deprovision user)

Limitations:

  • Requires SSO (SAML) to be configured and active before SCIM can be enabled.
  • Only available on the Business/Pro Unlimited plan ($299/month).
  • Group (team) provisioning via SCIM is not documented as supported; only user provisioning.
  • Supported IdPs include Okta and Microsoft Entra ID (Azure AD); Google Workspace and OneLogin are not officially supported.
  • SCIM token is generated within Basecamp account settings and must be stored securely.

Common scenarios

Three primary integration scenarios are supported by the API:

Provision a new employee: POST to /people/users.json to send an invitation, then poll GET /people.json until the user appears as active (invitation acceptance is required before project assignment). Then PUT to /projects/{project_id}/people/users.json with {"grant": [new_user_id]}. SCIM + IdP is the zero-touch alternative for Business plan accounts.

Deprovision a departing employee: GET /people.json to resolve the user's id by email_address, then DELETE /people/{person_id}.json to soft-trash the user. This retains all historical data. For Business plan customers, SCIM-triggered DELETE from the IdP is the recommended path and eliminates the polling step.

Sync all account users to an external directory: Paginate GET /people.json following Link: rel='next' headers until exhausted. Map id, name, email_address, admin, and created_at fields to your directory schema. A 500-person account requires approximately 34 sequential requests; implement Retry-After handling for HTTP 429 responses throughout.

Provision a new employee and add them to a project

  1. Authenticate via OAuth 2.0 and obtain access_token and account_id from https://launchpad.37signals.com/authorization.json.
  2. POST to /people/users.json with name and email_address to invite the user to the account.
  3. Wait for the user to accept the invitation (poll GET /people.json and check for the new user's presence and active status).
  4. PUT to /projects/{project_id}/people/users.json with {"grant": [new_user_id]} to add them to the relevant project.

Watch out for: The user must accept the email invitation before they appear as active and can be granted project access. Automate with SCIM + IdP for zero-touch provisioning.

Deprovision a departing employee

  1. Authenticate via OAuth 2.0.
  2. GET /people.json to find the user's id by email_address.
  3. DELETE /people/{person_id}.json to trash (deactivate) the user, revoking all account and project access.
  4. If using SCIM: send a DELETE /scim/v2/{account_id}/Users/{scim_user_id} from your IdP to automate this step.

Watch out for: DELETE via REST API is a soft trash; the user's data is retained. SCIM-based deprovisioning triggered by IdP offboarding is the recommended approach for Business plan customers.

Sync all account users to an external directory

  1. Authenticate via OAuth 2.0.
  2. GET /people.json and follow Link header pagination (rel='next') until all pages are retrieved.
  3. Map each person object (id, name, email_address, admin, created_at) to your directory schema.
  4. Store the Basecamp id for future update/delete operations.

Watch out for: Page size is fixed at 15; a 500-person account requires ~34 sequential requests. Respect the 50 req/10s rate limit and implement Retry-After handling for HTTP 429 responses.

Why building this yourself is a trap

The REST API does not support bulk user operations natively - every invite, update, or removal is a single synchronous call, and invitation-based provisioning introduces an asynchronous gap (user is inactive until they accept the email). There is no user lifecycle webhook; detecting new or removed users requires polling GET /people.json on a schedule.

SCIM 2.0 is available at https://3.basecampapi.com/scim/v2/{account_id} and supports full user provisioning lifecycle (GET, POST, PUT, PATCH, DELETE on /Users), but it is gated behind both the Pro Unlimited plan ($299/month) and an active SAML SSO configuration. SCIM cannot be enabled without SSO already in place.

Group provisioning via SCIM is not documented as supported - only user-level provisioning. Supported IdPs are limited to Okta and Microsoft Entra ID (Azure AD); Google Workspace and OneLogin have no official SCIM support path.

Automate Basecamp workflows without one-off scripts

Stitchflow builds and maintains end-to-end IT automation across your SaaS stack, including apps without APIs. Built for exactly how your company works, with human approvals where they matter.

Every app coverage, including apps without APIs
60+ app integrations plus browser automation for apps without APIs
IT graph reconciliation across apps and your IdP
Less than a week to launch, maintained as APIs and admin consoles change
SOC 2 Type II. ~2 hours of your team's time

UpdatedMar 4, 2026

* Details sourced from official product documentation and admin references.

Keep exploring

Related apps

15Five logo

15Five

Full API + SCIM
AutomationAPI + SCIM
Last updatedFeb 2026

15Five uses a fixed role-based permission model with six predefined roles: Account Admin, HR Admin, Billing Admin, Group Admin, Manager, and Employee. No custom roles can be constructed. User management lives at Settings gear → People → Manage people p

1Password logo

1Password

Full API + SCIM
AutomationAPI + SCIM
Last updatedFeb 2026

1Password's admin console at my.1password.com covers the full user lifecycle — invitations, group assignments, vault access, suspension, and deletion — without any third-party tooling. Like every app that mixes role-based and resource-level permissions

8x8 logo

8x8

Full API + SCIM
AutomationAPI + SCIM
Last updatedFeb 2026

8x8 Admin Console supports full lifecycle user management — create, deactivate, and delete — across its X Series unified communications platform. Every app a user can access (8x8 Work desktop, mobile, web, Agent Workspace) is gated by license assignmen