🤖 Atendimento - Cleo
Guia completo para integrar o assistente virtual Cleo e oferecer canais de atendimento aos seus clientes.
📋 Introdução
Este serviço permite que você disponibilize informações de contato e atendimento do emissor, incluindo:
- 🤖 Assistente virtual (Cleo)
- 📞 Telefones de contato
- 💬 Chat online
- 📧 E-mail e WhatsApp
- 🎧 Ouvidoria
URLs Base:
- Homologação:
https://apihml.credsystem.com.br/private-label-app/api/v1 - Produção:
https://api.credsystem.com.br/private-label-app/api/v1
- 🔧 Guia de Troubleshooting - Solução de problemas e erros comuns
- 📖 Especificação OpenAPI — Referência técnica completa (schemas, tipos, exemplos)
🔐 Autenticação
Esta API utiliza Red Hat SSO (Keycloak) com o fluxo Password Grant (usuário e senha).
Todos os endpoints requerem autenticação via Bearer Token (JWT) no header:
Authorization: Bearer <seu_access_token>
| Propriedade | Valor |
|---|---|
| Sistema | Red Hat SSO (Keycloak) |
| Fluxo OAuth2 | Password Grant |
| Tipo | Autenticação com usuário final (CPF + senha) |
| Tokens | Access Token + Refresh Token |
Tokens inválidos ou expirados retornarão erro 401 Unauthorized.
O token é gerado no fluxo de Login dos APPs. O access_token retornado deve ser enviado em todas as chamadas da área logada.
Área Logada
Para usuários autenticados, use o token JWT no header:
Authorization: Bearer <seu_token_jwt>
Área Pública (Não Logada)
Para área pública, não é necessário token JWT. Basta informar o idApp na URL.
Este serviço pode ser usado tanto em áreas logadas quanto públicas, facilitando o acesso a informações de contato.
📚 Endpoints Disponíveis
1. Obter Dados do Atendimento (Área Logada)
Retorne as informações completas de contato para usuários autenticados.
Endpoint: GET /cleo/dados
Headers:
Authorization: Bearer <seu_token_jwt>
Accept: application/json
Content-Type: application/json
Exemplo de Request:
GET /private-label-app/api/v1/atendimento/cleo/dados HTTP/1.1
Host: apihml.credsystem.com.br
Authorization: Bearer <token>
Accept: application/json
Resposta de Sucesso (200):
{
"whatsapp": "11999999999",
"email": "cleo@credsystem.com.br",
"nomeBot": "Cleo Assistente",
"statusCode": 200,
"telefones": {
"capitaisRegioesMetropolitanas": "1133334444",
"demaisRegioes": "1144445555",
"ouvidoria": "0800111111",
"ouvidoriaHorarios1": "08:00-17:00",
"ouvidoriaHorarios2": "seg-sex"
}
}
Campos da Resposta:
whatsapp: Número de WhatsApp para contato (formato com DDD)email: E-mail de contato do suportenomeBot: Nome do assistente virtualstatusCode: Código HTTP da respostatelefones: Objeto com todos os telefones de contatocapitaisRegioesMetropolitanas: Telefone para capitaisdemaisRegioes: Telefone para outras regiõesouvidoria: Número da ouvidoriaouvidoriaHorarios1: Horário de funcionamentoouvidoriaHorarios2: Dias de funcionamento
Exemplo de cURL:
curl -X 'GET' \
'https://apihml.credsystem.com.br/private-label-app/api/v1/atendimento/cleo/dados' \
-H 'accept: application/json' \
-H 'Authorization: Bearer SEU_TOKEN_JWT'
Use essas informações para criar uma página de "Fale Conosco" ou seção de atendimento no app.
Consulte o 🔧 Troubleshooting - Dados Emissor (Logado) para detalhes de erros e soluções.
2. Obter Dados do Atendimento (Área Pública)
Retorne as mesmas informações para usuários não autenticados usando o ID da aplicação.
Endpoint: GET /cleo/dados/{idApp}
Parâmetros:
idApp(path, obrigatório): ID da aplicação para identificar o emissor
Exemplo de Request:
GET /private-label-app/api/v1/atendimento/cleo/dados/123 HTTP/1.1
Host: apihml.credsystem.com.br
Accept: application/json
Resposta: Mesma estrutura do endpoint para área logada.
Exemplo de cURL:
curl -X 'GET' \
'https://apihml.credsystem.com.br/private-label-app/api/v1/atendimento/cleo/dados/123' \
-H 'accept: application/json'
Use este endpoint em telas de login, recuperação de senha ou qualquer área onde o usuário ainda não está autenticado.
Consulte o 🔧 Troubleshooting - Dados Emissor (Público) para detalhes de erros e soluções.
3. Gerar Link do Chat
Crie um link único para iniciar uma conversa com o assistente virtual Cleo.
Endpoint: GET /cleo/chat/link
Headers:
Authorization: Bearer <seu_token_jwt>
Accept: application/json
Content-Type: application/json
Exemplo de Request:
GET /private-label-app/api/v1/atendimento/cleo/chat/link HTTP/1.1
Host: apihml.credsystem.com.br
Authorization: Bearer <token>
Accept: application/json
Resposta de Sucesso (200):
{
"link": "https://chat.credsystem.com.br/cleo/session/abc123def456",
"protocolo": "PROTO-2025-12-03-001"
}
Campos da Resposta:
link: URL única para iniciar o chat com o assistenteprotocolo: Número de protocolo da sessão (útil para rastreamento)
Exemplo de cURL:
curl -X 'GET' \
'https://apihml.credsystem.com.br/private-label-app/api/v1/atendimento/cleo/chat/link' \
-H 'accept: application/json' \
-H 'Authorization: Bearer SEU_TOKEN_JWT'
- Obtenha o link do chat
- Guarde o protocolo para rastreamento
- Redirecione o cliente para o link
- O chat será aberto em uma nova sessão autenticada
Consulte o 🔧 Troubleshooting - Link Chat Cleo para detalhes de erros e soluções.
Códigos de Resposta
| Código | Status | Descrição |
|---|---|---|
| 200 | ✅ Sucesso | Dados retornados com sucesso |
| 204 | ∅ Sem conteúdo | Nenhum dado disponível |
| 400 | ⚠️ Bad Request | Parâmetros inválidos ou ausentes |
| 401 | ⛔ Unauthorized | Token inválido ou expirado (área logada) |
| 500 | 💥 Internal Error | Erro interno do servidor |
Tratamento de Erros
Erro de Autenticação (401)
{
"error": {
"message": "Não foi possível validar o token",
"code": 401
}
}
Erro de Requisição (400)
{
"error": {
"message": "Authorization é uma informação obrigatória.",
"code": 400
}
}
Casos de Uso
1. Página "Fale Conosco"
Crie uma página completa com todos os canais de atendimento:
// Exemplo de implementação
async function carregarDadosAtendimento() {
const response = await fetch(
'https://apihml.credsystem.com.br/private-label-app/api/v1/atendimento/cleo/dados',
{
headers: {
'Authorization': `Bearer ${token}`,
'Accept': 'application/json'
}
}
);
const dados = await response.json();
// Exibir informações na página
document.getElementById('whatsapp').href = `https://wa.me/${dados.whatsapp}`;
document.getElementById('email').href = `mailto:${dados.email}`;
document.getElementById('telefoneCapital').textContent = dados.telefones.capitaisRegioesMetropolitanas;
document.getElementById('telefoneInterior').textContent = dados.telefones.demaisRegioes;
document.getElementById('ouvidoria').textContent = dados.telefones.ouvidoria;
document.getElementById('horarioOuvidoria').textContent =
`${dados.telefones.ouvidoriaHorarios1} - ${dados.telefones.ouvidoriaHorarios2}`;
}
2. Botão "Chat com Assistente"
Implemente um botão para abrir o chat:
async function abrirChatCleo() {
const response = await fetch(
'https://apihml.credsystem.com.br/private-label-app/api/v1/atendimento/cleo/chat/link',
{
headers: {
'Authorization': `Bearer ${token}`,
'Accept': 'application/json'
}
}
);
const { link, protocolo } = await response.json();
// Guardar protocolo para rastreamento
localStorage.setItem('protocoloAtendimento', protocolo);
// Abrir chat em nova janela
window.open(link, '_blank', 'width=400,height=600');
}
3. Área Pública - Tela de Login
Mostre informações de contato antes do login:
async function carregarContatoPublico(idApp) {
const response = await fetch(
`https://apihml.credsystem.com.br/private-label-app/api/v1/atendimento/cleo/dados/${idApp}`,
{
headers: {
'Accept': 'application/json'
}
}
);
const dados = await response.json();
// Exibir apenas informações básicas
exibirRodape({
whatsapp: dados.whatsapp,
telefone: dados.telefones.capitaisRegioesMetropolitanas,
email: dados.email
});
}
Fluxo Recomendado
Para Área Logada
1. Usuário clica em "Ajuda" ou "Fale Conosco"
↓
2. Chamar GET /cleo/dados (com token JWT)
↓
3. Exibir todos os canais de atendimento
↓
4. SE cliente escolher "Chat Online":
├─ Chamar GET /cleo/chat/link
├─ Guardar protocolo
└─ Redirecionar para o link do chat
↓
5. Cliente inicia atendimento via chat
Para Área Pública
1. Usuário acessa tela de login/recuperação de senha
↓
2. Chamar GET /cleo/dados/{idApp} (sem token)
↓
3. Exibir informações básicas no rodapé:
├─ Telefone
├─ WhatsApp
└─ E-mail
↓
4. Cliente pode entrar em contato mesmo sem login
Boas Práticas
1. Cache de Informações
// Cache por 1 hora
const CACHE_TIME = 3600000; // 1 hora em ms
async function getDadosAtendimentoComCache() {
const cache = localStorage.getItem('dadosAtendimento');
const cacheTime = localStorage.getItem('dadosAtendimentoTime');
if (cache && cacheTime && (Date.now() - cacheTime < CACHE_TIME)) {
return JSON.parse(cache);
}
const dados = await buscarDadosAtendimento();
localStorage.setItem('dadosAtendimento', JSON.stringify(dados));
localStorage.setItem('dadosAtendimentoTime', Date.now());
return dados;
}
2. Formatação de Telefones
function formatarTelefone(numero) {
// Remove caracteres não numéricos
const limpo = numero.replace(/\D/g, '');
// Formata baseado no tamanho
if (limpo.length === 10) {
return limpo.replace(/(\d{2})(\d{4})(\d{4})/, '($1) $2-$3');
} else if (limpo.length === 11) {
return limpo.replace(/(\d{2})(\d{5})(\d{4})/, '($1) $2-$3');
}
return numero; // Retorna original se não conseguir formatar
}
3. Links Clicáveis
function criarLinksAtendimento(dados) {
return {
whatsappLink: `https://wa.me/${dados.whatsapp.replace(/\D/g, '')}`,
emailLink: `mailto:${dados.email}`,
telefoneCapitalLink: `tel:${dados.telefones.capitaisRegioesMetropolitanas.replace(/\D/g, '')}`,
telefoneInteriorLink: `tel:${dados.telefones.demaisRegioes.replace(/\D/g, '')}`,
ouvidoriaLink: `tel:${dados.telefones.ouvidoria.replace(/\D/g, '')}`
};
}
4. Rastreamento de Protocolos
function salvarProtocoloAtendimento(protocolo) {
const historico = JSON.parse(localStorage.getItem('protocolosAtendimento') || '[]');
historico.push({
protocolo,
dataHora: new Date().toISOString(),
tipo: 'chat'
});
// Manter apenas últimos 10 protocolos
if (historico.length > 10) {
historico.shift();
}
localStorage.setItem('protocolosAtendimento', JSON.stringify(historico));
}
5. Tratamento de Erros
async function buscarDadosAtendimentoSeguro() {
try {
const response = await fetch(url, options);
if (!response.ok) {
throw new Error(`Erro ${response.status}: ${response.statusText}`);
}
return await response.json();
} catch (error) {
console.error('Erro ao buscar dados de atendimento:', error);
// Retornar dados fallback
return {
whatsapp: '0800-XXX-XXXX',
email: 'suporte@empresa.com.br',
nomeBot: 'Assistente',
telefones: {
capitaisRegioesMetropolitanas: '0800-XXX-XXXX',
demaisRegioes: '0800-XXX-XXXX',
ouvidoria: '0800-XXX-XXXX',
ouvidoriaHorarios1: 'Consulte o site',
ouvidoriaHorarios2: 'seg-sex'
}
};
}
}
Exemplo de Interface
Card de Atendimento
<div class="atendimento-card">
<h2>Precisa de Ajuda?</h2>
<div class="canal">
<img src="whatsapp-icon.png" alt="WhatsApp">
<div>
<strong>WhatsApp</strong>
<a href="#" id="whatsapp-link">Enviar mensagem</a>
</div>
</div>
<div class="canal">
<img src="chat-icon.png" alt="Chat">
<div>
<strong id="nome-bot">Chat Online</strong>
<button onclick="abrirChatCleo()">Iniciar conversa</button>
</div>
</div>
<div class="canal">
<img src="phone-icon.png" alt="Telefone">
<div>
<strong>Telefone</strong>
<p>Capitais: <a href="#" id="tel-capital"></a></p>
<p>Interior: <a href="#" id="tel-interior"></a></p>
</div>
</div>
<div class="canal">
<img src="email-icon.png" alt="E-mail">
<div>
<strong>E-mail</strong>
<a href="#" id="email-link"></a>
</div>
</div>
<div class="canal ouvidoria">
<img src="ouvidoria-icon.png" alt="Ouvidoria">
<div>
<strong>Ouvidoria</strong>
<p><a href="#" id="ouvidoria-tel"></a></p>
<small id="ouvidoria-horario"></small>
</div>
</div>
</div>
Dicas de UX
- Priorize canais digitais: WhatsApp e Chat devem aparecer primeiro
- Destaque horários: Mostre claramente quando cada canal está disponível
- Salve protocolos: Permita que o cliente veja histórico de atendimentos
- Ícones claros: Use ícones reconhecíveis para cada canal
- Click-to-action: Transforme todos os contatos em links clicáveis
- Responsividade: Em mobile, use
tel:emailto:para abrir apps nativos - Feedback visual: Mostre quando o chat está sendo carregado
Integração com Outros Serviços
Com Notificações
// Notificar cliente quando chat for iniciado
async function iniciarChatComNotificacao() {
const { link, protocolo } = await getChatLink();
// Enviar notificação
await enviarNotificacao({
titulo: 'Atendimento Iniciado',
mensagem: `Seu protocolo: ${protocolo}`,
tipo: 'atendimento'
});
window.open(link, '_blank');
}
Com Analytics
// Rastrear qual canal o cliente usa
function rastrearCanalAtendimento(canal) {
analytics.track('Atendimento Iniciado', {
canal: canal, // 'whatsapp', 'chat', 'telefone', 'email'
origem: 'fale-conosco',
timestamp: new Date().toISOString()
});
}
Glossário
| Termo | Significado |
|---|---|
| Cleo | Nome do assistente virtual/bot de atendimento |
| Protocolo | Número único de identificação de uma sessão de atendimento |
| Ouvidoria | Canal para reclamações e sugestões |
| idApp | Identificador único da aplicação/emissor |
| Bearer Token | Tipo de token JWT usado para autenticação |
Perguntas Frequentes
1. Posso usar o serviço sem autenticação?
Sim! Use o endpoint /cleo/dados/{idApp} para áreas públicas.
2. O link do chat expira? Sim, links de chat têm validade limitada. Gere um novo link a cada sessão.
3. Como rastreio atendimentos?
Use o campo protocolo retornado ao gerar o link do chat.
4. Posso customizar o nome do bot?
O nome retorna do backend via campo nomeBot. A customização é feita no backoffice.
5. Como funciona em mobile?
Use tel: para telefones e https://wa.me/ para WhatsApp - abrem os apps nativos.
🎓 Recursos Adicionais
- 🔧 Guia de Troubleshooting — Solução de problemas e erros comuns
- 📄 Referência OpenAPI — Especificação técnica completa
Suporte
Para dúvidas ou problemas com a integração, entre em contato com a equipe de suporte técnico.