GET /api/v1/profile, PATCH /api/v1/profile, PATCH /api/v1/profile/dive-center and POST /api/v1/auth/register. Documented once here; the endpoint files link to it rather than repeating it.App\Http\Resources\Backend\UserResource.This resource is shared with the backend. It is not an API-specific resource, so a change made for an administrative screen changes this payload too. A dedicated Api\V1\UserResourceis planned; until it exists, treat the field list as liable to move.
data holds the user fields directly. There is no nested data and no second status inside it.{
"success": true,
"status": "success",
"message": "OK",
"data": {
"id": 164553,
"raid_id": "CA26-801-007",
"email": "diver@example.com",
"...": "..."
}
}| Field | Type | Nullable | Notes |
|---|---|---|---|
id | integer | No | Primary key |
raid_id | string | Yes | RAID member id, e.g. CA26-801-007 |
email | string | No | Also the username |
qrcode | string | No | A complete inline SVG document, roughly 9 kB. See the size warning below |
qualification | string | Yes | Highest qualification, plain text |
qualification_cast | string | Yes | Enum label, e.g. Recreational |
category | string | Yes | Enum label, null when no category is set |
first_name | string | Yes | |
last_name | string | Yes | |
full_name | string | Yes | Derived server-side, not directly writable |
nationality | string | Yes | ISO 3166-1 alpha-2 |
country | string | Yes | ISO 3166-1 alpha-2 |
state | string | Yes | Subdivision name |
state_code | string | Yes | Subdivision code |
city | string | Yes | |
address | string | Yes | |
timezone | string | Yes | PHP timezone identifier |
postal_code | string | Yes | |
phone | string | Yes | |
mobile | string | Yes | |
gender | string | Yes | Enum label |
dob | string | Yes | Y-m-d |
nok_first_name | string | Yes | Next of kin |
nok_last_name | string | Yes | Next of kin |
nok_phone | string | Yes | Next of kin |
nok_email | string | Yes | Next of kin |
nok_country | string | Yes | Next of kin |
avatar | string | No | Absolute URL. Falls back to a placeholder image |
e_card | string | No | Absolute URL of the certification card image |
guardian_first_name | string | Yes | Minors only |
guardian_last_name | string | Yes | Minors only |
guardian_email | string | Yes | Minors only |
guardian_accepted | boolean | No | |
default_language | string | Yes | Two-letter language code. May hold legacy codes (cn, kr, us); the API normalizes them when choosing the response language (README §10) |
currency | string | Yes | Derived from the country. Not the store currency — the store prices in USD only |
preferred_system | string | No | Enum label, Metric or Imperial |
vat_rate | number | Yes | VAT percentage applied to that user's purchases |
gdpr | string | Yes | Y-m-d |
terms | string | Yes | Y-m-d |
policy_accepted_at | string | Yes | Y-m-d |
email_verified_at | string | Yes | Y-m-d. null means the address is not verified |
created_at | string | No | ISO-8601 with microseconds and a UTC offset, e.g. 2026-09-10T09:21:23.000000Z |
updated_at | string | No | Same format as created_at |
dive_center | string | No | Centre name, or the literal string Not assigned |
distributor | string | No | Distributor name, or the literal string Not assigned |
status | string | No | Enum label, e.g. Account Active |
| Field | Present when | Type | Notes |
|---|---|---|---|
dive_center_id | a dive centre is assigned | integer | |
dive_center_date | a dive centre is assigned | string | Y-m-d, nullable |
distributor_id | a distributor is assigned | integer | |
distributor_date | a distributor is assigned | string | Y-m-d, nullable |
suspension_days | status is not active | integer | |
restore_date | status is not active | string | Y-m-d, nullable |
restore_status | status is not active | string | Enum label, nullable |
status_reason | status is not active | string | Free text written by administrators |
job_country | the account is a professional | string | |
professional_status | the account is a professional | string | Enum label, nullable |
professional_suspension_days | the account is a professional | integer | |
professional_restore_date | the account is a professional | string | Y-m-d, nullable |
professional_status_reason | the account is a professional | string | Free text written by administrators |
renewal_date | the account is a professional | string | Y-m-d, nullable |
expire_date | the account is a professional | string | Y-m-d, nullable |
qrcode is 9 292 — 87 %. The field is a complete <svg> document, not a URL and not base64. On a mobile connection this makes the profile call an order of magnitude heavier than the data it carries. If the client does not render the member QR code, it still pays for it on every call.Y-m-d strings. created_at and updated_at are full ISO-8601 with microseconds. Parse them differently.qualification_cast, category, gender, preferred_system, status, restore_status, professional_status all return a display string such as Recreational or Account Active. There is no stable code alongside it, and the label is in the response language (README §10). Do not branch on these strings: they are display text and can change. Returning both a value and a label is a decided change, not yet implemented.Not assigned is a sentinel, not a name. When no dive centre or distributor is set, dive_center and distributor contain that literal English string rather than null. A client checking for absence must compare against it.vat_rate, status_reason and professional_status_reason are visible to the account holder. The last two are free text written by administrators about the account. Reviewed and deliberately left visible for now, on the basis that the only consumer is the RAID mobile client. It should be revisited before the API is opened to third parties.docs/api/profile/_user-resource.md