Authentication
API keys (recommended for integrations)
Section titled “API keys (recommended for integrations)”An API key is a personal access token tied to a member of your account.
- Create one in Settings → Plugins → RolChat API keys. The secret is shown once; afterwards only its first ten characters are visible, and RolChat stores only a SHA-256 hash.
- Format:
rcp_followed by 32 random bytes in base64url, about 45 characters in all. The prefix makes a key recognisable in logs and distinct from a session token. - Scopes: chosen from a fixed catalogue of capabilities when the key is created. A key can never do more than the member who created it: on every call both conditions are checked, the capability is in the key’s scopes and the member still holds it. Narrow the member’s role and the key narrows with it.
- Lifetime: keys do not expire on their own. Revoke a key from the profile page or with
DELETE /api/v1/tokens/:id; revocation takes effect immediately. There is no in-place rotation: revoke and create a new key. - Creation and revocation are written to the audit log.
Send it as a bearer token - there is no separate API-key header:
curl https://api.rolchat.com/api/v1/contacts?limit=20 \ -H "Authorization: Bearer rcp_…" \ -H "X-Account-Id: 7c1d2c6e-…"Requests with a plugin API key are limited to 300 per minute.
JWT sessions
Section titled “JWT sessions”The web app and the mobile SDKs sign in with e-mail and password (or Google or Apple) and receive a token pair.
| Token | Lifetime | Notes |
|---|---|---|
| Access token | 15 minutes | RS256, verified against the JWKS at /.well-known/jwks.json |
| Refresh token | 30 days | Rotated on every refresh; reuse of a rotated token revokes the whole chain |
Claims: sub (user), acc (account), rl (role) and, for per-site roles, sts (allowed sites).
POST /auth/login, /auth/refresh, /auth/swap-company and /auth/logout are the only authenticated-flow endpoints that must not carry the X-Account-Id header described next.
The X-Account-Id header
Section titled “The X-Account-Id header”Every authenticated request except the four above must carry the account it is acting on:
X-Account-Id: <account uuid>The server checks that the header equals the acc claim of the token (or the account of the API key). A missing header is 400 missing_required_header; a mismatch is 403 account_context_mismatch. The header exists so that a client bug or a replayed token can never read another tenant’s data silently: the mismatch is rejected before any query runs, and every log line is attributable to an account without decoding the token.
Multi-company users
Section titled “Multi-company users”One person can belong to several companies. Each company has its own token (its own acc claim). To switch:
POST /api/v1/auth/swap-companyAuthorization: Bearer <current access token>
{ "account_id": "<target uuid>" }The target must be one of the caller’s available_companies (returned at login), otherwise 403 forbidden. The response is a new access and refresh token pair scoped to the target; the old refresh token is revoked and an auth.account.swapped audit event is written.
Multi-factor authentication
Section titled “Multi-factor authentication”TOTP-based MFA can be enrolled per member and required per account. When it is on, POST /auth/login returns a challenge and the session completes with POST /auth/mfa/verify. Backup codes are issued at enrolment.
Sign-in protection
Section titled “Sign-in protection”- Sign-in is limited to 5 attempts per IP per minute.
- Ten failed sign-ins lock the account for 30 minutes; the response carries
code: account_locked. - reCAPTCHA can be enabled per action (sign-up, sign-in, password reset); the public bootstrap configuration is served from
GET /api/v1/captcha.