Pular para o conteúdo principal

Intake Financeiro

O intake financeiro é a base de toda experiência do usuário no Ozzie. Ele captura um snapshot pontual do quadro financeiro mensal do usuário — renda, despesas e objetivo principal. O Ozzie usa esses dados para gerar um plano financeiro personalizado, calcular metas de poupança e fornecer recomendações contextuais.

Obrigatório antes da geração do plano

POST /v1/users/{user_id}/plan/generate retornará INTAKE_REQUIRED até que pelo menos um snapshot de intake financeiro tenha sido enviado. Sempre envie um intake antes de gerar um plano.


O Objeto Financial Intake

{
"object": "financial_intake",
"data": {
"id": "ozz_intake_01HX9M3FQKRNT8YDWP6BZ2LSA",
"user_id": "ozz_usr_01HX9KZMR4P5JQNBVT7YCW3DE",
"monthly_income": 5000,
"monthly_expenses": 3200,
"monthly_surplus": 1800,
"financial_goal": "savings",
"next_pay_date": "2025-05-15",
"created_at": "2025-05-05T14:31:00Z"
}
}

Campos do Objeto Financial Intake

CampoTipoDescrição
idstringUUID gerado pelo Ozzie para este snapshot de intake
user_idstringO usuário Ozzie a quem este intake pertence
monthly_incomenumberRenda mensal bruta na moeda base do usuário
monthly_expensesnumberTotal de despesas mensais
monthly_surplusnumberCampo calculado: monthly_income - monthly_expenses
financial_goalstring"savings" ou "debt" — o tipo de objetivo financeiro principal do usuário
next_pay_datestring | nullData do próximo pagamento do usuário no formato YYYY-MM-DD
created_atstringTimestamp UTC ISO 8601 de quando este snapshot foi criado

Modelo de Snapshot Imutável

Cada chamada a POST /v1/users/{user_id}/financial-intake cria um novo snapshot imutável. Snapshots anteriores são preservados no histórico. O Ozzie sempre usa o snapshot criado mais recentemente para geração de planos e recomendações.

Este design significa:

  • Você nunca precisa "atualizar" um intake — apenas envie um novo.
  • Snapshots históricos estão disponíveis via GET /v1/users/{user_id}/financial-intake/history para auditoria e análise de tendências.
  • Regenerar um plano após um novo envio de intake usará automaticamente os números mais recentes.
Intake de mai/1: income=4500, expenses=3100 ← usado para o plano de maio

Intake de mai/31: income=5000, expenses=3200 ← torna-se o novo mais recente

POST /plan/generate → usa snapshot de mai/31
Quando enviar um novo intake

Envie um intake novo quando o usuário reportar uma mudança significativa: aumento de salário, nova conta recorrente, quitação de dívida ou evento de vida (novo emprego, mudança de cidade). Reenvio mensal é um bom padrão.


POST /v1/users/{user_id}/financial-intake

Armazena um novo snapshot financeiro mensal para o usuário.

Parâmetros de Caminho

ParâmetroDescrição
user_idO UUID Ozzie do usuário ou external:{external_user_id}

Corpo da Requisição

CampoTipoObrigatórioRestriçõesDescrição
monthly_incomenumberSimDeve ser ≥ 0Renda mensal bruta na moeda base do usuário
monthly_expensesnumberSimDeve ser ≥ 0Total de despesas mensais (aluguel, alimentação, contas, assinaturas, etc.)
financial_goalstringSim"savings" | "debt"O objetivo financeiro principal do usuário
next_pay_datestringNãoData ISO YYYY-MM-DDData do próximo pagamento do usuário — usada para temporização do fluxo de caixa

Valores de financial_goal

ValorSignificadoComportamento do plano
"savings"Prioridade do usuário é construir poupança ou fundo de emergênciaPlano enfatiza taxa de contribuição e crescimento composto
"debt"Prioridade do usuário é quitar dívidasPlano enfatiza sequenciamento de pagamento de dívidas (avalanche ou bola de neve)

Resposta

Retorna o objeto financial_intake criado com HTTP 201 Created.

Erros

CódigoHTTPQuando
NOT_FOUND404O user_id não existe
VALIDATION_ERROR400Um campo obrigatório está ausente ou tem um valor inválido
UNAUTHORIZED401Credenciais ausentes ou inválidas

Exemplos

curl -X POST \
https://api.ozzieapp.com/v1/users/ozz_usr_01HX9KZMR4P5JQNBVT7YCW3DE/financial-intake \
-H "Authorization: Bearer czJjbGllbnQ6czJzZWNyZXQ=" \
-H "Content-Type: application/json" \
-d '{
"monthly_income": 5000,
"monthly_expenses": 3200,
"financial_goal": "savings",
"next_pay_date": "2025-05-15"
}'

Exemplo de Resposta (201 Created):

{
"object": "financial_intake",
"data": {
"id": "ozz_intake_01HX9M3FQKRNT8YDWP6BZ2LSA",
"user_id": "ozz_usr_01HX9KZMR4P5JQNBVT7YCW3DE",
"monthly_income": 5000,
"monthly_expenses": 3200,
"monthly_surplus": 1800,
"financial_goal": "savings",
"next_pay_date": "2025-05-15",
"created_at": "2025-05-05T14:31:00Z"
}
}

Resposta de Erro — Campo obrigatório ausente (400):

{
"error": {
"code": "VALIDATION_ERROR",
"message": "Field 'financial_goal' is required. Must be one of: 'savings', 'debt'."
}
}

Resposta de Erro — Valor de renda inválido (400):

{
"error": {
"code": "VALIDATION_ERROR",
"message": "Field 'monthly_income' must be a non-negative number. Received: -500."
}
}

GET /v1/users/{user_id}/financial-intake

Retorna o snapshot de intake financeiro criado mais recentemente para o usuário.

Parâmetros de Caminho

ParâmetroDescrição
user_idO UUID Ozzie do usuário ou external:{external_user_id}

Resposta

Retorna o objeto financial_intake com HTTP 200 OK. Se nenhum intake tiver sido enviado, retorna HTTP 404 com código NOT_FOUND.

Erros

CódigoHTTPQuando
NOT_FOUND404O usuário existe mas não enviou nenhum intake ainda, ou o user_id é inválido
UNAUTHORIZED401Credenciais ausentes ou inválidas

Exemplos

curl https://api.ozzieapp.com/v1/users/ozz_usr_01HX9KZMR4P5JQNBVT7YCW3DE/financial-intake \
-H "Authorization: Bearer czJjbGllbnQ6czJzZWNyZXQ="

Exemplo de Resposta (200 OK):

{
"object": "financial_intake",
"data": {
"id": "ozz_intake_01HX9M3FQKRNT8YDWP6BZ2LSA",
"user_id": "ozz_usr_01HX9KZMR4P5JQNBVT7YCW3DE",
"monthly_income": 5000,
"monthly_expenses": 3200,
"monthly_surplus": 1800,
"financial_goal": "savings",
"next_pay_date": "2025-05-15",
"created_at": "2025-05-05T14:31:00Z"
}
}

Resposta de Erro — Nenhum intake ainda (404):

{
"error": {
"code": "NOT_FOUND",
"message": "No financial intake found for user 'ozz_usr_01HX9KZMR4P5JQNBVT7YCW3DE'. Submit a POST /v1/users/{user_id}/financial-intake first."
}
}
Verificando intake antes da geração do plano

Antes de chamar POST /v1/users/{user_id}/plan/generate, você pode opcionalmente chamar este endpoint para confirmar que um intake existe e visualizar o monthly_surplus. Isso evita um erro de round-trip se o intake nunca foi enviado.