Using an access token
Call the account API at /v1/me with a personal access token to read or update your own profile from a script.
On this page
A personal access token lets a script call the account API as you. This page shows the one place a token is accepted, what it returns and how it fails. To create a token, see Access tokens.
Using a token with the account API is behind the pat_bearer_api feature flag, which defaults OFF, and it is available only where your organization allows it (an organization above yours can also switch tokens off). Where it is not available, calls with a token are refused in the same way as an invalid token.
Where a token works#
A token works on one address only: /v1/me, on the identity host. Nothing else under /v1/me accepts a token. The rest of the account API, such as sessions, security settings and data export, needs you to be signed in with a session or with a first-party sign-in, and refuses a token as invalid.
| Method | Scope the token needs | What it does |
|---|---|---|
GET /v1/me | identity.self.profile.read or identity.self.read | Reads your own profile. |
PATCH /v1/me | identity.self.profile.write or identity.self.write | Updates your own profile and returns the result. |
The other scopes you can tick when you create a token are not accepted anywhere yet. The token must also be unexpired (a token created with Never has no expiry), not revoked, used from an allowed address if you set a list, and its organization must still be one you are an active member of.
Send the token#
Present the token as a bearer credential. Its secret starts with tdaid_pat_.
curl https://identity.tdacorp.in/v1/me \ -H "Authorization: Bearer $TDAID_TOKEN"Keep the secret in an environment variable or a secret store, never in the command history or in source code.
Read your profile#
A successful GET answers 200 with a JSON object:
{ "email": "ada@example.com", "email_verified": true, "picture": "https://example.com/avatar.webp", "created_at": "2026-09-01T09:30:00.000Z", "sub": "01J...", "display_name": "Ada Lovelace", "username": "ada", "bio": null, "locale": "en-GB", "tz": "Europe/London", "updated_at": "2026-09-20T12:00:00.000Z"}| Field | Meaning |
|---|---|
sub | Your account identifier. An application registered for pairwise identifiers is given a different one for you. |
display_name | Your display name. |
username, bio, locale, tz | Your optional username, short bio, language tag and time zone. null when unset. |
email, email_verified | Your email address and whether it is verified. Present when you have one. |
picture | The address of your profile picture. Present only when you have uploaded one. |
created_at, updated_at | When the account was created and when the profile last changed. |
Update your profile#
A token with identity.self.profile.write or identity.self.write can change these fields:
curl -X PATCH https://identity.tdacorp.in/v1/me \ -H "Authorization: Bearer $TDAID_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "display_name": "Ada L.", "tz": "Europe/London" }'The body is a JSON object with any of display_name, username, bio, locale and tz. A field you leave out is left alone. Any other field is refused.
display_nameis required to be non-blank when present and is never cleared.username,bio,localeandtzare cleared by sendingnullor an empty string.- A username must pass the same checks as the one you set on your Profile page, and a username someone else holds is refused with
409and the errorusername_unavailable.
The response is the updated profile, in the same shape as GET.
Updating through the API is recorded in your activity like any other profile change.
Failures#
| Status | Body error | What it means |
|---|---|---|
| 400 | invalid_request | The body is not valid: a field that is not allowed, a blank display name, or a value that fails its check. The description says which. |
| 401 | invalid_token | The token is not accepted. The response carries WWW-Authenticate: Bearer error="invalid_token". |
| 409 | username_unavailable | Another account holds that username. |
| 429 | rate_limited | The token has used its allowance for now. The Retry-After header says how many seconds to wait. |
Every reason a token can be refused gives the same 401, whether it is wrong, expired, revoked, outside its address list or short of scope. This is deliberate: someone holding a stolen token learns nothing about its limits. If a token you expect to work is refused, open the Access tokens tab and check its status, expiry, scopes and Allowed IPs.
A refused attempt with a real token is also recorded as a security event in your feed.
Good practice#
- Create one token per script, with a name that says which.
- Give each the shortest expiry that works and only the scopes it needs.
- Use an address list when the script runs from a fixed place.
- Revoke a token when the script is retired, and replace it before it expires.
- If a token may have leaked, revoke it at once from the Access tokens tab.
Related#
- Access tokens
- Sessions and tokens: the tokens applications receive, which are a different thing.
- API reference: the account API surface.