Download OpenAPI specification:
Documentación oficial de la API de Sistema de Ventas. Esta documentación sirve como "Single Source of Truth" para Frontend, QA y Consumidores Externos.
Endpoints para el flujo completo de autenticación del sistema. Gestiona la obtención del Token Maestro (login), el Token Empresarial (company-access) y el cierre de sesión (logout).
Autentica al usuario con correo y contraseña. Devuelve un Token Maestro y la lista de empresas vinculadas al usuario.
Lógica del frontend según la respuesta:
user.roleSystem es "superadmin" o "soporte" → redirigir al dashboard global.
No requiere Token Empresarial.user.roleSystem es null y companies tiene 1 elemento → el Token Empresarial
ya viene precargado en companies[0].company.auth. Redirigir al dashboard empresarial.user.roleSystem es null y companies tiene más de 1 elemento → todos los
company.auth son null. Mostrar selector de empresa y llamar a POST /auth/company-access.Credenciales para iniciar sesión en el sistema.
| email required | string <email> <= 255 characters Correo electrónico registrado del usuario. |
| password required | string [ 6 .. 24 ] characters Contraseña del usuario. Mínimo 6, máximo 24 caracteres. |
{- "email": "usuario1@gmail.com",
- "password": "Password#123"
}roleSystem = "superadmin", companies = []. Entra directo al dashboard global. No necesita Token Empresarial.
{- "success": true,
- "message": "La sesión se ha iniciado correctamente.",
- "data": {
- "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlblR5cGUiOiJtYXN0ZXIifQ.55WudInmaPffOzq7upm_gPbtuLkj8cNU2-xeSt5gYbE",
- "type": "Bearer",
- "expirationAt": "2026-04-12T13:51:13.802129Z",
- "user": {
- "id": 1,
- "firstName": "Master System",
- "secondName": "Admin",
- "fullName": "Master System Admin",
- "documentType": "CI",
- "documentNumber": "9631256",
- "documentComplement": null,
- "email": "superadmin@valora.com",
- "phone": "59178533899",
- "image": null,
- "roleSystem": "superadmin",
- "state": "enabled",
- "emailVerifiedAt": "2026-04-02T06:11:55.000000Z"
}, - "companies": [ ]
}, - "errors": [ ],
- "meta": { },
- "traceId": "38ab526e-97f2-4ece-9bf5-5977940322f9"
}Genera un Token Empresarial para operar dentro de una empresa específica.
Cuándo usar este endpoint:
Solo cuando el usuario tiene más de una empresa vinculada y todos los company.auth
en la respuesta del login son null. El usuario debe elegir explícitamente con qué empresa
desea operar.
Cómo obtener los valores del body:
companyId → campo companyId de la empresa elegida en companies[] del login.companyUserId → campo companyUserId de ese mismo elemento del array.Resultado: El Token Empresarial recibido reemplaza al Token Maestro como token activo para todos los módulos empresariales (productos, ventas, facturación, clientes, etc.).
Datos para solicitar acceso a una empresa específica. Requiere Token Maestro en el header Authorization.
| companyId required | integer >= 1 ID de la empresa a la que se desea acceder. Debe coincidir con un "companyId" de la lista "companies" retornada en el login. |
| companyUserId required | integer >= 1 ID del vínculo usuario-empresa (campo "companyUserId" de la lista "companies" del login). Identifica la relación exacta entre el usuario y la empresa seleccionada. |
{- "companyId": 2,
- "companyUserId": 2
}{- "success": true,
- "message": "El acceso a la empresa ha sido concedido.",
- "data": {
- "companyId": 2,
- "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlblR5cGUiOiJjb21wYW55IiwiY29tcGFueUlkIjoyfQ.TOKEN_EMPRESA_A",
- "type": "Bearer",
- "expirationAt": "2026-04-17T14:14:49.317991Z"
}, - "errors": [ ],
- "meta": { },
- "traceId": "f392ed62-d94a-4a1a-94c6-4c72f38faf27"
}Revoca la sesión completa del usuario. Invalida el Token Maestro y todos los Tokens Empresariales generados a partir de él en una sola operación.
Comportamiento clave:
401 AUTH_TOKEN_REVOKED.No requiere body. Solo el header Authorization: Bearer <token>.
{- "success": true,
- "message": "La sesión se ha cerrado correctamente.",
- "data": null,
- "errors": [ ],
- "meta": { },
- "traceId": "821b948e-4f63-4d53-baa4-aa6aff665b66"
}Endpoints públicos accesibles sin autenticación previa. Gestionan el registro inicial de empresas en la plataforma SaaS.
Endpoint público que permite a un usuario externo registrar una nueva empresa en el sistema con una estructura mínima y controlada. No requiere autenticación previa.
Dos escenarios principales:
owner y se envía correo de bienvenida.Reglas clave del flujo:
isNewUser en meta para que el frontend interprete el resultado (R18).Datos mínimos requeridos para el registro público de una empresa en el sistema SaaS.
| nit required | string <= 30 characters ^\d+$ Número de Identificación Tributaria de la empresa. Solo dígitos numéricos. Debe ser único en el sistema. |
| category required | string <= 100 characters Categoría o rubro de la empresa. Valores permitidos: accessories, food, automotive, barbershop, boutique, coffee-shop, butcher-shop, clinic, commerce, construction, consulting, education, electronics, training, pharmacy, hardware-store, general, gym, home, printing, jewelry, bookstore, liquor-store, logistics, marketing, minimarket, fashion, furniture, stationery, bakery, hair-salon, perfumery, restaurant, health, supermarket, transportation, technology, tourism, veterinary, shoe-store. |
| legalName required | string <= 255 characters Razón social oficial de la empresa. |
| firstName required | string <= 120 characters Nombres del propietario de la empresa. |
| lastName required | string <= 120 characters Apellidos del propietario de la empresa. |
| email required | string <email> <= 255 characters Correo electrónico del propietario. Determina si el usuario ya existe en el sistema. Si existe, se reutiliza sin modificar sus datos. Si no, se crea un nuevo usuario. |
| password required | string [ 6 .. 24 ] characters Contraseña del propietario. Campo obligatorio por consistencia del flujo público, pero solo se aplica si el usuario no existe previamente en el sistema. Debe contener al menos 1 mayúscula, un número y un símbolo especial. |
{- "nit": "1234567890",
- "category": "technology",
- "legalName": "Mi Empresa de Prueba S.A.",
- "firstName": "Juan",
- "lastName": "Pérez García",
- "email": "juan.perez@example.com",
- "password": "Password#123"
}El correo no existía en el sistema. Se creó el usuario, se creó la empresa, se vincularon con rol owner y se encoló el correo de bienvenida.
{- "success": true,
- "message": "La empresa se ha registrado correctamente.",
- "data": null,
- "errors": [ ],
- "meta": {
- "isNewUser": true
}, - "traceId": "8d1a6ef2-c3f7-45ea-a88b-42bfa1c5bc19"
}Endpoint público que consume el token de verificación del correo empresarial, emitido previamente por el flujo de verificación de correo de empresa.
Comportamiento:
Seguridad:
| token required | string non-empty Token seguro emitido por el flujo de verificación de correo empresarial. |
{- "token": "aB3dEfGhIjKlMnOpQrStUvWxYz0123456789aB3dEfGhIjKlMnOpQrStUvWxYz01"
}El token era válido, vigente y coincidía con el correo actual de la empresa. Se registró la fecha de verificación y se cerró el proceso.
{- "success": true,
- "message": "El correo de la empresa se ha verificado correctamente.",
- "data": {
- "companyId": 21,
- "email": "contacto@saludexpress.com",
- "verified": true,
- "alreadyVerified": false,
- "verifiedAt": "2026-04-14T15:10:00.000000Z"
}, - "errors": [ ],
- "meta": { },
- "traceId": "d44bb1d1-0b1d-4f91-84ca-c4ac3d4ae7c6"
}Endpoints de gestión de empresas. Incluye gestión del perfil de la empresa actual (requiere Token Empresarial) y administración interna (requiere Token Maestro).
Crea una nueva empresa desde el panel administrativo. Si el correo del propietario no existe, se creará el usuario y se le asignará una contraseña autogenerada y enviada a su correo. Si existe, se reutilizará.
Datos requeridos para registrar una nueva empresa y vincular su propietario desde el sistema administrativo.
required | object Objeto con los datos empresariales. |
required | object Objeto con los datos del propietario. |
{- "company": {
- "nit": "1234567890",
- "category": "technology",
- "tradeName": "Mi Empresa Trade",
- "legalName": "Mi Empresa S.R.L.",
- "description": "Empresa de desarrollo de software.",
- "email": "empresa@ejemplo.com",
- "phone": "+59178500000",
- "department": "Santa Cruz",
- "address": "Av. Principal #123",
- "latitude": -17.7833,
- "longitude": -63.1821,
- "logo": "logo.png",
- "banner": "banner.jpg",
- "socialNetworks": [
], - "state": "enabled"
}, - "user": {
- "firstName": "Juan",
- "lastName": "Pérez",
- "email": "juan.perez@example.com",
- "phone": "+59171111111",
- "documentType": "CI",
- "documentNationality": "Boliviana",
- "documentNumber": "1234567",
- "documentComplement": "1B",
- "avatar": "avatar.png"
}
}{- "success": true,
- "message": "La empresa se ha registrado correctamente.",
- "data": null,
- "errors": [ ],
- "meta": {
- "isNewUser": true
}, - "traceId": "a3f2d1c8-4e5b-4f6a-9c7d-1b2e3f4a5b6c"
}Obtiene un listado paginado de todas las empresas registradas en la plataforma SaaS. Permite filtrar por categoría, estado y estado de verificación, además de buscar por término y ordenar por diferentes columnas.
| page | integer >= 1 Default: 1 Número de la página para la paginación. |
| per_page | integer [ 1 .. 100 ] Default: 10 Cantidad de elementos por página. |
| search | string Example: search=El termino a buscar Término de búsqueda para filtrar los resultados. |
| sortBy | string Enum: "nit" "legalName" "tradeName" "owner" "category" "status" "updatedAt" Example: sortBy=updatedAt Campo por el cual ordenar el listado. |
| sortDirection | string Enum: "asc" "desc" Example: sortDirection=desc Dirección del ordenamiento. |
| category | string Example: category=technology Filtro exacto por categoría de la empresa. |
| verification | string Enum: "pending" "completed" "rejected" Example: verification=pending Filtro por estado de verificación de los documentos de la empresa. |
| status | string Enum: "enabled" "disabled" "suspended" Example: status=enabled Filtro por estado general de la empresa. |
{- "success": true,
- "message": "El listado de empresas se ha obtenido correctamente.",
- "data": [
- {
- "id": 1,
- "legalName": "Tech Solutions S.A.",
- "tradeName": "Tech Solutions Trade",
- "nit": "1020304050",
- "owner": {
- "id": 5,
- "fullName": "Carlos Mendoza"
}, - "category": "technology",
- "verification": "completed",
- "status": "enabled",
- "updatedAt": "2026-05-01T10:00:00Z"
}, - {
- "id": 2,
- "legalName": "Comercializadora El Sol",
- "tradeName": null,
- "nit": "5040302010",
- "owner": {
- "id": 8,
- "fullName": "Ana Rojas"
}, - "category": "Comercio",
- "verification": "pending",
- "status": "suspended",
- "updatedAt": "2026-04-28T14:30:00Z"
}
], - "errors": [ ],
- "meta": {
- "pagination": {
- "page": 1,
- "perPage": 10,
- "total": 2,
- "lastPage": 1
}, - "sort": {
- "sortBy": "updatedAt",
- "sortDirection": "desc"
}, - "filters": {
- "category": null,
- "verification": null,
- "status": null
}, - "search": {
- "value": null
}
}, - "traceId": "b8c3e4d5-f6a7-8b9c-0d1e-2f3a4b5c6d7e"
}Obtiene un listado rápido de las empresas registradas en la plataforma, optimizado para selectores tipo "combobox" o listas con scroll infinito. Utiliza paginación por cursor en lugar de paginación tradicional para un mejor rendimiento con grandes volúmenes de datos. Solo retorna las empresas habilitadas (estado 'enabled').
| search | string Example: search=Tech Término de búsqueda parcial aplicado sobre el nombre legal (legalName) de la empresa. |
| orderBy | string Enum: "id" "legalName" "updatedAt" Example: orderBy=legalName Campo por el cual ordenar el listado. Por defecto es legalName. |
| orderDirection | string Enum: "asc" "desc" Example: orderDirection=asc Dirección del ordenamiento. |
| limit | integer Default: 15 Example: limit=15 Cantidad máxima de resultados a retornar en esta solicitud. Por defecto es 15. |
| cursor | string Example: cursor=eyJpdiI6IkhDOHVwTkdMOWs0bSIsIm1hYyI6IjFiMjMz...= Cursor opaco y encriptado para obtener la siguiente página de resultados.
Debe enviarse exactamente el valor devuelto en |
{- "success": true,
- "message": "El listado rápido de empresas se ha obtenido correctamente.",
- "data": [
- {
- "id": 1,
- "legalName": "Tech Solutions S.A.",
- "category": "technology"
}, - {
- "id": 2,
- "legalName": "Zeta Systems S.R.L.",
- "logo": null,
- "category": "commerce"
}
], - "errors": [ ],
- "meta": {
- "pagination": {
- "hasMore": true,
- "nextCursor": "eyJsYXN0VmFsdWUiOiJaZXRhIFN5c3RlbXMgUy5SLkwuIiwibGFzdElkIjoyfQ=="
}, - "sort": {
- "orderBy": "legalName",
- "orderDirection": "asc"
}, - "limit": 15
}, - "traceId": "b8c3e4d5-f6a7-8b9c-0d1e-2f3a4b5c6d7e"
}Obtiene el detalle completo de una empresa desde el entorno interno del sistema. Retorna toda la información necesaria para la revisión, gestión y seguimiento del perfil empresarial, incluyendo los datos completos del propietario principal y una vista resumida (últimos 5 registros) del historial reciente de verificación. Las imágenes y archivos se retornan como rutas completas listas para su consumo, acompañadas de metadatos básicos.
| id required | integer >= 1 Identificador único de la empresa. |
{- "success": true,
- "message": "Operación exitosa",
- "data": {
- "company": {
- "id": 21,
- "nit": "8763011631",
- "legalName": "Mi Salud Express SA.",
- "tradeName": "Farmacia Salud Express",
- "description": "Cadena minorista de productos farmacéuticos.",
- "category": "pharmacy",
- "email": "contacto@saludexpress.com",
- "phone": "+59163248810",
- "address": "3er Anillo Externo, Calle Angel Roca",
- "department": "Santa Cruz",
- "latitude": -17.7833,
- "longitude": -63.1821,
- "logoFile": {
- "name": "logo",
- "extension": "png",
- "size": 184320
}, - "bannerFile": {
- "name": "banner",
- "extension": "jpg",
- "size": 512000
}, - "socialNetworks": [
], - "verified": false,
- "state": "enabled",
- "verifiedAt": null,
- "emailVerifiedAt": null,
- "createdAt": "2026-04-10T10:00:00Z",
- "updatedAt": "2026-04-14T09:30:00Z"
}, - "user": {
- "id": 44,
- "email": "mariaparedes@gmail.com",
- "firstName": "Maria",
- "secondName": "Paredes",
- "fullName": "Maria Paredes",
- "phone": "+59169914251",
- "avatarFile": {
- "name": "avatar",
- "extension": "png",
- "size": 102400
}, - "documentType": "CI",
- "documentNationality": "Bolivia",
- "documentNumber": "8763011",
- "documentComplement": null,
- "state": "enabled",
- "emailVerifiedAt": "2026-04-12T08:00:00Z",
- "createdAt": "2026-04-10T10:00:00Z",
- "updatedAt": "2026-04-12T08:00:00Z"
}, - "verification": [
- {
- "id": 101,
- "requestCode": "d70cfc28-0693-41e3-9ca9-7e1342ffb99a",
- "status": "process",
- "observation": "Solicitud en revisión administrativa.",
- "user": {
- "id": 44,
- "fullName": "Maria Paredes",
}, - "createdAt": "2026-04-14T09:20:00Z"
}
]
}, - "errors": [ ],
- "meta": {
- "emailRequiresVerification": false,
- "verification": "completed"
}, - "traceId": "729bb1bf-882d-483b-89d3-5855dc5af3aa"
}Actualiza de manera parcial los datos de la empresa y del propietario.
Este endpoint requiere rol de superadmin o soporte.
Reglas de negocio críticas:
category o la legalName (Razón Social), la empresa perderá su estado de verificado automáticamente y se generará una nueva solicitud de verificación en el historial.enabled.| id required | integer ID interno de la empresa a actualizar. |
Datos requeridos para actualizar parcialmente una empresa y su propietario.
object Objeto con los datos empresariales a actualizar. | |
object Objeto con los datos del propietario vinculado. |
{- "company": {
- "category": "technology",
- "tradeName": "Mi Empresa Trade",
- "legalName": "Mi Empresa S.R.L.",
- "description": "Empresa dedicada al desarrollo de software",
- "email": "contacto@nuevaempresa.com",
- "phone": "+59178500000",
- "department": "Santa Cruz",
- "address": "Av. Principal #123",
- "latitude": -17.7833,
- "longitude": -63.1821,
- "logo": "logo.png",
- "banner": "banner.jpg",
- "socialNetworks": [
], - "state": "enabled"
}, - "user": {
- "phone": "+59170000001",
- "firstName": "Pedro",
- "lastName": "Gómez",
- "documentType": "CI",
- "documentNationality": "Boliviana",
- "documentNumber": "9876543",
- "documentComplement": "1B",
- "avatar": "avatar.png"
}
}{- "success": true,
- "message": "Operación exitosa",
- "data": null,
- "errors": [ ],
- "meta": {
- "verificationReset": true,
- "verificationRequestCreated": true,
- "emailVerificationReset": false
}, - "traceId": "729bb1bf-882d-483b-89d3-5855dc5af3aa"
}Elimina físicamente una empresa y sus dependencias directas desde el entorno administrativo.
Esta operación:
superadmin o soporte).restrictOnDelete() (ej. verificaciones NIT y correo, audit).| id required | integer >= 1 Example: 1 Identificador único de la empresa a eliminar. |
{- "success": true,
- "message": "Empresa eliminada permanentemente a través del endpoint de administración.",
- "data": null,
- "errors": [ ],
- "meta": {
- "deletedCompany": true,
- "deletedCompanyUsersCount": 2,
- "deletedUsersCount": 1,
- "preservedUsersCount": 1,
- "deletedNitVerificationCount": 3,
- "deletedEmailVerificationCount": 2
}, - "traceId": "729bb1bf-882d-483b-89d3-5855dc5af3aa"
}Obtiene el listado paginado de verificaciones NIT de empresas registradas en la plataforma. Solo muestra el último registro vigente de verificación por empresa dentro de una gestión (año) específica.
Este endpoint permite al equipo administrativo revisar el estado actual de las solicitudes de verificación NIT, identificar procesos pendientes, en revisión, aprobados o rechazados, y priorizar la atención según vencimiento, encargado, categoría, documento y fecha de actualización.
Reglas de negocio:
startedAt corresponde a la fecha de la solicitud original del ciclo.startedAt.approved o rejected, minutesRemaining devuelve 0 de forma fija, isExpired es false y category es 'none'.handler) es el usuario que registró el cambio al estado process.handler es null.| year required | integer Example: year=2026 Gestión (año) a consultar. Campo obligatorio. Filtra verificaciones cuya solicitud original pertenece a este año. |
| page | integer >= 1 Default: 1 Número de la página para la paginación. |
| per_page | integer [ 1 .. 100 ] Default: 10 Cantidad de elementos por página. |
| search | string Example: search=El termino a buscar Término de búsqueda para filtrar los resultados. |
| sortBy | string Default: "expiration" Enum: "legalName" "category" "document" "startedAt" "expiration" "handler" "status" "updatedAt" Example: sortBy=expiration Campo por el cual ordenar el listado. |
| sortDirection | string Default: "asc" Enum: "asc" "desc" Example: sortDirection=asc Dirección del ordenamiento. |
| category | string Example: category=pharmacy Filtro exacto por categoría de la empresa. Solo un valor. |
| document | string Enum: "certificate" "exhibition" "code" Example: document=certificate Filtro exacto por tipo de documento tributario presentado. |
| expiration | string Enum: "high" "medium" "low" "none" Example: expiration=high Filtro por rango de vencimiento del ciclo activo. Solo aplica a estados
|
| status | string Enum: "request" "process" "approved" "rejected" Example: status=process Filtro exacto por estado de la verificación. |
{- "success": true,
- "message": "El listado de verificaciones de empresas se ha obtenido correctamente.",
- "data": [
- {
- "id": 58,
- "companyId": 5,
- "verificationCode": "REQ-2026-NUEVA",
- "legalName": "Rutas del Oriente SRL.",
- "category": "transportation",
- "document": "Certificado de Registro",
- "startedAt": "2026-05-17T21:15:22-04:00",
- "expiration": {
- "deadline": "2026-05-20T21:15:22-04:00",
- "minutesRemaining": 2747,
- "isExpired": false
}, - "handler": null,
- "status": "solicitud",
- "updatedAt": "2026-05-17T21:15:22-04:00"
}, - {
- "id": 55,
- "companyId": 3,
- "verificationCode": "REQ-2026-MEDIA",
- "legalName": "Tecnologia Andina SRL.",
- "category": "technology",
- "document": "Documento de Exhibición",
- "startedAt": "2026-05-16T05:15:22-04:00",
- "expiration": {
- "deadline": "2026-05-19T05:15:22-04:00",
- "minutesRemaining": 347,
- "isExpired": false
}, - "handler": {
- "id": 2,
- "avatar": null,
- "firstName": "Support System",
- "lastName": "Admin"
}, - "status": "proceso",
- "updatedAt": "2026-05-16T05:45:22-04:00"
}
], - "errors": [ ],
- "meta": {
- "year": 2026,
- "pagination": {
- "page": 1,
- "perPage": 10,
- "total": 2,
- "lastPage": 1
}, - "sort": {
- "sortBy": "expiration",
- "sortDirection": "asc"
}, - "filters": {
- "category": null,
- "document": null,
- "expiration": null,
- "status": null
}, - "search": {
- "value": null
}
}, - "traceId": "f1e2d3c4-b5a6-7890-abcd-ef1234567890"
}Actualiza parcialmente los datos tributarios (NIT, razón social, régimen, representantes legales, etc.) asociados a un registro de verificación de empresa. Debe enviarse al menos un campo a modificar.
| verificationId required | integer Example: 101 ID del registro de verificación. |
| nitNumber | string or null <= 30 characters Número de Identificación Tributaria (NIT). |
| nitLegalName | string or null <= 255 characters Razón social asociada al NIT. |
| nitCertificationCode | string <= 255 characters Código de certificación tributaria. |
| nitImage | string <= 255 characters Ruta o identificador de la imagen del documento NIT. |
| nitTaxRegime | string or null Enum: "general" "simplified" "integrated" "unified" Régimen tributario. |
| nitTaxCategory | string or null Enum: "pricos" "gracos" "rest" Categoría tributaria. |
| nitTaxpayerType | string or null Enum: "natural" "legal" "unipersonal" Tipo de contribuyente. |
| nitTaxpayerState | string or null <= 255 characters Estado del contribuyente. |
| nitEntityType | string or null <= 255 characters Tipo de entidad. |
Array of objects or null non-empty Lista de actividades económicas. Si se envía, debe tener al menos un elemento. | |
Array of objects or null non-empty Lista de representantes legales. Si se envía, debe tener al menos un elemento. |
{- "nitNumber": "123456789",
- "nitLegalName": "Empresa de Ejemplo S.A.",
- "nitCertificationCode": "ABC123XYZ",
- "nitImage": "nit_image_45.jpg",
- "nitTaxRegime": "general",
- "nitTaxCategory": "rest",
- "nitTaxpayerType": "legal",
- "nitTaxpayerState": "Activo",
- "nitEntityType": "Sociedad Anónima",
- "nitEconomicActivities": [
- {
- "code": "62010",
- "name": "Desarrollo de software",
- "description": "Actividades de desarrollo de sistemas informáticos",
- "primary": true,
- "state": "Activo"
}
], - "nitLegalRepresentatives": [
- {
- "documentNumber": "1234567",
- "documentType": "CI",
- "fullName": "Juan Perez",
- "email": "juan.perez@ejemplo.com"
}
]
}{- "success": true,
- "message": "Los datos tributarios de la verificación se han actualizado correctamente.",
- "data": null,
- "errors": [ ],
- "meta": [ ],
- "traceId": "a3f2d1c8-4e5b-4f6a-9c7d-1b2e3f4a5b6f"
}Obtiene toda la información detallada de un registro de verificación NIT de una empresa, incluyendo datos de la empresa, propietario, información tributaria, historial de verificaciones, encargado y metadatos del estado del proceso.
Este endpoint permite al equipo administrativo revisar en profundidad toda la información relacionada con una solicitud de verificación, incluyendo el historial completo de cambios de estado, observaciones, y quién registró cada cambio.
| verificationId required | integer Example: 41 Identificador único del registro de verificación. |
{- "success": true,
- "message": "La información de verificación de la empresa se ha obtenido correctamente.",
- "data": {
- "company": {
- "id": 5,
- "logoFile": {
- "name": "logo.png",
- "extension": "png",
- "size": 12345
}, - "nit": "123456789",
- "legalName": "Rutas del Oriente SRL.",
- "category": "transportation",
- "phone": "78945612",
- "email": "contacto@rutasdeloriente.com",
- "department": "La Paz",
- "address": "Calle 1 Nro. 123, Zona Centro"
}, - "owner": {
- "id": 10,
- "firstName": "Juan",
- "lastName": "Perez",
- "email": "juan.perez@ejemplo.com",
- "documentNumber": "1234567",
- "documentType": "CI",
- "documentNationality": "Bolivia",
- "documentComplement": null
}, - "email": {
- "address": "contacto@rutasdeloriente.com",
- "confirmedAt": "2026-05-15T15:30:00Z"
}, - "document": {
- "nitDocumentType": "certificate",
- "documentFile": {
- "name": "nit.pdf",
- "extension": "pdf",
- "size": 567890
}, - "nitCertificationCode": "ABC123XYZ"
}, - "validation": {
- "nitNumber": "123456789",
- "certificationCode": "ABC123XYZ",
- "taxRegime": "general",
- "taxCategory": "pricos",
- "taxpayerType": "legal",
- "taxpayerState": "Activo",
- "entityType": "Sociedad Anónima",
- "economicActivities": [
- {
- "activityCode": "49390",
- "activityName": "Transporte de pasajeros por carretera, n.c.p.",
- "activityModel": "primary",
- "activityState": "Activo"
}
], - "legalRepresentatives": [
- {
- "documentType": "CI",
- "documentNumber": "1234567",
- "fullName": "Juan Perez",
- "email": "juan.perez@ejemplo.com"
}
]
}, - "verifications": [
- {
- "REQ-2026-001": [
- {
- "id": 41,
- "status": "process",
- "observation": "Revisando documentación tributaria.",
- "createdAt": "2026-05-17T21:45:22Z",
- "user": {
- "id": 2,
- "fullName": "Support System Admin",
- "avatar": null,
- "avatarFile": null,
- "role": "support"
}
}, - {
- "id": 40,
- "status": "request",
- "observation": null,
- "createdAt": "2026-05-17T21:15:22Z",
- "user": null
}
]
}
], - "handler": {
- "id": 2,
- "firstName": "Support System",
- "lastName": "Admin",
- "role": "support",
- "avatar": null,
- "avatarFile": null,
- "summary": {
- "approvedCount": 15,
- "rejectedCount": 3
}
}
}, - "errors": [ ],
- "meta": {
- "verificationStatus": {
- "status": "process",
- "observation": "Revisando documentación tributaria.",
- "requestCode": "REQ-2026-001",
- "currentRecordId": 41,
- "canRequestNew": false
}, - "expiration": {
- "deadline": "2026-05-20T21:15:22Z",
- "minutesRemaining": 2747,
- "isExpired": false
}, - "verificationData": {
- "isHandler": true,
- "step1": {
- "code": "request_accepted",
- "passed": true
}, - "step2": {
- "code": "validation_data_complete",
- "passed": true
}, - "step3": {
- "code": "final_resolution",
- "passed": false
}, - "step4": {
- "code": "final_resolution",
- "passed": false
}, - "step5": {
- "code": "final_resolution",
- "passed": false
}
}
}, - "traceId": "f1e2d3c4-b5a6-7890-abcd-ef1234567890"
}Actualiza el estado del proceso de verificación de una empresa. Permite confirmar una solicitud, aprobar una verificación o rechazar una solicitud/verificación según el estado actual del flujo.
| verificationId required | integer Example: 10 ID de la verificación a gestionar. |
Payload para cambiar el estado de verificación.
| status required | string Enum: "confirm" "approve" "reject" Acción a realizar sobre la verificación. Valores: confirm (Confirmar solicitud), approve (Aprobar proceso), reject (Rechazar solicitud o proceso). |
| observation | string or null <= 1500 characters Observaciones o motivos de rechazo/aprobación. Requerido para approve y reject (mín 50 caracteres). Opcional para confirm. |
{- "status": "approve",
- "observation": "Los documentos revisados cumplen con los requisitos legales y tributarios correspondientes a la categoría general. Se aprueba la solicitud."
}{- "success": true,
- "message": "La verificación ha sido confirmada.",
- "data": {
- "company": {
- "id": 10,
- "legalName": "Empresa S.A.",
- "verified": false
}, - "verification": {
- "id": 5,
- "currentStatus": "process",
- "observation": null
}, - "assignee": {
- "id": 1,
- "fullName": "Admin Test"
}
}, - "errors": [ ],
- "meta": { },
- "traceId": "123e4567-e89b-12d3-a456-426614174000"
}Inicia el proceso de verificación del correo electrónico empresarial enviando un código o enlace de verificación al correo registrado de la empresa.
Este enlace apunta a la aplicación Frontend (frontend_url) donde el usuario
podrá completar el proceso.
Este endpoint puede ser ejecutado por:
| companyId required | integer Example: 1 ID de la empresa a la que se le enviará la verificación. |
{- "success": true,
- "message": "La verificación del correo de la empresa se ha enviado correctamente.",
- "data": null,
- "errors": [ ],
- "meta": { },
- "traceId": "a3f2d1c8-4e5b-4f6a-9c7d-1b2e3f4a5b6c"
}Nota de Seguridad: Este endpoint requiere un Token Empresarial (no el Master Token normal). Debe obtenerse previamente mediante el endpoint /api/v1/auth/company-access.
Obtiene el perfil completo de la empresa vinculada al token actual, incluyendo sus datos generales, la información del propietario principal, y el historial agrupado de todas sus solicitudes de verificación.
{- "success": true,
- "message": "El perfil de la empresa se ha obtenido correctamente.",
- "data": {
- "company": {
- "id": 2,
- "nit": "8763011631",
- "legalName": "Mi Salud Express SA.",
- "tradeName": "Farmacia Salud Express",
- "description": "Farmacia especializada en productos naturales y atención de primer nivel.",
- "category": "pharmacy",
- "email": "info@farmaxpress.com",
- "phone": "+59163248810",
- "address": "3er. Anillo Externo, Calle Angel Roca, Comercial Romero, Local 4",
- "department": "Santa Cruz",
- "latitude": -17.769283,
- "longitude": -63.182745,
- "logoFile": {
- "name": "logo_farmaxpress.png",
- "extension": "png",
- "size": 102450
}, - "bannerFile": {
- "name": "banner_farmaxpress.jpg",
- "extension": "jpg",
- "size": 354020
}, - "socialNetworks": [
], - "verified": true,
- "state": "enabled",
- "verifiedAt": "2026-05-10T09:30:00Z",
- "emailVerifiedAt": "2026-05-11T10:15:00Z",
- "createdAt": "2026-05-01T08:00:00Z",
- "updatedAt": "2026-05-22T11:00:00Z"
}, - "user": {
- "id": 2,
- "email": "usuario2@gmail.com",
- "firstName": "Maria Lorena",
- "secondName": "Vargas",
- "fullName": "Maria Lorena Vargas",
- "phone": "+59171234567",
- "avatarFile": {
- "name": "avatar_maria.png",
- "extension": "png",
- "size": 85020
}, - "documentType": "CI",
- "documentNationality": "Bolivia",
- "documentNumber": "12345678",
- "documentComplement": "1G",
- "state": "enabled",
- "emailVerifiedAt": "2026-05-01T08:05:00Z",
- "createdAt": "2026-05-01T08:00:00Z",
- "updatedAt": "2026-05-22T10:45:00Z"
}, - "verification": [
- {
- "b3e5a2c1-8d2b-4e4f-8f1a-6d4b3c2a1e90": [
- {
- "id": 28,
- "status": "request",
- "observation": "Reinicio automático por actualización de Razón Social.",
- "user": {
- "id": 2,
- "fullName": "Maria Lorena Vargas",
- "role": "owner"
}, - "createdAt": "2026-05-22T11:45:00Z"
}
]
}, - {
- "d1f9b3e4-1c2a-4d5b-a678-c123456789ab": [
- {
- "id": 15,
- "status": "approved",
- "observation": "Documentos validados correctamente. Empresa verificada.",
- "user": {
- "id": 1,
- "fullName": "Admin Sistema",
- "role": "admin"
}, - "createdAt": "2026-05-10T09:30:00Z"
}
]
}
]
}, - "errors": [ ],
- "meta": {
- "emailRequiresVerification": false,
- "verification": {
- "status": "request",
- "requestCode": "b3e5a2c1-8d2b-4e4f-8f1a-6d4b3c2a1e90",
- "startedAt": "2026-05-22T11:45:00Z",
- "updatedAt": "2026-05-22T11:45:00Z",
- "currentRecordId": 28
}, - "expiration": {
- "deadline": "2026-05-23T11:45:00Z",
- "remainingMinutes": 1440,
- "expired": false
}
}, - "traceId": "729bb1bf-882d-483b-89d3-5855dc5af3aa"
}Nota de Seguridad: Este endpoint requiere un Token Empresarial activo.
Permite al propietario actualizar parcialmente el perfil de su empresa. Permite modificar datos generales de la empresa, datos básicos del propietario y campos visuales. No se permite actualizar identificadores sensibles como el NIT de la empresa o el correo del propietario.
Reglas Críticas:
request o process), no se permite actualizar.category, legalName de la empresa, o datos documentales del propietario) reiniciará el estado de verificación y generará una nueva solicitud automáticamente.email) reiniciará la verificación del correo electrónico.Datos requeridos para actualizar parcialmente el perfil de la empresa y su propietario.
object Objeto contenedor de los datos de la empresa. | |
object Objeto contenedor de los datos del propietario. |
{- "company": {
- "category": "technology",
- "tradeName": "MasterSCZ Devs",
- "legalName": "MasterSCZ Devs SRL",
- "description": "Desarrollo de software y soluciones tecnológicas avanzadas en Santa Cruz.",
- "email": "contacto@masterscz.com.bo",
- "phone": "+59178945612",
- "department": "Santa Cruz",
- "address": "Av. San Martín Esq. 4to Anillo, Edificio Empresarial Piso 5",
- "latitude": -17.769213,
- "longitude": -63.197211,
- "logo": "logo-masterscz.png",
- "banner": "banner-masterscz.jpg",
- "socialNetworks": [
]
}, - "user": {
- "phone": "+59171234567",
- "firstName": "Carlos Alberto",
- "lastName": "Mamani Rojas",
- "documentType": "ci",
- "documentNationality": "BO",
- "documentNumber": "1234567",
- "documentComplement": "SC",
- "avatar": "avatar-carlos.png"
}
}{- "success": true,
- "message": "El perfil de la empresa se ha actualizado correctamente.",
- "data": null,
- "errors": [ ],
- "meta": {
- "verificationRequestCreated": false,
- "emailVerificationReset": false
}, - "traceId": "5fdb1d84-0c41-49dc-8c38-79f8fb77e7f1"
}Inicia el proceso formal de verificación de una empresa.
Esta operación es exclusiva para el entorno de empresa y solo puede ser ejecutada por el propietario (owner).
Para poder crear la solicitud, la empresa debe cumplir requisitos mínimos (NIT, Razón Social, Categoría, Correo, Teléfono, Dirección), el propietario debe tener datos básicos completos, tener el correo verificado, y haber adjuntado la evidencia del tipo de documento legal seleccionado.
{- "success": true,
- "message": "La solicitud de verificación de la empresa se ha creado correctamente.",
- "data": null,
- "errors": [ ],
- "meta": { },
- "traceId": "86161ad0-79e7-4320-9c80-cad3e459122d"
}Actualiza la documentación legal que respalda la verificación y el NIT de la empresa actual desde su contexto autenticado.
Esta operación es exclusiva para el entorno empresarial y solo puede ser ejecutada por el propietario (OWNER).
La actualización de documentación de respaldo no genera una nueva solicitud de verificación por sí misma, sino que actualiza los datos que se enviarán en la solicitud de verificación.
| legalDocumentType required | string Enum: "exhibition" "certificate" "code" Tipo de documento legal de verificación del NIT. Valores permitidos:
|
| legalDocumentFile | string <binary> Archivo adjunto de evidencia del documento legal.
Es obligatorio si el campo |
| certificationCode | string Código de certificación tributaria.
Es obligatorio si el campo |
{- "success": true,
- "message": "La documentación legal de la empresa se ha actualizado correctamente.",
- "data": {
- "nombre": "9b4c6f3e-1c2a-4ad4-93b9-813f146f3b12.pdf",
- "extension": "pdf",
- "tamaño": 328145
}, - "errors": [ ],
- "meta": {
- "legalDocumentType": "exhibition",
- "requiresNewRequest": true,
- "fileStored": true
}, - "traceId": "9969dc5b-2e28-4d66-aa5f-3974db7754ef"
}Nota de Seguridad: Este endpoint requiere un Token Empresarial (no el Master Token normal). Debe obtenerse previamente mediante el endpoint /api/v1/auth/company-access.
Obtiene la información necesaria para que el propietario revise el estado de verificación de su empresa, los requisitos previos para solicitar una nueva verificación y el historial completo de solicitudes anteriores.
{- "success": true,
- "message": "La información de verificación de la empresa se ha obtenido correctamente.",
- "data": {
- "company": {
- "id": 21,
- "nit": "8763011631",
- "legalName": "Mi Salud Express SA.",
- "category": "pharmacy",
- "phone": "+59163248810",
- "email": "contacto@saludexpress.com",
- "department": "Santa Cruz",
- "address": "3er Anillo Externo, Calle Angel Roca"
}, - "owner": {
- "id": 44,
- "firstName": "Maria",
- "secondName": "Paredes",
- "email": "propietario@saludexpress.com",
- "documentNumber": "8763011",
- "documentType": "CI",
- "documentNationality": "BO",
- "documentComplement": null
}, - "email": {
- "email": "contacto@saludexpress.com",
- "confirmedAt": "2026-04-19T09:10:00Z"
}, - "document": {
- "vnitDocumentType": "code",
- "document": null,
- "documentFile": null,
- "vnitCertificationCode": "CERT-2026-000145"
}, - "verifications": [
- {
- "REQ-20260417-A66FSD23": [
- {
- "id": 196,
- "status": "approved",
- "observation": "Documentos revisados y aprobados.",
- "user": {
- "id": 7,
- "fullName": "Maria Elena Riquelmer Valdez",
- "avatarFile": {
- "name": "avatar.png",
- "extension": "png",
- "size": 15420
}, - "role": "support"
}, - "createdAt": "2026-04-18T15:00:00Z"
}, - {
- "id": 160,
- "status": "process",
- "observation": "En revisión por soporte técnico.",
- "user": {
- "id": 7,
- "fullName": "Maria Elena Riquelmer Valdez",
- "avatarFile": {
- "name": "avatar.png",
- "extension": "png",
- "size": 15420
}, - "role": "support"
}, - "createdAt": "2026-04-18T07:00:00Z"
}, - {
- "id": 145,
- "status": "request",
- "observation": null,
- "user": null,
- "createdAt": "2026-04-17T10:00:00Z"
}
]
}
]
}, - "errors": [ ],
- "meta": {
- "verificationStatus": {
- "status": "approved",
- "observation": "Documentos revisados y aprobados.",
- "requestCode": "REQ-20260417-A66FSD23",
- "currentRecordId": 196,
- "newRequestAvailable": false
}, - "requestVerificationStatus": {
- "completedSteps": 3,
- "totalSteps": 3,
- "step1": {
- "code": "company_owner_data",
- "completed": true
}, - "step2": {
- "code": "company_email_confirmed",
- "completed": true
}, - "step3": {
- "code": "legal_document_backup",
- "completed": true
}
}
}, - "traceId": "12d89c4c-7a4a-47ae-bf7a-2237713d5b13"
}Endpoints de gestión de usuarios. Incluye listados empresariales y operaciones relacionadas con los usuarios del sistema.
Obtiene un listado paginado de usuarios desde la vista administrativa. Permite listar usuarios del sistema (superadmin, support) o usuarios empresariales, con soporte para filtrado, búsqueda y ordenamiento.
| userType required | string Enum: "system" "business" Example: userType=business Tipo de usuario a listar. Requerido.
|
| search | string Example: search=juan Término de búsqueda parcial (nombre completo, correo o teléfono). |
| activity | string Enum: "today" "yesterday" "last_7_days" "last_30_days" "last_60_days" "over_60_days" Example: activity=last_30_days Filtro por última actividad (basado en la última conexión).
Valores: |
| role | string Enum: "superadmin" "support" "owner" "manager" "vendor" "assistant" Example: role=owner Filtro por rol. Debe ser un rol de sistema si |
| state | string Enum: "enabled" "disabled" "suspended" Example: state=enabled Filtro por estado del usuario o vínculo empresarial. |
| orderBy | string Default: "updatedAt" Enum: "fullName" "email" "phone" "company" "role" "state" "lastLoginAt" "updatedAt" Campo por el cual ordenar.
Valores: |
| orderDirection | string Default: "desc" Enum: "asc" "desc" Dirección del ordenamiento. |
| page | integer >= 1 Default: 1 Número de página para la paginación. |
| perPage | integer Default: 10 Enum: 5 10 25 50 100 Cantidad de registros por página. |
{- "success": true,
- "message": "El listado de usuarios se ha obtenido correctamente.",
- "data": [
- {
- "id": 1,
- "avatar": null,
- "fullName": "Admin Principal",
- "email": "admin@ejemplo.com",
- "phone": null,
- "company": null,
- "role": "superadmin",
- "state": "enabled",
- "lastLoginAt": "2026-06-19T10:00:00Z",
- "updatedAt": "2026-06-19T10:00:00Z"
}
], - "meta": {
- "pagination": {
- "page": 1,
- "perPage": 10,
- "total": 1,
- "lastPage": 1,
- "count": 1
}, - "sort": {
- "orderBy": "updatedAt",
- "orderDirection": "desc"
}, - "filters": {
- "userType": "system",
- "activity": null,
- "role": null,
- "state": null
}, - "search": {
- "value": null
}
}, - "errors": [ ],
- "traceId": "d4e5f6a7-b8c9-0123-def0-123456789012"
}Endpoint administrativo para eliminar un usuario de sistema o desvincular un usuario empresarial. Si el usuario de sistema tiene procesos activos (como verificaciones), no podrá ser eliminado. Si el usuario empresarial ya no cuenta con vínculos activos después de la desvinculación, su cuenta será eliminada completamente.
No se permite eliminar o desvincular usuarios con rol superadmin o owner empresarial.
| userId required | integer ID del usuario a eliminar o desvincular. |
| companyId | integer ID de la empresa (obligatorio solo para desvincular usuarios empresariales). |
{- "userId": 45,
- "companyId": 10
}{- "success": true,
- "message": "El usuario de sistema ha sido eliminado correctamente.",
- "data": {
- "result": "user_deleted",
- "userId": 45,
- "companyId": null
}, - "errors": [ ],
- "meta": { },
- "traceId": "a1b2c3d4-e5f6-7a8b-9c0d-1e2f3a4b5c6d"
}Endpoint administrativo para obtener el detalle completo de un usuario de sistema o empresarial. Devuelve la cuenta principal y todas las secciones del perfil disponibles: datos personales, documentación legal, direcciones personales, contactos de emergencia, formación académica, habilidades, experiencia laboral, contrato laboral y horario de trabajo.
Para usuarios de sistema se ignora el parámetro companyId. Para usuarios empresariales
se requiere companyId y se valida la pertenencia del usuario a esa empresa.
| userId required | integer Example: userId=19 Identificador del usuario a consultar. |
| companyId | integer Example: companyId=10 Identificador de empresa (obligatorio para usuarios empresariales, ignorado para sistema). |
{- "success": true,
- "message": "El detalle del usuario se ha obtenido correctamente.",
- "data": {
- "userId": 19,
- "userType": "system",
- "companyUserId": null,
- "account": {
- "email": "support@ejemplo.com",
- "phone": null,
- "role": "support",
- "state": "enabled",
- "company": null,
- "lastLoginAt": "2026-06-19T10:00:00Z",
- "createdAt": "2026-01-15T08:30:00Z",
- "updatedAt": "2026-06-19T10:00:00Z"
}, - "personalData": null,
- "legalDocument": null,
- "personalAddresses": [ ],
- "emergencyContacts": [ ],
- "academicFormation": null,
- "skills": [ ],
- "workExperiences": [ ],
- "employmentContract": null,
- "workSchedules": [ ]
}, - "errors": [ ],
- "meta": { },
- "traceId": "a1b2c3d4-e5f6-7a8b-9c0d-1e2f3a4b5c6d"
}Crea un nuevo usuario de sistema (support) o un usuario empresarial (manager, vendor, assistant). Si el usuario empresarial ya existe, se vincula a la empresa especificada sin modificar su cuenta principal.
Reglas Principales:
support no requiere companyId. Los roles empresariales sí requieren companyId.Datos requeridos para registrar o vincular un usuario de sistema o empresarial.
required | object Datos principales de la cuenta del usuario. |
required | object Datos personales básicos del perfil del usuario. |
object or null Información del documento de identidad o documentación legal del usuario. | |
Array of objects or null Lista de direcciones personales o corporativas asociadas al usuario. | |
Array of objects or null Lista de contactos en caso de emergencia. | |
object or null Información sobre el nivel educativo o formación académica alcanzada. | |
Array of objects or null Lista de habilidades técnicas, conocimientos o idiomas del usuario. | |
Array of objects or null Historial de experiencia laboral o empleos anteriores. | |
object or null Datos del contrato laboral. | |
Array of objects or null Esquema de horarios y turnos de trabajo asignados al usuario. |
{- "account": {
- "email": "nuevo-usuario@example.com",
- "phone": "+59176543210",
- "role": "support",
- "state": "enabled",
- "companyId": 2
}, - "personalData": {
- "firstName": "Carlos",
- "lastName": "Mendoza",
- "phone": "+59167587353",
- "email": "carlos.mendoza@example.com",
- "gender": "woman",
- "birthDate": "1990-05-12",
- "maritalStatus": "married",
- "biography": "Ingeniero de sistemas con 8 años de experiencia.",
- "avatar": "carlos-avatar.png"
}, - "legalDocumentation": {
- "type": "CI",
- "nationality": "BO",
- "number": "7633475",
- "complement": "1A",
- "expiresAt": "2035-12-31",
- "document": "carlos-ci.pdf"
}, - "personalAddresses": [
- {
- "type": "home",
- "country": "Bolivia",
- "city": "Santa Cruz",
- "address": "Calle Falsa 123",
- "isPrimary": true
}
], - "emergencyContacts": [
- {
- "fullName": "María Mendoza",
- "relationship": "sibling",
- "phone": "+593987654321",
- "email": "maria.mendoza@example.com",
- "address": "Calle Falsa 123",
- "description": "Contacto principal"
}
], - "academicFormation": {
- "title": "Ingeniería de Sistemas",
- "level": "universitario",
- "state": "completed",
- "description": "Universidad Estatal",
- "certificate": "certificado-ingenieria.pdf"
}, - "skills": [
- {
- "name": "PHP",
- "level": "professional",
- "experience": 5
}
], - "workExperiences": [
- {
- "company": "TechCorp",
- "position": "Desarrollador Backend",
- "startDate": "2018-01-01",
- "endDate": "2021-12-31",
- "description": "Desarrollo de APIs RESTful"
}
], - "employmentContract": {
- "type": "permanent",
- "modality": "on_site",
- "startDate": "2022-01-01",
- "endDate": null,
- "description": "Contrato indefinido bajo modalidad remota",
- "state": "active"
}, - "workSchedules": [
- {
- "day": "monday",
- "shift": "morning",
- "startTime": "08:00",
- "endTime": "12:00",
- "hasBreak": true
}
]
}{- "success": true,
- "message": "El usuario de sistema ha sido creado correctamente.",
- "data": {
- "result": "system_user_created",
- "userId": 10,
- "companyId": null,
- "companyUserId": null,
- "account": {
- "email": "admin@valora.com",
- "role": "support",
- "state": "enabled"
}, - "personalData": {
- "firstName": "Carlos",
- "lastName": "Mendoza",
- "fullName": "Carlos Mendoza"
}
}, - "errors": [ ],
- "meta": { },
- "traceId": "a3f2d1c8-4e5b-4f6a-9c7d-1b2e3f4a5b6c"
}Permite la actualización parcial de un usuario de sistema o empresarial desde el panel administrativo.
Reglas Principales:
userId es obligatorio y debe corresponder a un usuario existente.companyId se ignora y se actualiza el perfil general.companyId es obligatorio y debe corresponder a una empresa vinculada.superadmin ni owner.suspended.support.manager, vendor y assistant.[] o null elimina todos los registros existentes de esa sección.Payload de actualización parcial de usuario.
Solo se envían las secciones y campos que se desean modificar.
El campo userId es obligatorio.
El campo companyId es obligatorio para usuarios empresariales.
| userId required | integer Identificador del usuario a actualizar. |
| companyId | integer or null Identificador de la empresa. Obligatorio para usuarios empresariales, se ignora para usuarios de sistema. |
object or null Datos de la cuenta a actualizar. Para usuarios de sistema: phone, role y state se actualizan en la cuenta principal. Para usuarios empresariales: role y state se actualizan en el vínculo, phone en la cuenta principal. | |
object or null Datos personales básicos del perfil del usuario. Se actualiza o crea como registro único. | |
object or null Información del documento de identidad. Se actualiza o crea como registro único. | |
Array of objects or null Lista de direcciones personales. Reemplazo completo: enviar [] o null elimina todas las direcciones existentes. | |
Array of objects or null Lista de contactos de emergencia. Reemplazo completo: enviar [] o null elimina todos los contactos existentes. | |
object or null Formación académica. Se actualiza o crea como registro único. | |
Array of objects or null Lista de habilidades. Reemplazo completo: enviar [] o null elimina todas las habilidades existentes. | |
Array of objects or null Historial de experiencia laboral. Reemplazo completo: enviar [] o null elimina todas las experiencias existentes. | |
object or null Contrato laboral. Se actualiza o crea como registro único. | |
Array of objects or null Horarios de trabajo. Reemplazo completo: enviar [] o null elimina todos los horarios existentes. |
{- "userId": 10,
- "account": {
- "phone": "+59176543210",
- "state": "disabled"
}
}{- "success": true,
- "message": "El usuario de sistema ha sido actualizado correctamente.",
- "data": {
- "result": "system_user_updated",
- "userId": 10,
- "userType": "system",
- "companyId": null,
- "companyUserId": null,
- "sectionsUpdated": [
- "account",
- "personalData"
]
}, - "errors": [ ],
- "meta": { },
- "traceId": "a3f2d1c8-4e5b-4f6a-9c7d-1b2e3f4a5b6c"
}Crea un nuevo usuario empresarial o vincula un usuario existente a la empresa activa del token. El endpoint debe permitir a usuarios con rol propietario o administrador registrar usuarios empresariales con rol administrador, vendedor o auxiliar.
Reglas Principales:
owner (propietario) por esta vía.required | object Datos principales de la cuenta del usuario. Si el usuario ya existe en el sistema, estos datos no modificarán su cuenta principal existente, únicamente se utilizarán para resolver el vínculo con la empresa. |
required | object Datos personales básicos del perfil del usuario para esta empresa. |
object or null Información del documento de identidad o documentación legal del usuario. | |
Array of objects or null Lista de direcciones personales o corporativas asociadas al usuario. | |
Array of objects or null Lista de contactos en caso de emergencia. | |
object or null Información sobre el nivel educativo o formación académica alcanzada. | |
Array of objects or null Lista de habilidades técnicas, conocimientos o idiomas del usuario. | |
Array of objects or null Historial de experiencia laboral o empleos anteriores. | |
object or null Datos del contrato laboral establecido con la empresa. | |
Array of objects or null Esquema de horarios y turnos de trabajo asignados al usuario. |
{- "account": {
- "email": "nuevo-gestor@example.com",
- "phone": "+591 76543210",
- "role": "manager",
- "state": "enabled"
}, - "personalData": {
- "firstName": "Carlos",
- "lastName": "Mendoza",
- "phone": "+591 67587353",
- "email": "carlos.mendoza@example.com",
- "gender": "man",
- "birthDate": "1990-05-12",
- "maritalStatus": "single",
- "biography": "Ingeniero de sistemas con 8 años de experiencia.",
- "avatar": "carlos-avatar.png"
}, - "legalDocumentation": {
- "type": "CI",
- "nationality": "BO",
- "number": "+591 76334751",
- "complement": "A",
- "expiresAt": "2035-12-31",
- "document": "carlos-ci.pdf"
}, - "personalAddresses": [
- {
- "type": "home",
- "country": "BO",
- "city": "Santa Cruz",
- "address": "Calle Falsa 123",
- "isPrimary": true
}
], - "emergencyContacts": [
- {
- "fullName": "María Mendoza",
- "relationship": "father",
- "phone": "+591 76543210",
- "email": "maria.mendoza@example.com",
- "address": "Calle Falsa 123",
- "description": "Contacto principal"
}
], - "academicFormation": {
- "title": "Ingeniería de Sistemas",
- "level": "universitario",
- "state": "completed",
- "description": "Universidad Estatal",
- "certificate": "certificado-ingenieria.pdf"
}, - "skills": [
- {
- "name": "PHP",
- "level": "advanced",
- "experience": 5
}
], - "workExperiences": [
- {
- "company": "TechCorp",
- "position": "Desarrollador Backend",
- "startDate": "2018-01-01",
- "endDate": "2021-12-31",
- "description": "Desarrollo de APIs RESTful"
}
], - "employmentContract": {
- "type": "permanent",
- "modality": "remote",
- "startDate": "2022-01-01",
- "endDate": null,
- "description": "Contrato indefinido bajo modalidad remota",
- "state": "active"
}, - "workSchedules": [
- {
- "day": "monday",
- "shift": "morning",
- "startTime": "08:00:00",
- "endTime": "12:00:00",
- "hasBreak": true
}
]
}{- "success": true,
- "message": "El usuario ha sido creado y vinculado exitosamente a la empresa. Se ha enviado un correo con sus credenciales.",
- "data": {
- "userId": 10,
- "companyUserId": 15,
- "companyId": 2
}, - "errors": [ ],
- "meta": { },
- "traceId": "a3f2d1c8-4e5b-4f6a-9c7d-1b2e3f4a5b6c"
}Obtiene el listado paginado de usuarios vinculados a la empresa activa del contexto.
Reglas y Restricciones:
owner o manager.| search | string Buscar por coincidencia parcial en nombre completo, correo o teléfono. |
| activity | string Enum: "today" "yesterday" "last_7_days" "last_30_days" "last_60_days" "over_60_days" Filtro por rango de última conexión. |
| role | string Enum: "owner" "manager" "vendor" "assistant" Filtrar por rol en la empresa. |
| state | string Enum: "enabled" "disabled" "suspended" Filtrar por estado del vínculo con la empresa. |
| orderBy | string Default: "lastUpdate" Enum: "fullName" "email" "phone" "role" "state" "lastConnection" "lastUpdate" Campo por el cual ordenar el listado. |
| orderDirection | string Default: "desc" Enum: "asc" "desc" Dirección del ordenamiento. |
| page | integer >= 1 Default: 1 Número de página. |
| perPage | integer Default: 10 Enum: 5 10 25 50 100 Cantidad de registros por página. |
{- "success": true,
- "message": "Listado de usuarios de la empresa obtenido.",
- "data": [
- {
- "id": 101,
- "fullName": "Ana Lucia Vargas",
- "email": "ana.vargas@empresa.com",
- "phone": "+591 71234567",
- "role": "manager",
- "state": "enabled",
- "lastConnection": "2026-06-15T10:30:00Z",
- "lastUpdate": "2026-06-14T08:00:00Z"
}
], - "errors": [ ],
- "meta": {
- "pagination": {
- "page": 1,
- "perPage": 10,
- "total": 1,
- "lastPage": 1
}, - "sort": {
- "sortBy": "lastUpdate",
- "sortDirection": "desc"
}, - "filters": {
- "activity": null,
- "role": null,
- "state": null
}, - "search": {
- "value": null
}
}, - "traceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}Obtiene un listado rápido de los usuarios pertenecientes a la empresa activa. Está optimizado para selectores tipo "combobox" o listas con scroll infinito, retornando un contrato reducido con solo ID, nombre completo, rol y avatar. Utiliza paginación por cursor para un rendimiento óptimo.
| search | string Example: search=Juan Perez Término de búsqueda parcial aplicado sobre el nombre completo del usuario. |
| includeAssistants | boolean Example: includeAssistants=true Filtro opcional para incluir o excluir usuarios con rol de auxiliar. El valor predeterminado es true. |
| sortBy | string Default: "role" Enum: "id" "fullName" "role" Campo por el cual ordenar los resultados. Para garantizar la estabilidad de la paginación, siempre se utiliza el ID de forma interna como criterio de desempate. |
| sortDirection | string Default: "asc" Enum: "asc" "desc" Dirección de ordenamiento. |
| limit | integer [ 5 .. 25 ] Default: 5 Cantidad máxima de elementos a retornar por página. Se permiten valores entre 5 y 25. |
| cursor | string Example: cursor=eyJpdiI6Inl1Vn...XoifQ== Cursor opaco utilizado para obtener la siguiente página de resultados.
Debe tomarse directamente del campo |
{- "success": true,
- "message": "null",
- "data": {
- "items": [
- {
- "id": 45,
- "fullName": "Juan Perez",
- "role": "vendor",
}
], - "meta": {
- "pagination": {
- "hasMore": true,
- "nextCursor": "eyJpdiI6Inl1Vn...XoifQ=="
}, - "sort": {
- "sortBy": "role",
- "sortDirection": "asc"
}, - "limit": 5
}
}, - "errors": [
- null
], - "meta": { },
- "traceId": "729bb1bf-882d-483b-89d3-5855dc5af3aa"
}Devuelve el perfil completo de un usuario vinculado a la empresa activa del token. El perfil incluye información de cuenta, datos personales, documentación legal, direcciones, contactos de emergencia, formación académica, habilidades, experiencia laboral, contrato laboral y horarios de trabajo.
Reglas y Restricciones:
owner (propietario) o manager (administrador) pueden consultar el perfil.idUser debe ser un número entero. Si se envía un valor no numérico, la ruta no hace match y se retorna 404.null (para objetos únicos) o [] (para listas).| idUser required | integer Example: 6 Identificador único del usuario a consultar. |
{- "success": true,
- "message": "Perfil de usuario obtenido correctamente.",
- "data": {
- "userId": 6,
- "companyUserId": 4,
- "companyId": 1,
- "account": {
- "email": "ana.vargas@empresa.com",
- "role": "vendor",
- "state": "enabled"
}, - "personalData": {
- "firstName": "Ana",
- "lastName": "Vargas",
- "phone": "+591 71234567",
- "email": "ana.vargas@personal.com",
- "gender": "woman",
- "birthDate": "1990-05-12T00:00:00Z",
- "maritalStatus": "single",
- "biography": "Vendedora con 5 años de experiencia.",
}, - "legalDocumentation": {
- "type": "CI",
- "nationality": "BO",
- "number": "7654321",
- "complement": "A",
- "expiresAt": "2035-12-31T04:00:00Z",
}, - "personalAddresses": [
- {
- "type": "home",
- "country": "BO",
- "city": "Santa Cruz",
- "address": "Av. El Trompillo 456",
- "isPrimary": true
}
], - "emergencyContacts": [
- {
- "fullName": "Carlos Vargas",
- "relationship": "father",
- "phone": "+591 70000001",
- "email": null,
- "address": null,
- "description": null
}
], - "academicFormation": {
- "title": "Licenciatura en Administración",
- "level": "Universitario",
- "state": "completed",
- "description": null,
- "certificate": null
}, - "skills": [
- {
- "name": "Negociación",
- "level": "advanced",
- "experience": 4
}
], - "workExperiences": [
- {
- "company": "Distribuidora Norte S.A.",
- "position": "Asesora Comercial",
- "startDate": "2020-01-01T00:00:00Z",
- "endDate": "2023-12-31T00:00:00Z",
- "description": "Gestión de cartera de clientes."
}
], - "employmentContract": {
- "type": "permanent",
- "modality": "on_site",
- "startDate": "2024-01-15T00:00:00Z",
- "endDate": null,
- "description": null,
- "state": "active"
}, - "workSchedules": [
- {
- "day": "monday",
- "shift": "morning",
- "startTime": "08:00:00",
- "endTime": "12:00:00",
- "hasBreak": true
}
]
}, - "errors": [ ],
- "meta": { },
- "traceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}Actualiza parcialmente el perfil de un usuario vinculado a la empresa activa del token. Permite modificar el rol/estado del vínculo y cualquier sección del perfil empresarial: datos personales, documentación legal, direcciones, contactos de emergencia, formación académica, habilidades, experiencia laboral, contrato laboral y horarios de trabajo.
Reglas y Restricciones:
owner (propietario) o manager (administrador) pueden actualizar perfiles.manager no puede actualizar el perfil de un owner.manager, vendor o assistant. No se permite asignar owner.enabled y disabled. No se permite cambiar a ni desde suspended.personalData, legalDocumentation, academicFormation, employmentContract): si se envía null, se elimina el registro existente; si no se envía la llave, no se modifica nada.personalAddresses, emergencyContacts, skills, workExperiences, workSchedules): si se envía la llave (incluso con []), reemplaza completamente el contenido anterior.idUser debe ser un número entero. Si se envía un valor no numérico, la ruta no hace match y se retorna 404.| idUser required | integer Example: 6 Identificador único del usuario a actualizar. |
object Datos de la cuenta o vínculo con la empresa. Ignora campos como email o teléfono de la cuenta si se envían. | |
object Datos personales del usuario. Si se incluye, nombres y apellidos no pueden quedar vacíos. | |
object Documentación legal del usuario. | |
Array of objects Lista de direcciones personales. Al enviarse, reemplaza completamente las direcciones anteriores del vínculo. | |
Array of objects Lista de contactos de emergencia. Al enviarse, reemplaza completamente los contactos anteriores. | |
object Formación académica del usuario. | |
Array of objects Lista de habilidades. Al enviarse, reemplaza completamente las anteriores. | |
Array of objects Lista de experiencias laborales. Al enviarse, reemplaza completamente las anteriores. | |
object Contrato laboral del usuario. | |
Array of objects Lista de horarios de trabajo. Al enviarse, reemplaza completamente los anteriores. |
{- "account": {
- "role": "vendor",
- "state": "enabled"
}, - "personalData": {
- "firstName": "Ana María",
- "lastName": "Vargas Arce",
- "phone": "+591 70000002",
- "email": "ana.personal@email.com",
- "gender": "woman",
- "birthDate": "1990-05-12",
- "maritalStatus": "married",
- "biography": "5 años de experiencia en ventas.",
- "avatar": "ana-avatar.png"
}, - "legalDocumentation": {
- "type": "CI",
- "nationality": "BO",
- "number": "7654321",
- "complement": "1A",
- "expiresAt": null,
- "document": "ci-ana-vargas.pdf"
}, - "personalAddresses": [
- {
- "type": "home",
- "country": "BO",
- "city": "La Paz",
- "address": "Calle Mercado 123",
- "isPrimary": true
}, - {
- "type": "office",
- "country": "BO",
- "city": "La Paz",
- "address": "Edificio Empresarial, Piso 4",
- "isPrimary": false
}
], - "emergencyContacts": [
- {
- "fullName": "Carlos Vargas",
- "relationship": "sibling",
- "phone": "+591 71234567",
- "email": null,
- "address": null,
- "description": null
}
], - "academicFormation": {
- "title": "Licenciatura en Administración",
- "level": "Universitario",
- "state": "completed",
- "description": null,
- "certificate": null
}, - "skills": [
- {
- "name": "Negociación",
- "level": "advanced",
- "experience": 5
}, - {
- "name": "Excel",
- "level": "intermediate",
- "experience": 3
}
], - "workExperiences": [
- {
- "company": "Distribuidora Norte S.A.",
- "position": "Asesora Comercial",
- "startDate": "2020-01-01",
- "endDate": "2023-12-31",
- "description": "Gestión de cartera de clientes."
}
], - "employmentContract": {
- "type": "permanent",
- "modality": "on_site",
- "startDate": "2024-01-15",
- "endDate": null,
- "description": null,
- "state": "active"
}, - "workSchedules": [
- {
- "day": "monday",
- "shift": "morning",
- "startTime": "08:00:00",
- "endTime": "12:00:00",
- "hasBreak": true
}, - {
- "day": "tuesday",
- "shift": "morning",
- "startTime": "08:00:00",
- "endTime": "12:00:00",
- "hasBreak": false
}
]
}{- "success": true,
- "message": "Perfil de usuario actualizado correctamente.",
- "data": {
- "userId": 6,
- "companyUserId": 4,
- "companyId": 1,
- "sectionsUpdated": [
- "account",
- "personalData",
- "personalAddresses"
]
}, - "errors": [ ],
- "meta": { },
- "traceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}Desvincula a un usuario de la empresa activa. En términos de negocio, elimina el perfil completo asociado a la empresa (datos personales, contratos, horarios, etc.) y destruye físicamente el vínculo empresaUsuarios.
Reglas y Restricciones:
owner (propietario) en la empresa.owner.| idUser required | integer Identificador único del usuario a desvincular. |
{- "success": true,
- "message": "El usuario ha sido desvinculado de la empresa correctamente.",
- "data": {
- "userId": 45,
- "companyUserId": 101,
- "companyId": 10
}, - "errors": [ ],
- "meta": [ ],
- "traceId": "d4e5f6a7-b8c9-0123-def0-123456789012"
}Devuelve el perfil completo del usuario autenticado según el tipo de token utilizado:
company = null, rol y estado desde la cuenta principal.{- "success": true,
- "message": "Perfil de cuenta obtenido correctamente.",
- "data": {
- "userType": "business",
- "companyUserId": 4,
- "account": {
- "id": 6,
- "email": "ana.vargas@empresa.com",
- "company": {
- "id": 1,
- "legalName": "Comercial Norte S.R.L.",
- "tradeName": "Norte Distribuciones",
- "nit": "1234567890"
}, - "role": "vendor",
- "state": "enabled",
- "createdAt": "2024-01-15T04:00:00Z",
- "updatedAt": "2024-06-01T04:00:00Z"
}, - "personalData": {
- "firstName": "Ana",
- "lastName": "Vargas",
- "phone": "+591 71234567",
- "email": "ana.personal@email.com",
- "gender": "woman",
- "birthDate": "1990-05-12T00:00:00Z",
- "maritalStatus": "single",
- "biography": "Vendedora con 5 años de experiencia.",
}, - "legalDocumentation": {
- "type": "CI",
- "nationality": "BO",
- "number": "7654321",
- "complement": "A",
- "expiresAt": "2035-12-31T00:00:00Z",
}, - "personalAddresses": [
- {
- "type": "home",
- "country": "BO",
- "city": "Santa Cruz",
- "address": "Av. El Trompillo 456",
- "isPrimary": true
}
], - "emergencyContacts": [
- {
- "fullName": "Carlos Vargas",
- "relationship": "father",
- "phone": "+591 70000001",
- "email": null,
- "address": null,
- "description": null
}
], - "academicFormation": {
- "title": "Licenciatura en Administración",
- "level": "Universitario",
- "state": "completed",
- "description": null,
- "certificate": null
}, - "skills": [
- {
- "name": "Negociación",
- "level": "advanced",
- "experience": 4
}
], - "workExperiences": [
- {
- "company": "Distribuidora Norte S.A.",
- "position": "Asesora Comercial",
- "startDate": "2020-01-01T00:00:00Z",
- "endDate": "2023-12-31T00:00:00Z",
- "description": "Gestión de cartera de clientes."
}
]
}, - "errors": [ ],
- "meta": { },
- "traceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}Permite al usuario autenticado actualizar sus datos personales básicos (nombre, teléfono, biografía, etc.).
Reglas y Restricciones:
personalData en el cuerpo de la petición.null o no enviarse si no se desean modificar, excepto si se envía explícitamente vacío un campo requerido lógicamente (ej. no se puede borrar el firstName).AccountProfileData.required | object Objeto con los datos personales a actualizar. |
{- "personalData": {
- "firstName": "Ana María",
- "lastName": "Vargas Arce",
- "phone": "+591 70000002",
- "email": "ana.vargas@ejemplo.com",
- "gender": "woman",
- "birthDate": "1990-05-12",
- "maritalStatus": "single",
- "biography": "Actualizando mi descripción de perfil.",
- "avatar": "avatar_updated.png"
}
}{- "success": true,
- "message": "Datos personales actualizados correctamente.",
- "data": {
- "personalData": {
- "firstName": "Ana María",
- "lastName": "Vargas Arce",
- "phone": "+591 70000002",
- "email": "ana.vargas@ejemplo.com",
- "gender": "woman",
- "birthDate": "1990-05-12T00:00:00Z",
- "maritalStatus": "single",
- "biography": "Actualizando mi descripción de perfil.",
}
}, - "errors": [ ],
- "meta": { },
- "traceId": "d4e5f6a7-b8c9-0123-def0-123456789013"
}Permite al usuario autenticado actualizar su documentación legal (tipo de documento, número, nacionalidad, expiración y adjunto).
Reglas y Restricciones:
legalDocumentation en el cuerpo de la petición con al menos un campo válido.null o no enviarse si no se desean modificar.complement solo es aceptado y persistido si el tipo de documento (type) es CI.AccountProfileData.required | object Objeto con la documentación legal a actualizar. |
{- "legalDocumentation": {
- "type": "CI",
- "nationality": "BO",
- "number": "7654321",
- "complement": "A",
- "expiresAt": "2035-12-31",
- "document": "mi_carnet.pdf"
}
}{- "success": true,
- "message": "Documentación legal actualizada correctamente.",
- "data": {
- "legalDocumentation": {
- "type": "CI",
- "nationality": "BO",
- "number": "7654321",
- "complement": "A",
- "expiresAt": "2035-12-31T00:00:00Z",
}
}, - "errors": [ ],
- "meta": { },
- "traceId": "d4e5f6a7-b8c9-0123-def0-123456789013"
}Permite al usuario autenticado reemplazar completamente sus direcciones personales (casa, oficina, facturación, lugar temporal).
Reglas y Restricciones:
personalAddresses en el cuerpo de la petición.[] o null, se eliminarán todas las direcciones personales del contexto activo.isPrimary: true) por solicitud.AccountProfileData.required | Array of objects or null Arreglo de direcciones personales. Si es un arreglo vacío o nulo, se eliminarán todas las direcciones previas. |
{- "personalAddresses": [
- {
- "type": "home",
- "country": "BO",
- "city": "Santa Cruz de la Sierra",
- "address": "Av. Banzer, 4to Anillo, Condominio Sevilla, Casa 12",
- "isPrimary": true
}, - {
- "type": "office",
- "country": "BO",
- "city": "Santa Cruz de la Sierra",
- "address": "Equipetrol, Edificio Empresarial, Piso 3",
- "isPrimary": false
}
]
}{- "success": true,
- "message": "Direcciones personales actualizadas correctamente.",
- "data": {
- "personalAddresses": [
- {
- "type": "home",
- "country": "BO",
- "city": "Santa Cruz de la Sierra",
- "address": "Av. Banzer, 4to Anillo, Condominio Sevilla, Casa 12",
- "isPrimary": true
}, - {
- "type": "office",
- "country": "BO",
- "city": "Santa Cruz de la Sierra",
- "address": "Equipetrol, Edificio Empresarial, Piso 3",
- "isPrimary": false
}
]
}, - "errors": [ ],
- "meta": { },
- "traceId": "d4e5f6a7-b8c9-0123-def0-123456789013"
}Permite al usuario autenticado reemplazar completamente sus contactos de emergencia.
Reglas y Restricciones:
emergencyContacts en el cuerpo de la petición.[] o null, se eliminarán todos los contactos de emergencia del contexto activo.AccountProfileData.required | Array of objects or null Arreglo de contactos de emergencia. Si es un arreglo vacío o nulo, se eliminarán todos los contactos previos. |
{- "emergencyContacts": [
- {
- "fullName": "Carlos Vargas López",
- "relationship": "father",
- "phone": "+59170123456",
- "email": "carlos.vargas@gmail.com",
- "address": "Av. Américas, Zona Sur, La Paz",
- "description": "Llamar solo en caso de urgencia mayor."
}, - {
- "fullName": "Luis Vargas López",
- "relationship": "sibling",
- "phone": "+59171112233",
- "email": null,
- "address": null,
- "description": null
}
]
}{- "success": true,
- "message": "Contactos de emergencia actualizados correctamente.",
- "data": {
- "emergencyContacts": [
- {
- "fullName": "Carlos Vargas López",
- "relationship": "father",
- "phone": "+59170123456",
- "email": "carlos.vargas@gmail.com",
- "address": "Av. Américas, Zona Sur, La Paz",
- "description": "Llamar solo en caso de urgencia mayor."
}, - {
- "fullName": "Luis Vargas López",
- "relationship": "sibling",
- "phone": "+59171112233",
- "email": null,
- "address": null,
- "description": null
}
]
}, - "errors": [ ],
- "meta": { },
- "traceId": "d4e5f6a7-b8c9-0123-def0-123456789013"
}Permite al usuario autenticado actualizar parcial o completamente su información de formación académica.
Reglas y Restricciones:
null.AccountProfileData.required | object Objeto que contiene los datos de la formación académica. |
{- "academicFormation": {
- "title": "Ingeniería de Sistemas",
- "level": "Licenciatura",
- "state": "completed",
- "description": "Graduado con honores en 2023.",
- "certificate": "mi-diploma-universitario.pdf"
}
}{- "success": true,
- "message": "Formación académica actualizada correctamente.",
- "data": {
- "academicFormation": {
- "title": "Ingeniería de Sistemas",
- "level": "Licenciatura",
- "state": "completed",
- "description": "Graduado con honores en 2023."
}
}, - "errors": [ ],
- "meta": { },
- "traceId": "d4e5f6a7-b8c9-0123-def0-123456789013"
}Permite al usuario autenticado reemplazar completamente sus habilidades o conocimientos.
Reglas y Restricciones:
skills en el cuerpo de la petición.[] o null, se eliminarán todas las habilidades del contexto activo.AccountProfileData.required | Array of objects or null Arreglo de habilidades. Si es un arreglo vacío o nulo, se eliminarán todas las habilidades previas del contexto activo. |
{- "skills": [
- {
- "name": "Laravel",
- "level": "advanced",
- "experience": 3
}, - {
- "name": "Vue.js",
- "level": "intermediate",
- "experience": 1
}, - {
- "name": "Docker",
- "level": "beginner",
- "experience": 0
}
]
}{- "success": true,
- "message": "Habilidades actualizadas correctamente.",
- "data": {
- "skills": [
- {
- "name": "Laravel",
- "level": "advanced",
- "experience": 3
}, - {
- "name": "Vue.js",
- "level": "intermediate",
- "experience": 1
}, - {
- "name": "Docker",
- "level": "beginner",
- "experience": 0
}
]
}, - "errors": [ ],
- "meta": { },
- "traceId": "d4e5f6a7-b8c9-0123-def0-123456789013"
}Permite al usuario autenticado reemplazar completamente sus experiencias laborales.
Reglas y Restricciones:
workExperiences en el cuerpo de la petición.[] o null, se eliminarán todas las experiencias del contexto activo.company, position y startDate son obligatorios por cada experiencia.endDate: null indica que la experiencia laboral continúa vigente.endDate no puede ser anterior a startDate.AccountProfileData.required | Array of objects or null Arreglo de experiencias laborales. Si es un arreglo vacío o nulo, se eliminarán todas las experiencias previas del contexto activo. |
{- "workExperiences": [
- {
- "company": "Empresa de Ejemplo S.A.",
- "position": "Desarrollador Backend Senior",
- "startDate": "2022-03-01",
- "endDate": "2024-12-31",
- "description": "Desarrollo de APIs REST con Laravel y gestión de bases de datos MySQL."
}, - {
- "company": "Startup Tech Bolivia",
- "position": "Desarrollador Fullstack",
- "startDate": "2025-01-15",
- "endDate": null,
- "description": null
}
]
}{- "success": true,
- "message": "Experiencias laborales actualizadas correctamente.",
- "data": {
- "workExperiences": [
- {
- "company": "Empresa de Ejemplo S.A.",
- "position": "Desarrollador Backend Senior",
- "startDate": "2022-03-01T00:00:00Z",
- "endDate": "2024-12-31T00:00:00Z",
- "description": "Desarrollo de APIs REST con Laravel y gestión de bases de datos MySQL."
}, - {
- "company": "Startup Tech Bolivia",
- "position": "Desarrollador Fullstack",
- "startDate": "2025-01-15T00:00:00Z",
- "endDate": null,
- "description": null
}
]
}, - "errors": [ ],
- "meta": { },
- "traceId": "d4e5f6a7-b8c9-0123-def0-123456789013"
}Devuelve un resumen del perfil público de un usuario objetivo.
Si el usuario objetivo es empresarial, se requiere obligatoriamente el parámetro companyId.
Para usuarios de sistema, companyId es ignorado.
Autorización:
| userId required | integer Example: 45 Identificador único del usuario objetivo. |
| companyId | integer Example: companyId=12 Identificador de la empresa desde la cual se consulta.
|
{- "success": true,
- "message": "Operación exitosa",
- "data": {
- "user": {
- "fullName": "Juan Pérez",
- "email": "juan.perez@ejemplo.com",
- "phone": "+591 77777777",
- "userType": "business"
}, - "summary": [ ]
}, - "errors": [ ],
- "meta": { },
- "traceId": "729bb1bf-882d-483b-89d3-5855dc5af3aa"
}Devuelve la sección de información del perfil público de un usuario objetivo. Incluye datos básicos de cuenta, datos personales, documentación legal, biografía, direcciones personales y contactos de emergencia.
Si el usuario objetivo es empresarial, se requiere obligatoriamente el parámetro companyId.
Para usuarios de sistema, companyId es ignorado.
Autorización:
Reglas de visibilidad:
| userId required | integer Example: 3 Identificador único del usuario objetivo. |
| companyId | integer Example: companyId=1 Identificador de la empresa desde la cual se consulta.
|
{- "success": true,
- "message": "Operación exitosa",
- "data": {
- "user": {
- "fullName": "Juan Carlos Pérez Rodríguez",
- "email": "juan.perez@empresa.com",
- "phone": "+591 76543210",
- "userType": "business"
}, - "information": {
- "personalData": {
- "firstName": "Juan Carlos",
- "lastName": "Pérez Rodríguez",
- "corporateEmail": "jperez@empresa.com",
- "corporatePhone": "+591 33445566",
- "birthDate": "1988-03-22",
- "gender": "man",
- "maritalStatus": "married"
}, - "legalDocumentation": {
- "type": "CI",
- "number": "7654321",
- "complement": "1A",
- "expiresAt": null,
- "nationality": "BO"
}, - "biography": {
- "description": "Ingeniero en sistemas con más de 10 años de experiencia en desarrollo de software empresarial y gestión de proyectos."
}, - "personalAddresses": [
- {
- "type": "home",
- "country": "BO",
- "city": "Santa Cruz de la Sierra",
- "address": "Av. Banzer, 4to Anillo, Condominio Sevilla, Casa 12",
- "isPrimary": true
}, - {
- "type": "office",
- "country": "BO",
- "city": "Santa Cruz de la Sierra",
- "address": "Equipetrol, Edificio Empresarial, Piso 3, Of. 301",
- "isPrimary": false
}
], - "emergencyContacts": [
- {
- "fullName": "María Rodríguez de Pérez",
- "relationship": "mother",
- "phone": "+591 70111222",
- "email": "maria.rodriguez@gmail.com",
- "address": "Calle Sucre 456, Zona Centro, Cochabamba",
- "description": "Contactar en primera instancia."
}, - {
- "fullName": "Carlos Pérez López",
- "relationship": "sibling",
- "phone": "+591 71223344",
- "email": null,
- "address": null,
- "description": null
}
]
}
}, - "errors": [ ],
- "meta": { },
- "traceId": "729bb1bf-882d-483b-89d3-5855dc5af3aa"
}Devuelve la sección de experiencia del perfil público de un usuario objetivo. Incluye datos básicos de cuenta, formación académica, descripción académica, habilidades (skills) y experiencia laboral ordenada descendentemente por fecha de inicio.
Si el usuario objetivo es empresarial, se requiere obligatoriamente el parámetro companyId.
Para usuarios de sistema, companyId es ignorado.
Autorización:
Reglas de visibilidad:
| userId required | integer Example: 3 Identificador único del usuario objetivo. |
| companyId | integer Example: companyId=1 Identificador de la empresa desde la cual se consulta.
|
{- "success": true,
- "message": "Operación exitosa",
- "data": {
- "user": {
- "fullName": "Ana Laura Torres",
- "email": "ana.torres@empresa.com",
- "phone": "+591 76543210",
- "userType": "business"
}, - "experience": {
- "academicFormation": {
- "title": "Ingeniería de Sistemas",
- "level": "Licenciatura",
- "state": "completed",
- "certificate": {
- "name": "titulo_ingenieria.pdf",
}
}, - "academicDescription": {
- "description": "Graduada con honores y excelencia académica."
}, - "skills": [
- {
- "name": "PHP / Laravel",
- "level": "advanced"
}, - {
- "name": "Vue.js",
- "level": "intermediate"
}
], - "workExperiences": [
- {
- "company": "Desarrollos Web Bolivia",
- "position": "Líder Técnico Backend",
- "startDate": "2023-01-15",
- "startYear": 2023,
- "endDate": null,
- "endYear": null,
- "description": "Liderando equipo de backend para la creación de APIs REST."
}, - {
- "company": "Startup Tech",
- "position": "Programador Junior",
- "startDate": "2020-02-01",
- "startYear": 2020,
- "endDate": "2022-12-30",
- "endYear": 2022,
- "description": "Mantenimiento de sistemas heredados."
}
]
}
}, - "errors": [ ],
- "meta": { },
- "traceId": "729bb1bf-882d-483b-89d3-5855dc5af3aa"
}Devuelve la sección de empresas del perfil público de un usuario objetivo. Incluye datos básicos de cuenta y un listado de las empresas en las que tiene vinculación vigente. Para cada empresa, devuelve datos institucionales, contrato, horarios y un listado de sus miembros (hasta 300).
Si el usuario objetivo es empresarial, se requiere obligatoriamente el parámetro companyId.
Para usuarios de sistema, companyId es ignorado.
Autorización e Intersección:
Reglas de visibilidad:
| userId required | integer Example: 3 Identificador único del usuario objetivo. |
| companyId | integer Example: companyId=1 Identificador de la empresa desde la cual se consulta.
|
{- "success": true,
- "message": "Operación exitosa",
- "data": {
- "user": {
- "fullName": "Ana Laura Torres",
- "email": "ana.torres@empresa.com",
- "phone": "+591 76543210",
- "userType": "business"
}, - "companies": [
- {
- "companyId": 1,
- "company": {
- "tradeName": "Desarrollos Web Bolivia",
- "nit": "1234567015",
- "category": "services",
- "email": "contacto@dwb.com",
- "phone": "+591 33334444",
- "department": "Santa Cruz",
- "address": "Equipetrol Norte",
- "state": "enabled",
- "description": "Desarrollo de software y páginas web",
- "socialNetworks": {
- "instagram": null,
- "youtube": null,
- "tiktok": null,
}
}, - "members": {
- "total": 2,
- "limitExceeded": false,
- "items": [
- {
- "fullName": "Carlos Director",
- "role": "owner",
- "avatar": null
}, - {
- "fullName": "Ana Laura Torres",
- "role": "admin",
}
]
}, - "vinculation": {
- "registrationDate": "2022-01-15",
- "role": "admin",
- "state": "enabled"
}, - "contract": {
- "type": "permanent",
- "modality": "remote",
- "startDate": "2022-02-01",
- "endDate": null,
- "state": "active",
- "description": "Desarrollo backend remoto"
}, - "workSchedules": [
- {
- "day": "monday",
- "startTime": "09:00:00",
- "endTime": "18:00:00"
}, - {
- "day": "tuesday",
- "startTime": "09:00:00",
- "endTime": "18:00:00"
}
]
}
]
}, - "errors": [ ],
- "meta": { },
- "traceId": "729bb1bf-882d-483b-89d3-5855dc5af3aa"
}Devuelve la sección de cuenta del perfil público de un usuario objetivo. El nivel de información (completo o detalle) se determina dinámicamente según el rol y la identidad del consultante.
Si el usuario objetivo es empresarial, se requiere obligatoriamente el parámetro companyId.
Para usuarios de sistema, companyId es ignorado.
Niveles de Acceso:
full (Completo): Devuelve el detalle de la cuenta, plataformas conectadas, sesiones activas y dispositivos activos. Otorgado a: Token Maestro, perfiles propios, Propietarios y Administradores (de la misma empresa).detail (Detalle): Devuelve solo el detalle de la cuenta. Las plataformas, sesiones y dispositivos se omiten (se envían como null). Otorgado a: Vendedores y Auxiliares (de la misma empresa consultando a otro miembro).Reglas de autorización:
403 Forbidden.| userId required | integer Example: 3 Identificador único del usuario objetivo. |
| companyId | integer Example: companyId=1 Identificador de la empresa desde la cual se consulta.
|
{- "success": true,
- "message": "Operación exitosa",
- "data": {
- "user": {
- "fullName": "Ana Laura Torres",
- "email": "ana.torres@empresa.com",
- "phone": "+591 76543210",
- "userType": "business"
}, - "account": {
- "accessLevel": "full",
- "accountDetail": {
- "id": 3,
- "email": "ana.torres@empresa.com",
- "phone": "+591 76543210",
- "userType": "business",
- "state": "enabled",
- "registeredAt": "2026-01-01T00:00:00Z",
- "updatedAt": "2026-06-28T00:00:00Z",
- "lastLoginAt": "2026-06-28T19:00:00Z"
}, - "connectedPlatforms": [
- {
- "platform": "google",
- "email": "ana.torres@empresa.com",
- "registeredAt": "2026-01-01T12:00:00Z",
- "state": "enabled"
}
], - "sessions": {
- "total": 1,
- "limitExceeded": false,
- "items": [
- {
- "type": "access",
- "device": "other",
- "browser": null,
- "ip": "186.1.1.1",
- "loginMethod": "correo",
- "registeredAt": "2026-06-28T18:00:00Z",
- "lastUsedAt": "2026-06-28T19:00:00Z"
}
]
}, - "devices": {
- "total": 1,
- "limitExceeded": false,
- "items": [
- {
- "type": "other",
- "device": "Desconocido",
- "system": null,
- "version": null,
- "ip": "186.1.1.1",
- "registeredAt": "2026-06-28T18:00:00Z"
}
]
}
}
}, - "errors": [ ],
- "meta": { },
- "traceId": "729bb1bf-882d-483b-89d3-5855dc5af3aa"
}Devuelve la sección de actividad del perfil público de un usuario objetivo.
En esta primera versión, la sección activity siempre devuelve un arreglo vacío [].
La clave existe obligatoriamente en la respuesta para permitir futuras integraciones sin romper el contrato.
Si el usuario objetivo es empresarial, se requiere obligatoriamente el parámetro companyId.
Si el usuario objetivo es de sistema, el parámetro companyId es ignorado.
Reglas de autorización:
403 Forbidden.| userId required | integer Example: 3 Identificador único del usuario objetivo. |
| companyId | integer Example: companyId=1 Identificador de la empresa desde la cual se consulta.
|
{- "success": true,
- "message": "Operación exitosa",
- "data": {
- "user": {
- "avatar": null,
- "fullName": "Ana Laura Torres",
- "email": "ana.torres@empresa.com",
- "phone": "+591 76543210",
- "userType": "business"
}, - "activity": [ ]
}, - "errors": [ ],
- "meta": { },
- "traceId": "729bb1bf-882d-483b-89d3-5855dc5af3aa"
}Endpoints de gestión de sucursales. Incluye listados empresariales y operaciones relacionadas con las sucursales de una empresa.
Obtiene un listado rápido de las sucursales pertenecientes a la empresa activa. Está optimizado para selectores tipo "combobox" o listas con scroll infinito, retornando un contrato reducido con solo ID, nombre, dirección completa y banner. Utiliza paginación por cursor para un rendimiento óptimo.
| search | string Example: search=Central Término de búsqueda parcial aplicado sobre el nombre de la sucursal. |
| sortBy | string Enum: "id" "name" Example: sortBy=name Campo por el cual ordenar el listado. Por defecto es name. |
| sortDirection | string Enum: "asc" "desc" Example: sortDirection=asc Dirección del ordenamiento. Por defecto es asc. |
| limit | integer Default: 5 Example: limit=10 Cantidad máxima de resultados a retornar en esta solicitud (entre 5 y 25). Por defecto es 5. |
| cursor | string Example: cursor=eyJpdiI6IkhDOHVwTkdMOWs0bSIsIm1hYyI6IjFiMjMz...= Cursor opaco y encriptado para obtener la siguiente página de resultados.
Debe enviarse exactamente el valor devuelto en |
{- "success": true,
- "message": "Listado rápido de sucursales obtenido correctamente.",
- "data": [
- {
- "id": 1,
- "name": "Sucursal Central",
- "fullAddress": "Av. San Martin Calle 3",
- "banner": {
- "name": "uuid-banner.jpg",
}
}, - {
- "id": 2,
- "name": "Sucursal Norte",
- "fullAddress": "Av. Banzer 4to Anillo",
- "banner": null
}
], - "errors": [ ],
- "meta": {
- "pagination": {
- "hasMore": true,
- "nextCursor": "eyJsYXN0VmFsdWUiOiJTdWN1cnNhbCBOb3J0ZSIsImxhc3RJZCI6Mn0="
}, - "sort": {
- "sortBy": "name",
- "sortDirection": "asc"
}, - "limit": 5
}, - "traceId": "b8c3e4d5-f6a7-8b9c-0d1e-2f3a4b5c6d7e"
}Crea una nueva sucursal para la empresa activa del usuario autenticado.
El acceso está restringido a usuarios con rol owner o manager.
Se permite un registro mínimo (solo campos obligatorios) o un registro completo que incluye características, servicios, galería de imágenes ordenadas y horarios de atención. Toda la operación se realiza de forma transaccional.
Cuerpo de la petición para registrar una nueva sucursal.
| name required | string <= 120 characters Nombre de la sucursal. |
| department required | string <= 120 characters Departamento donde se encuentra la sucursal. |
| province | string or null <= 120 characters Provincia donde se encuentra la sucursal. |
| neighborhood required | string <= 120 characters Barrio donde se ubica la sucursal. |
| avenue required | string <= 120 characters Avenida principal de acceso. |
| street required | string <= 120 characters Calle exacta. |
| building | string or null <= 120 characters Nombre del edificio (si aplica). |
| floor | string or null <= 120 characters Piso del edificio (si aplica). |
| number required | string <= 60 characters Número de puerta o local. |
| latitude | number or null <float> Latitud geográfica (entre -90 y 90). Requerido si se envía longitud. |
| longitude | number or null <float> Longitud geográfica (entre -180 y 180). Requerido si se envía latitud. |
| banner | string or null <= 240 characters Referencia al nombre del archivo del banner. Debe tener extensión jpg, jpeg o png. |
| phone | string or null <= 24 characters Teléfono de contacto de la sucursal. |
| features | Array of strings or null Lista de características de la sucursal. |
| services | Array of strings or null Lista de servicios ofrecidos. |
| isMain required | boolean Indica si es la sucursal principal de la empresa. |
| state required | string Enum: "enabled" "disabled" "suspended" Estado operativo. |
Array of objects or null Galería de imágenes de la sucursal. | |
Array of objects or null Horarios de atención. |
{- "name": "Sucursal Norte",
- "department": "Santa Cruz",
- "province": "Andrés Ibáñez",
- "neighborhood": "Equipetrol",
- "avenue": "San Martín",
- "street": "Calle 3",
- "building": "Torre Norte",
- "floor": "2",
- "number": "210",
- "latitude": -17.783333,
- "longitude": -63.182222,
- "banner": "banner_norte.jpg",
- "phone": "+59133456789",
- "features": [
- "Estacionamiento",
- "Wifi gratuito"
], - "services": [
- "Delivery"
], - "isMain": true,
- "state": "enabled",
- "images": [
- {
- "name": "entrada_norte.jpg",
- "order": 1
}
], - "schedules": [
- {
- "day": "monday",
- "openingTime": "08:00",
- "closingTime": "18:00"
}
]
}{- "success": true,
- "message": "Operación exitosa",
- "data": {
- "id": 1,
- "name": "Sucursal Norte",
- "department": "Santa Cruz",
- "province": "Andrés Ibáñez",
- "neighborhood": "Equipetrol",
- "avenue": "San Martín",
- "street": "Calle 3",
- "building": "Torre Norte",
- "floor": "2",
- "number": "210",
- "latitude": -17.783333,
- "longitude": -63.182222,
- "banner": {
- "name": "banner_norte.jpg",
}, - "phone": "+59176356789",
- "features": [
- "Estacionamiento",
- "Aire acondicionado"
], - "services": [
- "Venta al por mayor"
], - "isMain": false,
- "state": "enabled",
- "images": [
- {
- "name": "entrada_norte.jpg",
- "order": 1
}
], - "schedules": [
- {
- "day": "monday",
- "openingTime": "08:00:00",
- "closingTime": "18:00:00"
}
], - "createdAt": "2026-07-08T10:00:00Z",
- "updatedAt": "2026-07-08T10:00:00Z"
}, - "errors": [ ],
- "meta": { },
- "traceId": "729bb1bf-882d-483b-89d3-5855dc5af3aa"
}Devuelve un listado paginado de las sucursales pertenecientes a la empresa activa del usuario autenticado.
Permite filtrar por búsqueda general, departamento, estado y actividad, así como ordenar por múltiples campos.
Solo accesible para usuarios con roles owner o manager.
| search | string Example: search=El termino a buscar Término de búsqueda para filtrar los resultados. |
| department | string <= 120 characters Filtra las sucursales por nombre de departamento exacto. |
| activity | string Enum: "open" "closed" "not_specified" Filtra las sucursales por su actividad actual (calculado en base al horario y estado). |
| state | string Enum: "enabled" "disabled" "suspended" Filtra las sucursales por su estado operativo. |
| sortBy | string Enum: "name" "department" "fullAddress" "phone" "state" "updatedAt" Campo por el cual ordenar los resultados. |
| sortDirection | string Default: "asc" Enum: "asc" "desc" Dirección de ordenamiento. |
| page | integer >= 1 Default: 1 Número de la página para la paginación. |
| per_page | integer [ 1 .. 100 ] Default: 10 Cantidad de elementos por página. |
{- "success": true,
- "message": "Listado de sucursales obtenido correctamente.",
- "data": [
- {
- "id": 1,
- "name": "Sucursal Central",
- "department": "Santa Cruz",
- "fullAddress": "Av. San Martin Calle 3",
- "phone": "+59171234567",
- "currentSchedule": {
- "openingTime": "08:00:00Z",
- "closingTime": "18:00:00Z"
}, - "activity": "open",
- "state": "enabled",
- "updatedAt": "2026-07-06T15:30:00Z"
}
], - "meta": {
- "pagination": {
- "page": 1,
- "perPage": 10,
- "total": 3,
- "lastPage": 1,
- "count": 3
}, - "filters": {
- "search": null,
- "department": "Santa Cruz",
- "activity": "open",
- "state": "enabled"
}, - "sort": {
- "sortBy": "name",
- "sortDirection": "asc"
}
}
}Devuelve la información completa de una sucursal perteneciente a la empresa del usuario autenticado.
Requiere rol de propietario (owner) o administrador (manager).
| branchId required | integer >= 1 Identificador único de la sucursal |
{- "success": true,
- "message": "Detalle de sucursal obtenido correctamente.",
- "data": {
- "id": 1,
- "name": "Sucursal Central",
- "department": "Santa Cruz",
- "province": "Andrés Ibáñez",
- "neighborhood": "Centro",
- "avenue": "Libertad",
- "street": "Suárez de Figueroa",
- "building": "Edificio Macor",
- "floor": "Planta Baja",
- "number": "123",
- "latitude": -17.783456,
- "longitude": -63.182094,
- "banner": {
- "name": "uuid-banner.jpg",
}, - "phone": "+591 71234567",
- "features": [
- "wifi",
- "estacionamiento"
], - "services": [
- "delivery"
], - "isMain": true,
- "state": "enabled",
- "currentSchedule": {
- "openingTime": "08:00:00",
- "closingTime": "18:00:00"
}, - "activity": "open",
- "images": [
- {
- "name": "uuid-img.jpg",
- "order": 1
}
], - "schedules": [
- {
- "day": "monday",
- "open": true,
- "openingTime": "08:00:00",
- "closingTime": "18:00:00"
}
], - "createdAt": "2026-07-06T10:30:00Z",
- "updatedAt": "2026-07-08T14:20:00Z"
}, - "errors": [ ],
- "meta": { },
- "traceId": "550e8400-e29b-41d4-a716-446655440000"
}Actualiza una sucursal perteneciente a la empresa activa del usuario autenticado.
El acceso está restringido a usuarios con rol owner o manager.
Permite actualización parcial o completa. Los campos omitidos conservan su valor actual,
mientras que enviar null (en los campos que lo soportan) elimina su valor.
Las colecciones (imágenes, horarios, características, servicios) se reemplazan completamente
cuando se envían, y se eliminan por completo al enviar un arreglo vacío [] o null.
| branchId required | integer ID de la sucursal a actualizar. |
Cuerpo de la petición para actualizar una sucursal existente. Todos los campos son opcionales. Omitir un campo conserva su valor actual, mientras que enviar null en campos que lo soportan eliminará el valor.
| name | string <= 120 characters Nombre de la sucursal. Si se envía, no puede ser vacío. |
| department | string <= 120 characters Departamento donde se encuentra la sucursal. |
| province | string or null <= 120 characters Provincia donde se encuentra la sucursal. null elimina el valor. |
| neighborhood | string <= 120 characters Barrio donde se ubica la sucursal. |
| avenue | string <= 120 characters Avenida principal de acceso. |
| street | string <= 120 characters Calle exacta. |
| building | string or null <= 120 characters Nombre del edificio (si aplica). null elimina el valor. |
| floor | string or null <= 120 characters Piso del edificio (si aplica). null elimina el valor. |
| number | string <= 60 characters Número de puerta o local. |
| latitude | number or null <float> Latitud geográfica (entre -90 y 90). |
| longitude | number or null <float> Longitud geográfica (entre -180 y 180). |
| banner | string or null <= 240 characters Referencia al nombre del archivo del banner. Debe tener extensión jpg, jpeg o png. null elimina el banner. |
| phone | string or null <= 24 characters Teléfono de contacto de la sucursal. null elimina el valor. |
| features | Array of strings or null Lista de características. Reemplaza la colección completa. null o [] eliminan todas las características. |
| services | Array of strings or null Lista de servicios ofrecidos. Reemplaza la colección completa. null o [] eliminan todos los servicios. |
| isMain | boolean Indica si es la sucursal principal de la empresa. No admite null. |
| state | string Enum: "enabled" "disabled" Estado operativo. No se permite transicionar desde/hacia suspended. |
Array of objects or null Galería de imágenes. Reemplaza la colección completa. null o [] eliminan todas las imágenes. | |
Array of objects or null Horarios de atención. Reemplaza la colección completa. null o [] eliminan todos los horarios. |
{- "name": "Sucursal Norte VIP Renovada",
- "department": "Santa Cruz",
- "province": "Andrés Ibáñez",
- "neighborhood": "Equipetrol Norte",
- "avenue": "Cuarto Anillo",
- "street": "Calle 4",
- "building": "Torre Empresarial VIP",
- "floor": "Piso 2",
- "number": "500-B",
- "latitude": -17.780123,
- "longitude": -63.180234,
- "phone": "+59177777777",
- "isMain": false,
- "state": "disabled",
- "banner": "ofertas_verano_2026.png",
- "features": [
- "Wi-Fi de Alta Velocidad",
- "Parqueo Subterráneo",
- "Cafetería Incluida"
], - "services": [
- "Atención VIP",
- "Soporte Técnico Especializado"
], - "images": [
- {
- "name": "fachada_norte_nueva.jpg",
- "order": 1
}, - {
- "name": "interior_norte_nueva.png",
- "order": 2
}, - {
- "name": "salas_de_reunion.jpg",
- "order": 3
}
], - "schedules": [
- {
- "day": "monday",
- "openingTime": "08:00",
- "closingTime": "20:00"
}, - {
- "day": "tuesday",
- "openingTime": "08:00",
- "closingTime": "20:00"
}, - {
- "day": "saturday",
- "openingTime": "09:00",
- "closingTime": "14:00"
}
]
}{- "success": true,
- "message": "Operación exitosa",
- "data": {
- "id": 1,
- "name": "Sucursal Norte",
- "department": "Santa Cruz",
- "province": "Andrés Ibáñez",
- "neighborhood": "Equipetrol",
- "avenue": "San Martín",
- "street": "Calle 3",
- "building": "Torre Norte",
- "floor": "2",
- "number": "210",
- "latitude": -17.783333,
- "longitude": -63.182222,
- "banner": {
- "name": "banner_norte.jpg",
}, - "phone": "+59176356789",
- "features": [
- "Estacionamiento",
- "Aire acondicionado"
], - "services": [
- "Venta al por mayor"
], - "isMain": false,
- "state": "enabled",
- "images": [
- {
- "name": "entrada_norte.jpg",
- "order": 1
}
], - "schedules": [
- {
- "day": "monday",
- "openingTime": "08:00:00",
- "closingTime": "18:00:00"
}
], - "createdAt": "2026-07-08T10:00:00Z",
- "updatedAt": "2026-07-08T10:00:00Z"
}, - "errors": [ ],
- "meta": { },
- "traceId": "729bb1bf-882d-483b-89d3-5855dc5af3aa"
}Elimina permanentemente una sucursal perteneciente a la empresa activa del usuario autenticado. Esta operación es destructiva y eliminará en cascada las imágenes y horarios relacionados de la sucursal.
Solo accesible para usuarios con el rol owner.
| branchId required | integer Identificador numérico de la sucursal a eliminar. |
{- "success": true,
- "message": "Operación exitosa",
- "data": {
- "result": "branch_deleted",
- "branchId": 123
}, - "errors": [ ],
- "meta": { },
- "traceId": "729bb1bf-882d-483b-89d3-5855dc5af3aa"
}Endpoints de gestión de puntos de venta. Incluye listados empresariales y operaciones relacionadas con los puntos de venta de una empresa.
Obtiene el listado paginado de los puntos de venta de la empresa activa del usuario. Permite filtrar por nombre, sucursal, actividad y estado, además de ordenamiento.
| search | string <= 255 characters Búsqueda por nombre del punto de venta o nombre completo del responsable de la sesión actual. |
| branchId | integer >= 1 Filtra por el ID de la sucursal. |
| activity | string Enum: "open" "closed" Filtra por actividad (depende de si existe una sesión de caja abierta actualmente). |
| state | string Enum: "enabled" "disabled" "suspended" Filtra por el estado del punto de venta. |
| sortBy | string Default: "name" Enum: "name" "branchId" "activity" "openedAt" "openedBy" "state" "updatedAt" Columna por la cual ordenar los resultados. |
| sortDirection | string Default: "asc" Enum: "asc" "desc" Dirección del ordenamiento. |
| page | integer >= 1 Default: 1 Número de página para la paginación. |
| perPage | integer Default: 10 Enum: 5 10 25 50 100 Cantidad de resultados por página permitidos. |
{- "success": true,
- "message": "Operación exitosa",
- "data": [
- {
- "id": 1,
- "name": "Caja Principal - Planta Baja",
- "branch": {
- "id": 1,
- "name": "Sucursal Norte",
- "department": "Santa Cruz"
}, - "activity": "open",
- "openedAt": "2026-07-13T10:00:00Z",
- "openedBy": {
- "id": 5,
- "fullName": "Juan Perez",
- "role": "vendor"
}, - "state": "enabled",
- "updatedAt": "2026-07-13T01:00:00Z",
- "currentSession": {
- "id": 12,
- "code": "SES-TEST-001",
- "openedBy": "Juan Perez",
- "note": "Turno mañana",
- "openingAmount": "1500.5000",
- "currentBalance": "1750.5000"
}
}
], - "errors": [ ],
- "meta": {
- "pagination": {
- "page": 1,
- "perPage": 10,
- "total": 3,
- "lastPage": 1,
- "count": 3
}, - "filters": {
- "search": null,
- "branchId": null,
- "activity": null,
- "state": null
}, - "sort": {
- "sortBy": "name",
- "sortDirection": "asc"
}
}, - "traceId": "729bb1bf-882d-483b-89d3-5855dc5af3aa"
}Obtiene un listado optimizado de puntos de venta de la empresa activa, devolviendo únicamente la información mínima necesaria (id, name, branchName).
Características clave:
id, name y el nombre de la sucursal (branchName como cadena directa).id o name, con manejo de colisiones interno.Nota: Este endpoint es útil para selects, typeaheads o vistas colapsadas donde no se requiere toda la información detallada del punto de venta.
| search | string <= 120 characters Example: search=Caja Término de búsqueda para filtrar puntos de venta.
Realiza una búsqueda parcial ( |
| sortBy | string Default: "name" Enum: "id" "name" Example: sortBy=name Columna por la cual ordenar los resultados. |
| sortDirection | string Default: "asc" Enum: "asc" "desc" Example: sortDirection=asc Dirección del ordenamiento. |
| limit | integer [ 5 .. 25 ] Default: 5 Example: limit=10 Número máximo de elementos a devolver por página.
|
| cursor | string <= 500 characters Example: cursor=eyJsYXN0VmFsdWUiOiJDYWphIFByaW5jaXBhbCIsImxhc3RJZCI6MX0= Cursor opaco para obtener la siguiente página de resultados.
Este valor debe ser exactamente el mismo string devuelto en el campo |
{- "success": true,
- "message": "Petición procesada exitosamente.",
- "data": {
- "items": [
- {
- "id": 1,
- "name": "Caja Principal - Planta Baja",
- "branchName": "Sucursal Central"
}
], - "meta": {
- "pagination": {
- "hasMore": true,
- "nextCursor": "eyJsYXN0VmFsdWUiOiJDYWphIFByaW5jaXBhbCIsImxhc3RJZCI6MX0="
}, - "sort": {
- "sortBy": "name",
- "sortDirection": "asc"
}, - "limit": 5
}
}, - "errors": [ ],
- "meta": { },
- "traceId": "982365c3-644b-4307-9d11-44a23e7f6cd3"
}Registra un nuevo punto de venta en una sucursal de la empresa activa.
Requiere token de empresarial y rol de owner, manager, o vendor.
| name required | string <= 120 characters Nombre del punto de venta. No vacío, max 120 caracteres. |
| branchId required | integer >= 1 Identificador de la sucursal activa. |
| description required | string <= 240 characters Descripción del punto de venta. |
| type required | string Enum: "fixed" "mobile" Tipo de punto de venta. Para 'mobile' la ubicación operativa es obligatoria. |
| isMain required | boolean Indica si es el punto de venta principal de la sucursal. |
| state required | string Enum: "enabled" "disabled" Estado del punto de venta. No se permite crear en estado suspendido. |
| neighborhood | string <= 120 characters Barrio. Obligatorio si type = mobile. |
| avenue | string <= 120 characters Avenida. Obligatorio si type = mobile. |
| street | string <= 120 characters Calle. Obligatorio si type = mobile. |
| building | string <= 120 characters Edificio. Opcional. |
| floor | string <= 120 characters Piso. Opcional. |
| number | string <= 60 characters Número. Obligatorio si type = mobile. |
| latitude | number <float> [ -90 .. 90 ] Latitud. Obligatorio si se envía longitud. |
| longitude | number <float> [ -180 .. 180 ] Longitud. Obligatorio si se envía latitud. |
{- "name": "Caja Principal - Planta Baja",
- "branchId": 1,
- "description": "Caja principal para cobros en efectivo y tarjeta.",
- "type": "fixed",
- "isMain": true,
- "state": "enabled",
- "neighborhood": "Equipetrol",
- "avenue": "Av. San Martín",
- "street": "Calle 3 Oeste",
- "building": "Edificio Torre Sur",
- "floor": "Planta Baja",
- "number": "245",
- "latitude": -17.75549,
- "longitude": -63.19794
}{- "success": true,
- "message": "Operación exitosa",
- "data": {
- "id": 1,
- "name": "Caja Principal - Planta Baja",
- "description": "Caja principal para cobros en efectivo y tarjeta.",
- "type": "fixed",
- "isMain": true,
- "state": "enabled",
- "neighborhood": "Equipetrol",
- "avenue": "Av. San Martín",
- "street": "Calle 3 Oeste",
- "building": "Edificio Comercial (Parada Temporal)",
- "floor": "Planta Baja",
- "number": "S/N",
- "latitude": -17.75549,
- "longitude": -63.19794,
- "branch": {
- "id": 1,
- "name": "Sucursal Central",
- "department": "Santa Cruz",
- "province": "Andrés Ibáñez",
- "fullAddress": "Equipetrol Calle 3, Edificio Torre Sur",
- "state": "enabled"
}, - "currentSession": {
- "responsible": {
- "id": 5,
- "fullName": "Brandom Julio Rekilme",
- "role": "vendor"
}, - "openedAt": "2026-07-13T10:00:00Z",
- "durationMinutes": 125,
- "openingAmount": "1500.5000",
- "incomeAmount": "300.0000",
- "expenseAmount": "50.0000",
- "currentBalance": "1750.5000"
}, - "createdAt": "2026-07-13T01:00:00Z",
- "updatedAt": "2026-07-13T01:00:00Z"
}, - "errors": [ ],
- "meta": { },
- "traceId": "729bb1bf-882d-483b-89d3-5855dc5af3aa"
}Devuelve la información detallada de un punto de venta. El punto de venta debe pertenecer a la empresa activa del usuario autenticado.
Incluye un mapeo completo del punto de venta, mapeo parcial de la sucursal y la sesión actualmente abierta si existe, con cálculos de duración y saldos.
| pointOfSaleId required | integer >= 1 Identificador único del punto de venta. |
{- "success": true,
- "message": "Operación exitosa",
- "data": {
- "id": 1,
- "name": "Caja Principal - Planta Baja",
- "description": "Caja principal para cobros en efectivo y tarjeta.",
- "type": "fixed",
- "isMain": true,
- "state": "enabled",
- "neighborhood": "Equipetrol",
- "avenue": "Av. San Martín",
- "street": "Calle 3 Oeste",
- "building": "Edificio Comercial (Parada Temporal)",
- "floor": "Planta Baja",
- "number": "S/N",
- "latitude": -17.75549,
- "longitude": -63.19794,
- "branch": {
- "id": 1,
- "name": "Sucursal Central",
- "department": "Santa Cruz",
- "province": "Andrés Ibáñez",
- "fullAddress": "Equipetrol Calle 3, Edificio Torre Sur",
- "state": "enabled"
}, - "currentSession": {
- "responsible": {
- "id": 5,
- "fullName": "Brandom Julio Rekilme",
- "role": "vendor"
}, - "openedAt": "2026-07-13T10:00:00Z",
- "durationMinutes": 125,
- "openingAmount": "1500.5000",
- "incomeAmount": "300.0000",
- "expenseAmount": "50.0000",
- "currentBalance": "1750.5000"
}, - "createdAt": "2026-07-13T01:00:00Z",
- "updatedAt": "2026-07-13T01:00:00Z"
}, - "errors": [ ],
- "meta": { },
- "traceId": "729bb1bf-882d-483b-89d3-5855dc5af3aa"
}Actualiza de forma parcial o total la información de un punto de venta. El punto de venta debe pertenecer a la empresa activa del usuario autenticado.
No se puede actualizar el punto de venta si tiene una sesión de caja abierta actualmente. Tampoco se puede cambiar la sucursal a la que pertenece ni actualizar a estado suspendido. Los campos obligatorios dependen del tipo (fijo o móvil) resultante después de la actualización.
| pointOfSaleId required | integer >= 1 Identificador único del punto de venta. |
Al menos un campo debe estar presente en el cuerpo de la solicitud.
| name | string <= 120 characters Nombre del punto de venta. Si se envía, no debe estar vacío. |
| description | string <= 240 characters Descripción del punto de venta. |
| type | string Enum: "fixed" "mobile" Tipo de punto de venta. Para 'mobile' la ubicación operativa será obligatoria. |
| isMain | boolean Indica si es el punto de venta principal de la sucursal. |
| state | string Enum: "enabled" "disabled" "suspended" Estado del punto de venta. No se permite actualizar a estado 'suspended'. |
| neighborhood | string or null <= 120 characters Barrio. Si el tipo final es móvil, será obligatorio. |
| avenue | string or null <= 120 characters Avenida. Si el tipo final es móvil, será obligatorio. |
| street | string or null <= 120 characters Calle. Si el tipo final es móvil, será obligatorio. |
| building | string or null <= 120 characters Edificio. Opcional. |
| floor | string or null <= 120 characters Piso. Opcional. |
| number | string or null <= 60 characters Número. Si el tipo final es móvil, será obligatorio. |
| latitude | number or null <float> [ -90 .. 90 ] Latitud. Obligatorio si se envía longitud. |
| longitude | number or null <float> [ -180 .. 180 ] Longitud. Obligatorio si se envía latitud. |
{- "name": "Caja Principal - Planta Baja",
- "description": "Caja principal para cobros en efectivo y tarjeta.",
- "type": "fixed",
- "isMain": true,
- "state": "enabled",
- "neighborhood": "Equipetrol",
- "avenue": "Av. San Martín",
- "street": "Calle 3 Oeste",
- "building": "Edificio Torre Sur",
- "floor": "Planta Baja",
- "number": "245",
- "latitude": -17.75549,
- "longitude": -63.19794
}{- "success": true,
- "message": "Operación exitosa",
- "data": {
- "id": 1,
- "name": "Caja Principal - Planta Baja",
- "description": "Caja principal para cobros en efectivo y tarjeta.",
- "type": "fixed",
- "isMain": true,
- "state": "enabled",
- "neighborhood": "Equipetrol",
- "avenue": "Av. San Martín",
- "street": "Calle 3 Oeste",
- "building": "Edificio Comercial (Parada Temporal)",
- "floor": "Planta Baja",
- "number": "S/N",
- "latitude": -17.75549,
- "longitude": -63.19794,
- "branch": {
- "id": 1,
- "name": "Sucursal Central",
- "department": "Santa Cruz",
- "province": "Andrés Ibáñez",
- "fullAddress": "Equipetrol Calle 3, Edificio Torre Sur",
- "state": "enabled"
}, - "currentSession": {
- "responsible": {
- "id": 5,
- "fullName": "Brandom Julio Rekilme",
- "role": "vendor"
}, - "openedAt": "2026-07-13T10:00:00Z",
- "durationMinutes": 125,
- "openingAmount": "1500.5000",
- "incomeAmount": "300.0000",
- "expenseAmount": "50.0000",
- "currentBalance": "1750.5000"
}, - "createdAt": "2026-07-13T01:00:00Z",
- "updatedAt": "2026-07-13T01:00:00Z"
}, - "errors": [ ],
- "meta": { },
- "traceId": "729bb1bf-882d-483b-89d3-5855dc5af3aa"
}Elimina físicamente un punto de venta perteneciente a la empresa activa. Esta operación también eliminará en cascada las sesiones históricas (cerradas) asociadas a este punto.
Restricciones:
| pointOfSaleId required | integer >= 1 Identificador único del punto de venta a eliminar. |
{- "success": true,
- "message": "Operación exitosa",
- "data": {
- "id": 12,
- "name": "Caja Principal - Planta Baja"
}, - "errors": [ ],
- "meta": { },
- "traceId": "729bb1bf-882d-483b-89d3-5855dc5af3aa"
}Registra la apertura de sesión de un punto de venta perteneciente a la empresa activa.
Requiere token empresarial y rol de owner, manager o vendor. El rol assistant no tiene permitido abrir sesiones.
Reglas de negocio:
assistant y no tener otra sesión abierta.owner: Puede asignar a cualquier usuario elegible de la empresa.manager: Puede asignarse a sí mismo o a cualquier vendedor.vendor: Solo puede asignarse a sí mismo.| pointOfSale required | integer >= 1 Identificador del punto de venta. |
| responsible required | integer >= 1 Identificador del usuario responsable asignado a la sesión de caja. |
| openingAmount required | number <float> >= 0 Monto de apertura en la moneda principal. Debe ser mayor o igual a 0. |
| note | string <= 500 characters Nota opcional sobre la apertura. |
{- "pointOfSale": 1,
- "responsible": 5,
- "openingAmount": 5000,
- "note": "Apertura de turno matutino con fondo chico."
}{- "success": true,
- "message": "Operación exitosa",
- "data": {
- "id": 1,
- "code": "SES-20260713-00001",
- "openedAt": "2026-07-13T14:30:00Z",
- "openingAmount": "5000.0000",
- "finalBalance": "5000.0000",
- "note": "Apertura de turno matutino con fondo chico.",
- "state": "open",
- "pointOfSale": {
- "id": 1,
- "name": "Caja Principal - Recepción"
}, - "responsible": {
- "id": 5,
- "fullName": "Brandom Julio Rekilme",
- "role": "vendor",
}
}, - "errors": [ ],
- "meta": { },
- "traceId": "729bb1bf-882d-483b-89d3-5855dc5af3aa"
}Registra el cierre de una sesión abierta de punto de venta.
Requiere token empresarial y rol de owner, manager o vendor. El rol assistant no tiene permitido cerrar sesiones.
Reglas de negocio:
owner puede cerrar cualquier sesión activa de la empresa.manager puede cerrar sesiones donde él mismo sea el responsable, o donde el responsable tenga rol vendor. No puede cerrar sesiones de propietarios ni de otros administradores.vendor solo puede cerrar su propia sesión.incomeAmount y expenseAmount hasta la futura integración de la caja.finalBalance se calcula automáticamente: openingAmount + incomeAmount - expenseAmount.| sessionId required | integer >= 1 Identificador de la sesión de punto de venta a cerrar. |
| note | string <= 500 characters Nota opcional de cierre de sesión. |
{- "note": "Cierre de turno vespertino sin novedades."
}{- "success": true,
- "message": "Operación exitosa",
- "data": {
- "id": 1,
- "code": "SES-20260713-00001",
- "openedAt": "2026-07-13T14:30:00Z",
- "closedAt": "2026-07-13T22:00:00Z",
- "openingAmount": "5000.0000",
- "incomeAmount": "4523.7500",
- "expenseAmount": "1200.3400",
- "finalBalance": "8323.4100",
- "note": "Cierre de turno vespertino sin novedades.",
- "state": "closed",
- "pointOfSale": {
- "id": 1,
- "name": "Caja Principal - Recepción"
}, - "openedBy": {
- "id": 5,
- "fullName": "Brandom Julio Rekilme",
- "role": "vendor",
}, - "closedBy": {
- "id": 3,
- "fullName": "Sergio Vega",
- "role": "manager",
}
}, - "errors": [ ],
- "meta": { },
- "traceId": "729bb1bf-882d-483b-89d3-5855dc5af3aa"
}Obtiene el listado paginado de sesiones de puntos de venta de la empresa activa.
Requiere token empresarial y rol permitido (owner, manager, vendor, assistant).
Permite filtrar por gestión (obligatorio), búsqueda general, punto de venta, estado, tipo de saldo y ordenar.
| fiscalYear required | integer Example: fiscalYear=2026 Gestión a consultar (año de 4 dígitos). Filtra la fecha de cierre (sesiones cerradas) o fecha de apertura (sesiones abiertas). |
| search | string Example: search=El termino a buscar Término de búsqueda para filtrar los resultados. |
| pointOfSale | integer >= 1 Filtra por el ID del punto de venta. |
| balanceType | string Enum: "positive" "negative" "neutral" Filtra por tipo de saldo (calculado como openingAmount + incomeAmount - expenseAmount). |
| state | string Enum: "open" "closed" Filtra por el estado de la sesión. |
| sortBy | string Default: "updatedAt" Enum: "code" "pointOfSale" "responsible" "openedAt" "closedAt" "openingAmount" "currentBalance" "state" "updatedAt" Columna por la cual ordenar los resultados. |
| sort | string Example: sort=created_at,desc Campo por el cual ordenar seguido de su dirección (asc o desc). Ejemplo: nombre,asc |
| page | integer >= 1 Default: 1 Número de la página para la paginación. |
| per_page | integer [ 1 .. 100 ] Default: 10 Cantidad de elementos por página. |
{- "success": true,
- "message": "Operación exitosa",
- "data": [
- {
- "id": 45,
- "code": "SES-00000045",
- "pointOfSale": {
- "id": 10,
- "name": "Caja Principal - Planta Baja"
}, - "responsible": {
- "id": 25,
- "fullName": "Brandom Julio Rekilme",
- "role": "vendor",
}, - "openedAt": "2026-06-12T10:00:00Z",
- "closedAt": "2026-06-12T18:00:00Z",
- "openingAmount": "100.0000",
- "currentBalance": "350.5000",
- "state": "closed",
- "updatedAt": "2026-06-12T18:00:00Z",
- "description": "Apertura turno mañana"
}
], - "errors": [ ],
- "meta": {
- "pagination": {
- "page": 1,
- "perPage": 10,
- "total": 45,
- "lastPage": 5,
- "count": 10
}, - "filters": {
- "fiscalYear": 2026,
- "search": null,
- "pointOfSale": null,
- "balanceType": "positive",
- "state": "closed"
}, - "sort": {
- "sortBy": "updatedAt",
- "sortDirection": "desc"
}
}, - "traceId": "729bb1bf-882d-483b-89d3-5855dc5af3aa"
}Endpoints de gestión de categorias. Incluye listados empresariales y operaciones relacionadas con las categorías y subcategorías para los productos de una empresa.
Obtiene un listado rápido de las categorías pertenecientes a la empresa activa. Está optimizado para selectores tipo "combobox" o listas con scroll infinito, retornando un contrato reducido con solo ID, nombre, código e ícono. Utiliza paginación por cursor para un rendimiento óptimo.
| search | string Example: search=Bebidas Término de búsqueda parcial aplicado sobre el nombre y el código de la categoría. |
| type | string Default: "all" Enum: "all" "parents" "subcategories" Example: type=all Filtro para devolver todas las categorías, solo padres o solo subcategorías. Por defecto es all. |
| sortBy | string Default: "name" Enum: "id" "name" Example: sortBy=name Campo por el cual ordenar el listado. Por defecto es name. |
| sortDirection | string Default: "asc" Enum: "asc" "desc" Example: sortDirection=asc Dirección del ordenamiento. Por defecto es asc. |
| limit | integer [ 5 .. 25 ] Default: 5 Example: limit=10 Cantidad máxima de resultados a retornar en esta solicitud (entre 5 y 25). Por defecto es 5. |
| cursor | string Example: cursor=eyJpdiI6IkhDOHVwTkdMOWs0bSIsIm1hYyI6IjFiMjMz...= Cursor opaco y encriptado para obtener la siguiente página de resultados.
Debe enviarse exactamente el valor devuelto en |
{- "success": true,
- "message": "Listado rápido de categorías obtenido correctamente.",
- "data": [
- {
- "id": 5,
- "name": "Bebidas",
- "code": "BEB-001",
}, - {
- "id": 6,
- "name": "Comidas",
- "code": "COM-001",
- "icon": null
}
], - "errors": [ ],
- "meta": {
- "pagination": {
- "hasMore": true,
- "nextCursor": "eyJsYXN0VmFsdWUiOiJDb21pZGFzIiwibGFzdElkIjo2fQ=="
}, - "sort": {
- "sortBy": "name",
- "sortDirection": "asc"
}, - "limit": 5
}, - "traceId": "b8c3e4d5-f6a7-8b9c-0d1e-2f3a4b5c6d7e"
}Obtiene un listado paginado de las categorías y subcategorías pertenecientes a la empresa activa del usuario. Permite filtrar por categoría padre, visibilidad y estado, así como buscar por código o nombre y ordenar los resultados. El listado solo incluirá categorías de la empresa asociada al token activo.
Roles permitidos: propietario, administrador, vendedor, auxiliar.
| search | string Término de búsqueda que aplica coincidencia parcial sobre el código o el nombre de la categoría (máx. 255 caracteres). |
| categoryId | integer ID de la categoría padre. Retorna las subcategorías cuyo padre coincide con este ID. |
| visibility | string Enum: "visible" "hidden" Filtra por visibilidad en ventas. |
| state | string Enum: "enabled" "disabled" "suspended" Filtra por el estado de la categoría. |
| sortBy | string Default: "updatedAt" Enum: "code" "name" "category" "order" "visibility" "products" "state" "updatedAt" Nombre del campo por el cual ordenar los resultados. |
| sortDirection | string Default: "desc" Enum: "asc" "desc" Dirección del ordenamiento. |
| page | integer Default: 1 Número de página para la paginación de resultados. |
| perPage | integer Default: 10 Enum: 5 10 25 50 100 Cantidad de resultados a devolver por página. |
{- "success": true,
- "message": "Operación exitosa",
- "data": [
- {
- "id": 5,
- "code": "BEB-001",
- "name": "Bebidas",
- "order": 1,
- "visibility": "visible",
- "state": "enabled",
- "color": "#3498DB",
- "icon": {
- "name": "bebidas.png",
}, - "productCount": 0,
- "parent": {
- "id": 1,
- "code": "MENU-001",
- "name": "Menú Principal"
}, - "updatedAt": "2026-07-16T12:00:00Z"
}
], - "errors": [ ],
- "meta": {
- "pagination": {
- "page": 1,
- "perPage": 10,
- "total": 12,
- "lastPage": 2,
- "count": 10
}, - "filters": {
- "search": null,
- "categoryId": null,
- "visibility": null,
- "state": null
}, - "sort": {
- "sortBy": "updatedAt",
- "sortDirection": "desc"
}
}, - "traceId": "729bb1bf-882d-483b-89d3-5855dc5af3aa"
}Registra una nueva categoría (raíz o subcategoría) asociada a la empresa activa del usuario.
Si se proporciona parentId, se registrará como una subcategoría; de lo contrario, será una categoría raíz.
Restricciones:
enabled o disabled.| parentId | integer ID de la categoría padre (si es subcategoría). |
| code required | string Código único de la categoría dentro de la empresa (máx. 120 caracteres). |
| name required | string Nombre visible de la categoría (máx. 120 caracteres). |
| description | string Descripción opcional de la categoría (máx. 240 caracteres). |
| order required | integer Orden de visualización de la categoría. |
| visibility required | string Enum: "visible" "hidden" Visibilidad de la categoría en ventas. |
| state required | string Enum: "enabled" "disabled" Estado inicial de la categoría. |
| color | string Color hexadecimal de la categoría. |
| icon | string Nombre del archivo de ícono (debe tener extensión .jpg, .jpeg o .png). |
{- "parentId": 1,
- "code": "BEB-001",
- "name": "Bebidas",
- "description": "Todas las bebidas disponibles.",
- "order": 1,
- "visibility": "visible",
- "state": "enabled",
- "color": "#3498DB",
- "icon": "bebidas.png"
}{- "success": true,
- "message": "Operación exitosa",
- "data": {
- "id": 5,
- "code": "BEB-001",
- "name": "Bebidas",
- "description": "Todas las bebidas disponibles.",
- "order": 1,
- "visibility": "visible",
- "state": "enabled",
- "color": "#3498DB",
- "icon": {
- "name": "bebidas.png",
}, - "productCount": 0,
- "parent": {
- "id": 1,
- "name": "Menú Principal"
}, - "createdAt": "2026-07-16T12:00:00Z",
- "updatedAt": "2026-07-16T12:00:00Z"
}, - "errors": [ ],
- "meta": { },
- "traceId": "729bb1bf-882d-483b-89d3-5855dc5af3aa"
}Obtiene el detalle completo de una categoría perteneciente a la empresa activa.
Disponible para los roles: owner, manager, vendor, assistant.
| categoryId required | integer >= 1 Identificador único de la categoría. |
{- "success": true,
- "message": "Detalle de categoría obtenido correctamente.",
- "data": {
- "id": 1,
- "code": "ELEC-01",
- "name": "Electrónicos",
- "description": "Categoría de productos electrónicos",
- "order": 1,
- "color": "#FF0000",
- "visibility": "visible",
- "state": "enabled",
- "categoryType": "parent",
- "parent": {
- "id": 2,
- "name": "Hogar",
- "code": "HOG-01",
- "description": "Productos para el hogar",
- "order": 1,
- "state": "enabled",
}, - "subcategoryCount": 2,
- "productCount": 0,
- "createdAt": "2026-07-20T10:30:00Z",
- "updatedAt": "2026-07-20T14:20:00Z"
}, - "errors": [ ],
- "meta": { },
- "traceId": "550e8400-e29b-41d4-a716-446655440000"
}Actualiza una categoría existente dentro de la empresa activa. Se permite actualización parcial; solo los campos enviados serán modificados.
Restricciones:
| categoryId required | integer >= 1 Identificador único de la categoría a actualizar. |
| code | string <= 120 characters Código único de la categoría en la empresa. |
| name | string <= 120 characters Nombre de la categoría. |
| description | string or null <= 240 characters Descripción opcional. Enviar |
| order | integer [ 1 .. 255 ] Orden de aparición de la categoría. |
| visibility | string Enum: "visible" "hidden" Visibilidad para ventas. |
| state | string Enum: "enabled" "disabled" Estado de la categoría. No se permite enviar |
| color | string or null Color en formato hexadecimal. Enviar |
| icon | string or null Nombre de archivo de la imagen de ícono (ej. icon.png). Enviar |
{- "code": "CAT-001",
- "name": "Electrónica",
- "description": "Productos electrónicos",
- "order": 1,
- "visibility": "visible",
- "state": "enabled",
- "color": "#FF5733",
- "icon": "icon.png"
}{- "success": true,
- "message": "Operación exitosa",
- "data": {
- "id": 5,
- "code": "BEB-001",
- "name": "Bebidas",
- "description": "Todas las bebidas disponibles.",
- "order": 1,
- "visibility": "visible",
- "state": "enabled",
- "color": "#3498DB",
- "icon": {
- "name": "bebidas.png",
}, - "productCount": 0,
- "parent": {
- "id": 1,
- "name": "Menú Principal"
}, - "createdAt": "2026-07-16T12:00:00Z",
- "updatedAt": "2026-07-16T12:00:00Z"
}, - "errors": [ ],
- "meta": { },
- "traceId": "729bb1bf-882d-483b-89d3-5855dc5af3aa"
}Elimina físicamente una categoría existente dentro de la empresa activa del usuario. Esta operación eliminará en cascada las subcategorías dependientes (y todos sus descendientes), respetando la jerarquía.
Restricciones:
| categoryId required | integer >= 1 Identificador único de la categoría a eliminar. |
{- "success": true,
- "message": "Operación exitosa",
- "data": {
- "result": "category_deleted",
- "categoryId": 5,
- "childrenDeleted": 3
}, - "errors": [ ],
- "meta": { },
- "traceId": "729bb1bf-882d-483b-89d3-5855dc5af3aa"
}Endpoints de gestión de productos. Incluye operaciones para el registro de productos, variantes e imágenes en el catálogo de una empresa.
Elimina físicamente un producto o servicio existente dentro de la empresa activa del usuario. Esta operación eliminará en cascada todas las variantes e imágenes (generales y de variante) asociadas al producto.
Restricciones:
| productId required | integer >= 1 Identificador único del producto a eliminar. |
{- "success": true,
- "message": "Operación exitosa",
- "data": {
- "result": "product_deleted",
- "id": 10,
- "code": "PROD-001",
- "name": "Laptop Dell XPS",
- "productType": "product",
- "deletedVariants": 2,
- "deletedImages": 5
}, - "errors": [ ],
- "meta": { },
- "traceId": "729bb1bf-882d-483b-89d3-5855dc5af3aa"
}Obtiene un listado paginado del catálogo administrativo de productos y servicios pertenecientes a la empresa activa del usuario. Permite filtrar por categoría, tipo de producto y estado, así como buscar por código, nombre o marca y ordenar los resultados. El listado solo incluirá registros de la empresa asociada al token activo.
Roles permitidos: propietario, administrador, vendedor, auxiliar.
| search | string Término de búsqueda que aplica coincidencia parcial sobre el código, nombre o marca del producto (máx. 255 caracteres). |
| categoryId | integer ID de la categoría asociada al producto. |
| productType | string Enum: "product" "service" Filtra por el tipo de registro (producto o servicio). |
| state | string Enum: "enabled" "disabled" "suspended" Filtra por el estado del producto. |
| sortBy | string Default: "updatedAt" Enum: "code" "name" "category" "brand" "productType" "price" "state" "updatedAt" Nombre del campo por el cual ordenar los resultados. |
| sortDirection | string Default: "desc" Enum: "asc" "desc" Dirección del ordenamiento. |
| page | integer Default: 1 Número de página para la paginación de resultados. |
| perPage | integer Default: 10 Enum: 5 10 25 50 100 Cantidad de resultados a devolver por página. |
{- "success": true,
- "message": "Operación exitosa",
- "data": [
- {
- "id": 12,
- "mainImage": {
- "name": "smartphone_main.jpg",
}, - "code": "PRD-001",
- "name": "Smartphone Galaxy Ultra 5G",
- "category": {
- "id": 1,
- "icon": {
- "name": "electronica.png",
}, - "code": "CAT-001",
- "name": "Electrónica"
}, - "brand": "Samsung",
- "productType": "product",
- "price": 1200.5,
- "state": "enabled",
- "updatedAt": "2026-07-22T15:00:00Z"
}
], - "errors": [ ],
- "meta": {
- "pagination": {
- "page": 1,
- "perPage": 10,
- "total": 12,
- "lastPage": 2,
- "count": 10
}, - "filters": {
- "search": null,
- "categoryId": null,
- "productType": null,
- "state": null
}, - "sort": {
- "sortBy": "updatedAt",
- "sortDirection": "desc"
}
}, - "traceId": "729bb1bf-882d-483b-89d3-5855dc5af3aa"
}Registra un nuevo producto o servicio dentro del catálogo de la empresa activa del usuario. La categoría informada debe existir y pertenecer a la empresa.
El registro incluye tanto los datos básicos como galerías de imágenes y variantes, ejecutándose toda la persistencia de forma transaccional.
Restricciones:
código debe ser único dentro de la empresa.código de barras, si se envía, también debe ser único en la empresa.suspended.| category required | integer ID de la categoría perteneciente a la empresa activa. |
| code required | string Código único del producto en la empresa (máx. 240 caracteres). |
| name required | string Nombre visible del producto o servicio (máx. 240 caracteres). |
| description | string or null Texto descriptivo del producto. |
| supplier | string or null Proveedor del producto. |
| brand | string or null Marca del producto. |
| note | string or null Nota interna o administrativa. |
| barcode | string or null Código de barras único en la empresa. |
| price required | number <float> Precio base de venta. Debe ser mayor a 0. |
| cost | number or null <float> Costo de adquisición. |
| unitOfMeasure required | string Enum: "unit" "kilogram" "liter" "box" "bag" "gram" "milliliter" "meter" "centimeter" "pack" "piece" "service" Unidad de medida de venta (ej. unit, kilogram, liter, box). |
| quantityIncrement required | number <float> Incremento al vender. |
| minimumQuantity required | number <float> Cantidad mínima por venta. |
| maximumQuantity | number or null <float> Cantidad máxima por venta (debe ser mayor o igual a la mínima). |
| mainImage | string or null Referencia del archivo de imagen principal (sin URL absoluta). |
| tags | Array of strings or null Etiquetas descriptivas. |
| discountType | string or null Enum: "percentage" "amount" Tipo de descuento promocional base. |
| discountAmount | number or null <float> Valor del descuento. Si el tipo es porcentaje, no debe superar 100. |
| discountEndsAt | string or null <date-time> Fecha de caducidad del descuento (debe ser futura). |
| visibility required | string Enum: "visible" "hidden" Determina si se muestra en el catálogo de ventas. |
| featured | boolean or null Marca si es un producto destacado. |
| type required | string Enum: "product" "service" Tipo de ítem. |
| state required | string Enum: "enabled" "disabled" Estado comercial inicial. |
Array of objects or null Galería general de imágenes. | |
Array of objects or null Variantes del producto. Cada una debe tener tamaño o color, y un orden único. |
{- "category": 1,
- "code": "PRD-FULL-001",
- "name": "Smartphone Galaxy Ultra 5G",
- "price": 1200.5,
- "unitOfMeasure": "unit",
- "quantityIncrement": 1,
- "minimumQuantity": 1,
- "visibility": "visible",
- "type": "product",
- "state": "enabled",
- "description": "El teléfono más potente de la serie Galaxy con cámara de 200MP.",
- "supplier": "Samsung Electronics",
- "brand": "Samsung",
- "note": "Edición especial con cargador incluido",
- "barcode": "7891234560001",
- "cost": 950,
- "maximumQuantity": 50,
- "mainImage": "imagen_principal_samsung.jpg",
- "featured": true,
- "tags": [
- "smartphone",
- "5g",
- "samsung"
], - "discountType": "amount",
- "discountAmount": 50,
- "discountEndsAt": "2026-12-31T23:59:59Z",
- "images": [
- {
- "name": "vista_frontal.jpg",
- "order": 1
}, - {
- "name": "vista_trasera.jpg",
- "order": 2
}
], - "variants": [
- {
- "size": "256GB",
- "color": "#000000",
- "order": 1,
- "price": 1200.5,
- "state": "enabled",
- "images": [
- {
- "name": "variante_negro_1.jpg",
- "order": 1
}
]
}, - {
- "size": "512GB",
- "color": "#FFFFFF",
- "order": 2,
- "price": 1350,
- "state": "enabled",
- "images": [
- {
- "name": "variante_blanco_1.jpg",
- "order": 1
}, - {
- "name": "variante_blanco_2.jpg",
- "order": 2
}
]
}
]
}{- "success": true,
- "message": "Operación exitosa",
- "data": {
- "id": 12,
- "code": "PRD-001",
- "name": "Zapatillas Deportivas",
- "description": "Zapatillas ideales para correr.",
- "supplier": "Nike",
- "brand": "Nike",
- "note": "Stock de prueba",
- "barcode": "7501234567890",
- "price": "450.5000",
- "cost": "300.0000",
- "profitMargin": "150.5000",
- "unitOfMeasure": "unit",
- "quantityIncrement": "1.0000",
- "minimumQuantity": "1.0000",
- "maximumQuantity": "50.0000",
- "tags": [
- "deporte",
- "calzado",
- "running"
], - "discountType": "percentage",
- "discountAmount": "10.0000",
- "discountEndsAt": "2026-12-31T23:59:59Z",
- "salesVisibility": true,
- "featured": true,
- "productType": "product",
- "state": "enabled",
- "category": {
- "id": 5,
- "name": "Calzados"
}, - "images": [
- {
- "id": 10,
- "name": "zapatillas_main.jpg",
- "order": 1
}
], - "variants": [
- {
- "id": 5,
- "size": "42",
- "color": "#FF0000",
- "order": 1,
- "price": "460.0000",
- "state": "enabled",
- "images": [
- {
- "id": 10,
- "name": "zapatillas_main.jpg",
- "order": 1
}
]
}
], - "createdAt": "2026-07-21T15:00:00Z",
- "updatedAt": "2026-07-21T15:00:00Z"
}, - "errors": [ ],
- "meta": { },
- "traceId": "729bb1bf-882d-483b-89d3-5855dc5af3aa"
}Obtiene la información completa de un producto o servicio perteneciente a la empresa activa del usuario. La consulta incluye la categoría parcial asociada con su padre opcional, información económica persistida, cantidades, galería general y colección de variantes con sus imágenes específicas. La empresa se resuelve desde el token empresarial; no se admite enviar identificadores de empresa.
Comportamiento:
name y url pública cuando existen. Si una imagen no existe o no se tiene principal, se retorna null.[] y los campos opcionales sin valor retornan null.| productId required | integer >= 1 Identificador del producto (entero mayor que cero). |
{- "success": true,
- "message": "Operación exitosa",
- "data": {
- "id": 12,
- "code": "PRD-001",
- "name": "Zapatillas Deportivas",
- "description": "Zapatillas ideales para correr.",
- "supplier": "Nike",
- "brand": "Nike",
- "note": "Stock de prueba",
- "barcode": "7501234567890",
- "category": {
- "id": 5,
- "icon": {
- "name": "calzados.png",
}, - "code": "CAT-002",
- "name": "Calzados",
- "type": "subcategory",
- "parent": {
- "id": 1,
- "code": "CAT-001",
- "name": "Ropa"
}
}, - "price": 450.5,
- "cost": 300,
- "profitMargin": 150.5,
- "unitOfMeasure": "unit",
- "quantityIncrement": 1,
- "minimumQuantity": 1,
- "maximumQuantity": 50,
- "mainImage": {
- "name": "zapatillas_main.jpg",
}, - "tags": [
- "deporte",
- "calzado"
], - "discountType": "percentage",
- "discountAmount": 10,
- "discountEndsAt": "2026-12-31T23:59:59Z",
- "discountActive": true,
- "salesVisibility": "visible",
- "featured": true,
- "productType": "product",
- "state": "enabled",
- "images": [
- {
- "id": 10,
- "name": "zapatillas_main.jpg",
- "order": 1
}
], - "variants": [
- {
- "id": 5,
- "size": "42",
- "color": "#FF0000",
- "order": 1,
- "price": 460,
- "state": "enabled",
- "images": [
- {
- "id": 10,
- "name": "zapatillas_main.jpg",
- "order": 1
}
]
}
], - "counts": {
- "variants": 1,
- "generalImages": 2,
- "variantImages": 1,
- "totalImages": 3
}, - "createdAt": "2026-07-21T15:00:00Z",
- "updatedAt": "2026-07-21T15:00:00Z"
}, - "errors": [ ],
- "meta": { },
- "traceId": "729bb1bf-882d-483b-89d3-5855dc5af3aa"
}Actualiza parcial o totalmente un producto o servicio existente en el catálogo de la empresa activa del usuario.
Reglas de sincronización:
null: Limpian el contenido del campo (solo para opcionales).state a suspended).images, sincroniza la galería completa. Array vacío elimina todas. Si se omite, se conserva.Restricciones:
suspended ni modificar un producto que esté suspended.| productId required | integer >= 1 ID del producto a actualizar. |
| category | integer ID de la categoría perteneciente a la empresa activa. |
| code | string Código único del producto en la empresa. |
| name | string Nombre visible del producto o servicio. |
| description | string or null Texto descriptivo del producto. |
| supplier | string or null Proveedor del producto. |
| brand | string or null Marca del producto. |
| note | string or null Nota interna o administrativa. |
| barcode | string or null Código de barras único en la empresa. |
| price | number <float> Precio base de venta. Debe ser mayor a 0. |
| cost | number or null <float> Costo de adquisición. |
| profitMargin | number or null <float> Margen de ganancia manual. No se recalcula automáticamente. |
| unitOfMeasure | string Enum: "unit" "kilogram" "liter" "box" "bag" "gram" "milliliter" "meter" "centimeter" "pack" "piece" "service" Unidad de medida del producto o servicio. |
| quantityIncrement | number <float> Incremento de cantidad permitido (ej. 0.5 o 1). |
| minimumQuantity | number <float> Cantidad mínima permitida para venta. |
| maximumQuantity | number or null <float> Cantidad máxima por venta (debe ser mayor o igual a la mínima resultante). |
| mainImage | string or null Referencia del archivo de imagen principal, o null para remover. |
| tags | Array of strings or null Etiquetas descriptivas (reemplaza las actuales, null limpia). |
| discountType | string or null Enum: "percentage" "amount" Tipo de descuento a aplicar (porcentaje o monto fijo). |
| discountAmount | number or null <float> Valor del descuento. Porcentaje <= 100, Monto <= Precio. |
| discountEndsAt | string or null <date-time> Fecha límite en la que el descuento finaliza. |
| visibility | string Enum: "visible" "hidden" Control de visibilidad del producto para la venta. |
| featured | boolean Indica si el producto está destacado. |
| type | string Enum: "product" "service" Clasificación del registro (producto físico o servicio). |
| state | string Enum: "enabled" "disabled" Solo se permite habilitado/deshabilitado. |
Array of objects or null Galería general de imágenes. Reemplaza la colección actual si se envía. | |
Array of objects or null Variantes del producto. Reemplaza la colección actual si se envía. |
{- "category": 1,
- "code": "QA-355-FULL",
- "name": "Producto Completo Actualizado",
- "price": 500,
- "unitOfMeasure": "unit",
- "quantityIncrement": 1,
- "minimumQuantity": 1,
- "visibility": "visible",
- "featured": true,
- "type": "product",
- "state": "enabled",
- "description": "Descripción completa y detallada.",
- "supplier": "Proveedor SA",
- "brand": "Marca Premium",
- "note": "Nota interna",
- "barcode": "9876543210123",
- "cost": 300,
- "profitMargin": 200,
- "maximumQuantity": 100,
- "mainImage": "main_updated.jpg",
- "tags": [
- "premium",
- "nuevo",
- "actualizado"
], - "discountType": "percentage",
- "discountAmount": 15,
- "discountEndsAt": "2026-12-31T23:59:59Z",
- "images": [
- {
- "id": 23,
- "name": "foto_general_existente_mod.jpg",
- "order": 1
}, - {
- "name": "foto_general_nueva.jpg",
- "order": 2
}
], - "variants": [
- {
- "id": 11,
- "size": "L",
- "color": "black",
- "order": 1,
- "price": 550,
- "state": "enabled",
- "images": [
- {
- "name": "variante_negra_img.jpg",
- "order": 1
}
]
}, - {
- "size": "S",
- "color": "white",
- "order": 2,
- "price": 480,
- "state": "disabled",
- "images": [ ]
}
]
}{- "success": true,
- "message": "Operación exitosa",
- "data": {
- "id": 12,
- "code": "PRD-001",
- "name": "Zapatillas Deportivas",
- "description": "Zapatillas ideales para correr.",
- "supplier": "Nike",
- "brand": "Nike",
- "note": "Stock de prueba",
- "barcode": "7501234567890",
- "category": {
- "id": 5,
- "icon": {
- "name": "calzados.png",
}, - "code": "CAT-002",
- "name": "Calzados",
- "type": "subcategory",
- "parent": {
- "id": 1,
- "code": "CAT-001",
- "name": "Ropa"
}
}, - "price": 450.5,
- "cost": 300,
- "profitMargin": 150.5,
- "unitOfMeasure": "unit",
- "quantityIncrement": 1,
- "minimumQuantity": 1,
- "maximumQuantity": 50,
- "mainImage": {
- "name": "zapatillas_main.jpg",
}, - "tags": [
- "deporte",
- "calzado"
], - "discountType": "percentage",
- "discountAmount": 10,
- "discountEndsAt": "2026-12-31T23:59:59Z",
- "discountActive": true,
- "salesVisibility": "visible",
- "featured": true,
- "productType": "product",
- "state": "enabled",
- "images": [
- {
- "id": 10,
- "name": "zapatillas_main.jpg",
- "order": 1
}
], - "variants": [
- {
- "id": 5,
- "size": "42",
- "color": "#FF0000",
- "order": 1,
- "price": 460,
- "state": "enabled",
- "images": [
- {
- "id": 10,
- "name": "zapatillas_main.jpg",
- "order": 1
}
]
}
], - "counts": {
- "variants": 1,
- "generalImages": 2,
- "variantImages": 1,
- "totalImages": 3
}, - "createdAt": "2026-07-21T15:00:00Z",
- "updatedAt": "2026-07-21T15:00:00Z"
}, - "errors": [ ],
- "meta": { },
- "traceId": "729bb1bf-882d-483b-89d3-5855dc5af3aa"
}Endpoints de gestión de clientes. Incluye el registro de clientes de tipo persona y empresa dentro del contexto de una empresa.
Registra un nuevo cliente (persona o empresa) dentro de la empresa activa del usuario. La empresa se resuelve desde el token empresarial; no se admite enviar identificadores de empresa.
Restricciones:
fullName lo genera el backend; no debe enviarse.documentType acepta el catálogo público en minúsculas (ci, cex, pas, od, nit).| code required | string <= 240 characters Código único del cliente dentro de la empresa. |
| name required | string <= 120 characters Nombre del cliente (persona) o del contacto principal (empresa). |
| lastName required | string <= 120 characters Apellido del cliente o del contacto principal. |
| email required | string <email> <= 240 characters Correo del cliente. Se normaliza en minúsculas; no requiere unicidad. |
| type required | string Enum: "person" "business" Tipo de cliente. |
| state required | string Enum: "enabled" "disabled" Estado inicial del cliente (suspendido no está permitido al registrar). |
| businessName | string <= 255 characters Razón social. Obligatoria cuando el tipo es empresa. |
| phone | string <= 16 characters ^\+[1-9]\d{1,14}$ Teléfono de contacto en formato E.164 (signo + código de país y hasta 15 dígitos, sin espacios ni guiones). |
| avatar | string <= 240 characters Referencia final del avatar (nombre de archivo .jpg, .jpeg, .png). |
| note | string Nota interna del cliente. |
| birthDate | string <date> Fecha de nacimiento (solo para persona, no futura). |
| gender | string Enum: "male" "female" "prefer_not_to_say" Género (solo para persona). |
| country | string = 2 characters Código de país ISO alfabético de dos letras. |
| city | string <= 120 characters Ciudad del cliente. |
| address | string <= 255 characters Dirección del cliente. |
| latitude | number [ -90 .. 90 ] Latitud. Debe enviarse junto con la longitud. |
| longitude | number [ -180 .. 180 ] Longitud. Debe enviarse junto con la latitud. |
| documentType | string Enum: "ci" "cex" "pas" "od" "nit" Tipo de documento (catálogo público en minúsculas). |
| documentNumber | string <= 30 characters Número de documento. Obligatorio cuando se envía el tipo de documento. |
| documentComplement | string <= 10 characters Complemento documental. Solo aplicable cuando el tipo de documento es CI. |
{- "code": "CLI-001",
- "name": "Juan",
- "lastName": "Pérez",
- "email": "juan@cliente.com",
- "type": "person",
- "state": "enabled",
- "businessName": "Tech Solutions S.R.L.",
- "phone": "+59170000000",
- "avatar": "cliente-12.png",
- "note": "Cliente frecuente.",
- "birthDate": "1990-05-20",
- "gender": "male",
- "country": "BO",
- "city": "La Paz",
- "address": "Av. Desconocida 123",
- "latitude": -16.5,
- "longitude": -68.15,
- "documentType": "ci",
- "documentNumber": "9876543",
- "documentComplement": "1A"
}{- "success": true,
- "message": "Operación exitosa",
- "data": {
- "id": 12,
- "code": "CLI-001",
- "name": "Juan",
- "lastName": "Pérez",
- "fullName": "Juan Pérez",
- "email": "juan@cliente.com",
- "phone": "+59170000000",
- "type": "person",
- "state": "enabled",
- "businessName": null,
- "note": null,
- "birthDate": "1990-05-20",
- "gender": "male",
- "country": "BO",
- "city": "La Paz",
- "address": "Av. Desconocida 123",
- "latitude": -16.5,
- "longitude": -68.15,
- "documentType": "ci",
- "documentNumber": "9876543",
- "documentComplement": null,
- "avatar": {
- "name": "cliente-12.png",
}, - "createdAt": "2026-07-22T12:00:00Z",
- "updatedAt": "2026-07-22T12:00:00Z"
}, - "errors": [ ],
- "meta": { },
- "traceId": "729bb1bf-882d-483b-89d3-5855dc5af3aa"
}Obtiene un listado paginado y resumido de los clientes pertenecientes a la empresa activa del usuario. La empresa se resuelve desde el token empresarial; no se admite enviar identificadores de empresa.
Permite búsqueda configurable por campos, filtros por tipo de documento, modelo y estado, ordenamiento y paginación. Todas las operaciones se resuelven desde base de datos.
Roles permitidos: propietario, administrador, vendedor y auxiliar.
| search | string <= 255 characters Término de búsqueda (coincidencia parcial). Se recorta; un valor vacío se trata como ausencia de búsqueda. |
| searchIn | Array of strings <= 5 items Items Enum: "code" "fullName" "email" "phone" "document" Campos sobre los que aplicar la búsqueda. Si se omite y hay término, se usan los cinco campos.
Con búsqueda activa debe contener entre 1 y 5 valores únicos y válidos.
Se envía separado por comas (ej. |
| documentType | string Enum: "ci" "cex" "pas" "od" "nit" Filtra por tipo documental (catálogo público en minúsculas). |
| model | string Enum: "person" "business" Filtra por modelo de cliente. Se mapea a la columna interna de tipo. |
| state | string Enum: "enabled" "disabled" "suspended" Filtra por estado del cliente. |
| sortBy | string Default: "fullName" Enum: "code" "fullName" "email" "phone" "documentType" "document" "state" "updatedAt" Campo por el cual ordenar los resultados. |
| sortDirection | string Default: "asc" Enum: "asc" "desc" Dirección del ordenamiento. |
| page | integer >= 1 Default: 1 Número de página. |
| perPage | integer Default: 10 Enum: 5 10 25 50 100 Cantidad de resultados por página. |
{- "success": true,
- "message": "Operación exitosa",
- "data": [
- {
- "id": 12,
- "avatar": {
- "name": "cliente-12.png",
}, - "code": "CLI-001",
- "fullName": "Juan Pérez",
- "email": "juan@cliente.com",
- "phone": "+59170000000",
- "documentType": "ci",
- "document": "9876543-1A",
- "state": "enabled",
- "updatedAt": "2026-07-22T12:00:00Z"
}
], - "errors": [ ],
- "meta": {
- "pagination": {
- "page": 1,
- "perPage": 10,
- "total": 12,
- "lastPage": 2,
- "count": 10
}, - "filters": {
- "search": null,
- "searchIn": [
- "code",
- "fullName",
- "email",
- "phone",
- "document"
], - "documentType": null,
- "model": null,
- "state": null
}, - "sort": {
- "sortBy": "fullName",
- "sortDirection": "asc"
}
}, - "traceId": "729bb1bf-882d-483b-89d3-5855dc5af3aa"
}Obtiene la información completa de un cliente perteneciente a la empresa activa del usuario. La empresa se resuelve desde el token empresarial; no se admite enviar identificadores de empresa.
Comportamiento:
| customerId required | integer >= 1 Identificador del cliente (entero mayor que cero). |
{- "success": true,
- "message": "Operación exitosa",
- "data": {
- "id": 12,
- "code": "CLI-001",
- "name": "Carlos",
- "lastName": "Pérez",
- "fullName": "Carlos Pérez",
- "avatar": {
- "name": "cliente-12.png",
}, - "email": "carlos@cliente.com",
- "phone": "+59170000000",
- "birthDate": "1990-05-20",
- "gender": "male",
- "note": "Cliente frecuente.",
- "country": "BO",
- "city": "La Paz",
- "address": "Av. Desconocida 123",
- "latitude": -16.5,
- "longitude": -68.15,
- "businessName": "Tech Solutions S.R.L.",
- "type": "person",
- "documentType": "ci",
- "documentNumber": "9876543",
- "documentComplement": "1A",
- "document": "9876543-1A",
- "state": "enabled",
- "createdAt": "2026-07-22T00:34:25Z",
- "updatedAt": "2026-07-22T22:41:48Z"
}, - "errors": [ ],
- "meta": { },
- "traceId": "729bb1bf-882d-483b-89d3-5855dc5af3aa"
}Actualiza (parcial o totalmente) un cliente perteneciente a la empresa activa del usuario. La empresa se resuelve desde el token empresarial; no se admite enviar identificadores de empresa.
Semántica de actualización:
null se limpia.code, name, lastName, email, type, state) no pueden quedar nulos ni vacíos. businessName es obligatoria cuando el tipo final es empresa.fullName lo reconstruye el backend cuando cambia name o lastName; no debe enviarse.enabled y disabled; suspended no puede enviarse como destino y un cliente suspendido no puede modificar su estado.| customerId required | integer >= 1 Identificador del cliente (entero mayor que cero). |
Colección parcial de propiedades modificables. Los opcionales admiten null para limpiarse.
| code | string <= 240 characters Código empresarial (controlado, único en la empresa). |
| name | string <= 120 characters Nombre del cliente o contacto principal (controlado). |
| lastName | string <= 120 characters Apellido del cliente o contacto principal (controlado). |
string <email> <= 240 characters Correo de contacto (controlado, se guarda en minúsculas). | |
| type | string Enum: "person" "business" Modelo del cliente. Puede cambiar entre persona y empresa. |
| state | string Enum: "enabled" "disabled" Estado operativo. Solo transiciones entre habilitado y deshabilitado. |
| businessName | string or null <= 255 characters Razón social. Obligatoria para empresa. |
| phone | string or null <= 16 characters ^\+[1-9]\d{1,14}$ Teléfono en formato E.164, o null para limpiar. |
| avatar | string or null <= 240 characters Referencia final del avatar, o null para retirar. |
| note | string or null Nota interna, o null para limpiar. |
| birthDate | string or null <date> Fecha de nacimiento (solo persona; no futura). |
| gender | string or null Enum: "male" "female" "prefer_not_to_say" null Género (solo persona). |
| country | string or null = 2 characters Código de país ISO de dos letras. |
| city | string or null <= 120 characters Ciudad, o null para limpiar. |
| address | string or null Dirección, o null para limpiar. |
| latitude | number or null [ -90 .. 90 ] Latitud (-90 a 90). Debe ir junto con la longitud. |
| longitude | number or null [ -180 .. 180 ] Longitud (-180 a 180). Debe ir junto con la latitud. |
| documentType | string or null Enum: "ci" "cex" "pas" "od" "nit" null Tipo de documento (catálogo público en minúsculas). |
| documentNumber | string or null <= 30 characters Número de documento (requiere tipo). |
| documentComplement | string or null <= 10 characters Complemento documental (solo para CI). |
{- "code": "CLI-001",
- "name": "Carlos",
- "lastName": "Pérez",
- "email": "carlos@cliente.com",
- "type": "person",
- "state": "enabled",
- "businessName": "Tech Solutions S.R.L.",
- "phone": "+59170000000",
- "avatar": "cliente-12.png",
- "note": "Cliente frecuente.",
- "birthDate": "1990-05-20",
- "gender": "male",
- "country": "BO",
- "city": "La Paz",
- "address": "Av. Siempre Viva 123",
- "latitude": -16.5,
- "longitude": -68.15,
- "documentType": "ci",
- "documentNumber": "9876543",
- "documentComplement": "1A"
}{- "success": true,
- "message": "Operación exitosa",
- "data": {
- "id": 12,
- "code": "CLI-001",
- "name": "Carlos",
- "lastName": "Pérez",
- "fullName": "Carlos Pérez",
- "avatar": {
- "name": "cliente-12.png",
}, - "email": "carlos@cliente.com",
- "phone": "+59170000000",
- "birthDate": "1990-05-20",
- "gender": "male",
- "note": "Cliente frecuente.",
- "country": "BO",
- "city": "La Paz",
- "address": "Av. Desconocida 123",
- "latitude": -16.5,
- "longitude": -68.15,
- "businessName": "Tech Solutions S.R.L.",
- "type": "person",
- "documentType": "ci",
- "documentNumber": "9876543",
- "documentComplement": "1A",
- "document": "9876543-1A",
- "state": "enabled",
- "createdAt": "2026-07-22T00:34:25Z",
- "updatedAt": "2026-07-22T22:41:48Z"
}, - "errors": [ ],
- "meta": { },
- "traceId": "729bb1bf-882d-483b-89d3-5855dc5af3aa"
}Elimina un cliente perteneciente a la empresa activa del usuario. La empresa se resuelve desde el token empresarial; no se admite enviar identificadores de empresa.
Restricciones y comportamiento:
| customerId required | integer >= 1 Identificador del cliente a eliminar (entero mayor que cero). |
{- "success": true,
- "message": "Operación exitosa",
- "data": {
- "result": "customer_deleted",
- "id": 12,
- "code": "CLI-001",
- "fullName": "Juan Pérez",
- "type": "person",
- "deletedRelations": 0
}, - "errors": [ ],
- "meta": { },
- "traceId": "729bb1bf-882d-483b-89d3-5855dc5af3aa"
}Endpoints de gestión y administración de archivos del sistema. Exclusivos para usuarios con tokens maestros o tokens empresariales.
Sube un archivo de imagen o documento segun el tipo especificado (logo - banner - avatar - documento - certificado). El acceso esta abierto a usuarios de sistema y usuarios empresariales. El contenido de la solicitud debe estar en multipart/form-data.
Datos requeridos para subir un archivo de imagen a su respectivo entorno.
| file required | string <binary> Archivo de imagen o documento para subida. |
| type required | string Enum: "logo" "banner" "avatar" "documentation" "certificate" Destino del archivo asociado a la imagen. |
{- "success": true,
- "message": "El archivo de imagen se ha almacenado correctamente.",
- "data": {
- "name": "a1b01fe0-1511-4379-b505-572f9cdcfcd5",
- "extension": "jpg",
- "size": 117958,
}, - "errors": [ ],
- "meta": { },
- "traceId": "75b25c0f-31fc-4820-a093-22adbe797fd5"
}Restablece la base de datos a su estado inicial. Este endpoint está estrictamente protegido y solo funciona en entornos locales y de QA.
| reason required | string [ 10 .. 255 ] characters Razón o justificación por la cual se está solicitando el restablecimiento de la base de datos. |
{- "reason": "Restablecimiento por pruebas de integración y QA."
}{- "success": true,
- "message": "Operación exitosa",
- "data": null,
- "errors": [ ],
- "meta": { },
- "traceId": "729bb1bf-882d-483b-89d3-5855dc5af3aa"
}