Authentication

The API of JAAK Signa uses JWT (JSON Web Tokens) tokens authentication. That guide describes endpoints to get, renew and revoke access tokens.

Authentication flow

1. POST / sign-in → get token and refreshToken
2. Using Token at Leader Authorisation: Bearer TOKEN
3. When you expire → POST / refresh-token with refreshToken
4. When you log out → POST / sign-out

Duration of tokens

  • Access Token: 1 hour (3600 seconds)
  • Refresh token: 7 days

Log in

POST/api/v1/sign-in

Authors a user and returns access tokens

Body parameters

NameTypeRequiredDescription
emailstringUser Email Registered at JAAK Signa
passwordstringUser Password

Example of application

curl -X POST https://signa.sandbox.jaak.ai/api/v1/sign-in \
  -H "Content-Type: application/json" \
  -d '{
    "email": "usuario@empresa.com",
    "password": "Your -passing--sure"
  }'

Successful response (200 OK)

{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c3JfYWJjMTIzIiwiZW1haWwiOiJ1c3VhcmlvQGVtcHJlc2EuY29tIiwiaWF0IjoxNzA1MzE0MjAwLCJleHAiOjE3MDUzMTc4MDB9.signature",
  "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c3JfYWJjMTIzIiwidHlwZSI6InJlZnJlc2giLCJpYXQiOjE3MDUzMTQyMDAsImV4cCI6MTcwNTkxOTAwMH0.signature",
  "expiresIn": 3600,
  "user": {
    "id": "usr_abc123",
    "email": "usuario@empresa.com",
    "name": "User Example",
    "organizationId": "org_xyz789"
  }
}

Mistakes

CodeDescription
400Invalid parameters (email or missing password)
401Incorrect credentials
403Account suspended or disabled
429Too many attempts.

Example of error (401)

{
  "error": {
    "code": "INVALID_CREDENTIALS",
    "message": "Wrong email or password",
    "status": 401
  }
}

Test limits

After 5 failed attempts, the account is temporarily blocked for 15 minutes. Implement an exponential backoff mechanism in your integration.


Renew Token

POST/api/v1/refresh-token

Renew the access token using the refresh token

Use this endpoint as the access token expires to get a new one without applying for user credentials.

Body parameters

NameTypeRequiredDescription
refreshTokenstringRefresh token obtained at sign-in

Example of application

curl -X POST https://signa.sandbox.jaak.ai/api/v1/refresh-token \
  -H "Content-Type: application/json" \
  -d '{
    "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
  }'

Successful response (200 OK)

{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.nuevo-token...",
  "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.nuevo-refresh...",
  "expiresIn": 3600
}

Rotation of tokens

Each time you use the refresh token, you get a new pair of tokens. The previous refresh token is invalidated. That improves safety by limiting the dedicated tokens use window.

Mistakes

CodeDescription
400Refresh token missing or malformed
401Refresh token invalid or expired
403Refresh token revoked (closed)

Closing Session

POST/api/v1/sign-out

Review the tokens and close the session

Check out the currently available and its associated refresh token. All tokens issued for this session will cease to work.

Leaders

LeaderValue
AuthorisationBearer YOur _ TOKEN

Example of application

curl -X POST https://signa.sandbox.jaak.ai/api/v1/sign-out \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

Successful response (200 OK)

{
  "message": "Closed meeting"
}

Mistakes

CodeDescription
401Invalid or expired access kit

Multiple meetings

If users have active sessions on multiple devices, this endpoint only closes the current session. To close all sessions, use POST /api/v1/sign-out-all.


Token use

Once the token has been obtained, put it into the head Authorization of all applications:

curl -X GET https://signa.sandbox.jaak.ai/api/v1/templates \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

JWT Token Structure

The token contains the following information (decoded):

{
  "sub": "usr_abc123",
  "email": "usuario@empresa.com",
  "organizationId": "org_xyz789",
  "permissions": ["templates:read", "templates:write", "submissions:*"],
  "iat": 1705314200,
  "exp": 1705317800
}
FieldDescription
SubUnique user ID
emailUser Email
IdOrganization's ID
permitsUser's permission list
iatIssuing time (issued at)
expExpirand time

Management of authentication errors

Implement this logic into your integration:

async function apiCall(endpoint, options) {
  const response = await fetch(endpoint, {
    ...options,
    headers: {
      ...options.headers,
      'Authorization': `Bearer ${getToken()}`
    }
  });

  if (response.status === 401) {
    // Token expirado, intentar renovar
    const newTokens = await refreshTokens();
    if (newTokens) {
      // Retrying the original request
      return apiCall(endpoint, options);
    } else {
      // Refresh token also expired, redirected to login
      redirectToLogin();
    }
  }

  return response;
}

Following