Skip to content

Update User Profile

PUT
/api/v1/user/profile
curl --request PUT \
--url https://indepai.app/api/v1/user/profile \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "fullName": "John Doe", "displayName": "example", "avatarUrl": "https://example.com", "birthYear": 1990, "baseCurrency": "EUR", "countryCode": "DE", "city": "Berlin", "currentCitySlug": "berlin-germany", "timezone": "Europe/Berlin", "annualIncome": 80000, "annualExpenses": 40000, "monthlyPassiveIncome": 500, "currentSavings": 200000, "fireType": "traditional", "riskTolerance": "conservative", "targetFIAge": 45, "lifestyleCreepRate": 0.02, "estimatePolicy": "estimateOnly", "derivePassiveFromDividends": false }'

Update the authenticated user’s profile

Media typeapplication/json
object
fullName

User’s full name

string | null
>= 1 characters <= 100 characters
Example
John Doe
displayName

Display name (alias for fullName)

string
<= 100 characters
avatarUrl

Profile picture URL

string | null format: uri
birthYear

Birth year

integer | null
>= 1900 <= 2008
Example
1990
baseCurrency

Preferred base currency

string
>= 3 characters <= 3 characters
Example
EUR
countryCode

Country code (ISO 3166-1 alpha-2)

string | null
>= 2 characters <= 2 characters
Example
DE
city

City of residence

string | null
<= 100 characters
Example
Berlin
currentCitySlug

Slug FK to numbeo_data for geo-arbitrage

string | null
>= 1 characters <= 200 characters
Example
berlin-germany
timezone

Timezone

string
Example
Europe/Berlin
annualIncome

Annual income after tax

number
<= 100000000
Example
80000
annualExpenses

Annual expenses

number
<= 100000000
Example
40000
monthlyPassiveIncome

Monthly passive income (dividends, rental, interest)

number
<= 10000000
Example
500
currentSavings

Current savings/net worth

number
<= 1000000000
Example
200000
fireType

Preferred FIRE strategy type

string | null
Example
traditional
riskTolerance

Investment risk tolerance level

string | null
Allowed values: conservative moderate aggressive
Example
moderate
targetFIAge

Target age to reach FI

integer | null
>= 18 <= 100
Example
45
lifestyleCreepRate

Real annual spending growth above inflation (lifestyle creep); 0 = off

number | null
<= 0.03
Example
0.02
estimatePolicy

How the self-reported estimate (current_savings) combines with tracked holdings for net worth: holdingsAugment (estimate counts only as the ‘Other’ excess above holdings — default), holdingsOnly (ignore the estimate), or estimateOnly (net worth is the estimate).

string
Allowed values: estimateOnly holdingsAugment holdingsOnly
Example
holdingsAugment
derivePassiveFromDividends

Opt-in (default false): when true, the FI-Score augments monthly passive income with the forward-DIVIDEND projection from tracked holdings (dividends only — no double-count with the trigger-maintained monthly_passive_income).

boolean
Example
false

Profile updated

Media typeapplication/json
object
success
required
boolean
data
required
object
id
required

User ID

string format: uuid
email
required

User email

string format: email
fullName
required

User’s full name

string | null
avatarUrl
required

Profile picture URL

string | null format: uri
subscriptionTier
required

Current subscription tier

string
Allowed values: free starter pro premium enterprise
subscriptionStatus
required

Subscription status

string
Allowed values: active trialing past_due canceled incomplete
trialEndsAt
required

Trial end date (if applicable)

string | null format: date-time
currentPeriodEnd
required

Current billing period end date

string | null format: date-time
createdAt
required

Account creation date

string format: date-time
updatedAt
required

Last profile update

string format: date-time
meta
required
object
timestamp
required

Timestamp in ISO 8601 format

string format: date-time
Example
{
"success": true,
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "user@example.com",
"fullName": "John Doe",
"subscriptionTier": "free",
"subscriptionStatus": "active",
"trialEndsAt": "2024-01-15T10:30:00Z",
"currentPeriodEnd": "2024-01-15T10:30:00Z",
"createdAt": "2024-01-15T10:30:00Z",
"updatedAt": "2024-01-15T10:30:00Z"
},
"meta": {
"timestamp": "2024-01-15T10:30:00Z"
}
}

Validation error

Media typeapplication/json
object
success
required

Always false for error responses

boolean
error
required

Error type

string
code

Machine-readable error code

string
details

Detailed validation errors

Array<object>
object
path
required

Path to the invalid field

string
message
required

Error message

string
Example
{
"success": false,
"error": "Validation error",
"code": "VALIDATION_ERROR",
"details": [
{
"path": "currentAge",
"message": "Must be between 18 and 100"
}
]
}

Unauthorized

Media typeapplication/json
object
success
required

Always false for error responses

boolean
error
required

Error type

string
code

Machine-readable error code

string
details

Detailed validation errors

Array<object>
object
path
required

Path to the invalid field

string
message
required

Error message

string
Example
{
"success": false,
"error": "Validation error",
"code": "VALIDATION_ERROR",
"details": [
{
"path": "currentAge",
"message": "Must be between 18 and 100"
}
]
}