Pular para o conteúdo principal

Chat

POST /v1/users/:user_id/chat/completion é um endpoint de inferência de chat com IA sem estado. O chamador fornece a mensagem do usuário, o histórico da conversa e o tipo de personalidade. A camada de inteligência retorna uma resposta sem armazenar nada.

Sua aplicação é responsável por armazenar o histórico da conversa e passá-lo em history a cada chamada.


Como funciona

  1. Seu app carrega o histórico de conversa do usuário do seu banco de dados
  2. Seu app chama POST /v1/users/{user_id}/chat/completion com a mensagem, o histórico e o tipo de personalidade
  3. A camada de inteligência retorna uma resposta de IA
  4. Seu app armazena tanto a mensagem do usuário quanto a resposta
  5. Na próxima chamada, inclua o histórico atualizado

POST /v1/users/:user_id/chat/completion

Envie uma mensagem e receba uma resposta de IA sem estado.

Corpo da requisição

CampoTipoObrigatórioDescrição
messagestringSimMensagem do usuário. Máx 2000 caracteres.
historyarrayNãoTurnos anteriores da conversa [{ role, content }]
personality_typestringNãoHOTSHOT | STOCKPILER | GIVER | INDEPENDENT — molda o tom
languagestringNãoSobrepõe o idioma da resposta para esta requisição
contextstringNãoDica de contexto da conversa, ex.: "financial_planning"
user_contextobjectNãoSnapshot rico do usuário — veja os campos de user_context abaixo

Campos de user_context

Todos os campos dentro de user_context são opcionais. Passe o máximo de informações disponíveis — contexto mais rico produz respostas mais personalizadas.

CampoTipoDescrição
namestringNome de exibição do usuário
languagestringIdioma preferido do usuário ("en" | "pt" | "es")
personality_typestringHOTSHOT | STOCKPILER | GIVER | INDEPENDENT
plan_tierstringTier do plano da última geração, ex.: "20/80"
plan_speedstringVelocidade do plano da última geração: "conservative" | "moderate" | "aggressive"
monthly_incomenumberRenda bruta mensal do usuário
goal_progressobjectSnapshot da meta — veja abaixo
goal_progress.target_amount_centsnumberMeta alvo em centavos
goal_progress.total_contributed_centsnumberTotal contribuído até o momento em centavos
goal_progress.percentagenumberPercentual de contribuição (0–100)
next_moveobjectDetalhes do próximo passo
next_move.datestringData ISO do próximo movimento financeiro, ex.: "2026-05-20"
next_move.amount_centsnumberValor do próximo movimento em centavos
completed_moves_countnumberTotal de passos concluídos pelo usuário
total_saved_centsnumberTotal economizado em todos os passos em centavos
last_confirmation_notestringNota em texto livre que o usuário deixou na confirmação do último passo
entry_pointstringDe onde o usuário chegou — molda a mensagem de abertura do Ozzie. Veja os valores de entry_point
spending_alert_envelopestringNome do envelope de alerta de gastos, ex.: "lifestyle" (usado com entry_point: "spending_alert")
spending_alert_rationumberRazão entre gastos reais e alocados, ex.: 1.25 significa 25% acima do orçamento
rag_contextstringContexto de recuperação em texto livre injetado no prompt de IA, ex.: padrões comportamentais do seu banco de dados

Valores de entry_point

entry_point indica ao Ozzie de onde o usuário chegou. O Ozzie usa isso para gerar uma mensagem de abertura contextualmente adequada, retornada como entry_point_opener na resposta.

entry_pointQuando usarOzzie abre com
weekly_expenseUsuário chegou por um prompt de despesas semanais do WhatsAppPede as despesas com opções de entrada
spending_alertUsuário chegou por uma notificação push de gastos excessivosFaz referência ao envelope específico (spending_alert_envelope) e pergunta sobre recalibração
monthly_reviewUsuário chegou por um link de revisão mensal do WhatsAppResume o mês passado e pergunta sobre este mês
move_reminderUsuário chegou por um lembrete de movimento financeiro do WhatsAppRetorna entry_point_opener: null — o canal renderiza o card de confirmação do passo
unpromptedUsuário abriu o app diretamente (padrão quando nenhum entry_point é fornecido)Saudação personalizada referenciando o último passo e o total economizado

Quando nenhum entry_point é fornecido, entry_point_opener é null na resposta.

curl -X POST https://channel.ozzieapp.com/v1/users/ozz_usr_01HX9KZMR4P5JQNBVT7YCW3DE/chat/completion \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"message": "How am I doing with my savings goal?",
"personality_type": "STOCKPILER",
"language": "en"
}'

Resposta

CampoTipoDescrição
objectstringSempre "chat_completion"
data.contentstringTexto da resposta de IA
data.entry_point_openerstring | nullMensagem de abertura pré-construída para a sessão. Não nulo quando entry_point foi fornecido e não é move_reminder. Nulo para move_reminder (o canal renderiza o card do passo) e quando nenhum entry_point foi enviado.
data.contextstringContexto ativo da conversa
{
"object": "chat_completion",
"data": {
"role": "assistant",
"content": "You're on track. Your STOCKPILER profile means consistent, automated saving is your edge — keep that monthly transfer running and you'll hit your monthly target comfortably.",
"entry_point_opener": null,
"context": "general",
"created_at": "2026-05-15T10:10:00Z"
}
}

Exemplos de entry_point

unprompted — app aberto diretamente

Requisição:

{
"message": "oi",
"user_context": {
"name": "Ramon",
"language": "pt",
"personality_type": "STOCKPILER",
"completed_moves_count": 8,
"total_saved_cents": 125000,
"next_move": {
"date": "2026-05-20",
"amount_cents": 20000
},
"entry_point": "unprompted"
}
}

Resposta:

{
"object": "chat_completion",
"data": {
"content": "Oi Ramon! Você completou 8 passos e já guardou $1,250. Seu próximo passo é dia 2026-05-20. Sobre o que você quer falar hoje?",
"entry_point_opener": "Oi Ramon! Você completou 8 passos e já guardou $1,250. Seu próximo passo é dia 2026-05-20. Sobre o que você quer falar hoje?",
"context": "general"
}
}

weekly_expense — chegou pelo prompt do WhatsApp

Requisição:

{
"message": "",
"user_context": {
"name": "Ramon",
"language": "pt",
"entry_point": "weekly_expense"
}
}

Resposta:

{
"object": "chat_completion",
"data": {
"content": "Ramon, vamos registrar seus gastos da semana! Me conta o que você gastou — pode ser no formato livre ou escolha uma categoria para começar.",
"entry_point_opener": "Ramon, vamos registrar seus gastos da semana! Me conta o que você gastou — pode ser no formato livre ou escolha uma categoria para começar.",
"context": "weekly_expense"
}
}

spending_alert — chegou por notificação push de gastos excessivos

Requisição:

{
"message": "",
"user_context": {
"name": "Ramon",
"language": "pt",
"entry_point": "spending_alert",
"spending_alert_envelope": "lifestyle",
"spending_alert_ratio": 1.25
}
}

Resposta:

{
"object": "chat_completion",
"data": {
"content": "Ramon, seu envelope lifestyle está 25% acima do planejado este mês. Quer recalibrar ou conversar sobre o que aconteceu?",
"entry_point_opener": "Ramon, seu envelope lifestyle está 25% acima do planejado este mês. Quer recalibrar ou conversar sobre o que aconteceu?",
"context": "spending_alert"
}
}

Requisição:

{
"message": "",
"user_context": {
"name": "Ramon",
"language": "pt",
"entry_point": "monthly_review",
"goal_progress": {
"target_amount_cents": 500000,
"total_contributed_cents": 125000,
"percentage": 25
}
}
}

Resposta:

{
"object": "chat_completion",
"data": {
"content": "Ramon, o mês passou! Você contribuiu $1,250 e está 25% do caminho para sua meta. O que você quer priorizar no próximo mês?",
"entry_point_opener": "Ramon, o mês passou! Você contribuiu $1,250 e está 25% do caminho para sua meta. O que você quer priorizar no próximo mês?",
"context": "monthly_review"
}
}

move_reminder — chegou pelo lembrete de passo do WhatsApp

Requisição:

{
"message": "",
"user_context": {
"name": "Ramon",
"language": "pt",
"entry_point": "move_reminder",
"next_move": {
"date": "2026-05-20",
"amount_cents": 20000
}
}
}

Resposta:

{
"object": "chat_completion",
"data": {
"content": null,
"entry_point_opener": null,
"context": "move_reminder"
}
}

entry_point_opener é null para move_reminder porque o canal (WhatsApp ou o app) é responsável por renderizar o card de confirmação do passo. O Ozzie não gera um texto de abertura para esse fluxo.

Erros

CódigoHTTPQuando
UNAUTHORIZED401Credenciais ausentes ou inválidas
NOT_FOUND404Usuário não existe
VALIDATION_ERROR400message ausente ou acima de 2000 caracteres
RATE_LIMIT_EXCEEDED429Muitas requisições de chat

Coaching adaptado à personalidade

O coach de IA adapta suas respostas com base no personality_type passado. Exemplos:

STOCKPILER perguntando sobre progresso de poupança:

"You've built $750 of your $1,500 monthly target — exactly on pace. Your STOCKPILER profile means this consistency compounds. Keep the automation running and you'll hit your emergency fund milestone in 8 months."

HOTSHOT perguntando sobre o mesmo:

"You're at 50% of your monthly savings target. That's solid, but if you redirect your $300 lifestyle envelope surplus this month, you'd hit 70% — which puts your investment timeline 3 weeks ahead of schedule."

GIVER perguntando sobre gastos com família:

"Your people envelope has $285 left this month — well within your $375 allocation. Spending on family is part of your GIVER profile, not a deviation from your plan."


GET /v1/users/:user_id/chat/messages

Retorna o histórico completo de conversa de um usuário. É um alias para o log de chat armazenado pelo canal — as mesmas mensagens que o canal injeta em history a cada chamada de POST /chat/completion.

curl https://channel.ozzieapp.com/v1/users/external:usr_8821/chat/messages \
-H "Authorization: Bearer YOUR_TOKEN"

Resposta (200 OK):

{
"object": "chat_history",
"data": {
"messages": [
{
"role": "user",
"content": "Como estou indo?",
"created_at": "2026-05-16T10:00:00Z"
},
{
"role": "assistant",
"content": "Você está no caminho certo.",
"created_at": "2026-05-16T10:00:01Z"
}
]
}
}

Erros:

CódigoHTTPQuando
UNAUTHORIZED401Credenciais ausentes ou inválidas
NOT_FOUND404Usuário não existe