Users
This section contains 1 subgroups.
Get Current User
/users/me?language=en1curl --request GET "$ONDI_BASE_URL/users/me?language=en" \2 --header "Authorization: Bearer {{access_token}}"Query parameters
languageOptionalen
Language code (Optional)
Headers
AuthorizationOptionalBearer {{access_token}}
Responses
1{2 "success": true,3 "message": "Users retrieved successfully",4 "user": {5 "id": "user-uuid",6 "email": "user@example.com",7 "first_name": "John",8 "last_name": "Doe",9 "status": "active",10 "notifications_enabled": true,11 "is_system_admin": false,12 "is_staff": true,13 "is_market_user": true,14 "market_id": "market-uuid",15 "is_restaurant_user": false,16 "restaurant_location_id": null,17 "login_country": {18 "code": "IN",19 "name": "India",20 "dial_code": "+91"21 },22 "role": {23 "id": "role-uuid",24 "name": "restaurant_staff",25 "scope": "tenant"26 },27 "panel_type": "dispatcher",28 "warehouse_staff": [],29 "restaurant_staff": {30 "id": "staff-uuid",31 "location_id": "location-uuid",32 "staff_role": "cashier",33 "location": {34 "id": "location-uuid",35 "name": {},36 "code": 1000,37 "tenant_id": "tenant-uuid",38 "active": true39 }40 }41 }42}Update My Context
/users/me/context?language=en1curl --request POST "$ONDI_BASE_URL/users/me/context?language=en" \2 --header "Authorization: Bearer {{access_token}}" \3 --header "Content-Type: application/json" \4 --header "Content-Type: application/json" \5 --data '{6 "portal": "market",7 "market_id": "{{market_id}}"8}'1{2 "portal": "market",3 "market_id": "{{market_id}}"4}Query parameters
languageOptionalen
Language code (Optional)
Request body fields
portalExampleExample field from the request body.
market_idExampleExample field from the request body.
Headers
AuthorizationOptionalBearer {{access_token}}
Content-TypeOptionalapplication/json
Responses
1{2 "success": true,3 "message": "User Updated Successfully",4 "data": {5 "id": "user-uuid",6 "is_market_user": true,7 "market_id": "market-uuid",8 "is_restaurant_user": false,9 "restaurant_location_id": null10 }11}1{2 "success": true,3 "message": "User Updated Successfully",4 "data": {5 "id": "user-uuid",6 "is_market_user": true,7 "market_id": "market-uuid",8 "is_restaurant_user": true,9 "restaurant_location_id": "restaurant-location-uuid"10 }11}1{2 "success": false,3 "message": "Market not found",4 "data": null5}Get List Users
/users?language=en&page=1&limit=10&status=active&search=&tenant_id=&role_id=&startDate=&endDate=&role=driver,manager&is_business=&show_all=true&include_customer=true&exclude_customers=&is_market_user=&market_id=&is_restaurant_user=&restaurant_location_id=&sort_by=&sort_order=&column_filters={"role_id":"role-uuid"}Lists users with pagination, search, sorting, advanced column filters, and tenant KPI stats. Existing top-level filters continue to work. Authentication: - Requires valid authentication token Query Parameters: - language, page, limit, status, search, tenant_id, role_id, role, is_business, startDate, endDate, show_all, include_customer, exclude_customers, is_market_user, market_id, is_restaurant_user, restaurant_location_id - role_id: exact role-ID filter - role: exact role-name filter. Supports comma-separated values such as driver,manager - sort_by: full_name, email, phone, status, role_name, user_type, created_at, last_login_at - sort_order: asc or desc (defaults to desc when sort_by is provided) - column_filters: JSON string with keys full_name, email, phone, status, role, role_id, role_name, role_scope, user_type, is_market_user, is_restaurant_user, created_at, last_login_at - column_filters.role_id: exact role-ID filter, for example {"role_id":"e103e9a4-8c78-4c95-a27a-893d278ac590"} - column_filters.role: exact role-name filter with comma-separated values such as driver,manager - When both top-level role_id and column_filters.role_id are provided, both filters must match. Frontend integration: send the selected role UUID either as top-level role_id or as column_filters.role_id. Continue using column_filters.role only for role names. No navigation behavior changes. Invalid filter types return HTTP 400. Response: includes stats (totalUsers, activeUsers, pendingUsers, recentlyJoined) plus the existing statusCounts block.
1curl --request GET "$ONDI_BASE_URL/users?language=en&page=1&limit=10&status=active&search=&tenant_id=&role_id=&startDate=&endDate=&role=driver,manager&is_business=&show_all=true&include_customer=true&exclude_customers=&is_market_user=&market_id=&is_restaurant_user=&restaurant_location_id=&sort_by=&sort_order=&column_filters={"role_id":"role-uuid"}" \2 --header "Authorization: Bearer {{access_token}}"Query parameters
languageOptionalen
Language code for response localization (Optional, default: en)
pageOptional1
Page number for pagination (Optional, default: 1)
limitOptional10
Number of records per page (Optional, default: 10)
statusOptionalactive
Filter users by status (Optional, values: active, inactive, pending, blocked)
searchOptionalSearch term to filter users by email, first name, or last name (Optional)
tenant_idOptionalFilter users by tenant ID (Optional)
role_idOptionalFilter users by role ID (Optional)
startDateOptionalFilter users created after this date (ISO format, optional)
endDateOptionalFilter users created before this date (ISO format, optional)
roleOptionaldriver,manager
Filter users by exact role name. Supports comma-separated values for multiple roles, e.g. driver,manager (Optional)
is_businessOptionalFilter by business type: 'true' for business users, 'false' for individual users (Optional)
show_allOptionaltrue
Show all users regardless of filters (Optional, default: true)
include_customerOptionaltrue
Include users without any assigned roles (customers) in the results (Optional, default: true). Set to 'false' to exclude users without roles.
exclude_customersOptionalAlias for excluding customer rows. Set to 'true' to force include_customer=false.
is_market_userOptionalFilter users by market-context flag (true or false) (Optional)
market_idOptionalFilter users by market ID (Optional)
is_restaurant_userOptionalFilter users by restaurant-context flag (true or false) (Optional)
restaurant_location_idOptionalFilter users by restaurant location ID (Optional)
sort_byOptionalSort by one of: full_name, email, phone, status, role_name, user_type, created_at, last_login_at
sort_orderOptionalSort order: asc or desc. Defaults to desc when sort_by is provided.
column_filtersOptional{"role_id":"role-uuid"}
JSON string with column filters. Supported keys: full_name, email, phone, status, role, role_id, role_name, role_scope, user_type, is_market_user, is_restaurant_user, created_at, last_login_at
Headers
AuthorizationOptionalBearer {{access_token}}
Responses
1{2 "success": true,3 "message": "Users retrieved successfully",4 "users": [5 {6 "id": "user-uuid",7 "email": "user@example.com",8 "first_name": "John",9 "last_name": "Doe",10 "full_name": "John Doe",11 "phone": "+1234567890",12 "avatar_url": "https://example.com/avatar.jpg",13 "status": "active",14 "is_market_user": true,15 "market_id": "market-uuid",16 "is_restaurant_user": false,17 "restaurant_location_id": null,18 "user_type": "business",19 "roles": {20 "id": "role-uuid",21 "name": "admin",22 "scope": "tenant"23 },24 "tenant": {25 "id": "tenant-uuid",26 "name": "Example Tenant"27 },28 "created_at": "2023-01-01T00:00:00Z",29 "last_login_at": "2023-01-15T10:30:00Z"30 }31 ],32 "stats": {33 "totalUsers": 42,34 "activeUsers": 30,35 "pendingUsers": 8,36 "recentlyJoined": [37 {38 "id": "user-uuid",39 "full_name": "John Doe",40 "avatar_url": "https://example.com/avatar.jpg",41 "created_at": "2025-09-20T10:42:09.258391+00:00"42 }43 ]44 },45 "page": 1,46 "limit": 10,47 "total": 42,48 "statusCounts": {49 "active": 30,50 "inactive": 8,51 "pending": 4,52 "total": 4253 }54}1{2 "error": "Unauthorized",3 "message": "Authentication required",4 "status": 4015}1{2 "error": "Forbidden",3 "message": "Insufficient permissions",4 "status": 4035}1{2 "success": false,3 "message": "Error retrieving users"4}Get User by ID
/users/:id?language=en&response_type=fullRetrieves a specific user by their ID. Query params: - response_type: full (default) | basic - full: returns user with roles, permissions, teams, tenant_info, driver_details, warehouse_staff, and stats - basic: lightweight response with only profile fields (id, name, email, phone, status, avatar, user_type, last_login_at, created_at). Use for popups/cards where full detail is not needed. Success response includes: - user: user payload (varies by response_type) - stats: top-level KPI block (only in full mode) stats fields (full only): - wallet_balance - total_orders - pending_payouts - active_api_keys Permissions and error responses follow the existing endpoint behavior.
1curl --request GET "$ONDI_BASE_URL/users/:id?language=en&response_type=full" \2 --header "Authorization: Bearer {{access_token}}"Path parameters
idRequireduser-uuid
UUID of the user to retrieve (Required)
Query parameters
languageOptionalen
Language code for response localization (Optional, default: en)
response_typeOptionalfull
Response detail level: 'full' (default) returns all data including roles, permissions, teams, stats; 'basic' returns only essential profile info (id, name, email, phone, status, avatar, user_type, last_login, created_at)
Headers
AuthorizationOptionalBearer {{access_token}}
Responses
1{2 "success": true,3 "message": "User retrieved successfully",4 "user": {5 "id": "a1b2c3d4-e5f6-7890-1234-567890abcdef",6 "avatar_url": "https://example.com/avatars/a1b2c3d4.png",7 "email": "user@example.com",8 "first_name": "John",9 "last_name": "Doe",10 "full_name": "John Doe",11 "phone": "+15551234567",12 "status": "active",13 "user_type": "member",14 "role": {15 "id": "role-uuid-789",16 "name": "tenant_member",17 "scope": "tenant"18 },19 "tenant_info": {20 "id": "tenant-uuid-abc",21 "name": "Example Tenant Inc.",22 "slug": "example-tenant-inc",23 "status": "active",24 "metadata": {25 "industry": "tech"26 },27 "contact_info": {28 "address": "123 Main St"29 }30 },31 "panel_type": "customer",32 "permissions": [33 "view_deliveries",34 "create_deliveries"35 ],36 "teams": [37 {38 "id": "team-uuid",39 "name": "Team A"40 }41 ],42 "all_teams": false,43 "created_at": "2023-01-15T10:30:00Z",44 "updated_at": "2023-10-20T14:45:00Z",45 "last_login_at": "2023-11-01T09:00:00Z",46 "requires_driver_setup": false47 },48 "stats": {49 "wallet_balance": 150.5,50 "total_orders": 42,51 "pending_payouts": 2,52 "active_api_keys": 153 }54}1{2 "success": true,3 "message": "User retrieved successfully",4 "user": {5 "id": "a1b2c3d4-e5f6-7890-1234-567890abcdef",6 "email": "user@example.com",7 "phone": "+15551234567",8 "full_name": "John Doe",9 "first_name": "John",10 "last_name": "Doe",11 "status": "active",12 "avatar_url": "https://example.com/avatars/a1b2c3d4.png",13 "user_type": "member",14 "last_login_at": "2023-11-01T09:00:00Z",15 "created_at": "2023-01-15T10:30:00Z"16 }17}1{2 "error": "Unauthorized",3 "message": "Authentication token is missing or invalid",4 "status": 4015}1{2 "success": false,3 "message": "Unauthorized to access this resource"4}1{2 "success": false,3 "message": "User not found"4}1{2 "success": false,3 "message": "Internal server error",4 "error": {5 "message": "Details of the internal error if available..."6 }7}Get User Accounting
/users/:userId/accounting?tenant_id=&from_date=&to_date=&language=enReturns the accounting summary used by the user-detail Accounting tab. This endpoint is driver-linked: the user must have a driver record in the tenant. Includes: - Balance summary for selected period (creditor/debtor) - Cash collected (COD + order fee) - Earnings (cash vs online/credit) - Order costs (cash/paid-by-receiver/card/wallet) - Company earnings - Paid withdrawals - From support buckets Auth: - Self OR tenant permissions (finance/operations/tenant view).
1curl --request GET "$ONDI_BASE_URL/users/:userId/accounting?tenant_id=&from_date=&to_date=&language=en" \2 --header "Authorization: Bearer {{access_token}}"Path parameters
userIdRequired{{user_id}}
User UUID (required)
Query parameters
tenant_idOptionalTenant ID (optional, defaults to auth context)
from_dateOptionalFrom date (ISO8601, optional)
to_dateOptionalTo date (ISO8601, optional)
languageOptionalen
Language code (optional)
Headers
AuthorizationOptionalBearer {{access_token}}
Responses
1{2 "success": true,3 "message": "user_accounting_retrieved_successfully",4 "data": {5 "period": {6 "from_date": null,7 "to_date": null8 },9 "currency": "IQD",10 "balance_summary": {11 "amount": 0,12 "type": "creditor",13 "description": "Account is settled."14 },15 "cash_collected": {16 "total": 0,17 "breakdown": {18 "cod": 0,19 "order_fee": 020 }21 },22 "earnings": {23 "total": 0,24 "breakdown": {25 "cash": 0,26 "online_credit": 027 }28 },29 "order_costs": {30 "total": 0,31 "breakdown": {32 "cash": 0,33 "paid_by_receiver": 0,34 "card": 0,35 "wallet": 036 }37 },38 "company_earnings": 0,39 "paid_withdrawals": 0,40 "from_support": {41 "cod_type_creditor": 0,42 "cod_type_debtor": 0,43 "support_type_creditor": 0,44 "support_type_debtor": 045 }46 }47}Invite User
/users?language=enInvites a new user to the system via email. User receives an invitation email to set their password. Required: email, first_name, last_name. Optional: avatar_url, role_id. If role_id is provided, the role is automatically assigned based on caller's context: - tenant_admin: assigns as tenant role - system_admin: assigns as system role User status will be 'pending' until they confirm email and set password. Error responses: On failure, data is null and details may include a step (e.g. invite_redirect_config, auth_invite_user_by_email, lookup_existing_user_by_email, tenant_membership_lookup, tenant_users_insert, unhandled_exception) plus provider-safe fields such as redirect_to, PostgREST code/message, or Auth API status/message.
1curl --request POST "$ONDI_BASE_URL/users?language=en" \2 --header "Authorization: Bearer {{access_token}}" \3 --header "Content-Type: application/json" \4 --header "Content-Type: application/json" \5 --data '{6 "email": "new.user@example.com",7 "first_name": "John",8 "last_name": "Doe",9 "avatar_url": "https://example.com/avatar.png",10 "role_id": "role-uuid-optional"11}'1{2 "email": "new.user@example.com",3 "first_name": "John",4 "last_name": "Doe",5 "avatar_url": "https://example.com/avatar.png",6 "role_id": "role-uuid-optional"7}Query parameters
languageOptionalen
Language code for response localization (Optional, default: en)
Request body fields
emailExampleExample field from the request body.
first_nameExampleExample field from the request body.
last_nameExampleExample field from the request body.
avatar_urlExampleExample field from the request body.
role_idExampleExample field from the request body.
Headers
AuthorizationOptionalBearer {{access_token}}
Content-TypeOptionalapplication/json
Responses
1{2 "success": true,3 "message": "invitation_sent_successfully",4 "data": {5 "user": {6 "id": "new-user-uuid",7 "email": "new.user@example.com"8 }9 }10}1{2 "success": false,3 "message": "user_already_exists",4 "data": null5}1{2 "success": false,3 "message": "invitation_failed",4 "data": null,5 "details": {6 "step": "auth_invite_user_by_email",7 "redirect_to": "https://admin.example.com/update-password",8 "name": "AuthApiError",9 "message": "Error message from Auth API",10 "status": 40011 }12}1{2 "success": false,3 "message": "Internal Server Error",4 "data": null,5 "details": {6 "step": "invite_redirect_config",7 "reason": "ADMIN_WEB_URL secret is missing or empty; cannot build invite redirect URL"8 }9}Add User (auto-confirm)
/users/add?language=enCreates a new user with auto-confirmation. At least one of email or phone is required. If provided, email and phone are auto-confirmed. Required: password. Optional: first_name, last_name, phone, email, avatar_url, is_staff, role_id. If role_id is provided, the role is automatically assigned based on caller's context: - tenant_admin: assigns as tenant role - system_admin: assigns as system role User is immediately active and can login with the provided password.
1curl --request POST "$ONDI_BASE_URL/users/add?language=en" \2 --header "Authorization: Bearer {{access_token}}" \3 --header "Content-Type: application/json" \4 --header "Content-Type: application/json" \5 --data '{6 "email": "new.user@example.com",7 "phone": "+1234567890",8 "password": "SecurePassword123!",9 "first_name": "New",10 "last_name": "User",11 "avatar_url": "https://example.com/avatar.png",12 "is_staff": false,13 "role_id": "role-uuid-optional"14}'1{2 "email": "new.user@example.com",3 "phone": "+1234567890",4 "password": "SecurePassword123!",5 "first_name": "New",6 "last_name": "User",7 "avatar_url": "https://example.com/avatar.png",8 "is_staff": false,9 "role_id": "role-uuid-optional"10}Query parameters
languageOptionalen
Language code for response localization (Optional, default: en)
Request body fields
emailExampleExample field from the request body.
phoneExampleExample field from the request body.
passwordExampleExample field from the request body.
first_nameExampleExample field from the request body.
last_nameExampleExample field from the request body.
avatar_urlExampleExample field from the request body.
is_staffExampleExample field from the request body.
role_idExampleExample field from the request body.
Headers
AuthorizationOptionalBearer {{access_token}}
Content-TypeOptionalapplication/json
Responses
1{2 "success": true,3 "message": "user_created_successfully",4 "data": {5 "user": {6 "id": "new-user-uuid",7 "email": "new.user@example.com",8 "phone": "+1234567890"9 }10 }11}1{2 "success": false,3 "message": "email_or_phone_required"4}1{2 "success": false,3 "message": "user_already_exists"4}Add Customer (auto-confirm phone)
/users/add-customer?language=enCreates a customer user with phone and name. Phone is auto-confirmed; email is optional. Password is generated automatically.
1curl --request POST "$ONDI_BASE_URL/users/add-customer?language=en" \2 --header "Authorization: Bearer {{access_token}}" \3 --header "Content-Type: application/json" \4 --header "Content-Type: application/json" \5 --data '{6 "name": "Jane Customer",7 "phone": "+1234567890",8 "email": "optional@example.com"9}'1{2 "name": "Jane Customer",3 "phone": "+1234567890",4 "email": "optional@example.com"5}Query parameters
languageOptionalen
Language code for response localization (Optional, default: en)
Request body fields
nameExampleExample field from the request body.
phoneExampleExample field from the request body.
emailExampleExample field from the request body.
Headers
AuthorizationOptionalBearer {{access_token}}
Content-TypeOptionalapplication/json
Responses
1{2 "success": true,3 "message": "user_created_successfully",4 "data": {5 "user": {6 "id": "customer-uuid",7 "phone": "+1234567890",8 "email": "optional@example.com"9 }10 }11}1{2 "success": false,3 "message": "user_already_exists"4}Resend User Invitation
/users/resend-invitation?language=enResends an invitation email to a user who was previously invited but may not have received or acted on the original invitation. Authentication: - Requires valid authentication token - Must have appropriate permissions to invite users Endpoint: POST /users/resend-invitation Required Fields: - email: Valid email address of the user to resend invitation to
1curl --request POST "$ONDI_BASE_URL/users/resend-invitation?language=en" \2 --header "Authorization: Bearer {{access_token}}" \3 --header "Content-Type: application/json" \4 --header "Content-Type: application/json" \5 --data '{6 "email": "user@example.com"7}'1{2 "email": "user@example.com"3}Query parameters
languageOptionalen
Language code for response localization (Optional, default: en)
Request body fields
emailExampleExample field from the request body.
Headers
AuthorizationOptionalBearer {{access_token}}
Content-TypeOptionalapplication/json
Responses
1{2 "success": true,3 "message": "Invitation resent successfully",4 "data": {5 "user": {6 "id": "user-uuid",7 "email": "user@example.com",8 "invited_at": "2023-01-01T00:00:00Z"9 }10 }11}1{2 "success": false,3 "message": "Invitation failed"4}1{2 "success": false,3 "message": "User not found"4}1{2 "success": false,3 "message": "User already confirmed"4}1{2 "success": false,3 "message": "Internal server error"4}List Customers
/users/customers?language=en&page=1&limit=10&tenant_id={{tenant_id}}&is_business=&is_market_user=&market_id=&is_restaurant_user=&restaurant_location_id=&search=&sort_by=&sort_order=&column_filters=Lists customers (users without assigned roles) with pagination, search, sorting, column filters, and KPI stats. Legacy top-level is_business still works. Authentication: - Requires valid authentication token - Requires tenant context Query Parameters: - language, page, limit, tenant_id, is_business, is_market_user, market_id, is_restaurant_user, restaurant_location_id, search - sort_by: name, email, created_at, last_login_at - sort_order: asc or desc - column_filters: JSON string with keys full_name, email, phone, status, user_type, is_market_user, is_restaurant_user, created_at, last_login_at
1curl --request GET "$ONDI_BASE_URL/users/customers?language=en&page=1&limit=10&tenant_id={{tenant_id}}&is_business=&is_market_user=&market_id=&is_restaurant_user=&restaurant_location_id=&search=&sort_by=&sort_order=&column_filters=" \2 --header "Authorization: Bearer {{access_token}}"Query parameters
languageOptionalen
Language code for response localization (Optional, default: en)
pageOptional1
Page number for pagination (Optional, default: 1)
limitOptional10
Number of records per page (Optional, default: 10)
tenant_idOptional{{tenant_id}}
Tenant ID to filter customers (Optional, uses context if not provided)
is_businessOptionalFilter by customer type: true for business, false for individual (Optional)
is_market_userOptionalFilter customers by market-context flag (true or false) (Optional)
market_idOptionalFilter customers by market ID (Optional)
is_restaurant_userOptionalFilter customers by restaurant-context flag (true or false) (Optional)
restaurant_location_idOptionalFilter customers by restaurant location ID (Optional)
searchOptionalToolbar search across first_name, last_name, full_name, email, and phone
sort_byOptionalSort by one of: name, email, created_at, last_login_at
sort_orderOptionalSort order: asc or desc. Defaults to desc when sort_by is provided.
column_filtersOptionalJSON string with keys: full_name, email, phone, status, user_type, is_market_user, is_restaurant_user, created_at, last_login_at
Headers
AuthorizationOptionalBearer {{access_token}}
Responses
1{2 "success": true,3 "message": "Users retrieved successfully",4 "users": [5 {6 "id": "user-uuid",7 "email": "customer@example.com",8 "first_name": "Jane",9 "last_name": "Doe",10 "full_name": "Jane Doe",11 "user_type": "individual",12 "is_market_user": false,13 "market_id": null,14 "is_restaurant_user": false,15 "restaurant_location_id": null,16 "roles": {17 "id": null,18 "name": "customer",19 "scope": "tenant"20 },21 "tenant": {22 "id": "tenant-uuid",23 "name": "Example Tenant"24 }25 }26 ],27 "stats": {28 "totalUsers": 25,29 "activeUsers": 20,30 "pendingUsers": 3,31 "recentlyJoined": [32 {33 "id": "user-uuid",34 "first_name": "Jane",35 "last_name": "Doe",36 "email": "customer@example.com",37 "avatar_url": null,38 "created_at": "2025-09-20T10:42:09.258391+00:00"39 }40 ]41 },42 "page": 1,43 "limit": 10,44 "total": 2545}Update User
/users/:id?language=enUpdates a user's information. Users can update their own information, while system administrators can update any user. Authentication: - Requires valid authentication token - Users can update their own profile (including status) - System administrators / tenant administrators can update any user profile (email change is self-only) Path Parameters: - id: UUID of the user to update (Required) Query Parameters: - language (optional): Language code for localized response messages (e.g., 'en') Updatable Fields: - email: Change login email (self-only). Triggers a confirmation email and redirects to sign-in after confirmation. - first_name: User's first name - last_name: User's last name - status: User account status (self or admin) - phone: User's phone number - avatar_url: URL to user's profile image - profile_data: Object containing additional profile information - customer_delivery_preferences: Object containing delivery preferences Notes: - Only provided fields will be updated. Fields not included in the request will remain unchanged. - Email change sends a confirmation email via Supabase Auth and is allowed only when updating your own user. - When email is updated, the API returns immediately with requires_email_confirmation: true and new_email. The frontend should display the message instructing the user to check their new email inbox to confirm.
1curl --request PUT "$ONDI_BASE_URL/users/:id?language=en" \2 --header "Authorization: Bearer {{access_token}}" \3 --header "Content-Type: application/json" \4 --header "Content-Type: application/json" \5 --data '{6 "email": "new.email@example.com",7 "first_name": "Updated",8 "last_name": "Name",9 "status": "inactive",10 "phone": "+9876543210",11 "avatar_url": "https://example.com/avatar.jpg",12 "profile_data": {13 "bio": "Updated user bio",14 "preferences": {15 "theme": "dark",16 "notifications": true17 }18 },19 "customer_delivery_preferences": {20 "preferred_time": "evening",21 "special_instructions": "Leave at the door"22 }23}'1{2 "email": "new.email@example.com",3 "first_name": "Updated",4 "last_name": "Name",5 "status": "inactive",6 "phone": "+9876543210",7 "avatar_url": "https://example.com/avatar.jpg",8 "profile_data": {9 "bio": "Updated user bio",10 "preferences": {11 "theme": "dark",12 "notifications": true13 }14 },15 "customer_delivery_preferences": {16 "preferred_time": "evening",17 "special_instructions": "Leave at the door"18 }19}Path parameters
idRequireduser-uuid
UUID of the user to update (Required)
Query parameters
languageOptionalen
Language code for response localization (Optional, default: en)
Request body fields
emailExampleExample field from the request body.
first_nameExampleExample field from the request body.
last_nameExampleExample field from the request body.
statusExampleExample field from the request body.
phoneExampleExample field from the request body.
avatar_urlExampleExample field from the request body.
profile_dataExampleExample field from the request body.
profile_data.bioExampleExample field from the request body.
profile_data.preferencesExampleExample field from the request body.
profile_data.preferences.themeExampleExample field from the request body.
profile_data.preferences.notificationsExampleExample field from the request body.
customer_delivery_preferencesExampleExample field from the request body.
customer_delivery_preferences.preferred_timeExampleExample field from the request body.
customer_delivery_preferences.special_instructionsExampleExample field from the request body.
Headers
AuthorizationOptionalBearer {{access_token}}
Content-TypeOptionalapplication/json
Responses
1{2 "success": true,3 "message": "User updated successfully",4 "user": {5 "id": "user-uuid",6 "email": "user@example.com",7 "first_name": "Updated",8 "last_name": "Name",9 "status": "inactive",10 "phone": "+9876543210",11 "avatar_url": "https://example.com/avatar.jpg",12 "profile_data": {13 "bio": "Updated user bio",14 "preferences": {15 "theme": "dark",16 "notifications": true17 }18 },19 "customer_delivery_preferences": {20 "preferred_time": "evening",21 "special_instructions": "Leave at the door"22 },23 "created_at": "2023-01-01T00:00:00Z",24 "updated_at": "2023-01-01T00:00:00Z"25 }26}1{2 "success": true,3 "message": "Please check your inbox at new.email@example.com to confirm the email change",4 "requires_email_confirmation": true,5 "new_email": "new.email@example.com"6}1{2 "success": false,3 "message": "Unauthorized"4}1{2 "success": false,3 "message": "Failed to update user"4}1{2 "success": true,3 "message": "User updated successfully",4 "user": { ... }5}Update My Password
/users/me/password?language=enUpdates the current authenticated user's password. Authentication: - Requires valid authenticated user bearer token - API key authentication is not allowed Query Parameters: - language (optional): Language code for localized response messages (e.g., 'en') Required Fields: - new_password: New password (min: 8, max: 128 characters) Optional Fields: - current_password: Required when the user already has a password. Omit it only when setting a password for the first time after OTP or magic link sign-in. Notes: - The authenticated user is always the target user - Users with an existing password must provide the correct current password - Users without an existing password can set one by providing only new_password
1curl --request PUT "$ONDI_BASE_URL/users/me/password?language=en" \2 --header "Authorization: Bearer {{access_token}}" \3 --header "Content-Type: application/json" \4 --header "Content-Type: application/json" \5 --data '{6 "current_password": "CurrentSecurePassword123!",7 "new_password": "NewSecurePassword123!"8}'1{2 "current_password": "CurrentSecurePassword123!",3 "new_password": "NewSecurePassword123!"4}Query parameters
languageOptionalen
Language code for response localization (Optional, default: en)
Request body fields
current_passwordExampleExample field from the request body.
new_passwordExampleExample field from the request body.
Headers
AuthorizationOptionalBearer {{access_token}}
Content-TypeOptionalapplication/json
Responses
1{2 "success": true,3 "message": "Password updated successfully",4 "data": {5 "user_id": "user-uuid"6 }7}1{2 "success": false,3 "message": "Current password is required"4}1{2 "success": false,3 "message": "Unauthorized"4}1{2 "success": false,3 "message": "User not found"4}1{2 "success": false,3 "message": "Internal server error"4}Update My Notification Settings
/users/me/notifications?language=enEnable or disable in-app/push/email/SMS notifications for the current user. When notifications_enabled is false, new rows in notifications are stored with status skipped_disabled_notification and are not delivered; they do not appear in GET /messaging/notifications (which only returns status: sent). Authentication: Bearer token only (API key not supported). Request body: - notifications_enabled (boolean, required) Response (200): { success, message, data: { user_id, notifications_enabled } }
1curl --request PUT "$ONDI_BASE_URL/users/me/notifications?language=en" \2 --header "Authorization: Bearer {{access_token}}" \3 --header "Content-Type: application/json" \4 --header "Content-Type: application/json" \5 --data '{6 "notifications_enabled": true7}'1{2 "notifications_enabled": true3}Query parameters
languageOptionalen
Language code for response localization (Optional, default: en)
Request body fields
notifications_enabledExampleExample field from the request body.
Headers
AuthorizationOptionalBearer {{access_token}}
Content-TypeOptionalapplication/json
Responses
1{2 "success": true,3 "message": "Notification settings updated successfully",4 "data": {5 "user_id": "user-uuid",6 "notifications_enabled": true7 }8}1{2 "success": false,3 "message": "field_required"4}1{2 "success": false,3 "message": "Unauthorized"4}Reset User Password by ID
/users/:id/reset-password?language=enResets a user's password by user ID. Authentication: - Requires valid authentication token - Only system admins and tenant admins can use this endpoint Path Parameters: - id: UUID of the user whose password to reset (Required) Query Parameters: - language (optional): Language code for localized response messages (e.g., 'en') Required Fields: - password: New password (min: 8, max: 128 characters) Notes: - Use this endpoint for admin-managed password reset only - Password must be between 8 and 128 characters - User is identified by the ID in the URL path
1curl --request PUT "$ONDI_BASE_URL/users/:id/reset-password?language=en" \2 --header "Authorization: Bearer {{access_token}}" \3 --header "Content-Type: application/json" \4 --header "Content-Type: application/json" \5 --data '{6 "password": "NewSecurePassword123!"7}'1{2 "password": "NewSecurePassword123!"3}Path parameters
idRequireduser-uuid
UUID of the user whose password to reset (Required)
Query parameters
languageOptionalen
Language code for response localization (Optional, default: en)
Request body fields
passwordExampleExample field from the request body.
Headers
AuthorizationOptionalBearer {{access_token}}
Content-TypeOptionalapplication/json
Responses
1{2 "success": true,3 "message": "User updated successfully",4 "data": {5 "user_id": "user-uuid",6 "email": "user@example.com",7 "phone": "+1234567890"8 }9}1{2 "success": false,3 "message": "Validation error"4}1{2 "success": false,3 "message": "Unauthorized"4}1{2 "success": false,3 "message": "User not found"4}1{2 "success": false,3 "message": "Internal server error"4}Delete User
/users/:id?language=enDelete a user. This operation may be permanent or may mark the user as deleted depending on implementation.
1curl --request DELETE "$ONDI_BASE_URL/users/:id?language=en" \2 --header "Authorization: Bearer {{access_token}}"Path parameters
idRequireduser-uuid
UUID of the user to delete (Required)
Query parameters
languageOptionalen
Language code for response localization (Optional, default: en)
Headers
AuthorizationOptionalBearer {{access_token}}
Responses
1{2 "error": "Not Found",3 "message": "User not found",4 "status": 4045}1{2 "error": "Forbidden",3 "message": "Cannot delete own account",4 "status": 4035}Assign User Role
/users/:userId/roles?language=enAssigns a role to a user. A user can only have one role assignment at a time. The role can be either a system-level role or a tenant-specific role. Business Rules: 1. A user can only have one role assignment at a time 2. System roles cannot be associated with a tenant 3. Tenant roles must specify a tenant ID 4. If a user already has a role assigned, the request will update it 5. A user cannot change their own role 6. Cannot change the role of the last tenant_admin for a tenant 7. Cannot change the role of the last system_admin
1curl --request POST "$ONDI_BASE_URL/users/:userId/roles?language=en" \2 --header "Authorization: Bearer {{access_token}}" \3 --header "Content-Type: application/json" \4 --header "Content-Type: application/json" \5 --data '{6 "role_id": "role-uuid",7 "role_type": "tenant",8 "tenant_id": "tenant-uuid"9}'1{2 "role_id": "role-uuid",3 "role_type": "tenant",4 "tenant_id": "tenant-uuid"5}Path parameters
userIdRequiredThe unique identifier of the user to assign the role to
Query parameters
languageOptionalen
Language code for response messages (default: en)
Request body fields
role_idExampleExample field from the request body.
role_typeExampleExample field from the request body.
tenant_idExampleExample field from the request body.
Headers
AuthorizationOptionalBearer {{access_token}}
Content-TypeOptionalapplication/json
Responses
1{2 "success": true,3 "message": "Role assigned successfully"4}1{2 "success": false,3 "message": "User already has role"4}1{2 "success": false,3 "message": "System role cannot be assigned to tenant"4}1{2 "success": false,3 "message": "You cannot change your own role"4}1{2 "success": false,3 "message": "Cannot remove the last admin of this tenant. Assign another admin first."4}Get User Role
/users/:userId/roles?language=enRetrieves roles assigned to a user. This endpoint returns all roles associated with the specified user, including role name, scope, role type, and tenant ID.
1curl --request GET "$ONDI_BASE_URL/users/:userId/roles?language=en" \2 --header "Authorization: Bearer {{access_token}}"Path parameters
userIdRequiredID of the user to get roles for
Query parameters
languageOptionalen
Language code for response localization (Optional, default: en)
Headers
AuthorizationOptionalBearer {{access_token}}
Responses
1{2 "success": true,3 "message": "Role retrieved successfully",4 "roles": [5 {6 "id": "role-123",7 "name": "Admin",8 "scope": "global",9 "role_type": "admin",10 "tenant_id": "tenant-456"11 },12 {13 "id": "role-789",14 "name": "Editor",15 "scope": "tenant",16 "role_type": "user",17 "tenant_id": "tenant-456"18 }19 ]20}1{2 "success": false,3 "message": "Failed to get role"4}Remove User Role
/users/:userId/roles/:roleId?language=enRemoves a specific role assignment from a user. This endpoint deletes the association between a user and a role in the system. Business Rules: 1. Only tenant_admin or system_admin can remove roles 2. A user cannot remove their own role 3. tenant_admin can only remove roles within their own tenant 4. Cannot remove the last tenant_admin of a tenant 5. Cannot remove the last system_admin
1curl --request DELETE "$ONDI_BASE_URL/users/:userId/roles/:roleId?language=en" \2 --header "Authorization: Bearer {{access_token}}"Path parameters
userIdRequiredID of the user to remove the role from
roleIdRequiredID of the role to be removed from the user
Query parameters
languageOptionalen
Language code for response localization (Optional, default: en)
Headers
AuthorizationOptionalBearer {{access_token}}
Responses
1{2 "success": true,3 "message": "Role removed successfully"4}1{2 "success": false,3 "message": "Failed to remove role"4}1{2 "success": false,3 "message": "You cannot change your own role"4}1{2 "success": false,3 "message": "Cannot remove the last admin of this tenant. Assign another admin first."4}Get User Addresses
/users/:userId/addresses?language=en&page=1&limit=10Lists addresses belonging to a specific user with pagination. Users can only access their own addresses, while system administrators can access any user's addresses. Authentication: - Requires valid authentication token - Users can only access their own addresses - System administrators can access any user's addresses Path Parameters: - userId: UUID of the user whose addresses to retrieve (Required) Query Parameters: - language (optional): Language code for localized response messages (e.g., 'en') - page (optional): Page number for pagination (default: 1) - limit (optional): Number of records per page (default: 10)
1curl --request GET "$ONDI_BASE_URL/users/:userId/addresses?language=en&page=1&limit=10" \2 --header "Authorization: Bearer {{access_token}}"Path parameters
userIdRequireduser-uuid
UUID of the user whose addresses to retrieve (Required)
Query parameters
languageOptionalen
Language code for response localization (Optional, default: en)
pageOptional1
Page number for pagination (Optional, default: 1)
limitOptional10
Number of records per page (Optional, default: 10)
Headers
AuthorizationOptionalBearer {{access_token}}
Responses
1{2 "success": true,3 "message": "Addresses retrieved successfully",4 "addresses": [5 {6 "id": "address-uuid",7 "user_id": "user-uuid",8 "title": "Home",9 "address_line1": "123 Main St",10 "address_line2": "Apt 4B",11 "city": "New York",12 "state": "NY",13 "postal_code": "10001",14 "country": "US",15 "is_primary": true,16 "is_active": true,17 "latitude": 40.7128,18 "longitude": -74.006,19 "created_at": "2023-01-01T00:00:00Z",20 "updated_at": "2023-01-01T00:00:00Z"21 }22 ],23 "total": 5,24 "page": 1,25 "limit": 1026}1{2 "success": false,3 "message": "Unauthorized"4}1{2 "success": false,3 "message": "Error retrieving addresses"4}