Skip to main content
Admin API

This endpoint requires admin-level roles (platform_admin, tenant_admin, or system_admin). Accessible via the API gateway at /v1/platform/*.

Users API

Manage users and their access across the platform.

Overview

The Users API provides comprehensive user management:

FeatureDescription
User CRUDCreate, read, update, delete users
InvitationsInvite users to join
RolesAssign and manage roles
AccessControl tenant/location access
ProfilesUser profile management

User Model

{
"id": "user-abc123",
"email": "john.smith@example.com",
"name": "John Smith",
"status": "active",
"roles": ["manager"],
"primary_location_id": "loc-xyz789",
"locations": ["loc-xyz789", "loc-abc456"],
"created_at": "2025-06-15T10:00:00Z"
}

List Users

Request

GET /api/v1/users?tenant_id=tenant-abc123&status=active
Authorization: Bearer {access_token}

Query Parameters

ParameterTypeDescription
tenant_idstringFilter by tenant
location_idstringFilter by location
rolestringFilter by role
statusstringFilter by status
searchstringSearch by name or email

Response

{
"users": [
{
"id": "user-abc123",
"email": "john.smith@example.com",
"name": "John Smith",
"status": "active",
"roles": ["manager"],
"primary_location": {
"id": "loc-xyz789",
"name": "Downtown Location"
},
"last_login": "2026-01-18T08:00:00Z"
}
],
"pagination": {
"total": 45,
"limit": 20,
"offset": 0
}
}

Get User

Request

GET /api/v1/users/{user_id}
Authorization: Bearer {access_token}

Response

{
"id": "user-abc123",
"email": "john.smith@example.com",
"phone": "+1-415-555-1234",
"name": "John Smith",
"first_name": "John",
"last_name": "Smith",
"avatar_url": "https://cdn.olympuscloud.ai/avatars/user-abc123.jpg",
"status": "active",
"tenant_id": "tenant-abc123",
"roles": [
{
"id": "role-manager",
"name": "Manager",
"scope": "location"
}
],
"locations": [
{
"id": "loc-xyz789",
"name": "Downtown Location",
"is_primary": true
},
{
"id": "loc-abc456",
"name": "Uptown Location",
"is_primary": false
}
],
"permissions": [
"orders.read",
"orders.write",
"orders.refund",
"reports.read",
"staff.read",
"staff.write"
],
"preferences": {
"language": "en",
"timezone": "America/Los_Angeles",
"notifications": {
"email": true,
"push": true,
"sms": false
}
},
"employment": {
"employee_id": "EMP001",
"department": "Front of House",
"hire_date": "2024-06-15",
"pay_rate": 25.00,
"pay_type": "hourly"
},
"security": {
"mfa_enabled": true,
"mfa_methods": ["totp"],
"last_password_change": "2025-12-01T00:00:00Z"
},
"last_login": "2026-01-18T08:00:00Z",
"created_at": "2024-06-15T10:00:00Z",
"updated_at": "2026-01-15T14:30:00Z"
}

Create User

Request

POST /api/v1/users
Authorization: Bearer {access_token}
Content-Type: application/json
{
"email": "jane.doe@example.com",
"first_name": "Jane",
"last_name": "Doe",
"phone": "+1-415-555-5678",
"tenant_id": "tenant-abc123",
"location_ids": ["loc-xyz789"],
"role_ids": ["role-server"],
"send_invitation": true
}

Parameters

FieldTypeRequiredDescription
emailstringYesUser email address
first_namestringYesFirst name
last_namestringYesLast name
phonestringNoPhone number
tenant_idstringYesTenant to add user to
location_idsarrayYesLocations user can access
role_idsarrayYesRoles to assign
send_invitationbooleanNoSend email invitation

Response

{
"id": "user-new123",
"email": "jane.doe@example.com",
"name": "Jane Doe",
"status": "invited",
"invitation_sent_at": "2026-01-18T12:00:00Z",
"invitation_expires_at": "2026-01-25T12:00:00Z",
"created_at": "2026-01-18T12:00:00Z"
}

Update User

Request

PATCH /api/v1/users/{user_id}
Authorization: Bearer {access_token}
Content-Type: application/json
{
"phone": "+1-415-555-9999",
"employment": {
"department": "Management",
"pay_rate": 30.00
}
}

Invite User

Send or resend an invitation to a user.

Request

POST /api/v1/users/{user_id}/invite
Authorization: Bearer {access_token}
Content-Type: application/json
{
"message": "Welcome to the team! Click the link below to set up your account."
}

Response

{
"user_id": "user-abc123",
"invitation_sent_at": "2026-01-18T12:00:00Z",
"invitation_expires_at": "2026-01-25T12:00:00Z"
}

Bulk Invite Users

Request

POST /api/v1/users/bulk-invite
Authorization: Bearer {access_token}
Content-Type: application/json
{
"users": [
{
"email": "user1@example.com",
"first_name": "User",
"last_name": "One",
"role_ids": ["role-server"],
"location_ids": ["loc-xyz789"]
},
{
"email": "user2@example.com",
"first_name": "User",
"last_name": "Two",
"role_ids": ["role-server"],
"location_ids": ["loc-xyz789"]
}
]
}

Response

{
"created": 2,
"failed": 0,
"users": [
{"email": "user1@example.com", "id": "user-111", "status": "invited"},
{"email": "user2@example.com", "id": "user-222", "status": "invited"}
]
}

Assign Roles

Request

PUT /api/v1/users/{user_id}/roles
Authorization: Bearer {access_token}
Content-Type: application/json
{
"role_ids": ["role-manager", "role-trainer"],
"location_id": "loc-xyz789"
}

Update Location Access

Request

PUT /api/v1/users/{user_id}/locations
Authorization: Bearer {access_token}
Content-Type: application/json
{
"location_ids": ["loc-xyz789", "loc-abc456", "loc-new123"],
"primary_location_id": "loc-xyz789"
}

Set PIN

Set a quick-access PIN for POS login.

Request

PUT /api/v1/users/{user_id}/pin
Authorization: Bearer {access_token}
Content-Type: application/json
{
"pin": "1234"
}

PIN Requirements

  • 4-6 digits
  • Must be unique within the location
  • Cannot be sequential (1234) or repeated (1111)

Reset Password

Request Password Reset

POST /api/v1/users/{user_id}/password-reset
Authorization: Bearer {access_token}

Response

{
"user_id": "user-abc123",
"reset_email_sent": true,
"expires_at": "2026-01-18T13:00:00Z"
}

Deactivate User

Request

POST /api/v1/users/{user_id}/deactivate
Authorization: Bearer {access_token}
Content-Type: application/json
{
"reason": "Employment ended",
"effective_date": "2026-01-18",
"revoke_sessions": true
}

Response

{
"id": "user-abc123",
"status": "inactive",
"deactivated_at": "2026-01-18T12:00:00Z",
"sessions_revoked": 3
}

Reactivate User

Request

POST /api/v1/users/{user_id}/reactivate
Authorization: Bearer {access_token}
Content-Type: application/json
{
"send_notification": true
}

Delete User

Permanently delete a user.

Request

DELETE /api/v1/users/{user_id}
Authorization: Bearer {access_token}
Content-Type: application/json
{
"confirm": true,
"anonymize_data": true
}

User Activity

Get Activity Log

GET /api/v1/users/{user_id}/activity?limit=50
Authorization: Bearer {access_token}

Response

{
"activities": [
{
"id": "act-001",
"type": "login",
"timestamp": "2026-01-18T08:00:00Z",
"ip_address": "192.168.1.100",
"device": "POS Terminal 1",
"location": "Downtown Location"
},
{
"id": "act-002",
"type": "order_created",
"timestamp": "2026-01-18T08:15:00Z",
"details": {
"order_id": "order-12345",
"amount": 45.99
}
},
{
"id": "act-003",
"type": "refund_processed",
"timestamp": "2026-01-18T09:30:00Z",
"details": {
"order_id": "order-12340",
"amount": 12.99,
"reason": "Customer complaint"
}
}
]
}

User Preferences

Get Preferences

GET /api/v1/users/{user_id}/preferences
Authorization: Bearer {access_token}

Update Preferences

PUT /api/v1/users/{user_id}/preferences
Authorization: Bearer {access_token}
Content-Type: application/json
{
"language": "es",
"timezone": "America/New_York",
"date_format": "DD/MM/YYYY",
"notifications": {
"email": true,
"push": true,
"sms": true,
"schedule_changes": true,
"shift_reminders": true
},
"dashboard": {
"default_view": "sales",
"date_range": "today"
}
}

Get Current User

Request

GET /api/v1/users/me
Authorization: Bearer {access_token}

Returns the authenticated user's profile.


Error Responses

User Not Found (404)

{
"error": {
"code": "USER_NOT_FOUND",
"message": "User does not exist"
}
}

Email Already Exists (409)

{
"error": {
"code": "EMAIL_EXISTS",
"message": "A user with this email already exists"
}
}

Seat Limit Exceeded (403)

{
"error": {
"code": "SEAT_LIMIT_EXCEEDED",
"message": "Maximum users reached for subscription plan",
"current": 100,
"limit": 100
}
}