Users API - arilonUK/iotagentmesh GitHub Wiki
The Users API provides comprehensive user management within organizations, including user profiles, role-based access control, invitation workflows, and activity tracking for the IoT Agent Mesh platform.
The user management system provides:
- Organization-scoped user management with role-based access control
- User invitation and onboarding workflows
- Profile management and preferences
- Activity tracking and audit logging
- Team collaboration features
- Integration with authentication system
/rest/v1/users
All endpoints require JWT authentication with appropriate organization access permissions.
Required Headers:
Authorization: Bearer YOUR_JWT_TOKEN
apikey: YOUR_SUPABASE_ANON_KEY
Content-Type: application/json
Retrieve all users within the authenticated user's organization.
GET /rest/v1/users
| Parameter | Type | Required | Description |
|---|---|---|---|
| select | string | No | Columns to return (default: *) |
| role | string | No | Filter by role (admin, user, viewer) |
| status | string | No | Filter by status (active, inactive, pending) |
| order | string | No | Sort order (default: created_at.desc) |
| limit | integer | No | Number of results (default: 50, max: 1000) |
| offset | integer | No | Number of results to skip |
Rate limits are per authenticated user per organization.
# Users APIThe Users API provides comprehensive user management within organizations, including user profiles, role-based access control, invitation workflows, and activity tracking for the IoT Agent Mesh platform.
The user management system provides:
- Organization-scoped user management with role-based access control
- User invitation and onboarding workflows
- Profile management and preferences
- Activity tracking and audit logging
- Team collaboration features
- Integration with authentication system
/rest/v1/users
All endpoints require JWT authentication with appropriate organization access permissions.
Required Headers:
Authorization: Bearer YOUR_JWT_TOKEN
apikey: YOUR_SUPABASE_ANON_KEY
Content-Type: application/jsonRetrieve all users within the authenticated user's organization.
GET /rest/v1/users| Parameter | Type | Required | Description |
|---|---|---|---|
select |
string | No | Columns to return (default: *) |
role |
string | No | Filter by role (admin, user, viewer) |
status |
string | No | Filter by status (active, inactive, pending) |
order |
string | No | Sort order (default: created_at.desc) |
limit |
integer | No | Number of results (default: 50, max: 1000) |
offset |
integer | No | Number of results to skip |
{
"data": [
{
"id": "user_01H8K2M3N4P5Q6R7S8T9U0V1W2",
"organization_id": "org_01H8K2M3N4P5Q6R7S8T9U0V1W2",
"email": "[email protected]",
"role": "admin",
"status": "active",
"profile": {
"full_name": "John Doe",
"avatar_url": "https://example.com/avatar1.jpg",
"phone": "+1-555-0123",
"title": "Operations Manager",
"department": "Engineering",
"timezone": "America/New_York",
"preferences": {
"email_notifications": true,
"sms_notifications": true,
"dashboard_theme": "dark",
"language": "en-US"
}
},
"permissions": {
"agents": ["read", "write", "delete"],
"telemetry": ["read", "write"],
"alerts": ["read", "write", "acknowledge"],
"users": ["read", "write", "invite"],
"organization": ["read", "write"]
},
"activity": {
"last_login": "2024-07-23T16:30:00Z",
"login_count": 245,
"last_active": "2024-07-23T16:45:00Z",
"total_sessions": 312
},
"invitation": {
"invited_by": "user_01H8K2M3N4P5Q6R7S8T9U0V1W1",
"invited_at": "2024-01-10T10:00:00Z",
"accepted_at": "2024-01-10T14:30:00Z"
},
"created_at": "2024-01-10T14:30:00Z",
"updated_at": "2024-07-23T16:30:00Z"
},
{
"id": "user_02H8K2M3N4P5Q6R7S8T9U0V1W3",
"organization_id": "org_01H8K2M3N4P5Q6R7S8T9U0V1W2",
"email": "[email protected]",
"role": "user",
"status": "active",
"profile": {
"full_name": "Jane Smith",
"avatar_url": "https://example.com/avatar2.jpg",
"phone": "+1-555-0124",
"title": "IoT Technician",
"department": "Operations",
"timezone": "America/New_York"
},
"permissions": {
"agents": ["read", "write"],
"telemetry": ["read"],
"alerts": ["read", "acknowledge"],
"users": ["read"],
"organization": ["read"]
},
"activity": {
"last_login": "2024-07-23T15:15:00Z",
"login_count": 89,
"last_active": "2024-07-23T15:45:00Z"
},
"created_at": "2024-02-15T09:20:00Z",
"updated_at": "2024-07-23T15:15:00Z"
}
],
"count": 12,
"status": 200,
"statusText": "OK"
}JavaScript/TypeScript:
// Get all organization users
const { data: users, error } = await supabase
.from('users')
.select('*')
.order('created_at', { ascending: false })
// Filter by role
const { data: admins } = await supabase
.from('users')
.select('*')
.eq('role', 'admin')
// Search by name
const { data: searchResults } = await supabase
.from('users')
.select('*')
.ilike('profile->>full_name', '%john%')Python:
# Get all users with pagination
response = supabase.table('users')\
.select('*')\
.order('created_at', desc=True)\
.limit(50)\
.execute()
users = response.dataRetrieve detailed information about a specific user.
GET /rest/v1/users?id=eq.{user_id}{
"data": [
{
"id": "user_01H8K2M3N4P5Q6R7S8T9U0V1W2",
"organization_id": "org_01H8K2M3N4P5Q6R7S8T9U0V1W2",
"email": "[email protected]",
"role": "admin",
"status": "active",
"profile": {
"full_name": "John Doe",
"avatar_url": "https://example.com/avatar1.jpg",
"phone": "+1-555-0123",
"title": "Operations Manager",
"department": "Engineering",
"timezone": "America/New_York",
"bio": "Experienced IoT operations manager with 10+ years in industrial automation",
"social_links": {
"linkedin": "https://linkedin.com/in/johndoe",
"github": "https://github.com/johndoe"
},
"preferences": {
"email_notifications": true,
"sms_notifications": true,
"dashboard_theme": "dark",
"language": "en-US",
"date_format": "MM/DD/YYYY",
"timezone_display": "local"
}
},
"permissions": {
"agents": ["read", "write", "delete"],
"telemetry": ["read", "write"],
"alerts": ["read", "write", "acknowledge", "resolve"],
"users": ["read", "write", "invite", "remove"],
"organization": ["read", "write"]
},
"activity": {
"last_login": "2024-07-23T16:30:00Z",
"login_count": 245,
"last_active": "2024-07-23T16:45:00Z",
"total_sessions": 312,
"average_session_duration_minutes": 45,
"favorite_agents": ["agent_01H8K2M3N4P5Q6R7S8T9U0V1W2"],
"recent_activities": [
{
"action": "acknowledged_alert",
"resource": "alert_01H8K3L4M5N6O7P8Q9R0S1T2U3V4",
"timestamp": "2024-07-23T16:35:00Z"
},
{
"action": "updated_agent_config",
"resource": "agent_01H8K2M3N4P5Q6R7S8T9U0V1W2",
"timestamp": "2024-07-23T15:20:00Z"
}
]
},
"security": {
"two_factor_enabled": true,
"last_password_change": "2024-06-15T10:00:00Z",
"login_attempts": {
"failed_attempts": 0,
"last_failed_attempt": null
},
"api_keys": [
{
"key_id": "key_01H8K3L4M5N6O7P8Q9R0S1T2U3V4",
"name": "Production API Key",
"last_used": "2024-07-23T14:30:00Z",
"created_at": "2024-06-01T10:00:00Z"
}
]
},
"created_at": "2024-01-10T14:30:00Z",
"updated_at": "2024-07-23T16:30:00Z"
}
]
}JavaScript/TypeScript:
const { data: user, error } = await supabase
.from('users')
.select('*')
.eq('id', userId)
.single()
if (error) throw error
console.log('User details:', user)Send an invitation to join the organization.
POST /functions/v1/invite-user{
"email": "[email protected]",
"role": "user",
"profile": {
"full_name": "Alice Johnson",
"title": "IoT Analyst",
"department": "Engineering"
},
"permissions": {
"agents": ["read", "write"],
"telemetry": ["read"],
"alerts": ["read", "acknowledge"]
},
"welcome_message": "Welcome to our IoT monitoring team! You'll be working with sensor data from our warehouse facilities.",
"expires_in_hours": 72
}{
"invitation_id": "inv_01H8K3L4M5N6O7P8Q9R0S1T2U3V4",
"email": "[email protected]",
"role": "user",
"status": "pending",
"invitation_url": "https://yourapp.com/accept-invitation?token=inv_token_123",
"invited_by": {
"id": "user_01H8K2M3N4P5Q6R7S8T9U0V1W2",
"name": "John Doe",
"email": "[email protected]"
},
"expires_at": "2024-07-26T17:00:00Z",
"created_at": "2024-07-23T17:00:00Z"
}JavaScript/TypeScript:
const response = await supabase.functions.invoke('invite-user', {
body: {
email: '[email protected]',
role: 'user',
profile: {
full_name: 'Alice Johnson',
title: 'IoT Analyst',
department: 'Engineering'
},
permissions: {
agents: ['read', 'write'],
telemetry: ['read'],
alerts: ['read', 'acknowledge']
},
welcome_message: 'Welcome to our IoT monitoring team!'
}
})
console.log('Invitation sent:', response.data)Accept a user invitation and complete account setup.
POST /functions/v1/accept-invitation{
"invitation_token": "inv_token_123",
"password": "secure-password",
"profile_updates": {
"phone": "+1-555-0125",
"timezone": "America/Los_Angeles",
"preferences": {
"email_notifications": true,
"sms_notifications": false,
"dashboard_theme": "light"
}
}
}{
"user": {
"id": "user_03H8K2M3N4P5Q6R7S8T9U0V1W4",
"email": "[email protected]",
"role": "user",
"status": "active",
"organization_id": "org_01H8K2M3N4P5Q6R7S8T9U0V1W2"
},
"session": {
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expires_at": 1721754000
},
"welcome_complete": true
}Get all pending invitations for the organization.
GET /functions/v1/pending-invitations{
"invitations": [
{
"invitation_id": "inv_01H8K3L4M5N6O7P8Q9R0S1T2U3V4",
"email": "[email protected]",
"role": "user",
"status": "pending",
"invited_by": {
"id": "user_01H8K2M3N4P5Q6R7S8T9U0V1W2",
"name": "John Doe"
},
"expires_at": "2024-07-26T17:00:00Z",
"created_at": "2024-07-23T17:00:00Z",
"reminder_sent": false
}
],
"total_pending": 1
}Update a user's profile information and preferences.
PATCH /rest/v1/users?id=eq.{user_id}{
"profile": {
"full_name": "John Smith",
"title": "Senior Operations Manager",
"phone": "+1-555-0199",
"bio": "Leading IoT operations with focus on predictive maintenance",
"preferences": {
"email_notifications": true,
"sms_notifications": true,
"dashboard_theme": "light",
"language": "en-US",
"timezone_display": "utc"
}
}
}{
"data": [
{
"id": "user_01H8K2M3N4P5Q6R7S8T9U0V1W2",
"profile": {
"full_name": "John Smith",
"title": "Senior Operations Manager",
"phone": "+1-555-0199",
"bio": "Leading IoT operations with focus on predictive maintenance",
"preferences": {
"email_notifications": true,
"sms_notifications": true,
"dashboard_theme": "light",
"language": "en-US",
"timezone_display": "utc"
}
},
"updated_at": "2024-07-23T17:30:00Z"
}
]
}JavaScript/TypeScript:
const { data: user, error } = await supabase
.from('users')
.update({
profile: {
full_name: 'John Smith',
title: 'Senior Operations Manager',
preferences: {
email_notifications: true,
dashboard_theme: 'light'
}
}
})
.eq('id', userId)
.select()
.single()
if (error) throw error
console.log('Profile updated:', user)Change a user's role within the organization (admin only).
PATCH /rest/v1/users?id=eq.{user_id}{
"role": "admin",
"permissions": {
"agents": ["read", "write", "delete"],
"telemetry": ["read", "write"],
"alerts": ["read", "write", "acknowledge", "resolve"],
"users": ["read", "write", "invite", "remove"],
"organization": ["read", "write"]
}
}{
"data": [
{
"id": "user_02H8K2M3N4P5Q6R7S8T9U0V1W3",
"role": "admin",
"permissions": {
"agents": ["read", "write", "delete"],
"telemetry": ["read", "write"],
"alerts": ["read", "write", "acknowledge", "resolve"],
"users": ["read", "write", "invite", "remove"],
"organization": ["read", "write"]
},
"updated_at": "2024-07-23T17:35:00Z"
}
]
}| Role | Description | Default Permissions |
|---|---|---|
| admin | Full organization access | All permissions |
| user | Standard user access | Read/write agents, read telemetry, acknowledge alerts |
| viewer | Read-only access | Read-only access to all resources |
| Category | Available Permissions | Description |
|---|---|---|
| agents |
read, write, delete
|
IoT agent management |
| telemetry |
read, write
|
Telemetry data access |
| alerts |
read, write, acknowledge, resolve
|
Alert management |
| users |
read, write, invite, remove
|
User management |
| organization |
read, write
|
Organization settings |
Retrieve detailed activity logs for a user.
GET /functions/v1/user-activity?user_id={user_id}| Parameter | Type | Required | Description |
|---|---|---|---|
user_id |
string | Yes | User ID to get activity for |
activity_type |
string | No | Filter by activity type |
start_date |
string | No | Start date for activity range |
end_date |
string | No | End date for activity range |
limit |
integer | No | Number of results (default: 100) |
{
"user_id": "user_01H8K2M3N4P5Q6R7S8T9U0V1W2",
"activities": [
{
"id": "activity_01H8K3L4M5N6O7P8Q9R0S1T2U3V4",
"type": "alert_acknowledged",
"resource": {
"type": "alert",
"id": "alert_01H8K3L4M5N6O7P8Q9R0S1T2U3V4",
"name": "High Temperature Alert"
},
"details": {
"acknowledgment_note": "Investigating temperature spike",
"severity": "high"
},
"ip_address": "192.168.1.100",
"user_agent": "Chrome/91.0.4472.124",
"timestamp": "2024-07-23T16:35:00Z"
},
{
"id": "activity_02H8K3L4M5N6O7P8Q9R0S1T2U3V5",
"type": "agent_configuration_updated",
"resource": {
"type": "agent",
"id": "agent_01H8K2M3N4P5Q6R7S8T9U0V1W2",
"name": "Temperature Sensor 01"
},
"details": {
"changes": {
"sampling_rate": {
"old": 60000,
"new": 30000
}
}
},
"timestamp": "2024-07-23T15:20:00Z"
}
],
"summary": {
"total_activities": 156,
"activities_today": 8,
"most_common_activity": "telemetry_viewed"
}
}JavaScript/TypeScript:
const response = await supabase.functions.invoke('user-activity', {
body: {
user_id: 'user_01H8K2M3N4P5Q6R7S8T9U0V1W2',
start_date: '2024-07-20T00:00:00Z',
end_date: '2024-07-23T23:59:59Z',
limit: 50
}
})
console.log('User activities:', response.data.activities)Get real-time presence information for organization users.
GET /functions/v1/user-presence{
"users": [
{
"user_id": "user_01H8K2M3N4P5Q6R7S8T9U0V1W2",
"name": "John Doe",
"avatar_url": "https://example.com/avatar1.jpg",
"status": "online",
"last_seen": "2024-07-23T16:45:00Z",
"current_activity": "viewing_dashboard",
"location": {
"page": "/dashboard",
"section": "alerts"
}
},
{
"user_id": "user_02H8K2M3N4P5Q6R7S8T9U0V1W3",
"name": "Jane Smith",
"avatar_url": "https://example.com/avatar2.jpg",
"status": "away",
"last_seen": "2024-07-23T15:30:00Z",
"current_activity": null
}
]
}POST /functions/v1/mention-user{
"mentioned_user_id": "user_02H8K2M3N4P5Q6R7S8T9U0V1W3",
"context": {
"type": "alert_comment",
"resource_id": "alert_01H8K3L4M5N6O7P8Q9R0S1T2U3V4",
"message": "@jane Can you check the HVAC system in warehouse A?"
},
"notification_channels": ["email", "in_app"]
}Deactivate a user account without removing historical data.
PATCH /rest/v1/users?id=eq.{user_id}{
"status": "inactive",
"deactivation_reason": "Employee departure",
"deactivated_by": "user_01H8K2M3N4P5Q6R7S8T9U0V1W2"
}Permanently remove a user from the organization.
DELETE /rest/v1/users?id=eq.{user_id}Removing a user will:
- Permanently delete their profile and preferences
- Remove them from all alert acknowledgments
- Transfer ownership of created resources to the organization
- Cannot be undone
Import multiple users from a CSV file.
POST /functions/v1/import-users{
"file": "users.csv",
"mapping": {
"email": "email_address",
"full_name": "name",
"role": "user_role",
"department": "dept"
},
"default_role": "user",
"send_invitations": true
}Export user data for backup or compliance purposes.
GET /functions/v1/export-users| Parameter | Type | Required | Description |
|---|---|---|---|
format |
string | No | Export format (csv, json) |
include_activity |
boolean | No | Include activity logs |
include_preferences |
boolean | No | Include user preferences |
| HTTP Code | Error Code | Description |
|---|---|---|
| 400 | INVALID_ROLE |
Invalid user role specified |
| 400 | INVALID_PERMISSIONS |
Invalid permission configuration |
| 401 | UNAUTHORIZED |
Missing or invalid JWT token |
| 403 | INSUFFICIENT_PERMISSIONS |
User lacks required permissions |
| 404 | USER_NOT_FOUND |
User not found in organization |
| 409 | EMAIL_ALREADY_EXISTS |
Email already exists in organization |
| 409 | INVITATION_EXISTS |
Pending invitation already exists |
| 422 | INVALID_USER_DATA |
Invalid user profile data |
| 429 | RATE_LIMIT_EXCEEDED |
Too many user management requests |
{
"error": {
"code": "INSUFFICIENT_PERMISSIONS",
"message": "User lacks required permissions to perform this action",
"details": {
"required_permission": "users:write",
"current_permissions": ["users:read"],
"user_role": "viewer"
}
},
"status": 403
}- Role Assignment: Assign appropriate roles based on job functions
- Regular Audits: Regularly review user access and permissions
- Invitation Expiry: Set reasonable expiration times for invitations
- Activity Monitoring: Monitor user activity for security and compliance
- Principle of Least Privilege: Grant minimal required permissions
- Regular Reviews: Conduct regular access reviews
- Deactivation Process: Promptly deactivate departing users
- Audit Logging: Maintain comprehensive audit logs
- Pagination: Use pagination for large user lists
- Selective Queries: Use select parameters to limit returned data
- Caching: Cache user profile data appropriately
- Bulk Operations: Use bulk operations for multiple user updates
- [Organizations API](API-Organizations.md) - Organization management and settings
- [Authentication API](API-Authentication.md) - User authentication and sessions
- [Audit Logs API](API-Audit-Logs.md) - User activity and audit tracking
- [Alerts API](API-Alerts.md) - User involvement in alert management
| Operation | Rate Limit | Window |
|---|---|---|
| List Users | 100 requests | 1 minute |
| Get User Details | 200 requests | 1 minute |
| Update User Profile | 30 requests | 1 minute |
| Invite User | 10 requests | 1 minute |
| Update Role | 20 requests | 1 minute |
| User Activity | 50 requests | 1 minute |
| Bulk Operations | 5 requests | 1 minute |
Rate limits are per authenticated user per organization.