Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/fredy-rizo/MultiSas/llms.txt

Use this file to discover all available pages before exploring further.

MultiSas uses JSON Web Tokens (JWT) for authentication. Two separate login flows exist: one for company admins (login-company) and one for sub-users such as sellers and consultants (login-user-company). Both flows return a signed JWT that expires after 365 days. On every protected route, include the token in the token-access request header as Bearer <token>. The TokenAny middleware accepts tokens from either identity type, while Token accepts Company tokens only, and TokenAuthorize restricts access further by role.
All endpoints are prefixed with /api/user. A Super Admin is the platform-level operator who registers and activates company accounts. An Admin is the owner-level user of a specific company.

POST /api/user/register-company

Register a new company on the platform. No token is required. On success, the company record is created with active_account set to Pendiente (pending payment review) and role_user defaulting to Sin rol. Request
name_company
string
required
Display name of the company (e.g. "Estampados del Norte").
name_founder
string
required
Full name of the company founder or primary contact.
nit_company
string
required
Tax identification number (NIT/RUT) for the company. Must be unique across all tenants.
password
string
required
Plain-text password for the company admin account. The API bcrypt-hashes this value before storage (salt rounds: 6).
type_company
string
Business category that determines which feature counters are initialised (e.g. "sublimacion"). When provided, it must match a valid entry in the platform’s companyConfig map; an unrecognised value returns HTTP 400 {"msj": "Tipo de empresa invalida", "status": false}. Omit this field for Super Admin accounts.
Response
msj
string
Human-readable status message: "Empresa registrada exitosamente".
status
boolean
true on success, false on any error.
save_company
object
The full persisted company document as returned by MongoDB, including the generated _id, all submitted fields, and the computed defaults (active_account, available_plans, counters).
curl -X POST https://your-domain.com/api/user/register-company \
  -H "Content-Type: application/json" \
  -d '{
    "name_company": "Estampados del Norte",
    "name_founder": "Carlos Rizo",
    "nit_company": "900123456-1",
    "password": "s3cur3P@ss",
    "type_company": "sublimacion"
  }'
{
  "msj": "Empresa registrada exitosamente",
  "status": true,
  "save_company": {
    "_id": "64f1a2b3c4d5e6f7a8b9c0d1",
    "name_company": "Estampados del Norte",
    "name_founder": "Carlos Rizo",
    "nit_company": "900123456-1",
    "type_company": "sublimacion",
    "role_user": "Sin rol",
    "active_account": [{ "name": "Pendiente", "value": "1" }],
    "available_plans": "Sin Plan",
    "type_available_plans": "Vacio",
    "months_quantity": 0,
    "counters": {}
  }
}
If a company with the same nit_company already exists the API returns HTTP 202 with {"msj": "Esta empresa ya se encuentra registrada", "status": false}. NIT values must be globally unique.

POST /api/user/login-company

Authenticate as a company admin. On success, a signed JWT is issued and stored on the company record. Use the returned token value in the token-access header for all subsequent requests made by this company admin. Request
nit_company
string
required
The company’s NIT/RUT identifier, as registered via register-company.
password
string
required
Plain-text password for the company admin account.
Response
msj
string
"Bienvenido!" on success.
status
boolean
true on success.
token
string
Signed JWT valid for 365 days. Pass this as Bearer <token> in the token-access header.
user
object
Snapshot of the authenticated company’s data embedded in the response.
curl -X POST https://your-domain.com/api/user/login-company \
  -H "Content-Type: application/json" \
  -d '{
    "nit_company": "900123456-1",
    "password": "s3cur3P@ss"
  }'
{
  "msj": "Bienvenido!",
  "status": true,
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "user": {
    "_id": "64f1a2b3c4d5e6f7a8b9c0d1",
    "name_company": "Estampados del Norte",
    "name_founder": "Carlos Rizo",
    "name_sellers": null,
    "nit_company": "900123456-1",
    "role_user": "Admin",
    "active_account": [{ "name": "Activo", "value": "2" }],
    "available_plans": "Plan Profesional",
    "day_available_plans": "15/3/2025",
    "expired_available_plans": "15/4/2025"
  }
}
The JWT payload includes _id, name_company, name_founder, name_sellers, nit_company, role_user, active_account, available_plans, day_available_plans, and expired_available_plans. The Token middleware decodes this payload and looks up the Company record to populate req.user on protected routes.

POST /api/user/login-user-company

Authenticate as a sub-user (employee or seller) belonging to a company. The sub-user must have been created by a company Admin via create-user-company-by-admin and must have active: true before login is permitted. Request
nit_company_by_user
string
required
The NIT/RUT of the parent company this sub-user belongs to, as stored on the UserCompany record.
password_user_company
string
required
Plain-text password set when the sub-user profile was created.
Response
msj
string
"Iniciando sesion..." on success.
status
boolean
true on success.
token
string
Signed JWT valid for 365 days. Use as Bearer <token> in token-access.
data
object
Sub-user profile data.
curl -X POST https://your-domain.com/api/user/login-user-company \
  -H "Content-Type: application/json" \
  -d '{
    "nit_company_by_user": "900123456-1",
    "password_user_company": "vendedor123"
  }'
{
  "msj": "Iniciando sesion...",
  "status": true,
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "data": {
    "company": "64f1a2b3c4d5e6f7a8b9c0d1",
    "email_user_company": "vendedor@example.com",
    "name_user_company": "Ana Gómez",
    "role_user_company": "Vendedor",
    "nit_company_by_user": "900123456-1",
    "active": true
  }
}
If the sub-user account has active: false, the API returns HTTP 403 with {"msj": "Empleado inactivo dentro de la empresa", "status": false}. A company Admin must activate the account first via PUT /api/user/active-account-user-by-company/:user_company_id.

PUT /api/user/logout-company

Invalidate the current session for a company admin by clearing the stored token field on the company document. After logout, any requests using the old token will fail business-logic checks on protected routes. Auth: TokenAny required — include token-access: Bearer <token> in the request headers. Request
nit_company
string
required
The NIT/RUT of the company being logged out. Must match the company associated with the bearer token.
Response
msj
string
"Cerrando sesion..." on success.
status
boolean
true on success, false on error.
curl -X PUT https://your-domain.com/api/user/logout-company \
  -H "Content-Type: application/json" \
  -H "token-access: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
  -d '{
    "nit_company": "900123456-1"
  }'
{
  "msj": "Cerrando sesion...",
  "status": true
}
The JWT itself is not blocklisted at the cryptographic level — the token field on the Company document is set to an empty string "". The token field is cleared in storage; subsequent requests using the old JWT will still pass signature verification.

Error Responses

All protected endpoints share a common set of error shapes returned by the Token and TokenAny middleware layers.
HTTP StatusWhenResponse Body
401No token-access header provided (Token middleware){"msj": "Sin autorizacion", "status": false}
403JWT has expired (jwt expired error){"msj": "Sesion finalizada", "status": false}
403Other JWT verification failure{"msj": "<err.message>. Rechazo en la conexion", "status": false}
404Company record not found during token lookup{"msj": "Usuario no encontrado", "status": false}
401 — No token:
{ "msj": "Sin autorizacion", "status": false }
403 — Expired session:
{ "msj": "Sesion finalizada", "status": false }
403 — Other JWT rejection:
{ "msj": "<err.message>. Rechazo en la conexion", "status": false }
404 — User not found:
{ "msj": "Usuario no encontrado", "status": false }

Build docs developers (and LLMs) love