> ## Documentation Index
> Fetch the complete documentation index at: https://docs.fourdos.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Get user details

> Read a member's profile, update it, and manage typed attributes

This walkthrough reads and maintains a member you've already created
([Create a user](/walkthroughs/create-a-user)).

```bash theme={null}
export API_BASE_URL="https://api.develop.fourdos.dev"
export API_KEY="org_…"
export USER_ID="0198f2b1-…"
```

## 1. Fetch the profile

```bash theme={null}
curl "$API_BASE_URL/v1/users/$USER_ID" \
  -H "Authorization: Bearer $API_KEY"
```

`200 OK`:

```json theme={null}
{
  "id": "0198f2b1-…",
  "email": "ada.lovelace@example.com",
  "display_name": "Ada L.",
  "first_name": "Ada",
  "last_name": "Lovelace",
  "country": "GB",
  "age_band": "adult",
  "dob_verification_status": "unverified",
  "last_active_at": "2026-07-17T09:12:00.000Z",
  "status": "active",
  "wallet": { "status": "active", "address": "0x…" },
  "membership": {
    "id": "…",
    "external_id": "cust-001",
    "role": "member",
    "status": "active",
    "joined_at": "2026-07-17T00:00:00.000Z"
  }
}
```

The read is scoped to your organization: a user who exists on 4D but isn't a
member of your org is a `404`, not a `403` - membership is what makes them
visible to you. The profile is the **redacted partner view**: you get the
derived `age_band`, never the raw `dob`.

## 2. Update profile fields

`PATCH` takes any subset of the profile fields:

```bash theme={null}
curl -X PATCH "$API_BASE_URL/v1/users/$USER_ID" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "display_name": "Countess of Lovelace", "locale": "en-GB" }'
```

`200 OK` returns the updated user. Validation matches creation: `country`
must be an assigned ISO alpha-2 code, `dob` a real past date.

## 3. Set typed attributes

Beyond the fixed profile, your org's enabled attribute registry holds custom
typed fields ([Tenants and members](/concepts/tenants-and-members)). Write
values by key:

```bash theme={null}
curl -X PUT "$API_BASE_URL/v1/users/$USER_ID/attributes" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "values": [
      { "key": "phone", "value": "+44 20 7946 0000" },
      { "key": "shirt_size", "value": "m" }
    ]
  }'
```

`200 OK`:

```json theme={null}
{
  "values": [
    { "key": "phone", "value": "+44 20 7946 0000", "provenance": "partner_api" },
    { "key": "shirt_size", "value": "m", "provenance": "partner_api" }
  ]
}
```

Values are validated against each key's definition - a `single_choice`
attribute rejects values outside its configured choice list, an attribute key
your org hasn't enabled is rejected outright. Every stored value carries
`provenance`, so an API-written value is always distinguishable from one an
admin, the member, or a bulk import wrote.

## Common errors

| Status | Code               | Meaning                                                        |
| ------ | ------------------ | -------------------------------------------------------------- |
| `404`  | `NOT_FOUND`        | The user isn't a member of your organization                   |
| `422`  | `VALIDATION_ERROR` | A field failed validation - `details` carries per-field errors |
| `401`  | `UNAUTHORIZED`     | Missing or invalid API key                                     |
