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

StatusDescrição
200Tipos de bien (CustomerAssetTypePage)
defaultError (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

StatusDescrição
200El tipo de fábrica ya estaba activo (o se reactivó) (CustomerAssetType)
201Tipo activado o creado (CustomerAssetType)
defaultError (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

NomeEmObrigatórioTipoDescrição
type_idpathSimstring (uuid)

Respostas

StatusDescrição
200El tipo (CustomerAssetType)
defaultError (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

NomeEmObrigatórioTipoDescrição
type_idpathSimstring (uuid)

Corpo da solicitação (obrigatório)

  • application/json: CustomerAssetTypePatch

Respostas

StatusDescrição
200Tipo actualizado (CustomerAssetType)
defaultError (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

NomeEmObrigatórioTipoDescrição
type_idpathSimstring (uuid)

Respostas

StatusDescrição
204Borrado
defaultError (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

NomeEmObrigatórioTipoDescrição
phonequeryNãostring
qqueryNãostringNombre
tagqueryNãostring
limitqueryNãointeger default 25
cursorqueryNãostring

Respostas

StatusDescrição
200OK (owner/manager y API key: CustomerProfile; sesión staff: CustomerStaffItem con tope 10) (object)
422Error (RFC 9457) (Problem)
429Error (RFC 9457) (Problem)
defaultError (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

NomeEmObrigatórioTipoDescrição
Idempotency-KeyheaderNãostring

Corpo da solicitação (obrigatório)

  • application/json: CustomerCreate

Respostas

StatusDescrição
201Creado (CustomerProfile completo para lectores; {"id"} para staff o API key write-only) (CustomerProfile` / `CustomerWriteAck)
409Ya existe un cliente con ese teléfono (code=customer_exists); la extensión customer_id solo para quien tiene customers:read (``Problem / object)
defaultError (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

NomeEmObrigatórioTipoDescrição
customer_idpathSimstring (uuid)

Respostas

StatusDescrição
200Colección ordenada por predeterminada y fecha (object)
defaultError (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

NomeEmObrigatórioTipoDescrição
customer_idpathSimstring (uuid)
Idempotency-KeyheaderNãostringOpcional con cookie/CSRF y obligatorio con API key; evita duplicados en reintentos

Corpo da solicitação (obrigatório)

  • application/json: SavedCustomerAddressCreate

Respostas

StatusDescrição
201Dirección creada (SavedCustomerAddress)
defaultError (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

NomeEmObrigatórioTipoDescrição
customer_idpathSimstring (uuid)
address_idpathSimstring (uuid)

Corpo da solicitação (obrigatório)

  • application/json: SavedCustomerAddressPatch

Respostas

StatusDescrição
200Dirección actualizada (SavedCustomerAddress)
defaultError (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

NomeEmObrigatórioTipoDescrição
customer_idpathSimstring (uuid)
address_idpathSimstring (uuid)

Respostas

StatusDescrição
204Borrada
defaultError (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

NomeEmObrigatórioTipoDescrição
customer_idpathSimstring (uuid)
typequeryNãostringkey del tipo (vehicle)
include_archivedqueryNãoboolean default false

Respostas

StatusDescrição
200Bienes del cliente (CustomerAssetPage)
defaultError (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

NomeEmObrigatórioTipoDescrição
customer_idpathSimstring (uuid)
Idempotency-KeyheaderNãostringOpcional con cookie/CSRF y obligatorio con API key; evita duplicados en reintentos

Corpo da solicitação (obrigatório)

  • application/json: CustomerAssetCreate

Respostas

StatusDescrição
201Bien creado (CustomerAsset)
defaultError (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

NomeEmObrigatórioTipoDescrição
customer_idpathSimstring (uuid)
asset_idpathSimstring (uuid)

Respostas

StatusDescrição
200El bien (CustomerAsset)
defaultError (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

NomeEmObrigatórioTipoDescrição
customer_idpathSimstring (uuid)
asset_idpathSimstring (uuid)

Corpo da solicitação (obrigatório)

  • application/json: CustomerAssetPatch

Respostas

StatusDescrição
200Bien actualizado (CustomerAsset)
defaultError (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

NomeEmObrigatórioTipoDescrição
customer_idpathSimstring (uuid)
asset_idpathSimstring (uuid)

Respostas

StatusDescrição
204Borrado
defaultError (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

NomeEmObrigatórioTipoDescrição
customer_idpathSimstring (uuid)

Corpo da solicitação (obrigatório)

  • application/json: object

Respostas

StatusDescrição
200Ya existía una conversación activa por ese canal (CustomerConversationOpened)
201Conversación vacía creada (CustomerConversationOpened)
409Canal sin destinatario enrutable, no implementado o fuera de ventana (ColdOpenProblem)
429Límite diario de aperturas WAHooks del proyecto alcanzado (ColdOpenRateLimitProblem)
defaultError (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

NomeEmObrigatórioTipoDescrição
customer_idpathSimstring (uuid)

Respostas

StatusDescrição
200Destinos operativos mínimos (object)
defaultError (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

NomeEmObrigatórioTipoDescrição
idpathSimstring

Respostas

StatusDescrição
200OK (owner/manager y API key: CustomerDetail; sesión staff: vista mínima como CustomerStaffItem) (CustomerDetail)
defaultError (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

NomeEmObrigatórioTipoDescrição
idpathSimstring

Corpo da solicitação (obrigatório)

  • application/json: object

Respostas

StatusDescrição
200Actualizado (CustomerProfile completo para lectores; {"id"} para staff o API key write-only) (CustomerProfile` / `CustomerWriteAck)
409El teléfono nuevo ya es de otro cliente (code=customer_exists); la extensión customer_id solo para quien tiene customers:read (``Problem / object)
defaultError (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

NomeEmObrigatórioTipoDescrição
idpathSimstring
limitqueryNãointeger default 25
cursorqueryNãostring

Respostas

StatusDescrição
200Reservas sin notas, intake_data ni mensajes (object)
defaultError (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

NomeEmObrigatórioTipoDescrição
idpathSimstring

Respostas

StatusDescrição
200Resumen (object)
defaultError (RFC 9457) (Problem)