:::endpoint GET /v1/me

One call rather than five, because a cold start on a phone pays for every round
trip. Who you are, what you may do, which scopes this device holds, and which
mailboxes you can open.

## Request

```bash
curl https://api.proppertrading.com/v1/me \
  -H "Authorization: Bearer ptat_9f2c1a44_3b8e7d2f5c9a1b4e6d8f0a2c4e6b8d1f"
```

## Response

```json
{
    "data": {
        "object": "me",
        "id": "usr_hraj4wtnqgrkeu9b",
        "name": "Jamie Rivera",
        "email": "jamie@acmefunded.com",
        "avatar_url": "https://acmefunded.com/storage/avatars/3f9c2a1e7b4d6f8a0c2e4b6d8f1a3c5e.webp",
        "locale": "en",
        "type": "trader",
        "role": "Support",
        "two_factor": true,
        "two_factor_methods": ["totp"],
        "workspace": {
            "id": "acme",
            "name": "Acme Funded",
            "platform": false
        },
        "permissions": ["view_mailbox", "manage_tickets"],
        "scopes": ["me:read", "mail:write"],
        "mailboxes": [
            {
                "id": "mbx_w6sy3skvgydh5e3b",
                "email": "support@mail.acmefunded.com",
                "name": "Acme Support",
                "channel": "private-mail-address.mbx_w6sy3skvgydh5e3b"
            }
        ],
        "unread": 7,
        "channel": "private-App.Models.User.usr_hraj4wtnqgrkeu9b"
    },
    "meta": { "request_id": "req_01kz4bkr1aj1gv63d8fv3133ey" }
}
```

| Field         | Description                                                                                                                                        |
| ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`          | This account, such as `usr_hraj4wtnqgrkeu9b`. The same id arrives as `user_id` in a [push notification](/docs/api/apps/push-register), so an app signed in to several accounts can tell which one it is for |
| `avatar_url`  | The picture from the profile page, as an absolute URL. Null when there is none. Public, so load it without the token |
| `locale`      | The language this account chose on the web, such as `en`. Null when it never chose one: fall back to the device's language |
| `type`        | `trader`, `propfirm` or `superadmin`. Staff are traders carrying a role                                                                            |
| `role`        | The name of their role, or null for an account that owns the environment                                                                           |
| `two_factor_methods` | What answers the second step of signing in: `totp` for an authenticator, `passkey` for a passkey on the firm's website or in an app. Empty when `two_factor` is false |
| `permissions` | Slugs this account holds. `["*"]` means a role that holds everything. Empty for accounts that own the environment, which may do everything by type |
| `scopes`      | What this device holds, which may be narrower than what it asked for                                                                               |
| `mailboxes`   | The mailboxes this person may read. Empty without `view_mailbox`. Each `id` is the one [the mailbox list](/docs/api/mail/mailboxes) gives, and `channel` is the socket channel for it |
| `unread`      | Unread messages across those mailboxes, for a badge                                                                                                |
| `channel`     | The [socket channel](/docs/api/apps/realtime) your notifications arrive on, such as `private-App.Models.User.usr_hraj4wtnqgrkeu9b`. Subscribe to it as it is, without taking it apart or building it from `id`, so a change in how channels are named never reaches your code |

## Permissions and scopes are both ceilings

An action needs the scope on the device and the permission on the account. Draw
your interface from `permissions`, and expect a `403` anyway if a role changes
between the call and the tap.

`["*"]` rather than the full list is deliberate: a list would be yesterday's set
the moment a permission is added, and the client would disagree with the server
about a screen nobody had touched.

## Errors

| Status | Code                 | Meaning                                         |
| ------ | -------------------- | ----------------------------------------------- |
| 401    | `invalid_token`      | Not a token, or the secret does not match       |
| 401    | `revoked_token`      | Signed out here or from another device          |
| 401    | `expired_token`      | Ninety days without use, or a set expiry passed |
| 403    | `insufficient_scope` | This device does not hold `me:read`             |