Skip to content

Admin Users API

Super-admin provisioning and management of administration users — the staff and platform-admin accounts that operate the admin portal.

Every /admin/users endpoint requires an authenticated super_admin session; the router is mounted behind a requireRole('super_admin') guard. Any other role receives 403 AUTH_FORBIDDEN. The acting identity and role are taken from the verified session, never from the request body.

Roles and Areas

The admin portal is partitioned into manageable areas. A user's access is derived from its appRole plus, for the admin role, an explicit set of assigned areas.

Roles

RoleAreasAssignable here
super_adminAll areas (owner)No — owners are not managed here
adminThe subset assigned via managedAreas (platform-admin)Yes
activation_officerofficer (fixed)Yes
supportsupport (fixed)Yes
b2b_adminb2b (fixed)Yes
end_userNoneNo

Roles assignable through this API are exactly admin, b2b_admin, activation_officer, and support. super_admin and end_user can never be assigned here, so an owner cannot mint another owner through this endpoint.

Areas

AreaPortal section
activation-recordsActivation records dashboard
packagesPackage catalog
officerActivation officer tools
supportCustomer support
b2bB2B company portal

user-management is intentionally not an assignable area — provisioning admins is an owner-only power.

View vs Manage

For the admin role, areas are split into two levels:

  • managedAreas — the View baseline: areas the admin may open (read).
  • managedAreasWrite — the Manage subset: areas the admin may write to. Must be a subset of managedAreas.

Areas in managedAreas but not in managedAreasWrite are View-only. Fixed staff roles derive their single area from the role and omit both fields. The server resolves these at request time (never frozen in the JWT). A user's effective areas are returned in the user object of GET /auth/session as managedAreas and managedAreasWrite.


Administration User Object

The shape returned by the list, create, and update endpoints:

FieldTypeDescription
idstring (uuid)User ID
phonestring | nullPhone in E.164 format; null for email-only users
emailstring | nullEmail address; null for phone-only users
namestring | nullDisplay name
rolestringAssigned UserRole
managedAreasstring[] | nullView areas (admin only; null for staff roles)
managedAreasWritestring[] | nullManage subset (admin only; null for staff roles)
isActivebooleanWhether the account is active
createdAtstringISO 8601 creation timestamp

Success responses are data envelopes (no localized message). Error messages are localized via Accept-Language, and the sign-in invitation sent to a new user is bilingual (English + Arabic).


GET /admin/users

List the manageable administration users, newest first. Excludes end_user accounts and super_admin owners.

Requires super_admin.

Response

200 OK

json
{
  "data": [
    {
      "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "phone": "+966501234567",
      "email": null,
      "name": "Sara Officer",
      "role": "activation_officer",
      "managedAreas": null,
      "managedAreasWrite": null,
      "isActive": true,
      "createdAt": "2026-06-29T00:00:00.000Z"
    },
    {
      "id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
      "phone": null,
      "email": "product.admin@skyte.sa",
      "name": "Platform Admin",
      "role": "admin",
      "managedAreas": ["packages", "activation-records"],
      "managedAreasWrite": ["packages"],
      "isActive": true,
      "createdAt": "2026-06-28T00:00:00.000Z"
    }
  ]
}

Error Responses

CodeStatusCondition
AUTH_REQUIRED401Missing token (an invalid or expired token returns AUTH_SESSION_EXPIRED)
AUTH_FORBIDDEN403Caller is not super_admin

POST /admin/users

Provision a new administration user. Requires at least one of phone or email, a name, and a role. For the admin role, managedAreas is required and non-empty; fixed staff roles must omit the area fields. After creation, a bilingual invitation is sent over whichever channel(s) were provided — best-effort, so a delivery failure does not fail creation.

Requires super_admin.

Request Body

FieldTypeRequiredDescription
phonestringConditionalSaudi E.164 (+966XXXXXXXXX). At least one of phone or email.
emailstringConditionalEmail address. At least one of phone or email.
namestringYesFull name (1–255 characters)
rolestringYesOne of admin, b2b_admin, activation_officer, support
managedAreasstring[]ConditionalRequired and non-empty when role is admin; must be omitted for other roles. Values from the area list.
managedAreasWritestring[]NoManage subset of managedAreas (admin only). Must be a subset of managedAreas.

Examples

Platform-admin with assigned areas:

json
{
  "email": "product.admin@skyte.sa",
  "name": "Platform Admin",
  "role": "admin",
  "managedAreas": ["packages", "activation-records"],
  "managedAreasWrite": ["packages"]
}

Fixed staff role (phone-only):

json
{
  "phone": "+966501234567",
  "name": "Sara Officer",
  "role": "activation_officer"
}

Response

201 Created — the created Administration User Object wrapped in data.

json
{
  "data": {
    "id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
    "phone": null,
    "email": "product.admin@skyte.sa",
    "name": "Platform Admin",
    "role": "admin",
    "managedAreas": ["packages", "activation-records"],
    "managedAreasWrite": ["packages"],
    "isActive": true,
    "createdAt": "2026-06-30T12:00:00.000Z"
  }
}

Error Responses

CodeStatusCondition
AUTH_REQUIRED401Missing token (an invalid or expired token returns AUTH_SESSION_EXPIRED)
AUTH_FORBIDDEN403Caller is not super_admin
VALIDATION_ERROR400Schema validation failed (no credential, area rules, managedAreasWrite not a subset of managedAreas, etc.)
ADMIN_USER_PHONE_EXISTS409Phone number already registered
ADMIN_USER_EMAIL_EXISTS409Email address already registered
ADMIN_USER_CREATE_FAILED502Auth account creation failed upstream
ADMIN_USER_PROFILE_NOT_CREATED502Profile row was not seeded; the orphaned auth identity is rolled back

PATCH /admin/users/:id

Update an administration user's access (role + areas) and/or active state. At least one field must be provided. Changing to a fixed staff role clears any admin scope; changing to admin sets the scope from the request. Identity (name/phone/email) is immutable here.

Requires super_admin.

Path Parameters

ParameterTypeRequiredDescription
idstring (uuid)YesTarget user ID

Request Body

All fields optional; at least one is required.

FieldTypeRequiredDescription
rolestringNoNew role (admin, b2b_admin, activation_officer, support). Required in order to change areas.
managedAreasstring[]ConditionalRequired and non-empty when role is admin
managedAreasWritestring[]NoManage subset of managedAreas
isActivebooleanNoActivate or deactivate the account

Examples

Grant admin scope:

json
{
  "role": "admin",
  "managedAreas": ["packages"],
  "managedAreasWrite": ["packages"]
}

Deactivate:

json
{
  "isActive": false
}

Response

200 OK — the updated Administration User Object wrapped in data.

Error Responses

CodeStatusCondition
AUTH_REQUIRED401Missing token (an invalid or expired token returns AUTH_SESSION_EXPIRED)
AUTH_FORBIDDEN403Caller is not super_admin
VALIDATION_ERROR400Schema validation failed (invalid id, no fields, area rules)
ADMIN_USER_NOT_FOUND404No manageable user with this id

DELETE /admin/users/:id

Permanently remove an administration user. Deletes the auth identity and the profile row, freeing the phone/email for re-registration.

Requires super_admin.

Path Parameters

ParameterTypeRequiredDescription
idstring (uuid)YesTarget user ID

Response

204 No Content — empty body.

Error Responses

CodeStatusCondition
AUTH_REQUIRED401Missing token (an invalid or expired token returns AUTH_SESSION_EXPIRED)
AUTH_FORBIDDEN403Caller is not super_admin
VALIDATION_ERROR400id is not a valid UUID
ADMIN_USER_NOT_FOUND404No manageable user with this id
ADMIN_USER_DELETE_FAILED502Auth identity removal failed upstream

POST /admin/users/:id/resend-invite

Re-send the bilingual sign-in invitation to an existing administration user over its stored channel(s). Best-effort delivery.

Requires super_admin.

Path Parameters

ParameterTypeRequiredDescription
idstring (uuid)YesTarget user ID

Response

200 OK

json
{
  "message": "Invitation re-sent"
}

Error Responses

CodeStatusCondition
AUTH_REQUIRED401Missing token (an invalid or expired token returns AUTH_SESSION_EXPIRED)
AUTH_FORBIDDEN403Caller is not super_admin
VALIDATION_ERROR400id is not a valid UUID
ADMIN_USER_NOT_FOUND404No manageable user with this id

Internal documentation - Activation System