# User Profile API > **Prefix:** `/api/v1/user-profile` User medical profiles store health information that can be shared with doctors. --- ## POST `/api/v1/user-profile` Create a medical profile for the authenticated user. **Permission:** `AUTH` ### Request Body (`application/json`) ```json { "name": "علی", "family": "احمدی", "fathers_name": "محمد", "national_code": "0012345678", "gender": "male", "blood_type": "A+", "marital_status": "married", "education": "لیسانس", "job": "مهندس", "address": "تهران، خیابان ولیعصر", "home_phone": "02112345678", "work_phone": "02198765432", "insurance_id": 1, "description": "توضیحات بیشتر", "sharing_with_user": true, "birthday": "1370-06-15", "date_of_birth": 648172800, "basic_insurance": "بیمه تأمین اجتماعی", "supplementary_insurance": "بیمه ایران", "other": {} } ``` | Field | Type | Required | Description | |-------|------|----------|-------------| | `name` | string | ❌ | First name | | `family` | string | ❌ | Last name | | `fathers_name` | string | ❌ | Father's name | | `national_code` | string | ❌ | National ID (10 digits) | | `gender` | string | ❌ | `"male"` or `"female"` | | `blood_type` | string | ❌ | `"A+"`, `"A-"`, `"B+"`, `"B-"`, `"AB+"`, `"AB-"`, `"O+"`, `"O-"` | | `marital_status` | string | ❌ | `"single"` or `"married"` | | `education` | string | ❌ | Education level | | `job` | string | ❌ | Occupation | | `address` | string | ❌ | Home address | | `home_phone` | string | ❌ | Home phone number | | `work_phone` | string | ❌ | Work phone number | | `insurance_id` | integer | ❌ | Insurance ID | | `description` | string | ❌ | Additional notes | | `sharing_with_user` | boolean | ❌ | Allow doctors to view this profile | | `birthday` | string | ❌ | Birthday in Jalali format `YYYY-MM-DD` | | `date_of_birth` | integer | ❌ | Birthday as Unix timestamp | | `basic_insurance` | string | ❌ | Basic insurance name | | `supplementary_insurance` | string | ❌ | Supplementary insurance name | | `other` | object | ❌ | Extra metadata | ### Response `201` ```json { "success": true, "data": { "uuid": "profile-uuid-...", "name": "علی", "family": "احمدی", "gender": "male", "blood_type": "A+", "national_code": "0012345678", "sharing_with_user": true, "created_at": 1717000000 } } ``` ### Errors | Code | HTTP | Description | |------|------|-------------| | `ERR_AUTH_001` | 401 | Missing token | | `ERR_CONFLICT_001` | 409 | Profile already exists for this user | --- ## GET `/api/v1/user-profile/{uuid}` Get a user profile. **Permission:** `AUTH` — must be the profile owner, or a doctor if `sharing_with_user: true`, or `ROLE_ADMIN` ### Path Parameters | Param | Type | Description | |-------|------|-------------| | `uuid` | string (UUID) | **Profile UUID or the owning User UUID** — both are accepted | > **Auto-resolve & lazy-create:** `{uuid}` is first looked up as a profile uuid, then as a user uuid. If it is the **current user's own** uuid and they have **no profile yet**, an empty profile is created and returned (HTTP 200) — so a freshly registered user always gets an editable profile instead of a 404. An **admin** reading **another** user's missing profile gets `404` (no profile is created as a side effect of reading). The response includes both the profile `uuid` and `user_uuid`; keep the profile `uuid` for subsequent PATCHes. ### Response `200` Full profile object including all fields (all `null` for a newly created empty profile). Response is double-nested: extract with `data.data`. ### Errors | Code | HTTP | Description | |------|------|-------------| | `ERR_AUTH_001` | 401 | Missing token | | `ERR_FORBIDDEN_001` | 403 | Not authorized to view this profile | | `ERR_VALIDATION_002` | 404 | No profile or user matches the uuid | --- ## PATCH `/api/v1/user-profile/{uuid}` Update a user profile. **Permission:** `AUTH` — must be the profile owner ### Path Parameters | Param | Type | Description | |-------|------|-------------| | `uuid` | string (UUID) | **Profile UUID or the owning User UUID** — both accepted; the profile is created if the current user has none yet | ### Request Body Same fields as POST — all optional. ### Response `200` Updated profile object. ### Errors | Code | HTTP | Description | |------|------|-------------| | `ERR_AUTH_001` | 401 | Missing token | | `ERR_FORBIDDEN_001` | 403 | Not the profile owner | | `ERR_NOT_FOUND_001` | 404 | Profile not found | --- ## DELETE `/api/v1/user-profile/{uuid}` Delete a user profile. **Permission:** `ROLE_ADMIN` ### Response `200` ```json { "success": true, "data": { "message": "پروفایل حذف شد" } } ``` ### Errors | Code | HTTP | Description | |------|------|-------------| | `ERR_AUTH_001` | 401 | Missing token | | `ERR_AUTH_006` | 403 | Not admin | | `ERR_NOT_FOUND_001` | 404 | Profile not found | --- ## POST `/api/v1/user-profile/avatar` Upload the current user's profile avatar. Creates the profile if it doesn't exist yet. **Permission:** `IS_AUTHENTICATED_FULLY` ### Request Raw file body with `Content-Disposition: filename="..."` and `Content-Type: application/octet-stream`. ### Response `200` ```json { "success": true, "data": { "avatar": "/uploads/avatars/2026-06/xxx.jpg", "url": "/uploads/avatars/2026-06/xxx.jpg" } } ``` The stored path is also returned as `avatar` in the profile GET/PATCH responses. ### Errors | Code | HTTP | Description | |------|------|-------------| | `ERR_VALIDATION_001` | 422 | Missing or invalid file | | `ERR_AUTH_001` | 401 | Missing token |