Listar clientes
Retorna os usuários da loja com filtros e paginação, e traz a busca avançada, a presença de PF e PJ e os totais.
Use estas operações para varrer a base de clientes: um CRM que sincroniza cadastros novos, um ERP que procura um cliente pelo CNPJ, ou uma tela de busca. A lista traz o resumo de cada usuário. Para endereços, grupos e campos de perfil, abra o usuário com Consultar cliente.
A mesma lista serve a clientes, administradores e usuários de seller: o filtro user_type escolhe quem entra. Quando você filtra por customer, os logins de subcontas (funcionários de uma empresa B2B) ficam de fora por padrão, porque o cliente comercial é a empresa.
/api/v1/admin/usersAdminLista os usuários
Exige view_users ou manage_users. Os filtros se combinam (E lógico).
Query parameters
pageintegerpadrão: 1per_pageintegerpadrão: 20sort_bystringpadrão: created_atcreated_atemailfirst_namelast_namelast_login_atupdated_atlogin_countcreated_at. O desempate é pelo id.sort_dirstringpadrão: descascdescuser_typestringcustomervendoradminroot_adminuser_typesstringadmin,vendor). Tem precedência sobre user_type.vendor_iduuidexclude_trade_rep_managersbooleanpadrão: truevendor, esconde os gerentes de venda que não são donos de seller. Mande false para incluí-los.exclude_subaccountsbooleanpadrão: truecustomer, esconde subcontas B2B. Mande false para ver todos os logins.statusstringADPactive, disabled, pending, inactive, deleted).searchstringemailstringphonestringcpfstringcnpjstringperson_typestringFPFJPJcitystringstatestringcountrystringlanguagestringpt-BRenesemail_verifiedbooleantrue ou false. Valor inválido é ignorado.marketing_opt_inbooleanwhatsapp_opt_inbooleanregistered_afterstringAAAA-MM-DD ou RFC 3339).registered_beforestringAAAA-MM-DD o dia inteiro entra.last_login_afterstringlast_login_beforestringAAAA-MM-DD).has_ordersbooleantrue: tem ao menos um pedido; false: nunca comprou.min_total_spendintegermax_total_spendintegerExemplo de requisição
curl "$BASE_URL/api/v1/admin/users?user_type=customer&person_type=J&has_orders=true&sort_by=created_at&sort_dir=desc&per_page=50" \
-H "Authorization: Bearer $TOKEN"Resposta
{
"users": [
{
"id": "3dc023ca-3746-4b6e-8afd-686a4a9af99f",
"email": "contato@paodoce.example.com",
"user_type": "customer",
"status": "A",
"first_name": "Padaria Pão Doce Ltda",
"last_name": "",
"phone": "+551133334444",
"cnpj": "11222333000181",
"legal_name": "Padaria Pão Doce Ltda",
"trade_name": "Pão Doce",
"language": "pt-BR",
"currency": "BRL",
"timezone": "America/Sao_Paulo",
"email_verified": false,
"login_count": 0,
"is_root": false,
"account_type": "individual",
"person_type": "J",
"person_type_declared": true,
"display_name": "Pão Doce",
"created_at": "2026-10-11T20:55:51.332285Z",
"updated_at": "2026-10-11T20:56:18.510829Z",
"user_id": "3dc023ca-3746-4b6e-8afd-686a4a9af99f",
"firstname": "Padaria Pão Doce Ltda",
"lastname": "",
"tax_id": "11222333000181",
"timestamp": 1791752151,
"updated_timestamp": 1791752178
}
],
"total": 8173,
"page": 1,
"per_page": 50,
"total_pages": 164
}Campos da resposta
usersarraysms_opt_in, push_opt_in, whatsapp_opt_in e notify_on_orders podem vir false mesmo quando a conta tem outro valor: leia o usuário para o valor real.totalintegerpageintegerper_pageintegertotal_pagesinteger/api/v1/admin/users/searchAdminBusca avançada de usuários
Busca com critérios no corpo, útil quando o filtro é longo ou combina grupo e endereço. Exige view_users ou manage_users (é uma leitura, apesar do POST). A resposta tem o mesmo formato de GET /api/v1/admin/users.
Corpo da requisição
searchstringuser_typestringcustomervendoradminstatusstringADPemailstringphonestringcitystringstatestringpostal_codestringcountrystringcpfstringcnpjstringusergroup_iduuidcreated_afterstringAAAA-MM-DD).created_beforestringlast_login_afterstringlast_login_beforestringpageintegerpadrão: 1per_pageintegerpadrão: 20sort_bystringpadrão: created_atsort_orderstringpadrão: descascdescsort_order, não sort_dir./api/v1/admin/users/person-type-presenceAdminQuais tipos de pessoa existem na loja
Responde se a loja tem ao menos um cliente PF e ao menos um PJ. Serve para telas que só mostram o filtro de CPF ou de CNPJ quando ele pode encontrar alguém. Exige view_users ou manage_users. Em caso de dúvida a resposta é true para os dois, nunca esconde.
{ "has_pf": true, "has_pj": true }/api/v1/admin/users/stats/summaryAdminTotais de usuários para um painel
Contagens para um painel: total, por status, por tipo e cadastros recentes. Exige view_users ou manage_users.
{
"total_users": 8175,
"active_users": 8172,
"pending_users": 0,
"disabled_users": 1,
"total_customers": 8044,
"total_vendors": 114,
"total_admins": 16,
"new_users_today": 4,
"new_users_week": 6,
"new_users_month": 8
}Campos da resposta
total_usersintegeractive_usersintegerA.pending_usersintegerP, mas hoje conta uma letra que nenhuma conta usa e por isso vem 0. Para saber quantos estão pendentes use GET /api/v1/admin/users?status=pending e leia total.disabled_usersintegerD.total_customersintegercustomer.total_vendorsintegervendor.total_adminsintegeradmin.new_users_todayintegernew_users_weekintegernew_users_monthintegerErros
| Status | Quando | Corpo |
|---|---|---|
| 400 | (busca avançada) corpo que não é JSON | {"error":"invalid request body","detail":"..."} |
| 401 | Sem credenciais, chave inválida ou token expirado | {"error":"missing authorization header"} ou {"error":"invalid or expired token"} |
| 403 | Usuário sem o privilégio necessário | {"error":"insufficient privileges","privilege_required_any":["manage_users","view_users"]} |
| 429 | Limite de requisições | {"error":"rate limit exceeded","detail":"too many requests, please try again later"} |
| 500 | Falha interna, ou UUID inválido em vendor_id | {"error":"failed to list users","detail":"..."} |