REST API

Authentication

The authenticated data endpoints use Passport OAuth bearer tokens (the auth:api guard). Send your token on every request:

Authorization: Bearer {token}

The same tokens authenticate both this REST API and the MCP connectors — one token, two surfaces.

Creating a token

Create a personal access token either way — both call the same Action:

  • In the app, on the Developers settings page.
  • Over the API, with POST /api/tokens.

The plaintext token is shown once, at creation time, and is never stored or shown again. Copy it immediately.

curl -X POST https://clickbase.so/api/tokens \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{"name": "Reporting script"}'

Team binding

A token is scoped to a single team. Tenancy is resolved by the LoadTeamFromToken middleware on every authenticated request:

  • Personal access tokens (created on the Developers page or via POST /api/tokens) are pinned to the team they were minted for. That binding is stable — it never follows the creating user's current-team switches. A token created for Team A always acts on Team A.
  • last_used_at is stamped on the token on every authenticated request.
  • Fail-closed on lost membership: the team is resolved through your team memberships. If you no longer belong to the token's team, the request is rejected with 403 Forbidden ("This token is bound to a team you no longer belong to.").

Because the resolved team is written onto the acting user's currentTeam, every endpoint scopes its reads and writes through $team->sites(). A token can never reach another team's data by passing a foreign id or domain.

Failure modes

Condition Status Detail
Missing / invalid token 401 Unauthorized The auth:api guard rejects the request.
Token bound to a team you left 403 Forbidden Membership is re-checked on every request.
Your account has no active team 422 Unprocessable Entity "Your account has no active team. Create a team before using the API."
Site not in your team (foreign or unknown id/domain) 404 Not Found Sites are looked up via $team->sites().

Example

curl https://clickbase.so/api/sites \
  -H "Authorization: Bearer {token}" \
  -H "Accept: application/json"