Authentication

Automation gets its own name. It does not borrow a person’s.

An API user is a principal in the organisation, with a client id, a secret shown once, and scopes you choose. You exchange those for a short-lived access token. A human session cannot be turned into that token. If you need a person in the loop, they use the portal.

Three doors. Do not mix the keys.

People

They sign in on the organisation host (or the shared portal, if Personal). Cookie session. They cannot mint a partner token from that session.

API users

This page. Client id, secret once, scopes, short-lived Bearer. Same authorisation as a careful person — not a back door around policy.

Channel

Creates an organisation and stops there. A channel token is refused on files, shares and audit. Selling Casewelt →

POST Mint an access token

/v1/oauth/token

client_credentials

JSON or form body. Only the client-credentials grant. The secret never appears again after create; rotate if it leaks. Typical lifetime: one hour.

POST /v1/oauth/token
Content-Type: application/json

{
  "grant_type": "client_credentials",
  "client_id": "cwpa_…",
  "client_secret": "cws_…"
}
{
  "access_token": "…",
  "token_type": "Bearer",
  "expires_in": 3600,
  "issued_token_type": "api_user"
}
curl -sS https://{org-host}/v1/oauth/token \
  -H 'Content-Type: application/json' \
  -d '{"grant_type":"client_credentials","client_id":"cwpa_…","client_secret":"cws_…"}'

GET See who you are

/v1/session/me

Always allowed for a valid token. Use it as a health check and to read organisation id, slug and scopes before you write anything.

GET /v1/session/me
Authorization: Bearer …

The body names the organisation, the slug, and the scopes this API user was minted with. If those are wrong, stop before you write.

POST Create the API user (once)

/v1/organisations/applications

organisation

Usually done from the organisation console by an administrator. The secret is in the create response only. List and get never return it.

{
  "name": "invoicing-bot",
  "scopes": ["files", "shares"],
  "ui_allowed": false,
  "allowed_cidrs": ["203.0.113.0/24"]
}

ui_allowed is for a browser console session. REST does not need it. You may restrict the client to address ranges. Origins matter when you embed Casewelt in another site. Omit scopes and Casewelt defaults to files, shares, signatures and office.

Headers you should send

Authorization: Bearer {access_token}
Content-Type: application/json
X-Request-Id: {uuid}
Idempotency-Key: {uuid}              # on creates you might retry
X-Casewelt-Organisation-Id: {uuid}   # if you are not already on the tenant host

What you will see when it is not you

CodeMeaning
invalid_clientId or secret is wrong, or the client was disabled.
human_api_forbiddenA person tried to mint or use a partner token as if they were automation.
api_ip_deniedThe call came from outside the address range you set.
denySigned in, still not allowed to do this to this object.

Machine certificates are a different door, for devices. They are not this token. Channel credentials that create organisations are a third door. Do not mix them.