Authentication: All endpoints require Authorization: Bearer <access_token>.

Overview

The User Profile module manages all personal details. Auth creates the base users row on first login — this module reads and writes the profile fields on top of that.

Updatable Fields

first_name, last_name, email, dob, gender, address, occupation, employer

Immutable Fields

phone (identity, set by Auth), aadhaar (set via separate KYC flow — returns 400 if attempted via PATCH)

GET /user/profile

Fetches the authenticated user’s complete profile. The profile_complete boolean is computed server-side on every request.

What happens server-side

  1. Extracts user_id from JWT claims
  2. Queries users WHERE id = user_id
  3. Computes profile_complete = (first_name IS NOT NULL AND last_name IS NOT NULL)
  4. Returns the profile with Aadhaar masked as XXXX-XXXX-{last4}
Authorization
string
required
Bearer <access_token>
curl http://localhost:8080/user/profile \
  -H 'Authorization: Bearer eyJhbGci...'
user_id
string (UUID)
required
Permanent unique identifier for the user.
phone
string
required
10-digit mobile number with +91 prefix. Set by Auth — never changes.
aadhaar
string
Always returned as XXXX-XXXX-{last4}. The full Aadhaar number is never returned. Only the last 4 digits are stored in the database.
profile_complete
boolean
required
true when both first_name and last_name are non-null and non-empty. Used by the app to decide whether to show the onboarding screen.
dob
string (ISO 8601 date)
Format: YYYY-MM-DD. Null if not set. Used for insurance premium age-loading calculation.
gender
string (enum)
One of MALE, FEMALE, OTHER. Null if not set. See enum values below.
occupation
string (enum)
One of the OccupationType values. Null if not set. See full list below.

PATCH /user/profile

Partially updates the user’s profile. Only the fields included in the request body are updated — all other fields remain unchanged.

What happens server-side

  1. Extracts user_id from JWT claims
  2. Validates all provided fields against their respective constraints
  3. Checks that no immutable fields (phone, aadhaar) are included — returns 400 if so
  4. Applies a partial SQL UPDATE (only non-null fields from the request body)
  5. Recomputes profile_complete
  6. Returns the full updated profile

profile_complete Transition

When this PATCH sets both first_name and last_name for the first time (transitioning profile_complete from false to true), the app should:
  1. Dismiss the onboarding screen
  2. Persist the profile_complete: true state locally
  3. Navigate to the home screen
The transition is idempotent — submitting the names again does not change any behaviour.
curl -X PATCH http://localhost:8080/user/profile \
  -H 'Authorization: Bearer eyJhbGci...' \
  -H 'Content-Type: application/json' \
  -d '{
    "first_name": "Priya",
    "last_name": "Sharma",
    "dob": "1990-05-15",
    "gender": "FEMALE",
    "address": "12, MG Road, Bengaluru",
    "occupation": "Delivery Partner",
    "employer": "Namma Yatri"
  }'
All request body fields are optional — send only the fields you want to update.

Field Validation Rules

FieldTypeConstraints
first_namestringMax 100 chars; trimmed whitespace
last_namestringMax 100 chars; trimmed whitespace
emailstringValid RFC 5322 format; max 255 chars
dobstringYYYY-MM-DD; must be strictly in the past; age 18–100 years
genderstring (enum)MALE | FEMALE | OTHER
addressstringMax 500 chars; free text
occupationstring (enum)See OccupationType list below
employerstringMax 100 chars; free text

Gender Enum Values

ValueNotes
MALE
FEMALE
OTHERInclusive — covers non-binary, prefer-not-to-say, and all other identities

OccupationType Enum Values

ValueDescription
DriverCab, auto, or bike taxi driver (Ola, Namma Yatri, Uber, Rapido)
Delivery PartnerPackage or food delivery (Swiggy, Zomato, Blinkit, Amazon, DTDC)
Domestic WorkerHouse cleaner, cook, nanny, or care assistant
Construction WorkerDaily-wage labourer on construction sites
Factory WorkerManufacturing or industrial floor worker
Healthcare WorkerNursing aide, ASHA/ANM worker, hospital support staff
Retail WorkerKirana, mall, or shop employee
Security GuardBuilding, campus, or premises security
OtherAny gig or informal work not listed above

PII Policy

Aadhaar Masking Logic

PII FieldStored AsReturned AsRationale
Aadhaar numberLast 4 digits only (aadhaar_last4)XXXX-XXXX-1234Minimises PII footprint; avoids DPDP Act compliance overhead for full national ID storage
Phone+91XXXXXXXXXXAs storedPrimary identity anchor
EmailPlaintextAs storedLow-sensitivity; used for notifications
NamePlaintextAs storedRequired for insurance
DOBDATE columnYYYY-MM-DD stringSensitive but necessary for age-rated insurance
Sending phone or aadhaar in the PATCH body will return 400 Bad Request. These are identity fields managed by dedicated flows. Phone is immutable after account creation. Aadhaar is set via a separate KYC flow and cannot be changed via the profile endpoint.