API keys

A scoped secret that lets an external system call the Carbon API on your behalf, with its own permissions.

An authenticates programmatic requests to Carbon. Each key belongs to one company and has explicit permission scopes independent of its creator. Manage keys under Settings → API Keys.

TIP

Connectors don't need a key

Claude.ai, Claude Desktop, and ChatGPT connect over OAuth. The connection inherits the authorizing user's role and company. Use an API key for clients without browser-based OAuth, including Claude Code, Cursor, VS Code, Codex, headless scripts, and CI. Stdio-only clients connect through mcp-remote. See Authentication for both flows.

Creating a key

The full key is shown exactly once at creation.

Select New API Key, enter a company-unique Name, optionally set Expires At, grant scopes, and save. A blank expiration means the key does not expire. Carbon displays the full key once and then stores only its SHA-256 hash and a five-character preview. Copy the key immediately; if it is lost, delete it and create another. The dialog also provides an MCP connection command.

HEADS UP

The key is a bearer secret

Anyone holding the key can act as it, within its scopes. Store it in a secret manager, never commit it, and rotate (delete and recreate) if it leaks.

Authenticating a request

Send the key as a bearer token; the hosted Data API lives at rest.carbon.ms:

http
GET /salesOrder?select=id,salesOrderId,status
Host: rest.carbon.ms
Authorization: Bearer crbn_your_key_here

API keys require no login or refresh flow. Carbon hashes each submitted key and checks its record, expiration, and rate limit before processing the request.

NOTE

Bearer at the edge, carbon-key underneath

rest.carbon.ms accepts Authorization: Bearer crbn_… and forwards the token internally in the carbon-key header. For direct PostgREST calls on a self-hosted installation, send carbon-key: crbn_… to /rest/v1/<table>. The MCP endpoint accepts the Bearer token in either deployment.

Scopes and rate limit

A key has only its stored module_action scopes, such as sales_view or inventory_create, and can access only its company. A key with no scopes can authenticate but cannot read or write data. Scope changes and deletion take effect immediately. On Carbon Cloud, API access requires the Business plan; Starter-plan requests return 403 regardless of scope. See Licensing.

New keys allow 20 requests per minute. Existing keys retain the rate limit shown in the Rate Limit column. All keys for a company share a separate limit of 60 requests per minute. Neither limit can be changed in Carbon. If an integration needs more, contact Carbon support: both limits can be raised for one company. A rejected request returns 429 with Retry-After and X-RateLimit-* headers; retry after the specified interval.

What the key unlocks

Use the Carbon API by default. It validates input, updates derived data, and enforces permissions through Carbon's service layer. Each operation accepts the same arguments over HTTP at POST /api/v1/{module}/{operation} and through MCP. Operations are classified as READ, WRITE, or DESTRUCTIVE so clients can gate them by risk. The reference includes examples and an OpenAPI specification for generating client SDKs.

The Data API provides direct REST access to tables and views under the app's row-level security policies.

HEADS UP

The Data API is outside the service layer

Data API writes bypass the service layer and do not recalculate derived values such as totals, statuses, or ledger entries. Use direct writes only when the Carbon API does not expose the required operation and you understand all affected data.

Keys versus webhooks

An API key authorizes requests to Carbon. A webhook notifies your service when a subscribed record changes. They are independent: a webhook is signed with its own signing secret, never with an API key. A typical integration uses the webhook as a change notification, then fetches the current record with an API key.