Browse documentation

Introduction

Authentication

Carebit uses OAuth2. Every developer project owns one or more API credentials (client_id + client_secret pairs), and every access token is scoped to a single credential.

Credential prefixes

Carebit prefixes every secret so leaked values can be detected and classified. Customer credentials use these prefixes:

Kind Prefix
Client secret carebit_cs_live_...
Access token carebit_at_live_...
Refresh token carebit_rt_live_...
Webhook signing secret carebit_whsec_live_...

client_id is the OAuth application UID. Do not depend on any specific prefix for client_id.

Never commit these values. Rotate a credential immediately if you suspect it has leaked.

Client-credentials grant

The token endpoint is POST /oauth/token. It accepts application/x-www-form-urlencoded per the OAuth2 spec.

Code example

curl -X POST "https://api.carebit.co/oauth/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "grant_type=client_credentials" \
  --data-urlencode "client_id=$CAREBIT_CLIENT_ID" \
  --data-urlencode "client_secret=$CAREBIT_CLIENT_SECRET" \
  --data-urlencode "scope=bookings.read bookings.create"

Response:

{
  "access_token": "carebit_at_live_...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "created_at": 1767193200,
  "refresh_token": "carebit_rt_live_...",
  "scope": "bookings.read bookings.create"
}

Refreshing tokens

Refresh tokens rotate on every use. Store the new refresh_token from each response and discard the old one.

Code example

curl -X POST "https://api.carebit.co/oauth/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "grant_type=refresh_token" \
  --data-urlencode "client_id=$CAREBIT_CLIENT_ID" \
  --data-urlencode "client_secret=$CAREBIT_CLIENT_SECRET" \
  --data-urlencode "refresh_token=$CAREBIT_REFRESH_TOKEN"

Revoking a token

POST /oauth/revoke immediately invalidates an access or refresh token.

Code example

curl -X POST "https://api.carebit.co/oauth/revoke" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "client_id=$CAREBIT_CLIENT_ID" \
  --data-urlencode "client_secret=$CAREBIT_CLIENT_SECRET" \
  --data-urlencode "token=$CAREBIT_ACCESS_TOKEN" \
  --data-urlencode "token_type_hint=access_token"

Scopes

Scopes are granular: resource.read, resource.create, resource.update, resource.delete. The developer project owns the maximum scope set. Credentials do not store their own scopes.

When you request scope on POST /oauth/token with grant_type=client_credentials, every requested scope must already be on the project. The issued token receives exactly the scopes you requested. If you omit scope, the token receives the project's full scope set. Requesting a scope the project does not have returns 400 with error.code invalid_scope.

Refresh grants ignore scope. The new access token keeps the scopes from the original grant, and those scopes must still be on the project.

Removing a scope from the project takes effect on the next API request, including for tokens that were already issued.

Sending an access token

Send the access token as an Authorization: Bearer header on every API request. Do not send the client credentials on regular API requests.

Code example

curl "https://api.carebit.co/v1/bookings?start_time_from=2026-08-01T00:00:00Z&start_time_to=2026-08-08T00:00:00Z" \
  -H "Authorization: Bearer $CAREBIT_ACCESS_TOKEN"

Prefer plain text? Append ?format=md or send Accept: text/markdown to receive this page as raw Markdown.