Authentication
All endpoints require a valid Bearer token in the Authorization header.Base URL
Endpoints Overview
| Endpoint | Method | Description | Required Permission |
|---|---|---|---|
/api/users/me | GET | Get current user’s details | Authenticated user |
/api/users/list | GET | List users in an organization | users:read |
/api/users/invite | POST | Invite a user to organization | users:write |
/api/users/update | PUT | Update a user’s role | users:write + owner role |
User Endpoints
Get Current User
Get the authenticated user’s details including all organization memberships.GET /api/users/me
Response:
| Field | Type | Description |
|---|---|---|
id | string (UUID) | User’s unique identifier |
email | string | User’s email address |
first_name | string | User’s first name |
last_name | string | User’s last name |
full_name | string | User’s full name |
organizations | array | List of organizations the user belongs to |
organizations[].id | string (UUID) | Organization ID |
organizations[].name | string | Organization name |
organizations[].slug | string | Organization URL slug |
organizations[].role_id | string (UUID) | User’s role ID in this organization |
organizations[].role_name | string | User’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.GET /api/users/list
Query Parameters:
| Parameter | Required | Description |
|---|---|---|
org_id | Yes | Organization ID |
offset | No | Page number (0-based, default: 0) |
limit | No | Items per page (default: 10) |
| Field | Type | Description |
|---|---|---|
users | array | List of users and pending invitations |
users[].id | string (UUID) or null | User ID (null for pending invitations) |
users[].email | string | User’s email address |
users[].first_name | string | User’s first name |
users[].last_name | string | User’s last name |
users[].full_name | string | User’s full name |
users[].status | string | Status: active, pending, or expired |
users[].invite_id | string (UUID) or null | Invitation ID (null for active users) |
users[].invited_at | string (ISO 8601) or null | Invitation timestamp |
users[].organizations | array | Organization and role information |
total | integer | Total count of users + pending invitations |
This endpoint returns a hybrid list combining:
- Active users (status: “active”)
- Pending invitations (status: “pending” or “expired”)
Invite User to Organization
Send an invitation to a user to join an organization with a specific role.POST /api/users/invite
Query Parameters:
| Parameter | Required | Description |
|---|---|---|
org_id | Yes | Organization ID |
| Field | Type | Required | Description |
|---|---|---|---|
email | string | Yes | Invitee’s email address |
first_name | string | Yes | Invitee’s first name |
last_name | string | Yes | Invitee’s last name |
role | string (UUID) | Yes | Role ID to assign to the user |
| Field | Type | Description |
|---|---|---|
id | string (UUID) | Invitation ID |
email | string | Invitee’s email address |
first_name | string | Invitee’s first name |
last_name | string | Invitee’s last name |
full_name | string | Invitee’s full name |
organizations | object | Organization and role details |
Invitation Flow:
- User record is pre-created with status “invited”
- Invitation email is sent via Stytch with a magic link
- Organization member record is created with status “invited”
- Invitation expires after 7 days
- When user accepts, their status changes to “active”
Update User Role
Update a user’s role within an organization.PUT /api/users/update
Query Parameters:
| Parameter | Required | Description |
|---|---|---|
org_id | Yes | Organization ID |
user_id | Yes | User ID to update |
| Field | Type | Required | Description |
|---|---|---|---|
role_id | string (UUID) | Yes | New role ID to assign to the user |
| Field | Type | Description |
|---|---|---|
id | string (UUID) | User’s unique identifier |
email | string | User’s email address |
first_name | string | User’s first name |
last_name | string | User’s last name |
full_name | string | User’s full name |
organizations | array | Updated organization and role information |
invite_id | null | Always null for active users |
last_active_at | string (ISO 8601) or null | Last activity timestamp |
created_at | string (ISO 8601) | Account creation timestamp |
To change a user’s role, the authenticated user must:
- Have
users:writepermission - Be an owner in the organization
users:write operations.Error Responses
| Status Code | Description |
|---|---|
| 400 | Bad Request - Invalid input, same role assignment, or non-active member |
| 401 | Unauthorized - Invalid or missing token |
| 403 | Forbidden - Insufficient permissions or not an owner |
| 404 | Not Found - User, organization, or role doesn’t exist |
| 500 | Internal Server Error - Server-side error |
Common Error Scenarios
Cannot Update Role - Not an Owner
Cannot Update Role - Not an Owner
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.
Cannot Assign Owner Role
Cannot Assign Owner Role
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.
User Already Has Role
User Already Has Role
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.
Cannot Update Invited User
Cannot Update Invited User
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:| Status | Description | Can Update Role? |
|---|---|---|
| active | User has accepted invitation and is active | Yes |
| invited | User has been invited but hasn’t accepted yet | No |
| suspended | User access has been temporarily disabled | No |
| deleted | User has been removed from organization | No |
Role Assignment Rules
-
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)
-
Role Hierarchy:
- Roles have hierarchy levels (0-100)
- Higher levels generally have more permissions
- Check role hierarchy before assignment
-
Permission Requirements:
- Viewing users:
users:readpermission - Inviting users:
users:writepermission - Updating roles:
users:writepermission AND owner role
- Viewing users:
Pagination
The/api/users/list endpoint uses offset-based pagination:
offset: Page number (0-based)limit: Items per pagetotal: Total count of items
Invitation Expiry
- Invitations expire after 7 days
- Expired invitations show status “expired” in user list
- To resend an expired invitation, create a new invitation
Related Documentation
- Invitation Flow - Complete invitation process
- Roles Service - Managing roles and permissions
- Organization Service - Managing organizations
- RBAC Permissions - Understanding permissions