Authentication
All API requests must be authenticated. Akol uses two types of credentials:
- Session tokens (JWT) — issued by
/auth/login, valid for 15 minutes, refreshed via/auth/refresh. Used by the dashboard and mobile app. - Personal access tokens — long-lived, scoped tokens for server-to-server integrations (CRM sync, custom dashboards, etc.). Generate them under Dashboard → Settings → API Keys.
Both are passed as a Bearer token in the Authorization header.
Using a token
curl https://api.akol.ai/api/v1/agents \
-H "Authorization: Bearer YOUR_TOKEN_HERE"Login flow (for dashboard / mobile clients)
POST /api/v1/auth/login
Content-Type: application/json
{
"email": "you@example.com",
"password": "..."
}Success response:
{
"success": true,
"data": {
"user": { "id": "user_xxx", "email": "you@example.com", "role": "USER", "plan": "STARTER" },
"token": "eyJhbGciOi...", // 15-min access token
"refreshToken": "eyJhbGciOi..." // 7-day refresh token
}
}Error responses:
401 Invalid email or password423 Account locked— too many failed attempts (30-min lockout)429 Too many login attempts— IP-level rate limit
If 2FA is enabled, the response is:
{
"success": true,
"data": {
"requires2FA": true,
"pendingToken": "..." // Pass to /auth/verify-2fa
}
}Refreshing an expired token
When a request returns 401, refresh the token instead of asking the user to
log in again:
POST /api/v1/auth/refresh
Content-Type: application/json
{ "refreshToken": "..." }Returns a new access + refresh pair. The old refresh token is revoked — token rotation, so a leaked refresh token is invalidated as soon as the legitimate client uses it.
Logout
POST /api/v1/auth/logout
Authorization: Bearer YOUR_TOKENThe token is added to a server-side blacklist (Redis-backed) so it cannot be reused even before its 15-minute expiry.
Personal access tokens
For long-running integrations, prefer personal access tokens. They:
- Don’t expire (can be revoked manually from the dashboard)
- Skip rate limits applied to login attempts
- Carry the same role/permissions as your account at the time of creation
Generate one at Dashboard → Settings → API Keys → Create Token. Tokens are shown once at creation time — store securely.
Common pitfalls
- Missing
Bearerprefix →401 No bearer token. Header value must literally start withBearer(note the trailing space). - Using a refresh token as Authorization → refresh tokens go in the body
of
/auth/refresh, not in the header. - Token from production with staging API URL (or vice versa) → tokens are signed per-environment.