Usuários - Endpoints
Referência completa dos endpoints de gestão de usuários da API Sinapse
Endpoints de Usuários
O módulo de usuários gerencia contas, perfis, permissões e grupos no sistema Sinapse.
Listar Usuários
Lista usuários com suporte a filtros e paginação.
GET /api/v1/usuarios
Authorization: Bearer {access_token}Query Parameters:
| Parâmetro | Tipo | Descrição |
|---|---|---|
page | integer | Número da página (padrão: 1) |
size | integer | Itens por página (padrão: 50, máx: 100) |
search | string | Busca por nome ou email |
nome | string | Filtrar por nome (parcial) |
email | string | Filtrar por email (parcial) |
admin | boolean | Filtrar administradores |
ativo | boolean | Filtrar por status |
cidade | string | Filtrar por cidade |
estado | string | Filtrar por UF |
grupo_id | integer | Filtrar por grupo [Em breve] |
sort | string | Campo para ordenação [Em breve] |
order | string | Direção: asc, desc [Em breve] |
Permissão necessária: usuarios.listar
Success Response (200):
{
"total": 150,
"page": 1,
"size": 50,
"pages": 3,
"items": [
{
"id": 123,
"nome": "João Silva",
"email": "[email protected]",
"cpf": "123.456.789-00",
"telefone": "(11) 98765-4321",
"avatar_url": "https://api.sinapse.org.br/avatars/123.jpg",
"cargo": "Analista de Sistemas",
"departamento": "TI",
"cidade": "São Paulo",
"estado": "SP",
"admin": false,
"ativo": true,
"email_verificado": true,
"mfa_habilitado": false,
"criado_em": "2025-01-15T10:00:00-03:00",
"atualizado_em": "2025-07-29T14:30:00-03:00",
"ultimo_acesso": "2025-07-29T10:00:00-03:00",
"grupos": [
{
"id": 2,
"nome": "analista",
"descricao": "Analista de dados"
}
],
"permissoes_diretas": [
"relatorios.exportar"
],
"total_permissoes": 15
}
],
// "agregacoes": **[Em breve]**
}Python - Busca com Filtros:
import requests
def listar_usuarios_ativos(token, estado=None, grupo=None):
headers = {"Authorization": f"Bearer {token}"}
params = {
"ativo": True,
"page": 1,
"size": 100,
"sort": "nome",
"order": "asc"
}
if estado:
params["estado"] = estado
if grupo:
params["grupo_id"] = grupo
response = requests.get(
"https://api.sinapse.org.br/v1/usuarios",
headers=headers,
params=params
)
if response.status_code == 200:
data = response.json()
print(f"Total de usuários: {data['total']}")
for user in data['items']:
grupos = ", ".join(g['nome'] for g in user['grupos'])
print(f"{user['nome']} - {user['email']} - Grupos: {grupos}")
return data
else:
print(f"Erro: {response.status_code}")
return NoneJavaScript - Busca com Paginação:
async function* listarTodosUsuarios(filtros = {}) {
let page = 1;
let hasMore = true;
while (hasMore) {
const params = new URLSearchParams({
...filtros,
page: page,
size: 50
});
const response = await fetch(
`/api/v1/usuarios?${params}`,
{
headers: {
'Authorization': `Bearer ${accessToken}`
}
}
);
if (!response.ok) break;
const data = await response.json();
// Yield cada usuário
for (const user of data.items) {
yield user;
}
hasMore = page < data.pages;
page++;
}
}
// Uso
for await (const usuario of listarTodosUsuarios({ ativo: true })) {
console.log(`${usuario.nome} (${usuario.email})`);
}Criar Usuário
Cria um novo usuário no sistema.
POST /api/v1/usuarios
Authorization: Bearer {access_token}
Content-Type: application/jsonBody Parameters:
{
"email": "[email protected]",
"senha": "SenhaForte123!",
"nome": "Maria Santos",
"cpf": "987.654.321-00",
"telefone": "(21) 91234-5678",
"cargo": "Enfermeira",
"departamento": "Vigilância Epidemiológica",
"cidade": "Rio de Janeiro",
"estado": "RJ",
"admin": false,
"ativo": true,
"grupos_ids": [3, 4],
"permissoes_ids": [10, 15, 20]
}Validações:
- Email único no sistema
- CPF válido e único
- Senha deve atender requisitos de segurança
- Grupos e permissões devem existir
Permissão necessária: usuarios.criar
Success Response (201):
{
"id": 124,
"email": "[email protected]",
"nome": "Maria Santos",
"cpf": "987.654.321-00",
"criado_em": "2025-07-29T15:00:00-03:00",
"grupos": [
{
"id": 3,
"nome": "usuario"
},
{
"id": 4,
"nome": "visualizador"
}
],
"mensagem": "Usuário criado com sucesso."
}Error Response (422):
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Dados inválidos",
"details": [
{
"field": "email",
"message": "Email já cadastrado no sistema"
},
{
"field": "senha",
"message": "Senha deve conter pelo menos 1 caractere especial"
},
{
"field": "permissoes_ids",
"message": "Permissões inválidas: [99, 100]"
}
]
}
}React Form Component:
function FormularioUsuario() {
const [formData, setFormData] = useState({
email: '',
senha: '',
confirmar_senha: '',
nome: '',
cpf: '',
telefone: '',
cargo: '',
departamento: '',
cidade: '',
estado: '',
grupos_ids: [],
permissoes_ids: []
});
const [errors, setErrors] = useState({});
const [loading, setLoading] = useState(false);
const validarSenha = (senha) => {
const requisitos = [];
if (senha.length < 8) {
requisitos.push('Mínimo 8 caracteres');
}
if (!/[A-Z]/.test(senha)) {
requisitos.push('Pelo menos 1 maiúscula');
}
if (!/[a-z]/.test(senha)) {
requisitos.push('Pelo menos 1 minúscula');
}
if (!/[0-9]/.test(senha)) {
requisitos.push('Pelo menos 1 número');
}
if (!/[^A-Za-z0-9]/.test(senha)) {
requisitos.push('Pelo menos 1 caractere especial');
}
return requisitos;
};
const handleSubmit = async (e) => {
e.preventDefault();
setErrors({});
// Validações locais
const newErrors = {};
if (formData.senha !== formData.confirmar_senha) {
newErrors.confirmar_senha = 'Senhas não coincidem';
}
const senhaErros = validarSenha(formData.senha);
if (senhaErros.length > 0) {
newErrors.senha = senhaErros.join(', ');
}
if (Object.keys(newErrors).length > 0) {
setErrors(newErrors);
return;
}
setLoading(true);
try {
const response = await fetch('/api/v1/usuarios', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${accessToken}`
},
body: JSON.stringify(formData)
});
if (response.ok) {
const usuario = await response.json();
alert(`Usuário ${usuario.nome} criado com sucesso!`);
// Redirecionar ou limpar form
} else {
const error = await response.json();
if (error.error.details) {
const fieldErrors = {};
error.error.details.forEach(detail => {
fieldErrors[detail.field] = detail.message;
});
setErrors(fieldErrors);
}
}
} catch (error) {
console.error('Erro ao criar usuário:', error);
} finally {
setLoading(false);
}
};
return (
<form onSubmit={handleSubmit}>
{/* Campos do formulário com tratamento de erros */}
</form>
);
}Buscar Usuário
Retorna detalhes de um usuário específico.
GET /api/v1/usuarios/{id}
Authorization: Bearer {access_token}Path Parameters:
| Parâmetro | Tipo | Descrição |
|---|---|---|
id | integer | ID do usuário |
Query Parameters:
| Parâmetro | Tipo | Descrição |
|---|---|---|
include | string | Relações: grupos,permissoes,historico [Em breve] |
Permissões:
usuarios.listarpara ver qualquer usuário- Ou ser o próprio usuário
Success Response (200):
{
"id": 123,
"nome": "João Silva",
"email": "[email protected]",
"cpf": "123.456.789-00",
"telefone": "(11) 98765-4321",
"avatar_url": "https://api.sinapse.org.br/avatars/123.jpg",
"cargo": "Analista de Sistemas",
"departamento": "TI",
// "endereco": {...} **[Em breve]**
"admin": false,
"ativo": true,
"email_verificado": true,
"mfa_habilitado": false,
"criado_em": "2025-01-15T10:00:00-03:00",
"atualizado_em": "2025-07-29T14:30:00-03:00",
"ultimo_acesso": "2025-07-29T10:00:00-03:00",
"grupos": [
{
"id": 2,
"nome": "analista",
"descricao": "Analista de dados",
"permissoes_count": 12
}
],
"permissoes_diretas": [
{
"id": 25,
"nome": "relatorios.exportar",
"descricao": "Exportar relatórios"
}
],
"permissoes_efetivas": [
"agravos.listar",
"agravos.criar",
"noticias.listar",
"relatorios.gerar",
"relatorios.exportar"
],
// "historico_acesso": {...} **[Em breve]**
}Atualizar Usuário
Atualiza dados de um usuário existente.
PUT /api/v1/usuarios/{id}
Authorization: Bearer {access_token}
Content-Type: application/jsonBody Parameters:
Envie apenas os campos que deseja atualizar:
{
"nome": "João Silva Santos",
"telefone": "(11) 98765-9999",
"cargo": "Coordenador de TI",
"departamento": "Tecnologia da Informação",
"cidade": "São Paulo",
"estado": "SP",
"ativo": true
}Campos especiais:
email: Requer verificação após mudançacpf: Não pode ser alteradosenha: Não pode ser alterada via PUTadmin: Requer permissãoadmingrupos_ids: Requerusuarios.gerenciar_grupospermissoes_ids: Requerusuarios.gerenciar_permissoes
Permissão necessária: usuarios.editar ou ser o próprio usuário (campos limitados)
Success Response (200):
{
"id": 123,
"message": "Usuário atualizado com sucesso",
"campos_alterados": [
"nome",
"telefone",
"cargo"
],
"requer_acao": {
"email_verificacao": false,
"relogin": false
}
}Error Response (403):
{
"error": {
"code": "PERMISSION_DENIED",
"message": "Você não tem permissão para alterar grupos de usuários",
"required_permission": "usuarios.gerenciar_grupos"
}
}JavaScript - Atualização com Validação:
class UserService {
async atualizarUsuario(userId, dados) {
// Separar campos que requerem permissões especiais
const { grupos_ids, permissoes_ids, admin, ...dadosBasicos } = dados;
try {
// Atualizar dados básicos
const response = await fetch(`/api/v1/usuarios/${userId}`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${this.token}`
},
body: JSON.stringify(dadosBasicos)
});
if (!response.ok) {
throw new Error('Erro ao atualizar usuário');
}
const resultado = await response.json();
// Se tem permissão, atualizar grupos
if (grupos_ids && this.temPermissao('usuarios.gerenciar_grupos')) {
await this.atualizarGrupos(userId, grupos_ids);
}
// Se tem permissão, atualizar permissões diretas
if (permissoes_ids && this.temPermissao('usuarios.gerenciar_permissoes')) {
await this.atualizarPermissoes(userId, permissoes_ids);
}
return resultado;
} catch (error) {
console.error('Erro:', error);
throw error;
}
}
async atualizarGrupos(userId, gruposIds) {
return fetch(`/api/v1/usuarios/${userId}/grupos`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${this.token}`
},
body: JSON.stringify({ grupos_ids: gruposIds })
});
}
temPermissao(permissao) {
return this.usuario.permissoes_efetivas.includes(permissao);
}
}Deletar Usuário
Remove um usuário do sistema (soft delete).
DELETE /api/v1/usuarios/{id}
Authorization: Bearer {access_token}Query Parameters:
| Parâmetro | Tipo | Descrição |
|---|---|---|
motivo | string | Motivo da exclusão (obrigatório) |
transferir_para | integer | ID do usuário para transferir responsabilidades [Em breve] |
force | boolean | Exclusão permanente (requer permissão especial) [Em breve] |
Permissão necessária: usuarios.deletar
Success Response (204):
Sem conteúdo de resposta
Response com Avisos (200):
{
"message": "Usuário desativado com sucesso",
"avisos": [
"Usuário tinha 15 casos de agravos atribuídos",
"Casos foram transferidos para o usuário ID 456"
],
"acoes_realizadas": {
"usuario_desativado": true,
"sessoes_encerradas": 3,
"casos_transferidos": 15,
"grupos_removidos": 2
}
}Alterar Senha [Em breve]
Permite que admin altere senha de qualquer usuário.
POST /api/v1/usuarios/{id}/alterar-senha
Authorization: Bearer {access_token}
Content-Type: application/jsonBody Parameters:
{
"nova_senha": "NovaSenhaForte123!",
"forcar_troca": true,
"notificar_usuario": true
}Permissão necessária: usuarios.editar ou admin
Success Response (200):
{
"message": "Senha alterada com sucesso",
"forcar_troca": true,
"email_enviado": true,
"sessoes_invalidadas": 2
}Gerenciar Grupos [Em breve]
Adicionar a Grupo [Em breve]
POST /api/v1/usuarios/{id}/grupos/{grupo_id}
Authorization: Bearer {access_token}Permissão: usuarios.gerenciar_grupos
Remover de Grupo [Em breve]
DELETE /api/v1/usuarios/{id}/grupos/{grupo_id}
Authorization: Bearer {access_token}Definir Grupos [Em breve]
PUT /api/v1/usuarios/{id}/grupos
Content-Type: application/json
{
"grupos_ids": [1, 2, 3]
}Gerenciar Permissões [Em breve]
Adicionar Permissão Direta [Em breve]
POST /api/v1/usuarios/{id}/permissoes/{permissao_id}
Authorization: Bearer {access_token}Permissão: usuarios.gerenciar_permissoes ou admin
Listar Permissões Efetivas [Em breve]
GET /api/v1/usuarios/{id}/permissoes
Authorization: Bearer {access_token}Resposta:
{
"grupos": [
{
"id": 2,
"nome": "analista",
"permissoes": ["agravos.listar", "agravos.criar"]
}
],
"permissoes_diretas": ["relatorios.exportar"],
"permissoes_efetivas": [
"agravos.listar",
"agravos.criar",
"relatorios.exportar"
],
"tem_permissao_admin": false
}Estatísticas de Usuários [Em breve]
Retorna estatísticas agregadas dos usuários.
GET /api/v1/usuarios/estatisticas
Authorization: Bearer {access_token}Query Parameters:
| Parâmetro | Tipo | Descrição |
|---|---|---|
periodo | string | ultimos_7_dias, ultimos_30_dias, mes_atual |
agrupar_por | string | estado, grupo, departamento |
Permissão necessária: usuarios.listar
{
"total_usuarios": 150,
"usuarios_ativos": 145,
"usuarios_inativos": 5,
"novos_usuarios_periodo": 12,
"por_grupo": {
"admin": 5,
"gestor": 20,
"analista": 50,
"usuario": 70,
"visualizador": 5
},
"por_estado": {
"SP": 45,
"RJ": 30,
"MG": 25,
"outros": 50
},
"acessos": {
"hoje": 89,
"media_diaria": 120,
"pico_horario": "14:00",
"dispositivos": {
"desktop": 65,
"mobile": 35
}
},
"seguranca": {
"com_mfa": 45,
"senhas_fracas": 3,
"contas_bloqueadas": 1,
"tentativas_login_falhas_hoje": 15
}
}Busca Avançada [Em breve]
Endpoint especializado para buscas complexas.
POST /api/v1/usuarios/buscar
Authorization: Bearer {access_token}
Content-Type: application/jsonBody:
{
"filtros": {
"and": [
{"campo": "ativo", "operador": "eq", "valor": true},
{"campo": "estado", "operador": "in", "valor": ["SP", "RJ"]},
{
"or": [
{"campo": "grupo", "operador": "eq", "valor": "analista"},
{"campo": "grupo", "operador": "eq", "valor": "gestor"}
]
}
]
},
"ordenacao": [
{"campo": "nome", "direcao": "asc"}
],
"paginacao": {
"pagina": 1,
"tamanho": 50
},
"incluir": ["grupos", "permissoes", "ultimo_acesso"]
}Exportar Usuários [Em breve]
Exporta lista de usuários em diferentes formatos.
POST /api/v1/usuarios/exportar
Authorization: Bearer {access_token}
Content-Type: application/json
{
"formato": "xlsx",
"filtros": {
"ativo": true,
"estado": "SP"
},
"campos": [
"nome",
"email",
"cargo",
"departamento",
"grupos",
"ultimo_acesso"
]
}Permissão: usuarios.exportar