Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions sections/authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,64 @@ curl -H "Authorization: Bearer $ACCESS_TOKEN" \
**Note on authenticating users via OAuth**: We don't recommend using the OAuth API to authenticate users in third-party services (e.g. a "Login with Basecamp" button). We don't verify email addresses, so an attacker could gain access using email addresses they don't own.


Get authorization from Basecamp
-------------------------------
Comment on lines +133 to +134

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Add the Basecamp authorization endpoint to the contents list

When readers use the endpoint list at the top of this section for discovery or anchor navigation, the newly added endpoint is missing, so they cannot see or jump to #get-authorization-from-basecamp from that list. Add a matching bullet alongside the existing authorization link, as required by the section-file structure.

AGENTS.md reference: AGENTS.md:L38-L42

Useful? React with 👍 / 👎.


* `GET https://3.basecampapi.com/authorization.json` will return the authorization details for a token, served by Basecamp itself.

Basecamp serves its own authorization document at the API root — no account
prefix — for any token it accepts: a Basecamp-issued OAuth token or personal
access token, or a legacy Launchpad-issued token. It mirrors Launchpad's
Comment on lines +139 to +140

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reconcile personal tokens with the OAuth-only guidance

For users choosing an authentication method, this newly documented support for personal access tokens directly conflicts with both this guide's opening statement that all requests use OAuth 2 and README.md's authentication section saying OAuth 2 is mandatory. Update the overview and main guide to describe when personal access tokens are supported; otherwise readers receive mutually exclusive instructions about a token type this endpoint explicitly accepts.

Useful? React with 👍 / 👎.

document above, with a few deliberate differences:

- `identity` carries only `id`. The name and email fields are omitted: they
were never suitable for identifying users within Basecamp (see the note on
the Launchpad document above) — use the [Get person][people] endpoints.
Comment on lines +143 to +145

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Direct users to the current-user profile endpoint

When a client needs the authenticated user's name or email omitted from this document, the linked Get person endpoint requires a Basecamp person ID, while this paragraph explicitly says the returned identity ID is not suitable for identifying that person. Following the link therefore leaves the client without a usable ID and may lead it to request the wrong profile; point readers to GET /my/profile.json (Get my personal info), which resolves the current user without an ID.

Useful? React with 👍 / 👎.

- Each account carries a `resource` indicator (`urn:bc:account:<id>`,
RFC 8707) instead of Launchpad's `product` and `app_href`. Pass it as the
`resource` parameter when requesting a token scoped to that account. A
client that reads both documents must treat `product` and `app_href` as
optional and select accounts by `href` or `resource`.
- `scope` is present for every Basecamp-issued token — OAuth and personal
access tokens alike. Legacy Launchpad-issued tokens predate scopes, so a
missing `scope` is not an error.
- `expires_at` is an ISO 8601 timestamp, as on Launchpad.

###### Example JSON Response
<!-- START GET https://3.basecampapi.com/authorization.json -->
```json
{
"identity": {
"id": 9999999
},
"accounts": [
{
"id": 99999999,
"name": "Honcho Design",
"href": "https://3.basecampapi.com/99999999",
"resource": "urn:bc:account:99999999"
}
],
"scope": "full",
"expires_at": "2026-02-16T12:00:00.000Z"
}
```
<!-- END GET https://3.basecampapi.com/authorization.json -->

###### Copy as cURL

```shell
curl -H "Authorization: Bearer $ACCESS_TOKEN" \
-A 'MyApp (yourname@example.com)' \
https://3.basecampapi.com/authorization.json
```

This example presents a bearer token. A DPoP-bound token authenticates here
the same way it does at every other endpoint: `Authorization: DPoP <token>`
plus its `DPoP` proof header — the `Bearer` scheme is rejected for bound
tokens (RFC 9449 §7.1).


Refreshing access tokens
-------------------------

Expand Down