C
Cotizera Docs

Clients

Clients API

Endpoints for managing your client directory. Each client has a unique email per tenant.


List Clients

GET /api/clients

Permission: clients:read

Retrieve a paginated list of active clients for the current tenant.

Query Parameters:

Parameter Type Required Description
search string No Search by contact name, company name, or email (case-insensitive)
page number No Page number (default: 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
}

cURL Example:

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

Create Client

POST /api/clients

Permission: clients:create

Create a new client. Email must be unique within the 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 Contact person name (min 1 character)
companyName string No Company or business name
email string Yes Valid email address (unique per tenant)
phone string No Phone number

Response 201 Created: Returns the created client object.

Errors:

Status Error When
400 Zod validation message Invalid input
401 "No autorizado" Missing or invalid session
403 "Sin permisos" Role lacks clients:create
409 "Ya existe un cliente con ese correo" Duplicate email in tenant

Side Effects:

  • Fires client.created webhook event
  • Triggers onboarding step first_client completion
  • Logs audit entry with action create

Get Single Client

GET /api/clients/:id

Permission: clients:read

Retrieve a single active client. Optionally include their quote history.

Query Parameters:

Parameter Type Required Description
includeQuotes string No Set to "true" to include the client's quotes

Response 200 OK (with 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 }
    }
  ]
}

Errors:

Status Error When
404 "Cliente no encontrado" Client not found, inactive, or wrong tenant

Update Client

PUT /api/clients/:id

Permission: clients:update

Update an existing client's information. If the email is changed, uniqueness is re-validated.

Request Body: Same schema as Create Client.

Response 200 OK: Returns the updated client object.

Errors:

Status Error When
404 "Cliente no encontrado" Client not found or inactive
409 "Ya existe un cliente con ese correo" New email conflicts with existing client

Delete Client (Soft Delete)

DELETE /api/clients/:id

Permission: clients:delete

Soft-deletes a client by setting isActive to false. The client's data is preserved but excluded from listings.

Response 200 OK:

{
  "success": true
}

Errors:

Status Error When
404 "Cliente no encontrado" Client not found or already inactive
© 2026 Cotizera. All rights reserved.