API reference
Users
Reading your userbase, and what a person may change themselves.
Two different things live here, and the difference is who is asking.
Your userbase: secret key
/v1/users /v1/users/{userId} Your administrative view. These read anybody, so they take a secret key and must be called from your server.
The signed-in person: session token
/v1/me Returns the caller, the organizations they belong to, and which one the session is currently acting as.
{
"user": { "id": "user_…", "email": "ada@example.com", "firstName": "Ada", "…": "…" },
"organizations": [
{ "id": "org_…", "name": "Acme", "slug": "acme", "role": "admin", "imageUrl": null }
],
"organization": null
}
The organizations list is what a switcher renders. switch-organization can
change the active one, but nothing else can tell you what the choices are.
Update your own profile
/v1/me { "firstName": "Ada", "lastName": "Lovelace", "username": "ada" }
imageUrl must be an https URL. Send null to remove the picture; leaving the
field out leaves it alone.
Ask for an upload URL
/v1/me/assets/upload-url {
"purpose": "user_avatar",
"contentType": "image/png",
"contentLength": 84213,
"sha256": "e3b0c44298fc1c14…",
"width": 512,
"height": 512
}
Returns a short-lived signed URL to PUT the bytes to, plus the publicUrl to
save afterwards with PATCH /v1/me. The file never passes through this API.
sha256 is the hex digest of the file and becomes the object key, so uploading
the same picture twice costs one upload: the second response comes back with
alreadyExists: true and no uploadUrl, and you save the publicUrl directly.
PNG, JPEG and WebP, up to 1 MB. SVG is refused: an SVG is a document that can carry a script, and these images render on sign-in screens.
purpose may be user_avatar or organization_image. The second needs the
org:manage permission on the organization, checked against the live
membership. Branding assets belong to you rather than to your users and are
uploaded from the console, not from here.
Change your password
/v1/me/password { "currentPassword": "…", "newPassword": "…" }
The current password is required even though the session already proves who signed in. A session is proof that somebody signed in, not that the person at the keyboard right now is the same one.
Every other session is revoked. The one making the change survives.
{ "changed": true, "otherSessionsRevoked": 3 } Updated at, Friday, August 28, 2026