Skip to main content
The Users Service provides endpoints for viewing user information, inviting users to organizations, and managing user roles within organizations.

Authentication

All endpoints require a valid Bearer token in the Authorization header.

Base URL

/api/users

Endpoints Overview

EndpointMethodDescriptionRequired Permission
/api/users/meGETGet current user’s detailsAuthenticated user
/api/users/listGETList users in an organizationusers:read
/api/users/invitePOSTInvite a user to organizationusers:write
/api/users/updatePUTUpdate a user’s roleusers:write + owner role

User Endpoints

Get Current User

Get the authenticated user’s details including all organization memberships.
curl -X GET "{{baseUrl}}/api/users/me" \
  -H "Authorization: Bearer YOUR_TOKEN"
Endpoint: GET /api/users/me Response:
FieldTypeDescription
idstring (UUID)User’s unique identifier
emailstringUser’s email address
first_namestringUser’s first name
last_namestringUser’s last name
full_namestringUser’s full name
organizationsarrayList of organizations the user belongs to
organizations[].idstring (UUID)Organization ID
organizations[].namestringOrganization name
organizations[].slugstringOrganization URL slug
organizations[].role_idstring (UUID)User’s role ID in this organization
organizations[].role_namestringUser’s role name in this organization
Returns only active organization memberships. Invited, suspended, or deleted memberships are not included.

List Users in Organization

Get a paginated list of users in an organization, including both active users and pending invitations.
curl -X GET "{{baseUrl}}/api/users/list?org_id=your-org-id&offset=0&limit=10" \
  -H "Authorization: Bearer YOUR_TOKEN"
Endpoint: GET /api/users/list Query Parameters:
ParameterRequiredDescription
org_idYesOrganization ID
offsetNoPage number (0-based, default: 0)
limitNoItems per page (default: 10)
Response:
FieldTypeDescription
usersarrayList of users and pending invitations
users[].idstring (UUID) or nullUser ID (null for pending invitations)
users[].emailstringUser’s email address
users[].first_namestringUser’s first name
users[].last_namestringUser’s last name
users[].full_namestringUser’s full name
users[].statusstringStatus: active, pending, or expired
users[].invite_idstring (UUID) or nullInvitation ID (null for active users)
users[].invited_atstring (ISO 8601) or nullInvitation timestamp
users[].organizationsarrayOrganization and role information
totalintegerTotal count of users + pending invitations
This endpoint returns a hybrid list combining:
  • Active users (status: “active”)
  • Pending invitations (status: “pending” or “expired”)
Results are sorted with active users first, then by creation date (newest first).

Invite User to Organization

Send an invitation to a user to join an organization with a specific role.
curl -X POST "{{baseUrl}}/api/users/invite?org_id=your-org-id" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "[email protected]",
    "first_name": "New",
    "last_name": "User",
    "role": "9d0e1f2a-3b4c-5d6e-7f8g-9h0i1j2k3l4m"
  }'
Endpoint: POST /api/users/invite Query Parameters:
ParameterRequiredDescription
org_idYesOrganization ID
Request Body:
FieldTypeRequiredDescription
emailstringYesInvitee’s email address
first_namestringYesInvitee’s first name
last_namestringYesInvitee’s last name
rolestring (UUID)YesRole ID to assign to the user
Response:
FieldTypeDescription
idstring (UUID)Invitation ID
emailstringInvitee’s email address
first_namestringInvitee’s first name
last_namestringInvitee’s last name
full_namestringInvitee’s full name
organizationsobjectOrganization and role details
Invitation Flow:
  1. User record is pre-created with status “invited”
  2. Invitation email is sent via Stytch with a magic link
  3. Organization member record is created with status “invited”
  4. Invitation expires after 7 days
  5. When user accepts, their status changes to “active”
See Invitation Flow for complete details.

Update User Role

Update a user’s role within an organization.
curl -X PUT "{{baseUrl}}/api/users/update?org_id=your-org-id&user_id=a1b2c3d4-e5f6-7g8h-9i0j-k1l2m3n4o5p6" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "role_id": "0e1f2a3b-4c5d-6e7f-8g9h-0i1j2k3l4m5n"
  }'
Endpoint: PUT /api/users/update Query Parameters:
ParameterRequiredDescription
org_idYesOrganization ID
user_idYesUser ID to update
Request Body:
FieldTypeRequiredDescription
role_idstring (UUID)YesNew role ID to assign to the user
Response:
FieldTypeDescription
idstring (UUID)User’s unique identifier
emailstringUser’s email address
first_namestringUser’s first name
last_namestringUser’s last name
full_namestringUser’s full name
organizationsarrayUpdated organization and role information
invite_idnullAlways null for active users
last_active_atstring (ISO 8601) or nullLast activity timestamp
created_atstring (ISO 8601)Account creation timestamp
Restrictions:
  • Only users with owner role can update user roles
  • The owner role cannot be assigned via this endpoint (reserved for organization creators)
  • Only active members can have their roles updated
  • Cannot assign the same role a user already has
  • Requires both users:write permission AND owner role
To change a user’s role, the authenticated user must:
  1. Have users:write permission
  2. Be an owner in the organization
This is more restrictive than other users:write operations.

Error Responses

Status CodeDescription
400Bad Request - Invalid input, same role assignment, or non-active member
401Unauthorized - Invalid or missing token
403Forbidden - Insufficient permissions or not an owner
404Not Found - User, organization, or role doesn’t exist
500Internal Server Error - Server-side error

Common Error Scenarios

Error: 403 Forbidden - “Only users with ‘owner’ role can update user roles”Solution: Only organization owners can update user roles. If you need to change roles, ask an owner to do it.
Error: 403 Forbidden - “The ‘owner’ role cannot be assigned to users”Solution: The owner role is reserved for organization creators and cannot be assigned via the API. To transfer ownership, contact support.
Error: 400 Bad Request - “User already has the ‘admin’ role assigned”Solution: Check the user’s current role before updating. You cannot assign the same role a user already has.
Error: 400 Bad Request - “Cannot update role for user with status ‘invited’”Solution: Wait for the user to accept the invitation first. Only active members can have their roles updated.

Implementation Notes

User Statuses

Users can have different statuses in an organization:
StatusDescriptionCan Update Role?
activeUser has accepted invitation and is activeYes
invitedUser has been invited but hasn’t accepted yetNo
suspendedUser access has been temporarily disabledNo
deletedUser has been removed from organizationNo

Role Assignment Rules

  1. Owner Role Special Case:
    • Owner role is automatically assigned when creating an organization
    • Cannot be assigned via API
    • Cannot be removed (organization must have at least one owner)
  2. Role Hierarchy:
    • Roles have hierarchy levels (0-100)
    • Higher levels generally have more permissions
    • Check role hierarchy before assignment
  3. Permission Requirements:
    • Viewing users: users:read permission
    • Inviting users: users:write permission
    • Updating roles: users:write permission AND owner role

Pagination

The /api/users/list endpoint uses offset-based pagination:
  • offset: Page number (0-based)
  • limit: Items per page
  • total: Total count of items
Example for page 3 with 10 items per page:
offset=2, limit=10  // Returns items 21-30

Invitation Expiry

  • Invitations expire after 7 days
  • Expired invitations show status “expired” in user list
  • To resend an expired invitation, create a new invitation