C
Cotizera Docs

Clientes

API de Clientes

Endpoints para administrar tu directorio de clientes. Cada cliente tiene un email único por tenant.


Listar Clientes

GET /api/clients

Permiso: clients:read

Obtén una lista paginada de clientes activos del tenant actual.

Query Parameters:

Parameter Type Required Description
search string No Busca por nombre de contacto, nombre de empresa o email (sin distinguir mayúsculas)
page number No Número de página (por defecto: 1)

Response 200 OK:

{
  "data": [
    {
      "id": "clxyz...",
      "contactName": "María López",
      "companyName": "Distribuidora del Norte S.A.",
      "email": "maria@distribuidora.mx",
      "phone": "+52 81 1234 5678",
      "isActive": true,
      "tenantId": "...",
      "createdAt": "2026-03-01T10:00:00.000Z",
      "updatedAt": "2026-03-15T14:00:00.000Z"
    }
  ],
  "total": 45,
  "page": 1,
  "totalPages": 3
}

Ejemplo con cURL:

curl -X GET "https://cotizera.com/api/clients?search=María&page=1" \
  -H "Cookie: next-auth.session-token=YOUR_TOKEN"

Crear Cliente

POST /api/clients

Permiso: clients:create

Crea un nuevo cliente. El email debe ser único dentro del tenant.

Request Body:

{
  "contactName": "Roberto García",
  "companyName": "Servicios Industriales MX",
  "email": "roberto@servindustrial.mx",
  "phone": "+52 55 9876 5432"
}
Field Type Required Description
contactName string Yes Nombre de la persona de contacto (mínimo 1 carácter)
companyName string No Nombre de la empresa o negocio
email string Yes Dirección de email válida (única por tenant)
phone string No Número de teléfono

Response 201 Created: Devuelve el objeto del cliente creado.

Errores:

Status Error Cuándo
400 Mensaje de validación Zod Entrada inválida
401 "No autorizado" Sesión ausente o inválida
403 "Sin permisos" El rol no tiene clients:create
409 "Ya existe un cliente con ese correo" Email duplicado en el tenant

Efectos secundarios:

  • Dispara el evento webhook client.created
  • Activa el paso de onboarding first_client
  • Registra una entrada de auditoría con acción create

Obtener un Cliente

GET /api/clients/:id

Permiso: clients:read

Obtén un cliente activo individual. Opcionalmente puedes incluir su historial de cotizaciones.

Query Parameters:

Parameter Type Required Description
includeQuotes string No Establece "true" para incluir las cotizaciones del cliente

Response 200 OK (con includeQuotes=true):

{
  "id": "clxyz...",
  "contactName": "María López",
  "companyName": "Distribuidora del Norte S.A.",
  "email": "maria@distribuidora.mx",
  "phone": "+52 81 1234 5678",
  "quotes": [
    {
      "id": "...",
      "quoteNumber": 42,
      "status": "WON",
      "total": "17900.00",
      "createdAt": "2026-03-31T10:00:00.000Z",
      "_count": { "items": 3 }
    }
  ]
}

Errores:

Status Error Cuándo
404 "Cliente no encontrado" Cliente no encontrado, inactivo o de otro tenant

Actualizar Cliente

PUT /api/clients/:id

Permiso: clients:update

Actualiza la información de un cliente existente. Si se cambia el email, se vuelve a validar la unicidad.

Request Body: Mismo esquema que Crear Cliente.

Response 200 OK: Devuelve el objeto del cliente actualizado.

Errores:

Status Error Cuándo
404 "Cliente no encontrado" Cliente no encontrado o inactivo
409 "Ya existe un cliente con ese correo" El nuevo email entra en conflicto con otro cliente existente

Eliminar Cliente (Soft Delete)

DELETE /api/clients/:id

Permiso: clients:delete

Elimina un cliente de forma lógica estableciendo isActive en false. Los datos del cliente se conservan pero se excluyen de los listados.

Response 200 OK:

{
  "success": true
}

Errores:

Status Error Cuándo
404 "Cliente no encontrado" Cliente no encontrado o ya está inactivo
© 2026 Cotizera. All rights reserved.