Admin users

Manage the back-office admin accounts themselves: list, invite, update roles/cities, and revoke access. Paths are relative to the /api/v1 prefix; these are back-office endpoints requiring a super-admin token.

Requires a super-admin bearer token (see Admin auth). Super-admin only.

See Common errors.

The role is super_admin or admin. A plain admin is restricted to the cities in its cities list; a super_admin has no city restriction (any city_ids sent for a super-admin are cleared).

Endpoints

Method URI Access Description
GET /admin/users Super admin List every admin account
POST /admin/users Super admin Create an admin account
PATCH /admin/users/{adminId} Super admin Update name, role, cities, or password
DELETE /admin/users/{adminId} Super admin Deactivate an admin (revokes access)

The admin object

List and single responses present each admin the same way:

{
  "id": 5,
  "name": "Ops Caracas",
  "email": "ops@aguita.app",
  "role": "admin",
  "is_active": true,
  "cities": [ { "id": 1, "name": "Caracas" } ],
  "last_activity_at": "2026-06-29T12:00:00+00:00",
  "created_at": "2026-06-01T09:00:00+00:00"
}

cities is empty for super-admins. last_activity_at is the admin's most recent activity, or null if they have never authenticated.


GET /admin/users

Lists all admins (newest first). Not paginated.

Response 200

{ "items": [ { "id": 5, "name": "Ops Caracas", "role": "admin", "is_active": true } ] }

POST /admin/users

Creates an admin. If password is omitted, a temporary one is generated and returned once in temporary_password so it can be shared with the invitee. city_ids are applied only when the new admin is a plain admin.

Request body

Field Type Required Rules
name string yes ≤ 120 chars
email string yes valid email, ≤ 160 chars, unique among admins
role string no admin (default) or super_admin
password string no 8–72 chars; if omitted, one is generated
is_active boolean no defaults to true
city_ids integer[] no each must exist in cities; ignored for super-admins

Response 201

{
  "admin": { "id": 9, "name": "Ops Valencia", "role": "admin", "is_active": true },
  "temporary_password": "Ab3xK9mQ2pLz"
}

temporary_password is present only when no password was supplied.


PATCH /admin/users/{adminId}

Updates an admin. Promoting to super_admin clears the admin's cities; for a plain admin, sending city_ids replaces the city list.

Request body (all optional)

Field Type Required Rules
name string no ≤ 120 chars
email string no valid email, ≤ 160 chars, unique among admins (ignoring self)
role string no admin or super_admin
password string no 8–72 chars
is_active boolean no
city_ids integer[] no each must exist in cities

Response 200

{ "admin": { "id": 5, "name": "Ops Caracas", "role": "super_admin", "is_active": true } }

Errors

Status Body When
404 { "error": "AdminNotFound" } No admin with that id
422 { "error": "CannotDemoteSelf", "message": "…" } You tried to remove your own super-admin role
422 { "error": "LastSuperAdmin", "message": "…" } Would demote/deactivate the last active super-admin

DELETE /admin/users/{adminId}

Deactivates the admin. This is not a hard delete.

Response 200

{ "ok": true, "deactivated": true }

Errors

Status Body When
404 { "error": "AdminNotFound" } No admin with that id
422 { "error": "CannotRemoveSelf", "message": "…" } You tried to deactivate your own account
422 { "error": "LastSuperAdmin", "message": "…" } Would deactivate the last active super-admin