Skip to main content

Groups

GET /orgs/{orgId}/api/v1/admin/groups
POST /orgs/{orgId}/api/v1/admin/groups
GET /orgs/{orgId}/api/v1/admin/groups/{groupId}
PUT /orgs/{orgId}/api/v1/admin/groups/{groupId}
DELETE /orgs/{orgId}/api/v1/admin/groups/{groupId}
GET /orgs/{orgId}/api/v1/admin/groups/{groupId}/members
POST /orgs/{orgId}/api/v1/admin/groups/{groupId}/members
DELETE /orgs/{orgId}/api/v1/admin/groups/{groupId}/members/{userId}
GET /orgs/{orgId}/api/v1/admin/groups/{groupId}/roles
POST /orgs/{orgId}/api/v1/admin/groups/{groupId}/roles
DELETE /orgs/{orgId}/api/v1/admin/groups/{groupId}/roles/{roleId}

Groups organize users and carry role assignments. Users inherit all roles from their groups at token issuance time.

Authentication​

All group management endpoints require an admin API key or a Bearer token with admin:groups:read / admin:groups:write.

Each endpoint needs the credential's scope and a permission. A session or Bearer caller must hold the permission; for an API key its creator must still hold it. A missing permission returns 403 forbidden with details.required_permissions. See Required permissions.

MethodEndpointPermissionAPI-key / token scope
GET/admin/groupsgroups.viewadmin:groups:read
GET/admin/groups/{groupId}groups.viewadmin:groups:read
POST/admin/groupsgroups.createadmin:groups:write
PUT PATCH/admin/groups/{groupId}groups.editadmin:groups:write
DELETE/admin/groups/{groupId}groups.deleteadmin:groups:write
GET/admin/groups/{groupId}/membersgroups.viewadmin:groups:read
POST/admin/groups/{groupId}/membersgroups.editadmin:groups:write
DELETE/admin/groups/{groupId}/members/{userId}groups.editadmin:groups:write
GET/admin/groups/{groupId}/rolesgroups.viewadmin:groups:read
POST/admin/groups/{groupId}/rolesgroups.editadmin:groups:write
DELETE/admin/groups/{groupId}/roles/{roleId}groups.editadmin:groups:write
PUT/admin/groups/{groupId}/rolesgroups.editadmin:groups:write

The Group Object​

Single-group responses are wrapped in a data envelope. roles and members are arrays of objects (not slug strings) and are returned only on the single-group GET /groups/{groupId} (detailed) response — list rows omit them.

Group Object
{
"data": {
"id": "01JF3KABCDE...",
"name": "Engineering Team",
"slug": "engineering",
"description": "Software engineers and SREs",
"isSystem": false,
"memberCount": 24,
"roleCount": 2,
"createdAt": "2026-01-15T10:30:00Z",
"roles": [
{ "id": 12, "name": "Developer", "slug": "developer" },
{ "id": 13, "name": "Deploy", "slug": "deploy" }
],
"members": [
{ "id": "01JF3KUSER...", "email": "alice@acme.com", "name": "Alice" }
],
"updatedAt": "2026-03-01T08:00:00Z"
}
}
note

There is no displayName field — a group is identified by name and a URL-safe slug. Sending displayName in a create/update body is ignored.

List Groups​

List Groups
curl "https://app.lumoauth.dev/orgs/acme-corp/api/v1/admin/groups?page=1&limit=50" \
-H "Authorization: ApiKey lmk_abc123"

Query Parameters​

ParameterDescription
pagePage number (default: 1)
limitResults per page (default: 25, max: 100)
searchFilter by name, slug, or description

Create Group​

Create a Group
curl -X POST https://app.lumoauth.dev/orgs/acme-corp/api/v1/admin/groups \
-H "Authorization: ApiKey lmk_abc123" \
-H "Content-Type: application/json" \
-d '{
"name": "Engineering Team",
"slug": "engineering",
"description": "Software engineers and SREs",
"roles": ["developer", "deploy"]
}'

Returns 201 Created with the new group object. name is required; if slug is omitted it is derived from name. roles is an optional array of role slugs to assign at creation time (only roles belonging to this organization are accepted).

Update Group​

Update a Group
curl -X PUT https://app.lumoauth.dev/orgs/acme-corp/api/v1/admin/groups/01JF3KABCDE... \
-H "Authorization: ApiKey lmk_abc123" \
-H "Content-Type: application/json" \
-d '{
"name": "Engineering & SRE",
"description": "Software engineers, SREs, and DevOps"
}'

Members​

List Members​

List Group Members
curl "https://app.lumoauth.dev/orgs/acme-corp/api/v1/admin/groups/01JF3KABCDE.../members" \
-H "Authorization: ApiKey lmk_abc123"

Add Members​

Accepts a single userId, an array userIds, or a users array.

Add a Single Member
curl -X POST https://app.lumoauth.dev/orgs/acme-corp/api/v1/admin/groups/01JF3KABCDE.../members \
-H "Authorization: ApiKey lmk_abc123" \
-H "Content-Type: application/json" \
-d '{"userId": "01JF3KUSER..."}'
Bulk Add Members
curl -X POST https://app.lumoauth.dev/orgs/acme-corp/api/v1/admin/groups/01JF3KABCDE.../members \
-H "Authorization: ApiKey lmk_abc123" \
-H "Content-Type: application/json" \
-d '{"userIds": ["01JF3KUSER...", "01JF3KUSER2..."]}'

Remove Member​

Remove a Member
curl -X DELETE \
"https://app.lumoauth.dev/orgs/acme-corp/api/v1/admin/groups/01JF3KABCDE.../members/01JF3KUSER..." \
-H "Authorization: ApiKey lmk_abc123"

Role Assignment​

Roles assigned to a group are inherited by all group members.

note

System roles cannot be assigned to groups.

Get Group Roles​

Get Group Roles
curl "https://app.lumoauth.dev/orgs/acme-corp/api/v1/admin/groups/01JF3KABCDE.../roles" \
-H "Authorization: ApiKey lmk_abc123"

Add a Role to a Group​

Assign a Role to a Group
curl -X POST https://app.lumoauth.dev/orgs/acme-corp/api/v1/admin/groups/01JF3KABCDE.../roles \
-H "Authorization: ApiKey lmk_abc123" \
-H "Content-Type: application/json" \
-d '{"roleId": "01JF3KROLE..."}'

Remove a Role from a Group​

Remove a Role from a Group
curl -X DELETE "https://app.lumoauth.dev/orgs/acme-corp/api/v1/admin/groups/01JF3KABCDE.../roles/01JF3KROLE..." \
-H "Authorization: ApiKey lmk_abc123"

Delete Group​

Delete a Group
curl -X DELETE "https://app.lumoauth.dev/orgs/acme-corp/api/v1/admin/groups/01JF3KABCDE..." \
-H "Authorization: ApiKey lmk_abc123"

Returns 200 on success. Members are not deleted — only their group membership is removed.