Saltar al contenido principal

Chat

POST /v1/users/:user_id/chat/completion es un endpoint de inferencia de chat IA sin estado. El que llama proporciona el mensaje del usuario, el historial de conversación y el tipo de personalidad. La capa de inteligencia devuelve una respuesta sin almacenar nada.

Tu aplicación es responsable de almacenar el historial de conversación y pasarlo en history en cada llamada.


Cómo funciona

  1. Tu aplicación carga el historial de conversación del usuario desde tu base de datos
  2. Tu aplicación llama a POST /v1/users/{user_id}/chat/completion con el mensaje, el historial y el tipo de personalidad
  3. La capa de inteligencia devuelve una respuesta de IA
  4. Tu aplicación almacena tanto el mensaje del usuario como la respuesta
  5. En la siguiente llamada, incluye el historial actualizado

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

Envía un mensaje y recibe una respuesta de IA sin estado.

Cuerpo de la solicitud

CampoTipoRequeridoDescripción
messagestringMensaje del usuario. Máx 2000 caracteres.
historyarrayNoTurnos previos de conversación [{ role, content }]
personality_typestringNoHOTSHOT | STOCKPILER | GIVER | INDEPENDENT — moldea el tono
languagestringNoSobrescribe el idioma de respuesta para esta solicitud
contextstringNoPista de contexto de conversación, ej. "financial_planning"
user_contextobjectNoInstantánea rica del usuario — ver campos de user_context abajo

Campos de user_context

Todos los campos dentro de user_context son opcionales. Pasa los que tengas disponibles — un contexto más rico produce respuestas más personalizadas.

CampoTipoDescripción
namestringNombre de visualización del usuario
languagestringIdioma preferido del usuario ("en" | "pt" | "es")
personality_typestringHOTSHOT | STOCKPILER | GIVER | INDEPENDENT
plan_tierstringTier del plan de la última generación, ej. "20/80"
plan_speedstringVelocidad del plan de la última generación: "conservative" | "moderate" | "aggressive"
monthly_incomenumberIngreso mensual bruto del usuario
goal_progressobjectInstantánea de la meta — ver abajo
goal_progress.target_amount_centsnumberMeta objetivo en centavos
goal_progress.total_contributed_centsnumberTotal contribuido hasta ahora en centavos
goal_progress.percentagenumberPorcentaje de contribución (0–100)
next_moveobjectDetalles del próximo passo
next_move.datestringFecha ISO del próximo movimiento de dinero, ej. "2026-05-20"
next_move.amount_centsnumberMonto del próximo movimiento en centavos
completed_moves_countnumberTotal de passos completados por el usuario
total_saved_centsnumberMonto total ahorrado en todos los passos en centavos
last_confirmation_notestringNota en texto libre que el usuario dejó en su última confirmación de passo
entry_pointstringDesde dónde llegó el usuario — moldea el mensaje de apertura de Ozzie. Ver valores de entry_point
spending_alert_envelopestringNombre del sobre para una alerta de gasto, ej. "lifestyle" (usado con entry_point: "spending_alert")
spending_alert_rationumberRatio de gasto real respecto al asignado, ej. 1.25 significa 25% sobre el presupuesto
rag_contextstringContexto de recuperación en texto libre inyectado en el prompt de IA, ej. patrones de comportamiento de tu base de datos

Valores de entry_point

entry_point le indica a Ozzie desde dónde llegó el usuario. Ozzie lo usa para generar un mensaje de apertura contextualizado devuelto como entry_point_opener en la respuesta.

entry_pointCuándo usarloOzzie abre con
weekly_expenseEl usuario llega desde un prompt semanal de gastos de WhatsAppSolicita los gastos con opciones de entrada
spending_alertEl usuario llega desde una notificación push sobre exceso de gastoHace referencia al sobre específico (spending_alert_envelope) y pregunta sobre recalibración
monthly_reviewEl usuario llega desde un enlace de revisión mensual de WhatsAppResume el mes pasado y pregunta sobre este mes
move_reminderEl usuario llega desde un recordatorio de movimiento de dinero de WhatsAppDevuelve entry_point_opener: null — el canal renderiza la tarjeta de confirmación del passo
unpromptedEl usuario abre la aplicación directamente (por defecto cuando no se proporciona entry_point)Saludo personalizado con referencia al último passo y el total ahorrado

Cuando no se proporciona entry_point, entry_point_opener es null en la respuesta.

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"
}'

Respuesta

CampoTipoDescripción
objectstringSiempre "chat_completion"
data.contentstringTexto de la respuesta de IA
data.entry_point_openerstring | nullMensaje de apertura pre-construido para la sesión. No es null cuando se proporcionó entry_point y no es move_reminder. Es null para move_reminder (el canal renderiza la tarjeta del passo) y cuando no se envió entry_point.
data.contextstringContexto de conversación activo
{
"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"
}
}

Ejemplos de entry_point

unprompted — aplicación abierta directamente

Solicitud:

{
"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"
}
}

Respuesta:

{
"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 — llegó desde un prompt de WhatsApp

Solicitud:

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

Respuesta:

{
"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 — llegó desde una notificación push de exceso de gasto

Solicitud:

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

Respuesta:

{
"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"
}
}

monthly_review — llegó desde un enlace de revisión mensual de WhatsApp

Solicitud:

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

Respuesta:

{
"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 — llegó desde un recordatorio de passo de WhatsApp

Solicitud:

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

Respuesta:

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

entry_point_opener es null para move_reminder porque el canal (WhatsApp o la aplicación) es responsable de renderizar la tarjeta de confirmación del passo. Ozzie no genera un texto de apertura para este flujo.

Errores

CódigoHTTPCuándo
UNAUTHORIZED401Credenciales ausentes o inválidas
NOT_FOUND404El usuario no existe
VALIDATION_ERROR400message faltante o supera los 2000 caracteres
RATE_LIMIT_EXCEEDED429Demasiadas solicitudes de chat

Coaching con consciencia de personalidad

El coach de IA adapta sus respuestas según el personality_type que pasas. Ejemplos:

STOCKPILER preguntando sobre el progreso de ahorro:

"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 preguntando lo mismo:

"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 preguntando sobre gastos en familia:

"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

Devuelve el historial de conversación completo de un usuario. Es un alias del registro de chat almacenado en el canal — los mismos mensajes que el canal inyecta en history en cada llamada a POST /chat/completion.

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

Respuesta (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"
}
]
}
}

Errores:

CódigoHTTPCuándo
UNAUTHORIZED401Credenciales ausentes o inválidas
NOT_FOUND404El usuario no existe