Chat
O endpoint Chat permite que os usuários enviem mensagens ao coach financeiro de IA do Ozzie. O coach mantém plena consciência do contexto financeiro do usuário — incluindo seu intake, histórico de transações, plano atual, metas e money moves — e responde com orientações personalizadas e acionáveis.
Cada resposta inclui metadados estruturados ao lado do texto da resposta, tornando fácil construir experiências de UI ricas sobre a conversa.
Como o coach funciona
O coach de IA não é um chatbot genérico. Para cada mensagem recebida, ele:
- Carrega o perfil financeiro completo do usuário (intake, transações, plano, metas)
- Identifica a intenção e o tópico da mensagem
- Responde no idioma configurado do usuário
- Retorna metadados (
emotion,topic,intent) que sua UI pode usar para adaptar a experiência
O coach adapta seu tom com base no personality_type do usuário se um tiver sido definido via POST /plan/personalize.
Referência do objeto
Requisição
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
message | string | Sim | A mensagem do usuário para o coach. Máx 2000 caracteres. |
Resposta
| Campo | Tipo | Descrição |
|---|---|---|
reply | string | A resposta do coach no idioma configurado do usuário |
emotion | string | O tom emocional da resposta (ex.: "encouraging", "neutral", "cautious", "celebratory") |
topic | string | O tópico financeiro relacionado à mensagem (ex.: "savings", "spending", "goals", "debt", "general") |
intent | string | Intenção classificada da mensagem do usuário (ex.: "progress_check", "advice_request", "transaction_log", "goal_update", "emotional_support") |
POST /v1/users/{user_id}/chat/messages
Envia uma mensagem ao coach financeiro de IA em nome de um usuário e retorna a resposta do coach.
Parâmetros de caminho
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
user_id | string | Sim | O ID do usuário Ozzie |
Corpo da requisição
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
message | string | Sim | A mensagem de texto do usuário |
Requisição
- curl
- Node.js
- Python
curl -X POST https://api.ozzieapp.com/v1/users/usr_4f8a1b2c3d/chat/messages \
-H "Authorization: Bearer ozp_Y2xpZW50X2ExYjJjM2Q0OnNrX2xpdmVfeEs5bVAycVI3dEwu" \
-H "Content-Type: application/json" \
-d '{
"message": "Como estou indo com minha meta de poupança?"
}'
const token = Buffer.from(
`${process.env.OZZIE_CLIENT_ID}:${process.env.OZZIE_CLIENT_SECRET}`
).toString('base64');
const response = await fetch(
'https://api.ozzieapp.com/v1/users/usr_4f8a1b2c3d/chat/messages',
{
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
message: 'Como estou indo com minha meta de poupança?',
}),
}
);
const { data } = await response.json();
console.log(data.reply);
import base64, os, httpx
token = base64.b64encode(
f"{os.environ['OZZIE_CLIENT_ID']}:{os.environ['OZZIE_CLIENT_SECRET']}".encode()
).decode()
response = httpx.post(
"https://api.ozzieapp.com/v1/users/usr_4f8a1b2c3d/chat/messages",
headers={
"Authorization": f"Bearer {token}",
"Content-Type": "application/json",
},
json={"message": "Como estou indo com minha meta de poupança?"},
)
print(response.json()["data"]["reply"])
Resposta
{
"object": "chat_message",
"data": {
"reply": "Você está fazendo um progresso real! Voc ê poupou R$1.200 em direção ao seu Fundo de Emergência de R$10.000 — isso é 12% da sua meta. Na sua contribuição quinzenal atual de R$150, você está no caminho certo para atingir R$3.000 em cerca de 9 meses. Sua próxima transferência agendada é no dia 19 de maio. Quer que eu mostre algumas formas de acelerar isso?",
"emotion": "encouraging",
"topic": "savings",
"intent": "progress_check"
}
}
Exemplos de conversas
Pedindo conselhos sobre gastos
Requisição:
{
"message": "Acho que estou gastando muito com comida. O que devo fazer?"
}
Resposta:
{
"object": "chat_message",
"data": {
"reply": "Você está certo em notar isso — comida é sua maior categoria discricionária este mês com R$680, o que é cerca de 18% da sua renda líquida. Uma meta razoável para alguém com sua renda e objetivos é cerca de R$400–450/mês. A maior lacuna parece ser comer fora (R$310) versus supermercado (R$370). Preparar duas ou três jantares por semana poderia realisticamente economizar R$80–100/mês sem parecer um grande sacrifício. Quer que eu adicione uma meta específica de gasto com comida ao seu plano?",
"emotion": "neutral",
"topic": "spending",
"intent": "advice_request"
}
}
Registrando uma transação via chat
Requisição:
{
"message": "Acabei de gastar R$45 no supermercado"
}
Resposta:
{
"object": "chat_message",
"data": {
"reply": "Anotado — registrei R$45 no Supermercado em Alimentação. Seu total em alimentação em maio agora é R$215. Você está no caminho certo para ficar dentro do seu orçamento de comida este mês, o que é ótimo. Continue assim!",
"emotion": "encouraging",
"topic": "spending",
"intent": "transaction_log"
}
}
Pedindo apoio emocional
Requisição:
{
"message": "Sinto que nunca vou sair das dívidas. É opressor."
}
Resposta:
{
"object": "chat_message",
"data": {
"reply": "Esse sentimento é completamente válido — carregar dívidas é genuinamente estressante. Mas aqui está o que seus números realmente dizem: na sua taxa de pagamento atual de R$200/mês, você ficará livre de dívidas em cerca de 26 meses. Isso não é para sempre — é uma linha de chegada. E cada pagamento que você faz encurta esse prazo. Você já pagou R$850 desde que começou. Quer dar uma olhada em uma pequena coisa que você poderia ajustar para reduzir alguns meses?",
"emotion": "cautious",
"topic": "debt",
"intent": "emotional_support"
}
}
Atualização de meta via chat
Requisição:
{
"message": "Quero mudar minha meta. Prefiro poupar para uma viagem do que pagar meu cartão de crédito."
}
Resposta:
{
"object": "chat_message",
"data": {
"reply": "Totalmente razoável — você decide o que importa. Só para ter o quadro completo: seu saldo do cartão de crédito é R$2.100 e você está pagando 19,9% de juros ao ano, o que significa que está custando cerca de R$35/mês em juros. Um fundo de viagem cresceria mais rápido se você quitasse o cartão primeiro. Dito isso, se a viagem é uma prioridade próxima que te mantém motivado, podemos absolutamente construir um plano em torno disso. Você gostaria que eu rodasse os dois cenários para você comparar?",
"emotion": "neutral",
"topic": "goals",
"intent": "goal_update"
}
}
Resposta em português (para usuário configurado como pt)
Requisição:
{
"message": "Quanto economizei esse mês?"
}
Resposta:
{
"object": "chat_message",
"data": {
"reply": "Em maio você economizou R$680 até agora — isso é 14% da sua renda líquida, acima da sua meta de 12%. Ótimo ritmo! Se mantiver isso até o fim do mês, vai adicionar mais de R$800 ao seu fundo de emergência. Quer ver como isso afeta a data prevista para atingir sua meta?",
"emotion": "celebratory",
"topic": "savings",
"intent": "progress_check"
}
}
Erros
| Código | Status HTTP | Quando ocorre |
|---|---|---|
UNAUTHORIZED | 401 | Credenciais ausentes ou inválidas |
NOT_FOUND | 404 | O usuário não existe |
VALIDATION_ERROR | 422 | Campo message ausente ou excede 2000 caracteres |
INVALID_JSON | 400 | Corpo da requisição não é JSON válido |
INTAKE_REQUIRED | 422 | O usuário não tem intake financeiro — o coach precisa de contexto para responder com significado |
RATE_LIMIT_EXCEEDED | 429 | Muitas requisições de chat na janela atual |
INTERNAL_ERROR | 500 | Geração de IA falhou — seguro para tentar novamente |
Use os campos topic e intent para enriquecer sua UI. Por exemplo: mostre um widget de gráfico de poupança quando topic for "savings", reproduza uma animação sutil quando emotion for "celebratory", ou solicite ao usuário que atualize sua meta quando intent for "goal_update".
O coach não armazena histórico de conversa entre chamadas na versão atual da API. Cada mensagem é processada com o contexto financeiro completo do usuário, mas sem memória de turnos anteriores do chat. Se sua aplicação precisar de uma UI de conversa persistente, mantenha o histórico de mensagens do seu lado e opcionalmente inclua contexto anterior relevante no texto da mensagem.