General

SDKs

You can call the Capacities API with any HTTP client. We also ship official SDKs that handle authentication headers, request validation, and typed responses.

TypeScript

The TypeScript SDK is published on npm as @capacities/api.

npm install @capacities/api

The client sets Authorization and X-Capacities-Api-Version on every request. Failed responses throw CapacitiesApiError with code, status, and message — see Errors.

Authentication

The SDK supports two authentication methods. Both send a standard Authorization: Bearer <token> header.

API token

The simplest option. Generate a token in Settings > Capacities API and pass it directly. Tokens do not expire.

import { CapacitiesClient } from '@capacities/api'

const client = new CapacitiesClient({
  apiToken: process.env.CAPACITIES_API_TOKEN!,
})

Use this for scripts and server-side automations where a single user's credentials are acceptable. See Personal API token for how to generate one.

OAuth 2.0

Use this when your product acts on behalf of end users. The SDK manages token refresh automatically. See OAuth 2.0 for the full flow and how to get a client_id.

What you receive after the OAuth flow

After a user completes the Authorization Code + PKCE flow, your server receives:

{
  "access_token": "eyJ...",
  "refresh_token": "abc...",
  "expires_in": 3600,
  "token_type": "Bearer"
}

Convert this into the OAuthTokens shape expected by the SDK:

import type { OAuthTokens } from '@capacities/api'

const tokens: OAuthTokens = {
  accessToken: data.access_token,
  refreshToken: data.refresh_token,
  // Store expiresAt so the SDK can refresh proactively before the token expires.
  expiresAt: Math.floor(Date.now() / 1000) + data.expires_in,
}

Initialising the client

import { CapacitiesClient } from '@capacities/api'

const client = new CapacitiesClient({
  oauth: {
    tokens,
    clientId: 'your_client_id',
    onTokenRefreshed: async (newTokens) => {
      // Both fields can change on every refresh. Persist the full set.
      await db.oauthTokens.upsert({ userId, ...newTokens })
    },
  },
})

How refresh works

TriggerBehaviour
Proactive (expiresAt within 60 s)SDK refreshes before sending the next request
Reactive (server returns 401)SDK refreshes and retries the request once
Concurrent requestsA single refresh call is shared; all waiting requests use the new token

Refresh tokens rotate on every use: the server returns a new refresh_token each time. The onTokenRefreshed callback receives the complete replacement OAuthTokens set. Persist both accessToken and refreshToken.

Error handling

import { CapacitiesOAuthError, CapacitiesApiError } from '@capacities/api'

try {
  const space = await client.space.get()
} catch (err) {
  if (err instanceof CapacitiesOAuthError) {
    // Refresh token expired or revoked. Re-initiate the OAuth flow.
    redirectToOAuthLogin()
  } else if (err instanceof CapacitiesApiError) {
    // API-level error (4xx / 5xx). Inspect err.status, err.code, err.message.
    console.error(err.code, err.message)
  }
}

CapacitiesOAuthError is thrown when the refresh request itself fails (network error, expired refresh token, revoked connection). Treat it as a signal to start a new authorisation flow.

Restoring tokens between sessions

Store the full OAuthTokens object in your database. On each new process or request, restore it:

const stored = await db.oauthTokens.findByUserId(userId)

const client = new CapacitiesClient({
  oauth: {
    tokens: stored,
    clientId: 'your_client_id',
    onTokenRefreshed: async (newTokens) => {
      await db.oauthTokens.update({ userId, ...newTokens })
    },
  },
})

Examples

Request examples for every endpoint live in the API Reference.

Open any operation in the reference UI and switch to the TypeScript SDK code sample. Samples use CapacitiesClient method names that mirror the REST paths (for example capacities.object.get, capacities.blocks.append).

Other languages

Only the TypeScript SDK is available today. For other stacks, use the reference's examples. You can also request a client library for your language of choice on our feedback board.

Are you missing something in the documentation?

Create a ticket on our feedback board. - Let us know if you have an idea for a feature, improvement or think there is something missing.

Request additions to the documentation. - If your questions are not getting answered, let us know and we will extend the documentation.