Skip to main content

API Flow and Sequence

This page describes the exact sequence of API calls to integrate ozzie-openapi from scratch. All calls go to https://api.ozzieapp.com/v1.


Onboarding sequence​

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ OZZIE ONBOARDING SEQUENCE (ozzie-openapi) β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

[1] POST /v1/users
β”‚ Creates user identity
β–Ό
[2] POST /v1/users/{user_id}/financial-intake
β”‚ Stores monthly income, expenses, goal
β–Ό
[3] GET /v1/personality/questions
β”‚ Fetches quiz catalog
β–Ό
POST /v1/personality/score
β”‚ Scores answers β†’ personality_type
β”‚ Your app stores the result
β–Ό
[4] POST /v1/users/{user_id}/plan/generate
β”‚ body: { personality_type }
β”‚ Returns plan with envelopes + plan_tier
β”‚ Your app stores plan_tier
β–Ό
ACTIVE USER β€” proceed to ongoing usage

Ongoing usage​

[5] GET /v1/users/{user_id}/financial-profile?personality_type=X
β”‚ Envelope allocations (percentages only)
β–Ό
[6] POST /v1/users/{user_id}/chat/completion
β”‚ body: { message, personality_type, history }
β”‚ Your app stores message + reply
β–Ό
[7] POST /v1/transactions/parse
β”‚ body: { type, content }
β”‚ Returns parsed transactions β†’ your app stores them
β–Ό
[8] POST /v1/money-moves/generate
β”‚ body: { user_id, personality_type, plan_tier }
β”‚ Returns weekly tasks β†’ your app stores + tracks them
β–Ό
Repeat steps 6–8 each week

Step-by-step reference​

Step 1 β€” Create user​

Endpoint: POST /v1/users

FieldTypeRequiredDescription
external_user_idstringYesYour internal user ID
namestringNoDisplay name
emailstringNoEmail address
languagestringNo"en" | "pt" | "es"
POST https://api.ozzieapp.com/v1/users
Authorization: Bearer czJjbGllbnQ6czJzZWNyZXQ=
Content-Type: application/json

{
"external_user_id": "usr_8821",
"name": "Maria Santos",
"email": "maria@example.com",
"language": "en"
}

Response:

{
"object": "user",
"data": {
"id": "ozz_usr_01HX9KZMR4P5JQNBVT7YCW3DE",
"external_user_id": "usr_8821",
"name": "Maria Santos",
"language": "en",
"created_at": "2026-05-15T14:30:00Z"
}
}
info

Save the id field. Use it in all subsequent API paths for this user.


Step 2 β€” Send financial intake​

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

POST https://api.ozzieapp.com/v1/users/ozz_usr_01HX9KZMR4P5JQNBVT7YCW3DE/financial-intake
Authorization: Bearer czJjbGllbnQ6czJzZWNyZXQ=
Content-Type: application/json

{
"monthly_income": 5000,
"monthly_expenses": 3200,
"financial_goal": "savings",
"next_pay_date": "2026-05-20"
}

Response:

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

Step 3 β€” Score personality​

Get questions:

GET https://api.ozzieapp.com/v1/personality/questions
Authorization: Bearer czJjbGllbnQ6czJzZWNyZXQ=

Score answers:

POST https://api.ozzieapp.com/v1/personality/score
Authorization: Bearer czJjbGllbnQ6czJzZWNyZXQ=
Content-Type: application/json

{
"answers": [
{ "question_id": "q_001", "option_id": "q_001_b" },
{ "question_id": "q_002", "option_id": "q_002_b" }
]
}

Response:

{
"object": "personality_score",
"data": {
"personality_type": "STOCKPILER",
"score_breakdown": {
"HOTSHOT": 1,
"STOCKPILER": 7,
"GIVER": 1,
"INDEPENDENT": 1
}
}
}

Store personality_type in your database. You will pass it explicitly on every subsequent intelligence call.


Step 4 β€” Generate plan​

Endpoint: POST /v1/users/{user_id}/plan/generate Requires: Financial intake submitted. Pass personality_type in the request body.

POST https://api.ozzieapp.com/v1/users/ozz_usr_01HX9KZMR4P5JQNBVT7YCW3DE/plan/generate
Authorization: Bearer czJjbGllbnQ6czJzZWNyZXQ=
Content-Type: application/json

{
"personality_type": "STOCKPILER"
}

Response:

{
"object": "plan",
"data": {
"id": "ozz_plan_01HX9N7C",
"user_id": "ozz_usr_01HX9KZMR4P5JQNBVT7YCW3DE",
"personality_type": "STOCKPILER",
"plan_tier": "30/70",
"envelopes": {
"bills": { "allocated_pct": 40.0, "allocated_amount": 2000.00 },
"future": { "allocated_pct": 30.0, "allocated_amount": 1500.00 },
"daily_living": { "allocated_pct": 10.5, "allocated_amount": 525.00 },
"health_wellness": { "allocated_pct": 6.0, "allocated_amount": 300.00 },
"lifestyle": { "allocated_pct": 6.0, "allocated_amount": 300.00 },
"people": { "allocated_pct": 7.5, "allocated_amount": 375.00 }
},
"action_items": [
"Automate a $1,500 transfer to savings on payday.",
"Your STOCKPILER profile means building security before all else."
],
"created_at": "2026-05-15T14:33:00Z"
}
}

Store plan_tier β€” you'll use it when generating money moves.


Step 5 β€” Financial profile​

GET https://api.ozzieapp.com/v1/users/ozz_usr_01HX9KZMR4P5JQNBVT7YCW3DE/financial-profile?personality_type=STOCKPILER
Authorization: Bearer czJjbGllbnQ6czJzZWNyZXQ=

Returns envelope allocation percentages.


Step 6 β€” Chat​

POST https://api.ozzieapp.com/v1/users/ozz_usr_01HX9KZMR4P5JQNBVT7YCW3DE/chat/completion
Authorization: Bearer czJjbGllbnQ6czJzZWNyZXQ=
Content-Type: application/json

{
"message": "Am I on track to build my emergency fund?",
"personality_type": "STOCKPILER",
"language": "en"
}

Response:

{
"object": "chat_completion",
"data": {
"role": "assistant",
"content": "Maria, your STOCKPILER profile means consistent, automated saving is your edge. Keep that transfer running and you'll hit your monthly target.",
"created_at": "2026-05-15T14:35:00Z"
}
}

Store the message and reply in your database. Pass history on subsequent calls.


Step 7 β€” Parse transactions​

POST https://api.ozzieapp.com/v1/transactions/parse
Authorization: Bearer czJjbGllbnQ6czJzZWNyZXQ=
Content-Type: application/json

{
"type": "text",
"content": "Groceries $45 at Whole Foods",
"language": "en"
}

Response:

{
"object": "transaction_list",
"data": {
"transactions": [
{
"amount_cents": 4500,
"currency": "USD",
"category": "food",
"envelope": "daily_living",
"description": "Groceries at Whole Foods",
"transaction_date": "2026-05-15"
}
]
}
}

Store the returned records in your database.


Step 8 β€” Generate weekly money moves​

POST https://api.ozzieapp.com/v1/money-moves/generate
Authorization: Bearer czJjbGllbnQ6czJzZWNyZXQ=
Content-Type: application/json

{
"user_id": "ozz_usr_01HX9KZMR4P5JQNBVT7YCW3DE",
"personality_type": "STOCKPILER",
"plan_tier": "30/70",
"week_start": "2026-05-13"
}

Store the returned tasks and track completion status in your database.


Error states and recovery​

SituationError codeRecovery
Plan generation before intakeINTAKE_REQUIREDSubmit POST /financial-intake first, then retry
Financial profile before planPLAN_REQUIREDGenerate plan first, then retry
Duplicate external_user_idCONFLICTUse GET /v1/users/external:{your_id} to retrieve the existing user
Too many requestsRATE_LIMIT_EXCEEDEDRespect Retry-After header; use exponential backoff

Error shape:

{
"error": {
"code": "INTAKE_REQUIRED",
"message": "Financial intake must be submitted before generating a plan."
}
}

Node.js end-to-end example​

import fetch from 'node-fetch';

const BASE = 'https://api.ozzieapp.com/v1';
const TOKEN = Buffer.from('your_client_id:your_client_secret').toString('base64');

const h = {
'Authorization': `Bearer ${TOKEN}`,
'Content-Type': 'application/json',
};

async function req(method, path, body) {
const res = await fetch(`${BASE}${path}`, {
method,
headers: h,
body: body ? JSON.stringify(body) : undefined,
});
const json = await res.json();
if (!res.ok) throw new Error(`[${json.error?.code}] ${json.error?.message}`);
return json.data;
}

async function main() {
// 1. Create user
const user = await req('POST', '/users', {
external_user_id: 'usr_8821',
name: 'Maria Santos',
language: 'en',
});
const uid = user.id;
console.log('User created:', uid);

// 2. Financial intake
const intake = await req('POST', `/users/${uid}/financial-intake`, {
monthly_income: 5000,
monthly_expenses: 3200,
financial_goal: 'savings',
});
console.log('Intake submitted | surplus:', intake.monthly_surplus);

// 3. Personality quiz
const { questions } = await req('GET', '/personality/questions');
console.log('Quiz questions:', questions.length);

const score = await req('POST', '/personality/score', {
answers: [
{ question_id: questions[0].id, option_id: questions[0].options[1].id },
],
});
const personalityType = score.personality_type;
console.log('Personality:', personalityType);
// Store personalityType in your database

// 4. Generate plan
const plan = await req('POST', `/users/${uid}/plan/generate`, {
personality_type: personalityType,
});
const planTier = plan.plan_tier;
console.log('Plan tier:', planTier);

// 5. Financial profile
const profile = await req('GET', `/users/${uid}/financial-profile?personality_type=${personalityType}`);
console.log('Daily living envelope:', profile.envelopes.daily_living);

// 6. Chat
const reply = await req('POST', `/users/${uid}/chat/completion`, {
message: 'Am I on track?',
personality_type: personalityType,
});
console.log('Chat reply:', reply.content.slice(0, 80) + '...');

// 7. Parse a transaction
const txResult = await req('POST', '/transactions/parse', {
type: 'text',
content: 'Coffee $5.50',
});
console.log('Transactions parsed:', txResult.transactions.length);

// 8. Generate money moves
const moves = await req('POST', '/money-moves/generate', {
user_id: uid,
personality_type: personalityType,
plan_tier: planTier,
});
console.log('Money move tasks:', moves.tasks.length);
}

main().catch(err => {
console.error('Integration failed:', err.message);
process.exit(1);
});