API · customers
Operações de customers do contrato OpenAPI que aceitam uma chave de API.
Atualizado:
GET /customer-asset-types
Tipos de bien del negocio
FIU-609 (ADR 0059 §2 y §8). Owner/manager o API key con customers:read. Primero «Direcciones» (address, system: true, sin id: sus bienes son las direcciones guardadas), después los tipos del negocio y al final los de fábrica sin activar (active: false, sin id).
- Autenticação: Chave de API ou sessão do painel
- Escopos:
customers:read
Respostas
| Status | Descrição |
|---|---|
200 | Tipos de bien (CustomerAssetTypePage) |
default | Error (RFC 9457) (Problem) |
POST /customer-asset-types
Activar un tipo de fábrica o crear un tipo de bien
FIU-609. Owner/manager con CSRF o API key con config:write. {"preset": "vehicle"} activa Vehículos (patente, marca, modelo, año, km y color, ninguno obligatorio): idempotente, devuelve 200 con el mismo tipo si ya estaba activo y lo reactiva si estaba desactivado. Sin preset, un tipo propio con key, name, name_one y fields (hasta 12; 409 asset_type_exists si la key ya existe).
- Autenticação: Chave de API ou sessão do painel
- Escopos:
config:write
Corpo da solicitação (obrigatório)
application/json: CustomerAssetTypeCreate
Respostas
| Status | Descrição |
|---|---|
200 | El tipo de fábrica ya estaba activo (o se reactivó) (CustomerAssetType) |
201 | Tipo activado o creado (CustomerAssetType) |
default | Error (RFC 9457) (Problem) |
GET /customer-asset-types/{type_id}
Ver un tipo de bien
FIU-609. Owner/manager o API key con customers:read.
- Autenticação: Chave de API ou sessão do painel
- Escopos:
customers:read
Parâmetros
| Nome | Em | Obrigatório | Tipo | Descrição |
|---|---|---|---|---|
type_id | path | Sim | string (uuid) |
Respostas
| Status | Descrição |
|---|---|
200 | El tipo (CustomerAssetType) |
default | Error (RFC 9457) (Problem) |
PATCH /customer-asset-types/{type_id}
Editar o desactivar un tipo de bien
FIU-609. Owner/manager con CSRF o API key con config:write. active: false desactiva el tipo: sus bienes quedan en solo lectura y nada se borra. Quitar un campo de fields no borra los valores guardados (vuelven si vuelve la misma key). identifier_key debe ser un campo del tipo.
- Autenticação: Chave de API ou sessão do painel
- Escopos:
config:write
Parâmetros
| Nome | Em | Obrigatório | Tipo | Descrição |
|---|---|---|---|---|
type_id | path | Sim | string (uuid) |
Corpo da solicitação (obrigatório)
application/json: CustomerAssetTypePatch
Respostas
| Status | Descrição |
|---|---|
200 | Tipo actualizado (CustomerAssetType) |
default | Error (RFC 9457) (Problem) |
DELETE /customer-asset-types/{type_id}
Borrar un tipo de bien sin bienes
FIU-609. Owner/manager con CSRF o API key con config:write. 409 asset_type_in_use si tiene bienes (desactivarlo con active=false).
- Autenticação: Chave de API ou sessão do painel
- Escopos:
config:write
Parâmetros
| Nome | Em | Obrigatório | Tipo | Descrição |
|---|---|---|---|---|
type_id | path | Sim | string (uuid) |
Respostas
| Status | Descrição |
|---|---|
204 | Borrado |
default | Error (RFC 9457) (Problem) |
GET /customers
Listar y buscar clientes reales (owner/manager; sesión staff con vista mínima)
Excluye is_test; cursor por última actividad descendente y UUID. q busca por nombre, email, empresa, etiqueta y teléfono (también el segundo); sirve al selector de cliente con escritura progresiva. Scope de API key customers:read. Actividad mutable puede cambiar el orden entre páginas. Sesión staff (F1-29): recibe CustomerStaffItem (id, name, phone_masked, tags, no_show_count; sin email, notas, documento, dirección, empresa ni segundo teléfono), solo con q de mínimo 3 caracteres (sin q, con phone/tag/cursor o con término corto ⇒ 422), tope 10 resultados y next_cursor null (sin paginación), y rate limit propio de 30 búsquedas/min por actor con headers RateLimit y 429 customer_search_rate_limited. Cada búsqueda de staff audita customer.search (solo el término, sin contenido de resultados). Alcance del repartidor (F2-52): solo encuentra clientes con tareas en sus recursos propios (vigentes o cerradas hace menos de 48 h). Viewer sigue en 403.
- Autenticação: Chave de API ou sessão do painel
- Escopos:
customers:read
Parâmetros
| Nome | Em | Obrigatório | Tipo | Descrição |
|---|---|---|---|---|
phone | query | Não | string | |
q | query | Não | string | Nombre |
tag | query | Não | string | |
limit | query | Não | integer default 25 | |
cursor | query | Não | string |
Respostas
| Status | Descrição |
|---|---|
200 | OK (owner/manager y API key: CustomerProfile; sesión staff: CustomerStaffItem con tope 10) (object) |
422 | Error (RFC 9457) (Problem) |
429 | Error (RFC 9457) (Problem) |
default | Error (RFC 9457) (Problem) |
POST /customers
Alta manual de un cliente (owner/manager/staff; CSRF y auditoría)
Exige al menos nombre, teléfono o email. El teléfono se normaliza a E.164; si ya existe un cliente con ese teléfono responde 409 customer_exists. Idempotency-Key opcional deduplica 24 h (sesión de panel y Bearer). Todos los datos ampliados son opcionales y personales (LGPD). Scope de API key customers:write. Escribe audit_log (customer.created, solo los nombres de los campos) y emite el evento customer.created. Respuesta (F1-29, cierre de hallazgo de seguridad): owner/manager y API keys con customers:read reciben el CustomerProfile completo; la sesión staff y las API keys solo con customers:write reciben solo {"id"}, sin PII. En el 409, la extensión customer_id solo se expone a quien tiene lectura.
- Autenticação: Chave de API ou sessão do painel
- Escopos:
customers:write,customers:read
Parâmetros
| Nome | Em | Obrigatório | Tipo | Descrição |
|---|---|---|---|---|
Idempotency-Key | header | Não | string |
Corpo da solicitação (obrigatório)
application/json: CustomerCreate
Respostas
| Status | Descrição |
|---|---|
201 | Creado (CustomerProfile completo para lectores; {"id"} para staff o API key write-only) (CustomerProfile` / `CustomerWriteAck) |
409 | Ya existe un cliente con ese teléfono (code=customer_exists); la extensión customer_id solo para quien tiene customers:read (``Problem / object) |
default | Error (RFC 9457) (Problem) |
GET /customers/{customer_id}/addresses
Direcciones guardadas del cliente
Owner/manager o API key con customers:read. Tenant desde credencial; sin direcciones archivadas por rollback.
- Autenticação: Chave de API ou sessão do painel
- Escopos:
customers:read
Parâmetros
| Nome | Em | Obrigatório | Tipo | Descrição |
|---|---|---|---|---|
customer_id | path | Sim | string (uuid) |
Respostas
| Status | Descrição |
|---|---|
200 | Colección ordenada por predeterminada y fecha (object) |
default | Error (RFC 9457) (Problem) |
POST /customers/{customer_id}/addresses
Agregar una dirección del cliente
Owner/manager con CSRF o API key con customers:write y customers:read. Idempotency-Key admite reintentos. La primera es predeterminada; guardar una dirección no modifica tareas anteriores.
- Autenticação: Chave de API ou sessão do painel
- Escopos:
customers:write,customers:read
Parâmetros
| Nome | Em | Obrigatório | Tipo | Descrição |
|---|---|---|---|---|
customer_id | path | Sim | string (uuid) | |
Idempotency-Key | header | Não | string | Opcional con cookie/CSRF y obligatorio con API key; evita duplicados en reintentos |
Corpo da solicitação (obrigatório)
application/json: SavedCustomerAddressCreate
Respostas
| Status | Descrição |
|---|---|
201 | Dirección creada (SavedCustomerAddress) |
default | Error (RFC 9457) (Problem) |
PATCH /customers/{customer_id}/addresses/{address_id}
Editar dirección o elegir predeterminada
Owner/manager con CSRF o API key customers:write y customers:read. is_default admite solamente true; no altera el snapshot de tareas existentes.
- Autenticação: Chave de API ou sessão do painel
- Escopos:
customers:write,customers:read
Parâmetros
| Nome | Em | Obrigatório | Tipo | Descrição |
|---|---|---|---|---|
customer_id | path | Sim | string (uuid) | |
address_id | path | Sim | string (uuid) |
Corpo da solicitação (obrigatório)
application/json: SavedCustomerAddressPatch
Respostas
| Status | Descrição |
|---|---|
200 | Dirección actualizada (SavedCustomerAddress) |
default | Error (RFC 9457) (Problem) |
DELETE /customers/{customer_id}/addresses/{address_id}
Borrar dirección del cliente
Owner/manager con CSRF o API key customers:write. Si se borra la predeterminada se elige la siguiente; el snapshot de las tareas no cambia.
- Autenticação: Chave de API ou sessão do painel
- Escopos:
customers:write
Parâmetros
| Nome | Em | Obrigatório | Tipo | Descrição |
|---|---|---|---|---|
customer_id | path | Sim | string (uuid) | |
address_id | path | Sim | string (uuid) |
Respostas
| Status | Descrição |
|---|---|
204 | Borrada |
default | Error (RFC 9457) (Problem) |
GET /customers/{customer_id}/assets
Bienes del cliente
FIU-609 (ADR 0059). Los vehículos (u otros bienes) de un cliente. Owner/manager o API key con customers:read. El predeterminado primero; sin archivados salvo include_archived=true. Los bienes de un tipo desactivado vienen con read_only: true. Dato personal: la lectura se audita.
- Autenticação: Chave de API ou sessão do painel
- Escopos:
customers:read
Parâmetros
| Nome | Em | Obrigatório | Tipo | Descrição |
|---|---|---|---|---|
customer_id | path | Sim | string (uuid) | |
type | query | Não | string | key del tipo (vehicle) |
include_archived | query | Não | boolean default false |
Respostas
| Status | Descrição |
|---|---|
200 | Bienes del cliente (CustomerAssetPage) |
default | Error (RFC 9457) (Problem) |
POST /customers/{customer_id}/assets
Agregar un bien del cliente
FIU-609. Owner/manager con CSRF o API key con customers:write y customers:read. type es la key del tipo: un tipo de fábrica sin activar (vehicle) se activa al vuelo. Para un auto alcanza con la patente o el modelo (422 asset_invalid si no viene ninguno). El primero es el predeterminado. 409 asset_duplicate (con asset_id) si el cliente ya tiene esa patente viva; 409 asset_type_archived si el tipo está desactivado. Una patente con formato desconocido para el país se acepta con warnings: ["plate_format"].
- Autenticação: Chave de API ou sessão do painel
- Escopos:
customers:write,customers:read
Parâmetros
| Nome | Em | Obrigatório | Tipo | Descrição |
|---|---|---|---|---|
customer_id | path | Sim | string (uuid) | |
Idempotency-Key | header | Não | string | Opcional con cookie/CSRF y obligatorio con API key; evita duplicados en reintentos |
Corpo da solicitação (obrigatório)
application/json: CustomerAssetCreate
Respostas
| Status | Descrição |
|---|---|
201 | Bien creado (CustomerAsset) |
default | Error (RFC 9457) (Problem) |
GET /customers/{customer_id}/assets/{asset_id}
Ver un bien del cliente
FIU-609. Owner/manager o API key con customers:read. 404 asset_not_found si no es de ese cliente.
- Autenticação: Chave de API ou sessão do painel
- Escopos:
customers:read
Parâmetros
| Nome | Em | Obrigatório | Tipo | Descrição |
|---|---|---|---|---|
customer_id | path | Sim | string (uuid) | |
asset_id | path | Sim | string (uuid) |
Respostas
| Status | Descrição |
|---|---|
200 | El bien (CustomerAsset) |
default | Error (RFC 9457) (Problem) |
PATCH /customers/{customer_id}/assets/{asset_id}
Editar un bien, elegirlo como predeterminado o archivarlo
FIU-609. Owner/manager con CSRF o API key customers:write y customers:read. data se mezcla con lo guardado (una clave con null borra ese valor). is_default admite solo true; archived: true lo saca de la lista y elige otro predeterminado. Para pasar un auto a otro cliente: crearlo en el otro y archivarlo acá. 409 asset_type_archived si el tipo está desactivado (solo lectura).
- Autenticação: Chave de API ou sessão do painel
- Escopos:
customers:write,customers:read
Parâmetros
| Nome | Em | Obrigatório | Tipo | Descrição |
|---|---|---|---|---|
customer_id | path | Sim | string (uuid) | |
asset_id | path | Sim | string (uuid) |
Corpo da solicitação (obrigatório)
application/json: CustomerAssetPatch
Respostas
| Status | Descrição |
|---|---|
200 | Bien actualizado (CustomerAsset) |
default | Error (RFC 9457) (Problem) |
DELETE /customers/{customer_id}/assets/{asset_id}
Borrar un bien del cliente
FIU-609. Owner/manager con CSRF o API key customers:write y customers:read. Borrado definitivo (dato personal); sus fotos se borran del almacenamiento. Si era el predeterminado se elige el siguiente. Para dejar de usarlo sin borrarlo, archivarlo.
- Autenticação: Chave de API ou sessão do painel
- Escopos:
customers:write,customers:read
Parâmetros
| Nome | Em | Obrigatório | Tipo | Descrição |
|---|---|---|---|---|
customer_id | path | Sim | string (uuid) | |
asset_id | path | Sim | string (uuid) |
Respostas
| Status | Descrição |
|---|---|
204 | Borrado |
default | Error (RFC 9457) (Problem) |
POST /customers/{customer_id}/conversations
Abrir la conversación del cliente por un canal (mensaje en frío)
Devuelve la conversación activa del cliente por ese canal (200, created: false) o crea una vacía en la conexión conectada (201, created: true); no envía nada, el mensaje se redacta con POST /conversations/{id}/messages. Permiso conversations:operate (owner, manager, staff con clientes de sus tareas; API key con messages:write; sesión con CSRF); tenant desde la credencial; 404 si el cliente no existe o el staff no lo ve. Idempotente por naturaleza (una conversación por conexión y cliente). Auditado conversation.opened_cold. 409 channel_unavailable con reason cerrado: no_channel_connection (sin conexión conectada o canal pausado), no_contact (WhatsApp sin teléfono válido; Telegram sin tg_user), channel_not_supported (webchat e Instagram no admiten iniciar: en Instagram solo el cliente abre la ventana de 24 h), channel_not_implemented (reservado), outside_window (ventana vencida) y test_customer. Cloud respeta ventana de 24 h/plantilla al enviar; WAHooks permite primer contacto sin ventana oficial, con aviso y límite por proyecto/día UTC (20 por defecto, COLD_OPEN_DAILY_LIMIT; 429 cold_open_rate_limited). Reintentos no consumen cupo.
- Autenticação: Chave de API ou sessão do painel
- Escopos:
messages:write
Parâmetros
| Nome | Em | Obrigatório | Tipo | Descrição |
|---|---|---|---|---|
customer_id | path | Sim | string (uuid) |
Corpo da solicitação (obrigatório)
application/json: object
Respostas
| Status | Descrição |
|---|---|
200 | Ya existía una conversación activa por ese canal (CustomerConversationOpened) |
201 | Conversación vacía creada (CustomerConversationOpened) |
409 | Canal sin destinatario enrutable, no implementado o fuera de ventana (ColdOpenProblem) |
429 | Límite diario de aperturas WAHooks del proyecto alcanzado (ColdOpenRateLimitProblem) |
default | Error (RFC 9457) (Problem) |
GET /customers/{customer_id}/task-addresses
Direcciones mínimas para capturar un destino operativo
Owner/manager o API key customers:read. Staff solo clientes visibles por tareas asignadas y ventana operativa vigente (404 fuera de alcance). No expone perfil ni timestamps. Seleccionar no concede consentimiento para guardar.
- Autenticação: Chave de API ou sessão do painel
- Escopos:
customers:read
Parâmetros
| Nome | Em | Obrigatório | Tipo | Descrição |
|---|---|---|---|---|
customer_id | path | Sim | string (uuid) |
Respostas
| Status | Descrição |
|---|---|
200 | Destinos operativos mínimos (object) |
default | Error (RFC 9457) (Problem) |
GET /customers/{id}
Ficha del cliente (owner/manager completa y auditada; sesión staff mínima)
Owner/manager y API key con customers:read reciben CustomerDetail completo (audita customer.viewed). La sesión de staff (F1-29) recibe solo id, name, phone_masked, tags y no_show_count (sin email, notas, documento, dirección, empresa, segundo teléfono, reservas ni conversaciones) y audita customer.read. Viewer sigue en 403.
- Autenticação: Chave de API ou sessão do painel
- Escopos:
customers:read
Parâmetros
| Nome | Em | Obrigatório | Tipo | Descrição |
|---|---|---|---|---|
id | path | Sim | string |
Respostas
| Status | Descrição |
|---|---|
200 | OK (owner/manager y API key: CustomerDetail; sesión staff: vista mínima como CustomerStaffItem) (CustomerDetail) |
default | Error (RFC 9457) (Problem) |
PATCH /customers/{id}
Editar datos del cliente (owner/manager/staff; CSRF y auditoría)
phone cambia el teléfono principal (identificador único del workspace): se normaliza a E.164 con la región del workspace y, si ya es de otro cliente (en cualquier formato, incluido el 9 móvil de BR/AR), responde 409 customer_exists con customer_id solo para quien tiene lectura; phone: null es 422. address solo se escribe por owner/manager o API key con customers:write y sincroniza la predeterminada; reemplaza la dirección completa; null o vacío la borra. Scope de API key customers:write. Respuesta como POST (F1-29): CustomerProfile completo solo para quien tiene lectura (customers:read); staff y API key write-only reciben solo {"id"}.
- Autenticação: Chave de API ou sessão do painel
- Escopos:
customers:write,customers:read
Parâmetros
| Nome | Em | Obrigatório | Tipo | Descrição |
|---|---|---|---|---|
id | path | Sim | string |
Corpo da solicitação (obrigatório)
application/json: object
Respostas
| Status | Descrição |
|---|---|
200 | Actualizado (CustomerProfile completo para lectores; {"id"} para staff o API key write-only) (CustomerProfile` / `CustomerWriteAck) |
409 | El teléfono nuevo ya es de otro cliente (code=customer_exists); la extensión customer_id solo para quien tiene customers:read (``Problem / object) |
default | Error (RFC 9457) (Problem) |
GET /customers/{id}/bookings
Historial mínimo de reservas (owner/manager todo; staff solo las suyas finalizadas; lectura auditada)
Permisos finished_tasks:read_all (owner, manager, API key con customers:read) y finished_tasks:read_own (staff), ver docs/security/matriz-de-permisos.md. Con read_own la lista trae solo tareas terminadas (completed, cancelled, no_show, failed) asignadas a los recursos del staff, y solo de clientes con los que trabaja; cualquier otro cliente responde 404 igual que uno inexistente. viewer responde 403. Cada lectura queda en el audit log con su alcance.
- Autenticação: Chave de API ou sessão do painel
- Escopos:
customers:read
Parâmetros
| Nome | Em | Obrigatório | Tipo | Descrição |
|---|---|---|---|---|
id | path | Sim | string | |
limit | query | Não | integer default 25 | |
cursor | query | Não | string |
Respostas
| Status | Descrição |
|---|---|
200 | Reservas sin notas, intake_data ni mensajes (object) |
default | Error (RFC 9457) (Problem) |
GET /customers/{id}/summary
Resumen del cliente, calculado en vivo (owner/manager)
Una consulta agrupada por (workspace, cliente, estado); sin tablas de estadísticas ni caché. total excluye held/expired. upcoming = confirmed/checked_in cuyo fin es posterior a ahora (futuras o en curso; las de modo cola no cuentan). last_visit_at = última completada. next_booking = la próxima de esas (id, inicio, servicio) o null. Un cliente real nunca cuenta reservas de prueba; un cliente de prueba devuelve su propio resumen con is_test=true. Solo owner/manager (PII, como /customers); staff/viewer 403; cross-tenant 404. Scope de API key customers:read (solo GET).
- Autenticação: Chave de API ou sessão do painel
- Escopos:
customers:read
Parâmetros
| Nome | Em | Obrigatório | Tipo | Descrição |
|---|---|---|---|---|
id | path | Sim | string |
Respostas
| Status | Descrição |
|---|---|
200 | Resumen (object) |
default | Error (RFC 9457) (Problem) |