Clientes (customers)
O recurso customers expõe a base de clientes da sua conta: dados de cadastro,
contato por e-mail e telefone, endereço e status. É um recurso de leitura e
escrita: você lista, busca por id, cria, atualiza e desativa clientes pela
API.
| Módulo | clientes — precisa estar habilitado no contrato |
| Escopos | customers:read para ler; customers:write para criar, atualizar e desativar |
| Operações | leitura e escrita |
Endpoints
Seção intitulada “Endpoints”| Método | Endpoint | Escopo | Descrição |
|---|---|---|---|
GET |
/v1/customers |
customers:read |
Lista clientes com paginação por cursor |
GET |
/v1/customers/{id} |
customers:read |
Busca um cliente pelo id |
POST |
/v1/customers |
customers:write |
Cria um cliente e responde 201 |
PATCH |
/v1/customers/{id} |
customers:write |
Atualização parcial: envie só os campos que mudam |
DELETE |
/v1/customers/{id} |
customers:write |
Desativa o cliente (is_active=false) e responde 204 |
| Campo | Tipo | Escrita | Descrição |
|---|---|---|---|
id |
uuid |
— | Identificador único do cliente |
full_name |
string |
criar, atualizar | Nome completo, de 1 a 255 caracteres. Obrigatório na criação |
email |
string | null |
criar, atualizar | E-mail válido. A criação exige e-mail ou telefone |
phone |
string | null |
criar, atualizar | Telefone, até 40 caracteres. A criação exige e-mail ou telefone |
document |
string | null |
criar, atualizar | CPF, CNPJ ou outro documento |
birth_date |
string | null |
criar, atualizar | Data de nascimento no formato YYYY-MM-DD |
gender |
string | null |
criar, atualizar | Gênero, em texto livre |
notes |
string | null |
criar, atualizar | Observações internas |
is_active |
boolean | null |
atualizar | Status do cliente. true na criação; false depois de DELETE |
accepts_communications |
boolean | null |
criar, atualizar | Se o cliente aceita receber comunicações |
address_country |
string | null |
criar, atualizar | País |
address_state |
string | null |
criar, atualizar | Estado (UF) |
address_city |
string | null |
criar, atualizar | Cidade |
address_neighborhood |
string | null |
criar, atualizar | Bairro |
address_street |
string | null |
criar, atualizar | Logradouro |
address_number |
string | null |
criar, atualizar | Número |
address_complement |
string | null |
criar, atualizar | Complemento |
address_zip_code |
string | null |
criar, atualizar | CEP |
valid_whatsapp |
boolean | null |
— | Se o telefone foi validado como WhatsApp, mantido pelo aplicativo |
profile_photo_url |
string | null |
— | URL da foto de perfil, mantida pelo aplicativo |
whatsapp_photo |
string | null |
— | Foto do WhatsApp, mantida pelo aplicativo |
created_at |
string (ISO 8601) |
— | Data de criação |
updated_at |
string (ISO 8601) | null |
— | Data da última atualização |
Campos com — na coluna Escrita são somente leitura pela API.
Filtros e ordenação
Seção intitulada “Filtros e ordenação”O formato do filtro é ?filter[<campo>][<operador>]=<valor>. Os operadores
disponíveis são eq, neq, gt, gte, lt, lte, in, nin, ilike e
is_null.
| Campo | Uso típico | Exemplo |
|---|---|---|
full_name |
busca por nome, com ilike e % |
filter[full_name][ilike]=%maria% |
email |
busca por e-mail | filter[email][eq]=maria@exemplo.com |
phone |
busca por telefone | filter[phone][eq]=%2B5541999998888 |
document |
busca por CPF ou CNPJ | filter[document][eq]=12345678900 |
is_active |
somente ativos | filter[is_active][eq]=true |
gender |
por gênero | filter[gender][eq]=feminino |
address_city |
por cidade | filter[address_city][ilike]=%curitiba% |
address_state |
por UF | filter[address_state][eq]=PR |
accepts_communications |
aptos a receber campanhas | filter[accepts_communications][eq]=true |
created_at |
criados a partir de uma data | filter[created_at][gte]=2026-06-01 |
updated_at |
alterados recentemente, para sincronização incremental | filter[updated_at][gte]=2026-07-01T00:00:00Z |
- Ordenação:
sort=created_at,sort=updated_atousort=full_name. O padrão é-created_at, dos mais recentes para os mais antigos. - Paginação por cursor:
?limit=50&cursor=<next_cursor>. Olimitvai de 1 a 100 e o padrão é 20. - Campos parciais:
?fields=id,full_name,email,phone. customersnão aceitainclude: este recurso não tem relações incluídas.
Os detalhes de cada parâmetro estão em Paginação, filtros e ordenação.
Exemplos
Seção intitulada “Exemplos”curl "$LIGGA_BASE/v1/customers?limit=2\&filter[is_active][eq]=true\&filter[address_state][eq]=PR\&sort=-created_at" \ -H "Authorization: Bearer $LIGGA_API_KEY"{ "data": [ { "id": "c1a2b3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d", "full_name": "Maria Oliveira Santos", "email": "maria.oliveira@exemplo.com", "phone": "+5541999998888", "document": "123.456.789-00", "birth_date": "1992-03-15", "notes": "Prefere atendimento à tarde", "is_active": true, "gender": "feminino", "address_country": "Brasil", "address_state": "PR", "address_city": "Curitiba", "address_neighborhood": "Batel", "address_street": "Av. do Batel", "address_number": "1230", "address_complement": "Ap 502", "address_zip_code": "80420-090", "accepts_communications": true, "valid_whatsapp": true, "profile_photo_url": null, "whatsapp_photo": null, "created_at": "2026-06-20T14:22:31Z", "updated_at": "2026-07-01T09:05:12Z" }, { "id": "9f8e7d6c-5b4a-4392-8170-6e5d4c3b2a19", "full_name": "João Pedro Almeida", "email": null, "phone": "+5541988887777", "document": null, "birth_date": null, "notes": null, "is_active": true, "gender": null, "address_country": "Brasil", "address_state": "PR", "address_city": "Curitiba", "address_neighborhood": null, "address_street": null, "address_number": null, "address_complement": null, "address_zip_code": null, "accepts_communications": false, "valid_whatsapp": null, "profile_photo_url": null, "whatsapp_photo": null, "created_at": "2026-06-18T10:00:00Z", "updated_at": null } ], "pagination": { "next_cursor": "eyJpZCI6IjlmOGU3ZDZjLi4uIiwidiI6IjIwMjYtMDYtMThUMTA6MDA6MDBaIn0", "has_more": true, "limit": 2 }, "meta": { "request_id": "req_01JXXXYYYZZZ" }}O cursor da próxima página está em pagination.next_cursor. Enquanto
pagination.has_more for true, repita a chamada com cursor igual a esse
valor.
Buscar por id
Seção intitulada “Buscar por id”curl "$LIGGA_BASE/v1/customers/c1a2b3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d" \ -H "Authorization: Bearer $LIGGA_API_KEY"{ "data": { "id": "c1a2b3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d", "full_name": "Maria Oliveira Santos", "email": "maria.oliveira@exemplo.com", "phone": "+5541999998888", "document": "123.456.789-00", "birth_date": "1992-03-15", "notes": "Prefere atendimento à tarde", "is_active": true, "gender": "feminino", "address_country": "Brasil", "address_state": "PR", "address_city": "Curitiba", "address_neighborhood": "Batel", "address_street": "Av. do Batel", "address_number": "1230", "address_complement": "Ap 502", "address_zip_code": "80420-090", "accepts_communications": true, "valid_whatsapp": true, "profile_photo_url": null, "whatsapp_photo": null, "created_at": "2026-06-20T14:22:31Z", "updated_at": "2026-07-01T09:05:12Z" }, "meta": { "request_id": "req_01JXXXYYYZZZ" }}Um id que não existe, ou que pertence a outra conta, responde
404 not_found.
As regras de validação são: full_name obrigatório, pelo menos um entre
email e phone, e birth_date no formato YYYY-MM-DD.
curl -X POST "$LIGGA_BASE/v1/customers" \ -H "Authorization: Bearer $LIGGA_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{ "full_name": "Ana Beatriz Costa", "email": "ana.costa@exemplo.com", "phone": "+5541977776666", "document": "987.654.321-00", "birth_date": "1988-11-02", "accepts_communications": true, "address_state": "PR", "address_city": "Curitiba", "address_zip_code": "80010-000" }'Resposta 201 Created:
{ "data": { "id": "7b6a5948-3c2d-4e1f-a0b9-c8d7e6f5a4b3", "full_name": "Ana Beatriz Costa", "email": "ana.costa@exemplo.com", "phone": "+5541977776666", "document": "987.654.321-00", "birth_date": "1988-11-02", "notes": null, "is_active": true, "gender": null, "address_country": null, "address_state": "PR", "address_city": "Curitiba", "address_neighborhood": null, "address_street": null, "address_number": null, "address_complement": null, "address_zip_code": "80010-000", "accepts_communications": true, "valid_whatsapp": null, "profile_photo_url": null, "whatsapp_photo": null, "created_at": "2026-07-10T16:40:00Z", "updated_at": null }, "meta": { "request_id": "req_01JAAABBBCCC" }}Atualizar
Seção intitulada “Atualizar”O PATCH é parcial: só os campos enviados mudam.
curl -X PATCH "$LIGGA_BASE/v1/customers/7b6a5948-3c2d-4e1f-a0b9-c8d7e6f5a4b3" \ -H "Authorization: Bearer $LIGGA_API_KEY" \ -H "Content-Type: application/json" \ -d '{"notes": "Cliente VIP", "accepts_communications": false}'A resposta é o cliente completo, no mesmo envelope da busca por id. Para
reativar um cliente desativado, envie {"is_active": true}.
Desativar
Seção intitulada “Desativar”curl -X DELETE "$LIGGA_BASE/v1/customers/7b6a5948-3c2d-4e1f-a0b9-c8d7e6f5a4b3" \ -H "Authorization: Bearer $LIGGA_API_KEY"A resposta é 204 No Content, sem corpo.
Erros comuns
Seção intitulada “Erros comuns”As respostas de erro usam application/problem+json, com type, title,
status e request_id. Os detalhes estão em Erros.
| HTTP | type |
Quando acontece |
|---|---|---|
| 401 | invalid_token |
Cabeçalho Authorization ausente ou chave inexistente |
| 401 | token_revoked |
A chave foi revogada |
| 401 | token_expired |
A chave passou da data de expiração |
| 403 | insufficient_scope |
A chave não tem customers:read ou customers:write |
| 403 | module_not_enabled |
Módulo clientes não habilitado no contrato |
| 404 | not_found |
id inexistente ou de outra conta em GET, PATCH e DELETE |
| 409 | idempotency_conflict |
Mesma Idempotency-Key reenviada com outro corpo da requisição |
| 422 | validation |
Corpo ou filtro inválido, por exemplo full_name vazio, birth_date fora de YYYY-MM-DD, criação sem email e sem phone, ou operador não permitido |
| 429 | rate-limit-exceeded |
Limite de requisições do plano excedido |
Subcadastros e vínculos
Seção intitulada “Subcadastros e vínculos”Os subcadastros usam os mesmos escopos customers:read e
customers:write. Cada coleção permite listar e criar; GET, PATCH e
DELETE em /<id> consultam, editam e removem/desativam conforme o recurso.
| Coleção | Conteúdo |
|---|---|
/v1/customers/tags |
Tags |
/v1/customers/custom-fields |
Definições de campos personalizados |
/v1/customers/document-types |
Tipos de documento |
/v1/customers/groups |
Grupos manuais |
/v1/customers/note-categories |
Categorias de notas |
/v1/customers/{customer_id}/notes |
Notas |
/v1/customers/{customer_id}/relationships |
Relacionamentos |
/v1/customers/{customer_id}/documents |
Documentos |
Listagens dos subcadastros usam after (UUID do último item) e limit
(1 a 100, padrão 50). Elas não aceitam o cursor opaco dos cadastros principais.
Para substituir os vínculos do cadastro, use PUT /v1/customers/{id}/tags
com tag_ids e PUT /v1/customers/{id}/custom-field-values com
custom_field_values. GET nos mesmos caminhos consulta os valores.
Clientes também possuem GET/PUT de /{id}/assignments (assigned_user_ids)
e /{id}/groups (group_ids). Grupos inteligentes podem ser consultados, mas
sua composição é calculada pelo aplicativo: somente grupos manuais recebem
escrita pela API. Relacionamentos mantêm o vínculo inverso de forma transacional.
Documentos são enviados em JSON com conteúdo base64 (máximo de 5 MiB por
arquivo), nos tipos PDF, JPEG, PNG ou texto. O servidor define o caminho de
armazenamento e valida a cota do contrato. Para baixar, consulte
/{id}/documents/{document_id}/download: a URL assinada vale por cinco minutos.
Nunca publique essa URL como endereço permanente. Consulte na
Referência o schema completo de upload e os campos de cada recurso.
Alterações compostas de cadastro e vínculos usam transações. Em caso de falha indeterminada, siga Idempotência antes de repetir a escrita.
Veja também
Seção intitulada “Veja também”- Módulos e escopos — o que o módulo
clienteslibera - Paginação, filtros e ordenação —
cursor,filter,sortefields - Idempotência — como repetir um
POSTcom segurança - Vendas (sales) — vendas ligadas a um cliente por
customer_id

