Skip to content
AISARAISAR

Authentication

Bearer tokens and how to manage them, roles and permissions, session mode, email/password login (per-user tokens), and rate limiting.

The AISAR API uses Bearer tokens backed by Laravel Sanctum personal access tokens. Every token belongs to its own service account, and each service account is bound to a single company — every request made with the token runs in that company's context.

Session authentication (cabinet)

Besides Bearer tokens, the private /v1 routes also accept Laravel Sanctum session authentication — used by the web cabinet (SPA) via cookies. It is not meant for server-to-server integrations: use API tokens (described below) instead.

The session login is a four-step flow:

  1. The frontend requests a CSRF cookie: GET /sanctum/csrf-cookie.
  2. Login: POST /v1/auth/login with email and password.
  3. The server issues a session cookie.
  4. Every subsequent request carries that cookie together with the CSRF token in a header.

Email/password login (per-user token)

The standard way to mint a token is service-account API tokens (below): one token per integration. When you instead need a separate token per end user — for example a mobile or partner app where each employee signs in with their own email and password — use POST /v1/auth/mobile/login. It is the only public endpoint that exchanges a user's credentials for a Bearer token.

POST /v1/auth/login (the session login above) creates a session cookie and does not return a Bearer token. To obtain a token from an email/password, call POST /v1/auth/mobile/login.

Request body:

FieldDescription
emailRequired. The user's email.
passwordRequired. The user's password.
device_nameRequired (up to 100 chars). A device label — it becomes the token name mobile:{device_name}.
Response (email verified)
{
  "data": {
    "message": "Logged in.",
    "email_verified": true,
    "token": "456|aisar_xxx_EXAMPLE"
  }
}
  • The token name is mobile:{device_name}. Logging in again with the same device_name revokes the previous same-named token, so each device holds exactly one live token.
  • The token gets full access within the user's role (Sanctum abilities ["*", "broadcasting:connect"]); the broadcasting:connect ability is what lets it authorize realtime WebSocket subscriptions.
  • Unlike service-account API tokens (which never expire), this token has a sliding expiry (90 days by default) that is extended on active use.

If the user's email is not yet verified, the token is still returned, but with email_verified: false. Finish verification by calling POST /v1/auth/email/verify-code with that Bearer token and the 6-digit code emailed to the user (resend the code via POST /v1/auth/email/resend-code):

POST /v1/auth/email/verify-code
{
  "code": "123456"
}

Errors: 422 with an email error — invalid credentials, an attempt to sign in with an API service account, or the account has no access to the AISAR app. 429 — the login throttle tripped: at most 5 attempts per 15 minutes per email + IP pair.

Send the token in the Authorization header on every request:

text
Authorization: Bearer 123|xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

The token format is {id}|{plaintext} (Sanctum's standard format). Send it in full, including the part before |.

Creating and revoking a token

A token is created in the company cabinet: Settings → Systems → API. This requires the Business plan (the api feature) and the api_token.create permission. AISAR provisions a new service account (a dedicated User flagged as a service account) and issues it a token — the plaintext value is shown only once, at creation time.

The same page manages tokens through REST endpoints (you can also call them directly, from an existing token/session):

Method & pathPurpose
GET /v1/api-tokensList the company's tokens
POST /v1/api-tokensCreate a token (name, description)
GET /v1/api-tokens/{id}Details of one token
PATCH /v1/api-tokens/{id}Rename / update the description
DELETE /v1/api-tokens/{id}Revoke the token permanently

Creating a token returns a token field with the full Bearer value — it is only ever returned in that response and is never shown again. Revoking (DELETE) removes the service account together with all of its tokens — the action is irreversible.

Tokens have no expiry by default — they remain valid until explicitly revoked.

Create a separate token per integration/agent — this lets you revoke access for one consumer without affecting the others.

Token permissions

The service account is created with the Admin role in the company, so a token has full access to the workspace by default. Individual endpoints additionally check specific permissions (for example conversation.create to send messages, conversation.view to upload files, template.view to read templates) — these are documented per endpoint in the REST reference and in the message-sending walkthrough.

Roles and permissions (RBAC)

Within a company, access is determined by the user's role. AISAR has three roles: admin, manager, and agent — each granting its own set of permissions, which individual endpoints check per request (see "Token permissions" above and the REST reference).

Permissions are scoped to the company (multi-tenancy): the same user can hold different roles in different companies, and every request runs in the context of the company the token is bound to.

The GET /v1/me response includes a permissions field — a flat array of strings listing every permission the user holds in the current company. Each key has the form {resource}.{action}, e.g. conversation.create, conversation.view, message.create, contact.create, deal.create, template.view, channel.view, broadcast.create, api_token.create. These are the same permissions the server endpoints check on every request; a frontend gates its controls (buttons, actions) on whether the required key is present in this array.

Rate limiting

Every Bearer token is limited to 3000 requests per 60 seconds. The limit is counted per token — one token's traffic does not affect another's.

Every response (except requests without a Bearer token) carries these headers:

HeaderValue
X-RateLimit-LimitWindow limit — 3000
X-RateLimit-RemainingRequests remaining in the current window

When the limit is exceeded the server returns 429 with a body and an extra Retry-After header (seconds until reset):

429 response
{
  "message": "Too Many Requests.",
  "retry_after": 42
}

A few endpoint groups (for example heavy broadcast and AI-agent operations) carry an additional, narrower limit — in that case a 429 can arrive before the overall 3000/min budget is exhausted.

Handling 401 and 429

  • 401 Unauthorized — the token is missing, invalid, or has been revoked. Body: {"message": "Unauthenticated."}. Check the Authorization header and confirm the token wasn't revoked in the cabinet.
  • 429 Too Many Requests — the limit was exceeded. Wait retry_after seconds (or the Retry-After header value) before retrying, ideally with exponential backoff on repeated hits.

The full status table and error format are covered in the Errors guide.