GET
/v1/meOne 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
curl https://api.proppertrading.com/v1/me \
-H "Authorization: Bearer ptat_9f2c1a44_3b8e7d2f5c9a1b4e6d8f0a2c4e6b8d1f"
Response
{
"data": {
"object": "me",
"id": "usr_hraj4wtnqgrkeu9b",
"name": "Jamie Rivera",
"email": "[email protected]",
"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": "[email protected]",
"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, 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 gives, and channel is the socket channel for it |
unread | Unread messages across those mailboxes, for a badge |
channel | The socket channel 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 |