Groups and Model Access API
The groups API manages user groups, their members, per-group DLP overrides, and model access rules. Groups are the primary mechanism for applying differential policy, quota, and model access controls to subsets of users within a tenant.
All endpoints require admin authentication (Authorization: Bearer <admin-api-key>).
Base path: /api/admin/groups
Endpoints summary
Section titled “Endpoints summary”| Method | Path | Description |
|---|---|---|
POST | /api/admin/groups | Create a group |
GET | /api/admin/groups | List all groups |
GET | /api/admin/groups/{group_id} | Get a single group |
PUT | /api/admin/groups/{group_id} | Update a group |
DELETE | /api/admin/groups/{group_id} | Delete a group |
GET | /api/admin/groups/{group_id}/members | List group members |
POST | /api/admin/groups/{group_id}/members | Add a member to a group |
DELETE | /api/admin/groups/{group_id}/members/{user_id} | Remove a member from a group |
GET | /api/admin/groups/{group_id}/dlp | Get per-group DLP overrides |
PUT | /api/admin/groups/{group_id}/dlp | Replace per-group DLP overrides |
GET | /api/admin/groups/model-access | List all model access rules (org-wide) |
GET | /api/admin/groups/{group_id}/model-access | List model access rules for a group |
POST | /api/admin/groups/{group_id}/model-access | Create a model access rule |
DELETE | /api/admin/groups/{group_id}/model-access/{model_id} | Delete a model access rule |
GroupResponse object
Section titled “GroupResponse object”Returned by all group CRUD endpoints.
| Field | Type | Description |
|---|---|---|
id | UUID | Unique group identifier |
name | string | Display name for the group |
description | string | null | Optional human-readable description |
external_group_id | string | null | Optional identifier linking this group to an external directory (e.g. Entra ID group OID, Okta group ID) |
tenant_id | UUID | Tenant this group belongs to |
member_count | integer | Current number of members |
created_at | string (ISO 8601) | Creation timestamp |
updated_at | string (ISO 8601) | Last modification timestamp |
Groups CRUD
Section titled “Groups CRUD”Create a group
Section titled “Create a group”POST /api/admin/groupsRequest body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | Display name. Must be unique within the tenant. |
description | string | null | no | Optional description |
external_group_id | string | null | no | External directory group ID for SCIM or SAML group sync |
curl -X POST https://gateway.arbitex.ai/api/admin/groups \ -H "Authorization: Bearer $ARBITEX_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "ML Engineering", "description": "Machine learning engineers with access to GPU-accelerated models", "external_group_id": "aad-group-oid-abc123" }'Response 201 Created
{ "id": "grp_01hx4k2m9n-...", "name": "ML Engineering", "description": "Machine learning engineers with access to GPU-accelerated models", "external_group_id": "aad-group-oid-abc123", "tenant_id": "tnt_01hx4k2m9n-...", "member_count": 0, "created_at": "2026-03-12T09:00:00Z", "updated_at": "2026-03-12T09:00:00Z"}Response 409 Conflict — a group with that name already exists in this tenant.
List groups
Section titled “List groups”GET /api/admin/groupsReturns all groups for the tenant.
curl https://gateway.arbitex.ai/api/admin/groups \ -H "Authorization: Bearer $ARBITEX_API_KEY"Response 200 OK
{ "groups": [ { "id": "grp_01hx4k2m9n-...", "name": "ML Engineering", "description": "Machine learning engineers with access to GPU-accelerated models", "external_group_id": "aad-group-oid-abc123", "tenant_id": "tnt_01hx4k2m9n-...", "member_count": 14, "created_at": "2026-03-12T09:00:00Z", "updated_at": "2026-03-12T09:00:00Z" }, { "id": "grp_01hx4k2m9p-...", "name": "Security", "description": null, "external_group_id": null, "tenant_id": "tnt_01hx4k2m9n-...", "member_count": 3, "created_at": "2026-02-20T14:30:00Z", "updated_at": "2026-03-01T11:10:00Z" } ], "total": 2}Get a group
Section titled “Get a group”GET /api/admin/groups/{group_id}Path parameters
| Parameter | Type | Description |
|---|---|---|
group_id | UUID | The group’s UUID |
curl https://gateway.arbitex.ai/api/admin/groups/grp_01hx4k2m9n-... \ -H "Authorization: Bearer $ARBITEX_API_KEY"Response 200 OK — single GroupResponse object.
Response 404 Not Found — group does not exist in this tenant.
Update a group
Section titled “Update a group”PUT /api/admin/groups/{group_id}Partial update — only fields provided in the request body are modified. Returns the updated group.
Path parameters
| Parameter | Type | Description |
|---|---|---|
group_id | UUID | The group’s UUID |
Request body (all fields optional)
| Field | Type | Description |
|---|---|---|
name | string | New display name. Must remain unique within the tenant. |
description | string | null | New description. Pass null to clear. |
external_group_id | string | null | New external group ID. Pass null to clear. |
curl -X PUT https://gateway.arbitex.ai/api/admin/groups/grp_01hx4k2m9n-... \ -H "Authorization: Bearer $ARBITEX_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "description": "ML engineers — GPU and frontier model access" }'Response 200 OK — updated GroupResponse object.
Response 404 Not Found — group does not exist.
Response 409 Conflict — the new name conflicts with an existing group.
Delete a group
Section titled “Delete a group”DELETE /api/admin/groups/{group_id}Deletes the group, its membership records, and all associated model access rules and DLP overrides. This action cannot be undone.
Path parameters
| Parameter | Type | Description |
|---|---|---|
group_id | UUID | The group’s UUID |
curl -X DELETE https://gateway.arbitex.ai/api/admin/groups/grp_01hx4k2m9n-... \ -H "Authorization: Bearer $ARBITEX_API_KEY"Response 204 No Content — group deleted.
Response 404 Not Found — group does not exist.
Group membership
Section titled “Group membership”List members
Section titled “List members”GET /api/admin/groups/{group_id}/membersReturns all members of the specified group.
Path parameters
| Parameter | Type | Description |
|---|---|---|
group_id | UUID | The group’s UUID |
curl https://gateway.arbitex.ai/api/admin/groups/grp_01hx4k2m9n-.../members \ -H "Authorization: Bearer $ARBITEX_API_KEY"Response 200 OK
[ { "id": "mem_01hx4k2m9n-...", "user_id": "usr_01hx3j1a8b-...", "group_id": "grp_01hx4k2m9n-...", "user_email": "alice@example.com", "joined_at": "2026-03-05T08:20:00Z" }, { "id": "mem_01hx4k2m9q-...", "user_id": "usr_01hx3j1a8c-...", "group_id": "grp_01hx4k2m9n-...", "user_email": "bob@example.com", "joined_at": "2026-03-06T10:45:00Z" }]MemberResponse fields
| Field | Type | Description |
|---|---|---|
id | UUID | Membership record identifier |
user_id | UUID | The member’s user UUID |
group_id | UUID | The group UUID |
user_email | string | The member’s email address |
joined_at | string (ISO 8601) | When the user was added to the group |
Add a member
Section titled “Add a member”POST /api/admin/groups/{group_id}/membersAdds an existing user to the group.
Path parameters
| Parameter | Type | Description |
|---|---|---|
group_id | UUID | The group’s UUID |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
user_id | UUID | yes | UUID of the user to add |
curl -X POST https://gateway.arbitex.ai/api/admin/groups/grp_01hx4k2m9n-.../members \ -H "Authorization: Bearer $ARBITEX_API_KEY" \ -H "Content-Type: application/json" \ -d '{"user_id": "usr_01hx3j1a8d-..."}'Response 201 Created — MemberResponse object for the new membership record.
{ "id": "mem_01hx4k2m9r-...", "user_id": "usr_01hx3j1a8d-...", "group_id": "grp_01hx4k2m9n-...", "user_email": "carol@example.com", "joined_at": "2026-03-12T09:15:00Z"}Response 404 Not Found — user_id does not exist in this tenant.
Response 409 Conflict — the user is already a member of this group.
Remove a member
Section titled “Remove a member”DELETE /api/admin/groups/{group_id}/members/{user_id}Removes a user from the group. The user account is not affected.
Path parameters
| Parameter | Type | Description |
|---|---|---|
group_id | UUID | The group’s UUID |
user_id | UUID | The user’s UUID |
curl -X DELETE \ https://gateway.arbitex.ai/api/admin/groups/grp_01hx4k2m9n-.../members/usr_01hx3j1a8d-... \ -H "Authorization: Bearer $ARBITEX_API_KEY"Response 204 No Content — member removed.
Response 404 Not Found — group or membership record not found.
Group DLP overrides
Section titled “Group DLP overrides”Per-group DLP overrides let you tighten or relax the tenant-level DLP policy for a specific group. Each override entry specifies an entity type and the action to take when that entity type is detected in a request or response from a group member.
Get DLP overrides
Section titled “Get DLP overrides”GET /api/admin/groups/{group_id}/dlpReturns the current DLP override configuration for the group.
Path parameters
| Parameter | Type | Description |
|---|---|---|
group_id | UUID | The group’s UUID |
curl https://gateway.arbitex.ai/api/admin/groups/grp_01hx4k2m9n-.../dlp \ -H "Authorization: Bearer $ARBITEX_API_KEY"Response 200 OK
[ { "entity_type": "credit_card", "action": "BLOCK" }, { "entity_type": "ssn", "action": "REDACT" }, { "entity_type": "internal_project_code", "action": "ALLOW" }]DLP override fields
| Field | Type | Description |
|---|---|---|
entity_type | string | The DLP entity type label (e.g. "credit_card", "ssn", "api_key") |
action | string | "ALLOW", "BLOCK", or "REDACT" |
An empty array means the group inherits the tenant-level DLP policy with no overrides.
Replace DLP overrides
Section titled “Replace DLP overrides”PUT /api/admin/groups/{group_id}/dlpReplaces the entire DLP override set for the group. This is a full replacement — any overrides not present in the request body are removed.
Path parameters
| Parameter | Type | Description |
|---|---|---|
group_id | UUID | The group’s UUID |
Request body — array of override objects
| Field | Type | Required | Description |
|---|---|---|---|
entity_type | string | yes | DLP entity type label |
action | string | yes | "ALLOW", "BLOCK", or "REDACT" |
curl -X PUT https://gateway.arbitex.ai/api/admin/groups/grp_01hx4k2m9n-.../dlp \ -H "Authorization: Bearer $ARBITEX_API_KEY" \ -H "Content-Type: application/json" \ -d '[ { "entity_type": "credit_card", "action": "BLOCK" }, { "entity_type": "ssn", "action": "REDACT" }, { "entity_type": "internal_project_code", "action": "ALLOW" } ]'Response 200 OK — the updated override array (same shape as the GET response).
To clear all overrides and revert to tenant-level policy, send an empty array: [].
Model access control
Section titled “Model access control”Model access rules determine which AI models members of a group are permitted to use. Rules are evaluated at request time; if a user’s groups have a DENY rule for the requested model, the request is rejected. ALLOW rules can grant access to models that are otherwise restricted at the tenant level.
List all model access rules (org-wide)
Section titled “List all model access rules (org-wide)”GET /api/admin/groups/model-accessReturns every model access rule across all groups for the tenant. Useful for auditing the full model access posture.
curl https://gateway.arbitex.ai/api/admin/groups/model-access \ -H "Authorization: Bearer $ARBITEX_API_KEY"Response 200 OK — array of ModelAccessRule objects (see field table below).
[ { "id": "mar_01hx4k2m9n-...", "group_id": "grp_01hx4k2m9n-...", "model_id": "claude-opus-4-6", "access_type": "ALLOW", "created_at": "2026-03-10T12:00:00Z" }, { "id": "mar_01hx4k2m9p-...", "group_id": "grp_01hx4k2m9p-...", "model_id": "gpt-4o", "access_type": "DENY", "created_at": "2026-03-11T08:30:00Z" }]List model access rules for a group
Section titled “List model access rules for a group”GET /api/admin/groups/{group_id}/model-accessReturns all model access rules configured for a specific group.
Path parameters
| Parameter | Type | Description |
|---|---|---|
group_id | UUID | The group’s UUID |
curl https://gateway.arbitex.ai/api/admin/groups/grp_01hx4k2m9n-.../model-access \ -H "Authorization: Bearer $ARBITEX_API_KEY"Response 200 OK
[ { "id": "mar_01hx4k2m9n-...", "group_id": "grp_01hx4k2m9n-...", "model_id": "claude-opus-4-6", "access_type": "ALLOW", "created_at": "2026-03-10T12:00:00Z" }, { "id": "mar_01hx4k2m9s-...", "group_id": "grp_01hx4k2m9n-...", "model_id": "gpt-4-turbo", "access_type": "DENY", "created_at": "2026-03-10T12:05:00Z" }]ModelAccessRule fields
| Field | Type | Description |
|---|---|---|
id | UUID | Rule identifier |
group_id | UUID | Group this rule applies to |
model_id | string | Model identifier as registered in the provider catalog (e.g. "claude-opus-4-6", "gpt-4o") |
access_type | string | "ALLOW" or "DENY" |
created_at | string (ISO 8601) | When the rule was created |
Create a model access rule
Section titled “Create a model access rule”POST /api/admin/groups/{group_id}/model-accessCreates a new model access rule for a group.
Path parameters
| Parameter | Type | Description |
|---|---|---|
group_id | UUID | The group’s UUID |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
model_id | string | yes | Model identifier from the provider catalog |
access_type | string | yes | "ALLOW" or "DENY" |
# Grant the ML Engineering group access to Claude Opuscurl -X POST \ https://gateway.arbitex.ai/api/admin/groups/grp_01hx4k2m9n-.../model-access \ -H "Authorization: Bearer $ARBITEX_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model_id": "claude-opus-4-6", "access_type": "ALLOW" }'Response 201 Created — the created ModelAccessRule object.
{ "id": "mar_01hx4k2m9t-...", "group_id": "grp_01hx4k2m9n-...", "model_id": "claude-opus-4-6", "access_type": "ALLOW", "created_at": "2026-03-12T09:30:00Z"}Response 404 Not Found — group does not exist in this tenant.
Response 409 Conflict — a rule for this model_id already exists for the group. Delete the existing rule before creating a replacement.
Delete a model access rule
Section titled “Delete a model access rule”DELETE /api/admin/groups/{group_id}/model-access/{model_id}Removes the model access rule for the specified model from the group. After deletion, access to the model falls back to tenant-level defaults.
Path parameters
| Parameter | Type | Description |
|---|---|---|
group_id | UUID | The group’s UUID |
model_id | string | The model identifier of the rule to remove |
curl -X DELETE \ https://gateway.arbitex.ai/api/admin/groups/grp_01hx4k2m9n-.../model-access/gpt-4-turbo \ -H "Authorization: Bearer $ARBITEX_API_KEY"Response 204 No Content — rule deleted.
Response 404 Not Found — group not found, or no rule exists for the specified model_id in this group.
Access rule evaluation
Section titled “Access rule evaluation”When a user makes a request to the gateway:
- The gateway resolves all groups the user belongs to.
- Model access rules are collected across all of the user’s groups.
- If any group has a
DENYrule for the requested model, the request is rejected with403 Forbidden. - If at least one group has an
ALLOWrule and no group has aDENYrule, access is granted. - If no group-level rule exists for the model, the tenant-level model allow-list applies.
DENY rules take precedence over ALLOW rules across groups.
Error codes
Section titled “Error codes”| Status | Meaning |
|---|---|
400 Bad Request | Malformed request body or invalid field value |
403 Forbidden | Caller is not an admin or does not have access to this tenant |
404 Not Found | Group, user, or rule does not exist within this tenant |
409 Conflict | Name uniqueness violation (group name or model access rule duplicate) |
See also
Section titled “See also”- Groups and RBAC — conceptual overview of groups, membership sync, and policy inheritance
- User and group management — managing users and group membership via the admin console
- API reference: Quotas — per-group token and cost limits
- DLP rules API — organisation-wide DLP rules; per-group overrides are configured here
- Routing and model controls — tenant-level model allow-lists and routing policy
- Entra ID SCIM — automatic group membership sync from Azure Active Directory