Collaborators
Collaborators API
Endpoints for managing team members. Owners can invite collaborators via email, activate/deactivate them, and resend invitations.
List Collaborators
GET /api/collaborators
Permission: collaborators:manage (Owner only)
List all collaborators for the current tenant.
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| search | string | No | Search by name or email (case-insensitive) |
Response 200 OK:
{
"data": [
{
"id": "clxyz...",
"email": "ana@empresa.mx",
"name": "Ana Rodríguez",
"isActive": true,
"confirmedAt": "2026-03-15T10:00:00.000Z",
"inviteExpiresAt": null,
"createdAt": "2026-03-10T08:00:00.000Z"
}
]
}A collaborator with confirmedAt: null has been invited but hasn't accepted yet.
Invite Collaborator
POST /api/collaborators
Permission: collaborators:manage | Plan limits enforced (FREE plan has a max collaborator count)
Send an email invitation to a new collaborator. Creates a user record with COLLABORATOR role and a temporary password. The invitee must accept the invite to set their password and activate their account.
Request Body:
{
"email": "nuevo@empresa.mx",
"name": "Jorge Hernández"
}| Field | Type | Required | Description |
|---|---|---|---|
| string | Yes | Valid email (must not exist in tenant or globally) | |
| name | string | Yes | Collaborator's name (min 2 characters) |
Response 201 Created:
{
"id": "clxyz...",
"email": "nuevo@empresa.mx",
"name": "Jorge Hernández",
"isActive": true,
"confirmedAt": null,
"inviteExpiresAt": "2026-04-03T10:00:00.000Z",
"createdAt": "2026-03-31T10:00:00.000Z",
"inviteUrl": "https://cotizera.com/invite/abc-123-def"
}Errors:
| Status | Error | When |
|---|---|---|
| 403 | "Límite de colaboradores alcanzado. Actualiza a Pro para invitar más." | FREE plan collaborator limit reached |
| 409 | "Ya existe un colaborador con ese correo en este negocio" | Email already in tenant |
| 409 | "Este correo ya está registrado en la plataforma" | Email exists globally |
Side Effects:
- Sends invitation email via Resend
- Invite token expires in 72 hours
- Logs audit entry with action
invite
Activate / Deactivate Collaborator
PUT /api/collaborators/:id
Permission: collaborators:manage
Toggle a collaborator's active status.
Request Body:
{
"isActive": false
}| Field | Type | Required | Description |
|---|---|---|---|
| isActive | boolean | Yes | true to activate, false to deactivate |
Response 200 OK: Returns the updated collaborator object.
Errors:
| Status | Error | When |
|---|---|---|
| 404 | "Colaborador no encontrado" | Collaborator not found in tenant |
Resend Invite
PATCH /api/collaborators/:id
Permission: collaborators:manage
Regenerate the invite token (extends expiry by 72 hours) and resend the invitation email. Only works for collaborators who haven't accepted yet.
Request Body: None required.
Response 200 OK:
{
"inviteUrl": "https://cotizera.com/invite/new-token-xyz"
}Errors:
| Status | Error | When |
|---|---|---|
| 400 | "Este colaborador ya aceptó la invitación" | Collaborator already confirmed |
| 404 | "Colaborador no encontrado" | Not found in tenant |
Validate Invite Token
GET /api/collaborators/accept
No authentication required — public endpoint.
Validate an invite token and return the invitee's information. Used by the invite acceptance page.
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| token | string | Yes | The invite token from the URL |
Response 200 OK:
{
"name": "Jorge Hernández",
"email": "nuevo@empresa.mx",
"companyName": "Acme Solutions S.A. de C.V."
}Errors:
| Status | Error | When |
|---|---|---|
| 400 | "Token requerido" | Missing token parameter |
| 400 | "Esta invitación ya fue aceptada" | Already confirmed |
| 404 | "Invitación inválida o ya utilizada" | Token not found |
| 410 | "La invitación ha expirado" | Token expired (72h) |
Accept Invite
POST /api/collaborators/accept
No authentication required — public endpoint.
Accept an invitation by providing the token and setting a password.
Request Body:
{
"token": "abc-123-def",
"password": "MiContraseña123"
}| Field | Type | Required | Description |
|---|---|---|---|
| token | string | Yes | Invite token |
| password | string | Yes | New password (min 6 characters) |
Response 200 OK:
{
"success": true
}Errors:
| Status | Error | When |
|---|---|---|
| 400 | "Esta invitación ya fue aceptada" | Already confirmed |
| 404 | "Invitación inválida o ya utilizada" | Token not found |
| 410 | "La invitación ha expirado. Solicita una nueva al administrador." | Expired token |