Skip to main content

Users

Manage user accounts. Standard users can see who the users of their organization are and update their own account. Administrative endpoints allow creating, archiving, and managing other user accounts.

All endpoints require authentication via X-API-Key header and the appropriate scope.


User Object​

GET /users and GET /users/:id answer each user as exactly three fields:

{
"username": "Jane Smith",
"email": "jane@example.com",
"role": "developer"
}
FieldTypeDescription
usernamestringThe user's name
emailstringThe user's email address
rolestring or nullThe user's platform role: admin, developer or app. null for a user who has none

Nothing else about a user is returned: no id, profile or organization. The id of a member of your organization is in GET /organizations/:id/members; the id of a user you create is in the POST /users response. Your own id, organization and API key are in GET /me.


GET /api/v1/users​

List the users in your organization, each as a user object.

Scope: users:read

Query Parameters

ParameterTypeRequiredDescription
qstringNoCase-insensitive match on email address or name (username is not searched)
archivedbooleanNotrue returns only archived users; otherwise archived users are left out
activebooleanNoFilter by active status
limitintegerNoNumber of results to return (default: 50, max: 200)
cursorstringNometa.nextCursor of the previous page; omit for the first page
sortstringNoSort field, prefixed with - for descending (default: -createdAt)

Response 200 OK

{
"data": [
{ "username": "Jane Smith", "email": "jane@example.com", "role": "developer" }
],
"meta": {
"total": 25,
"limit": 50,
"nextCursor": null,
"requestId": "req_abc123"
}
}

GET /api/v1/me​

Who you are authenticated as: your user (a user object plus its _id), your organization and your role in it, and the API key the call used (absent when you call with a session). It needs no scope, so it is the simplest way to check a key works.

Response 200 OK

{
"data": {
"_id": "fJHgtbiLZyMkFqJC6",
"username": "Jane Smith",
"email": "jane@example.com",
"role": "developer",
"organization": { "_id": "org_xyz", "role": "owner", "isMultiTenant": false, "isSolo": false },
"apiKey": { "_id": "key_abc123", "name": "CI", "keyPrefix": "sk-prod-ab12", "scopes": ["workflows:read"], "expiresAt": null }
},
"meta": { "requestId": "req_abc123" }
}

GET /api/v1/me/github-ssh-keys​

List your GitHub SSH keys: id, label, public key and fingerprint (never the private key). A GitHub source (an app's bundleSource, a volume's or project's code) names one of them as sshKeyId. Keys are added in your profile settings. It pages with limit and cursor (Pagination).

Scope: users:read

{
"data": [
{ "_id": "k1", "label": "laptop", "publicKey": "ssh-ed25519 AAAA...", "fingerprint": "SHA256:...", "createdAt": "2026-09-01T10:00:00.000Z" }
],
"meta": { "total": 1, "limit": 50, "nextCursor": null, "requestId": "req_abc123" }
}

PATCH /api/v1/me​

Update the currently authenticated user's own profile.

Scope: users:write

Request Body

{
"name": "Jane M. Smith",
"stanPersonality": "friendly"
}
FieldTypeRequiredDescription
namestringNoDisplay name
photostringNoProfile photo, as a URL or base64 image data
stanPersonalitystringNoSTAN's personality: professional, friendly, or concise

Any other field returns 400 validation-error.

Response 200 OK

You, as GET /api/v1/me shows you.


DELETE /api/v1/me​

Delete your own account: it is deactivated at once, its API keys are revoked, and its data is erased on schedule.

Scope: users:write

Response 200 OK: what deleting the account removed: { assetAction, assetResult }, assetAction delete and assetResult what was deleted (both null when the account was already deleted).


GET /api/v1/users/:id​

Get a user by ID as a user object.

Scope: users:read

Path Parameters

ParameterTypeRequiredDescription
idstringYesUser ID

Response 200 OK

{
"data": { "username": "Bob Johnson", "email": "bob@example.com", "role": "app" },
"meta": { "requestId": "req_abc123" }
}

POST /api/v1/users​

Create a new user account. Requires administrator privileges.

Scope: users:admin

Request Body

{
"email": "newuser@example.com",
"name": "New User",
"role": "developer",
"sendEmail": true
}
FieldTypeRequiredDescription
emailstringYesUser email address. Must be a valid address not already used by another user
namestringYesDisplay name
rolestringNoThe user's role: app, developer, or admin (default: app; any other value is treated as app)
sendEmailbooleanNoSend a welcome email with a link to set a password, when the platform can send email (default: true). Pass false to send no email and get a temporary password in the response instead
profileobjectNoExtra profile fields stored on the new user

There is no password field: the user sets their own password from the welcome email, or signs in with the temporary password. Any field not listed above returns 400 validation-error, as does a missing email or name or an invalid email address. An email that already belongs to a user is refused with 500 internal-error and the message User with this email already exists.

Response 201 Created

{
"data": {
"userId": "user_new001",
"temporaryPassword": null
},
"meta": { "requestId": "req_abc123" }
}

temporaryPassword is the generated password when sendEmail is false, otherwise null.


PATCH /api/v1/users/:id​

Update a user account. Requires administrator privileges.

Scope: users:admin

Path Parameters

ParameterTypeRequiredDescription
idstringYesUser ID

Request Body

{
"name": "Updated Name",
"isDeveloper": true,
"active": true
}
FieldTypeRequiredDescription
namestringNoDisplay name
emailstringNoNew email address. It is marked unverified and must be a valid address not used by another user
activebooleanNofalse deactivates the user
archivedbooleanNoArchive (true) or unarchive (false) the user without handling their resources; see archive for that
isAdminbooleanNoSets the user's single role: admin if isAdmin is true, otherwise developer if isDeveloper is true, otherwise app
isDeveloperbooleanNoSee isAdmin
isReviewerbooleanNoAccepted; sending it recomputes the role from isAdmin and isDeveloper as above

Any other field returns 400 validation-error.

Response 200 OK

The updated user.


GET /api/v1/users/:id/assets​

Get a summary of all resources owned by a user. Useful before archiving to understand the impact.

Scope: users:admin

Path Parameters

ParameterTypeRequiredDescription
idstringYesUser ID

Response 200 OK

{
"data": {
"userId": "user_789",
"userName": "Jane Smith",
"userEmail": "jane@example.com",
"organizationId": "org_xyz",
"isSSO": false,
"assets": {
"apps": 3,
"workspaces": 2,
"workflows": 5,
"projects": 1,
"volumes": 0,
"addons": 1,
"datasources": 2,
"prompts": 8,
"abTests": 0,
"routers": 1,
"aiModels": 4,
"guardrails": 2,
"mlModels": 0,
"total": 29
},
"deletion": {
"items": [
{ "label": "Apps", "count": 3 }
],
"total": 29,
"othersWorkspacesInProjects": 0
}
},
"meta": { "requestId": "req_abc123" }
}

deletion previews what the delete asset action would remove: each resource type the user owns with its count, and how many other users' workspaces sit inside projects the user owns (they are deleted with those projects).


POST /api/v1/users/:id/archive​

Archive a user account with asset handling. Archived users cannot log in. Admin chooses how to handle owned resources: transfer to another user, transfer to org admin, delete, or leave as-is.

Scope: users:admin

Path Parameters

ParameterTypeRequiredDescription
idstringYesUser ID

Request Body

ParameterTypeRequiredDescription
assetActionstringNotransfer, transfer-to-admin, delete, or leave-as-is. Defaults to leave-as-is
transferToUserIdstringConditionalRequired when assetAction is transfer. Must be an active user in the same organization

Response 200 OK​

The user, with what archiving did with their resources (assetResult is null when they were left as they are).

{
"data": {
"username": "Jane Smith",
"email": "jane@example.com",
"role": "developer",
"assetAction": "transfer-to-admin",
"assetResult": {
"success": true,
"transferred": { "apps": 3, "workflows": 5, "total": 29 },
"transferredTo": "admin_user_id"
}
},
"meta": { "requestId": "req_abc123" }
}

POST /api/v1/users/:id/unarchive​

Unarchive a previously archived user. Reactivates the account. Resources transferred or deleted during archival are not restored.

Scope: users:admin

Path Parameters

ParameterTypeRequiredDescription
idstringYesUser ID

Response 200 OK​

The user, active again.

{ "data": { "username": "Jane Smith", "email": "jane@example.com", "role": "developer" }, "meta": { "requestId": "req_abc123" } }

POST /api/v1/users/:id/reset-password​

Reset a user's password. Sends a password reset email or generates a temporary password. Requires administrator privileges.

Scope: users:admin

Path Parameters

ParameterTypeRequiredDescription
idstringYesUser ID

Response 200 OK​

The user, with emailSent. When the email could not be sent, resetToken is the token for the reset link (/reset-password/<resetToken>), shown once, to pass on another way.

{ "data": { "username": "Jane Smith", "email": "jane@example.com", "role": "developer", "emailSent": false, "resetToken": "..." }, "meta": { "requestId": "req_abc123" } }