Groups
Overview
The Groups API provides programmatic access to the directory groups synced from your Google, Microsoft, or Okta tenant: Google groups, Google org units, Microsoft groups, and Okta groups. List and filter groups, retrieve one by its encoded ID, list a group's member accounts, and update its licenses, per-group setting overrides, and the roles it grants. Each group exposes its type, name, email, member count, licenses, and effective settings with the layer they resolve from.
Five endpoints make up the Groups API:
List Groups (
GET /api/v1/groups): filter, sort, and page through groupsGet Group (
GET /api/v1/groups/{id}): retrieve a single group by its encoded IDList Group Members (
GET /api/v1/groups/{id}/members): retrieve the accounts that belong to a groupUpdate Group (
PATCH /api/v1/groups/{id}): update a group's licenses and setting overridesBulk Groups (
POST /api/v1/groups/bulk): apply up to 200 group update operations in one request
Filtering
List accepts search (a loose match on name, description, email, or org-unit path), email, type (okta, google_group, google_org_unit, or microsoft_group), memberOf (encoded account IDs), role, and hasOverrides. Per-setting filters use dotted params, for example setting.emailThreatRemediation=on, and take on, off, or overridden. These match the group's own override rather than the value it inherits. Comma-separated values match any of the listed values within a single filter, and each filter you add narrows the result set further.
Sorting
Sort with ?sort=<field>:asc|desc. Supported fields: name (default) and memberCount.
Read-only fields
Name, email, aliases, and membership are synced from your provider and can't be changed through this API. What you can write is licenses, settings, and roles. Setting a value to default clears the group-level override so the group inherits again.
Changing roles additionally requires role-management permission. A role granted here applies to every member of the group, and nothing stops you from removing the last Super Admin, which is irreversible without Material support.
Response Structure
List responses follow the standard two-part structure: a meta object (with totalCount, limit, hasMore, and nextCursor) and an items array.
A group's settings is an array, not a single object. A group can span several tenants, and its own override is instance-wide, but what that override inherits differs per tenant, so the response carries one entry per tenant you can access, each with its own settings and licenses and the layer they resolve from. To read what the group itself overrides, which is what PATCH writes and what the setting.<name> and hasOverrides filters match, take the entries of any tenant whose source is group.
Bulk responses return results, one entry per operation in request order, so results[i] corresponds to operations[i], plus a meta object counting how many succeeded and failed. Operations are applied best-effort: a well-formed envelope always returns 200, and individual failures are reported in results[].
Want a walkthrough?
Review Hello World.
Pagination and Rate Limiting
Material APIs use cursor-based pagination: pass the
nextCursorvalue from one response as thecursorparameter in the next request.The
limitparameter controls page size and is locked into the cursor, so later pages keep the page size of the first request.When
hasMoreis false andnextCursoris null, you've reached the last page.
Retrieves a paginated list of directory groups (Google groups, Google org units, Microsoft groups, Okta groups) synced from a provider. Filter by type, member account, per-setting overrides, and effective settings, and sort by name or member count.
Material Security API key
The pagination cursor returned in a previous response. Pass this value to retrieve the next page of results.
eyJ2IjoxLCJvIjoyNSwibCI6MjV9The maximum number of items to return per page.
25Loose match on the group's name, description, email address, or org-unit path.
engFilter to these exact email addresses, comma-separated.
eng@example.comFilter by the kind of directory group: okta (Okta), google_group (Google Group), google_org_unit (Google Org Unit), or microsoft_group (Microsoft Group).
google_groupPossible values: Filter to the groups that any of these accounts belong to, as comma-separated encoded account IDs (format acct.1.<base64>).
acct.1.ZXhhbXBsZV9pZF8xMjMFilter to groups that define at least one setting override of their own (true) or none at all (false).
Filter to groups that grant any of these roles to their members, comma-separated. Call GET /roles for the IDs available on your instance.
analystFilter by the group's own emailSync override: on or off (the group's override sets that value), or overridden (the group defines an override, whatever the value). Matches the group's own override, not the value it inherits.
Filter by the group's own fileSync override: on or off (the group's override sets that value), or overridden (the group defines an override, whatever the value). Matches the group's own override, not the value it inherits.
Filter by the group's own emailThreatRemediation override: on or off (the group's override sets that value), or overridden (the group defines an override, whatever the value). Matches the group's own override, not the value it inherits.
Filter by the group's own fileRemediation override: on or off (the group's override sets that value), or overridden (the group defines an override, whatever the value). Matches the group's own override, not the value it inherits.
Filter by the group's own sensitiveEmailRedaction override: on or off (the group's override sets that value), or overridden (the group defines an override, whatever the value). Matches the group's own override, not the value it inherits.
Filter by the group's own passwordResetProtection override: on or off (the group's override sets that value), or overridden (the group defines an override, whatever the value). Matches the group's own override, not the value it inherits.
Filter by the group's own oauthAppRemediation override: on or off (the group's override sets that value), or overridden (the group defines an override, whatever the value). Matches the group's own override, not the value it inherits.
Filter by the group's own emailBombProtection override: on or off (the group's override sets that value), or overridden (the group defines an override, whatever the value). Matches the group's own override, not the value it inherits.
Sort field, e.g. name:asc or memberCount:desc. A single field only.
name:ascSuccessful response
Bad request: invalid parameters or request body
Unauthorized: missing or invalid API key
Forbidden: the API key doesn't have permission to perform this action
Not found: the requested resource doesn't exist
Too many requests: the client has exceeded a rate limit and should retry later
Internal server error
GET /api/v1/groups HTTP/1.1
Host: your-instance.on.material.security
x-material-client-secret: YOUR_API_KEY
Accept: */*
{
"meta": {
"totalCount": 1,
"limit": 1,
"hasMore": true,
"nextCursor": "text"
},
"items": [
{
"id": "grp.1.ZXhhbXBsZV9pZF8xMjM",
"type": "google_group",
"name": "Engineering",
"description": "All engineering staff",
"email": "engineering@example.com",
"aliases": [],
"memberCount": 42,
"roles": [
{
"id": "analyst",
"tenants": [
"tnt.1.ZXhhbXBsZV9pZF8xMjM"
]
}
],
"settings": [
{
"tenant": "tnt.1.ZXhhbXBsZV9pZF8xMjM",
"settings": {
"emailSync": {
"enabled": true,
"source": "group"
},
"fileSync": {
"enabled": true,
"source": "group"
},
"emailThreatRemediation": {
"enabled": true,
"source": "group"
},
"fileRemediation": {
"enabled": true,
"source": "group"
},
"sensitiveEmailRedaction": {
"enabled": true,
"source": "group"
},
"passwordResetProtection": {
"enabled": true,
"source": "group"
},
"oauthAppRemediation": {
"enabled": true,
"source": "group"
},
"emailBombProtection": {
"mode": "enabled",
"source": "group"
}
},
"licenses": {
"values": [
"advanced"
],
"source": "group"
}
}
],
"lastUpdatedAt": "2026-01-01T00:00:00.000Z"
}
]
}Retrieves the full details of a single group by its encoded ID, including type, name, email, member count, licenses, and effective settings with their source.
Material Security API key
The encoded ID of the group to retrieve. Format: grp.1.<base64>.
grp.1.ZXhhbXBsZV9pZF8xMjMPattern: ^[a-z]{1,6}\.[0-9]{1,2}\.[A-Za-z0-9_-]+$Successful response
A directory group (Google group, Google org unit, Microsoft group, or Okta group) synced from your provider. A group can span several tenants and its own override is instance-wide, so settings reports how that override resolves inside each tenant your token can access.
The encoded group ID. Format: grp.1.<base64>.
grp.1.ZXhhbXBsZV9pZF8xMjMThe kind of directory group: okta (Okta), google_group (Google Group), google_org_unit (Google Org Unit), or microsoft_group (Microsoft Group).
google_groupPossible values: The group's display name.
EngineeringThe group's description. An empty string if it has none.
All engineering staffThe group's primary email address. Null for Okta groups and Google org units, which have none.
engineering@example.comAdditional email addresses that reach this group.
Estimated number of accounts in the group.
42When Material last synced this group, in ISO 8601 format. Null if it has never synced.
Bad request: invalid parameters or request body
Unauthorized: missing or invalid API key
Forbidden: the API key doesn't have permission to perform this action
Not found: the requested resource doesn't exist
Too many requests: the client has exceeded a rate limit and should retry later
Internal server error
GET /api/v1/groups/{id} HTTP/1.1
Host: your-instance.on.material.security
x-material-client-secret: YOUR_API_KEY
Accept: */*
{
"id": "grp.1.ZXhhbXBsZV9pZF8xMjM",
"type": "google_group",
"name": "Engineering",
"description": "All engineering staff",
"email": "engineering@example.com",
"aliases": [],
"memberCount": 42,
"roles": [
{
"id": "analyst",
"tenants": [
"tnt.1.ZXhhbXBsZV9pZF8xMjM"
]
}
],
"settings": [
{
"tenant": "tnt.1.ZXhhbXBsZV9pZF8xMjM",
"settings": {
"emailSync": {
"enabled": true,
"source": "group"
},
"fileSync": {
"enabled": true,
"source": "group"
},
"emailThreatRemediation": {
"enabled": true,
"source": "group"
},
"fileRemediation": {
"enabled": true,
"source": "group"
},
"sensitiveEmailRedaction": {
"enabled": true,
"source": "group"
},
"passwordResetProtection": {
"enabled": true,
"source": "group"
},
"oauthAppRemediation": {
"enabled": true,
"source": "group"
},
"emailBombProtection": {
"mode": "enabled",
"source": "group"
}
},
"licenses": {
"values": [
"advanced"
],
"source": "group"
}
}
],
"lastUpdatedAt": "2026-01-01T00:00:00.000Z"
}Updates a group's license allocation, per-group setting overrides, and the roles it grants its members. Name, email, membership, and provider settings are read-only, since they're synced from your provider. Only provided fields change, and a setting value of default clears the group override so it inherits from a higher level. Changing roles additionally requires role-management permission, and a tenant-scoped administrator can only grant roles they're allowed to bind themselves, within their own tenants. Be careful: roles granted here apply to every member of the group, and nothing stops you from removing the last Super Admin, which is irreversible without Material support.
Material Security API key
The encoded ID of the group to retrieve. Format: grp.1.<base64>.
grp.1.ZXhhbXBsZV9pZF8xMjMPattern: ^[a-z]{1,6}\.[0-9]{1,2}\.[A-Za-z0-9_-]+$Successful response
A directory group (Google group, Google org unit, Microsoft group, or Okta group) synced from your provider. A group can span several tenants and its own override is instance-wide, so settings reports how that override resolves inside each tenant your token can access.
The encoded group ID. Format: grp.1.<base64>.
grp.1.ZXhhbXBsZV9pZF8xMjMThe kind of directory group: okta (Okta), google_group (Google Group), google_org_unit (Google Org Unit), or microsoft_group (Microsoft Group).
google_groupPossible values: The group's display name.
EngineeringThe group's description. An empty string if it has none.
All engineering staffThe group's primary email address. Null for Okta groups and Google org units, which have none.
engineering@example.comAdditional email addresses that reach this group.
Estimated number of accounts in the group.
42When Material last synced this group, in ISO 8601 format. Null if it has never synced.
Bad request: invalid parameters or request body
Unauthorized: missing or invalid API key
Forbidden: the API key doesn't have permission to perform this action
Not found: the requested resource doesn't exist
Too many requests: the client has exceeded a rate limit and should retry later
Internal server error
PATCH /api/v1/groups/{id} HTTP/1.1
Host: your-instance.on.material.security
x-material-client-secret: YOUR_API_KEY
Content-Type: application/json
Accept: */*
Content-Length: 355
{
"licenses": {
"values": [
"advanced"
]
},
"settings": {
"emailSync": "on",
"fileSync": "on",
"emailThreatRemediation": "on",
"fileRemediation": "on",
"sensitiveEmailRedaction": "on",
"passwordResetProtection": "on",
"oauthAppRemediation": "on",
"emailBombProtection": "enabled"
},
"roles": {
"assign": [
{
"id": "analyst",
"tenants": [
"tnt.1.ZXhhbXBsZV9pZF8xMjM"
]
}
],
"remove": [
"analyst"
]
}
}{
"id": "grp.1.ZXhhbXBsZV9pZF8xMjM",
"type": "google_group",
"name": "Engineering",
"description": "All engineering staff",
"email": "engineering@example.com",
"aliases": [],
"memberCount": 42,
"roles": [
{
"id": "analyst",
"tenants": [
"tnt.1.ZXhhbXBsZV9pZF8xMjM"
]
}
],
"settings": [
{
"tenant": "tnt.1.ZXhhbXBsZV9pZF8xMjM",
"settings": {
"emailSync": {
"enabled": true,
"source": "group"
},
"fileSync": {
"enabled": true,
"source": "group"
},
"emailThreatRemediation": {
"enabled": true,
"source": "group"
},
"fileRemediation": {
"enabled": true,
"source": "group"
},
"sensitiveEmailRedaction": {
"enabled": true,
"source": "group"
},
"passwordResetProtection": {
"enabled": true,
"source": "group"
},
"oauthAppRemediation": {
"enabled": true,
"source": "group"
},
"emailBombProtection": {
"mode": "enabled",
"source": "group"
}
},
"licenses": {
"values": [
"advanced"
],
"source": "group"
}
}
],
"lastUpdatedAt": "2026-01-01T00:00:00.000Z"
}Retrieves the paginated list of accounts that belong to a specific group. Each member is returned as a full account object, equivalent to filtering the accounts list by this group.
Material Security API key
The encoded ID of the group to retrieve. Format: grp.1.<base64>.
grp.1.ZXhhbXBsZV9pZF8xMjMPattern: ^[a-z]{1,6}\.[0-9]{1,2}\.[A-Za-z0-9_-]+$The pagination cursor returned in a previous response. Pass this value to retrieve the next page of results.
eyJ2IjoxLCJvIjoyNSwibCI6MjV9The maximum number of items to return per page.
25Successful response
Bad request: invalid parameters or request body
Unauthorized: missing or invalid API key
Forbidden: the API key doesn't have permission to perform this action
Not found: the requested resource doesn't exist
Too many requests: the client has exceeded a rate limit and should retry later
Internal server error
GET /api/v1/groups/{id}/members HTTP/1.1
Host: your-instance.on.material.security
x-material-client-secret: YOUR_API_KEY
Accept: */*
{
"meta": {
"totalCount": 1,
"limit": 1,
"hasMore": true,
"nextCursor": "text"
},
"items": [
{
"id": "acct.1.ZXhhbXBsZV9pZF8xMjM",
"type": "google",
"displayName": "Jane Doe",
"givenName": "Jane",
"familyName": "Doe",
"email": "jane@example.com",
"aliases": [
"jane.doe@example.com"
],
"organization": "Engineering",
"vip": {
"enabled": true,
"emailAliases": [],
"displayNames": []
},
"licenses": {
"values": [
"advanced",
"ato_resilience"
],
"source": "group",
"sourceGroups": [
{
"id": "grp.1.ZXhhbXBsZV9pZF8xMjM",
"name": "Engineering"
}
],
"sourceTenant": "tnt.1.ZXhhbXBsZV9pZF8xMjM",
"requireMailbox": {
"enabled": true,
"source": "group",
"sourceGroups": [
{
"id": "grp.1.ZXhhbXBsZV9pZF8xMjM",
"name": "Engineering"
}
],
"sourceTenant": "tnt.1.ZXhhbXBsZV9pZF8xMjM"
}
},
"roles": [
{
"id": "analyst",
"tenants": [
"tnt.1.ZXhhbXBsZV9pZF8xMjM"
],
"source": "direct",
"groupId": "grp.1.ZXhhbXBsZV9pZF8xMjM"
}
],
"settings": {
"emailSync": {
"enabled": true,
"source": "group",
"sourceGroups": [
{
"id": "grp.1.ZXhhbXBsZV9pZF8xMjM",
"name": "Engineering"
}
],
"sourceTenant": "tnt.1.ZXhhbXBsZV9pZF8xMjM"
},
"fileSync": {
"enabled": true,
"source": "group",
"sourceGroups": [
{
"id": "grp.1.ZXhhbXBsZV9pZF8xMjM",
"name": "Engineering"
}
],
"sourceTenant": "tnt.1.ZXhhbXBsZV9pZF8xMjM"
},
"emailThreatRemediation": {
"enabled": true,
"source": "group",
"sourceGroups": [
{
"id": "grp.1.ZXhhbXBsZV9pZF8xMjM",
"name": "Engineering"
}
],
"sourceTenant": "tnt.1.ZXhhbXBsZV9pZF8xMjM"
},
"fileRemediation": {
"enabled": true,
"source": "group",
"sourceGroups": [
{
"id": "grp.1.ZXhhbXBsZV9pZF8xMjM",
"name": "Engineering"
}
],
"sourceTenant": "tnt.1.ZXhhbXBsZV9pZF8xMjM"
},
"sensitiveEmailRedaction": {
"enabled": true,
"source": "group",
"sourceGroups": [
{
"id": "grp.1.ZXhhbXBsZV9pZF8xMjM",
"name": "Engineering"
}
],
"sourceTenant": "tnt.1.ZXhhbXBsZV9pZF8xMjM"
},
"passwordResetProtection": {
"enabled": true,
"source": "group",
"sourceGroups": [
{
"id": "grp.1.ZXhhbXBsZV9pZF8xMjM",
"name": "Engineering"
}
],
"sourceTenant": "tnt.1.ZXhhbXBsZV9pZF8xMjM"
},
"oauthAppRemediation": {
"enabled": true,
"source": "group",
"sourceGroups": [
{
"id": "grp.1.ZXhhbXBsZV9pZF8xMjM",
"name": "Engineering"
}
],
"sourceTenant": "tnt.1.ZXhhbXBsZV9pZF8xMjM"
},
"emailBombProtection": {
"mode": "enabled",
"source": "group",
"sourceGroups": [
{
"id": "grp.1.ZXhhbXBsZV9pZF8xMjM",
"name": "Engineering"
}
],
"sourceTenant": "tnt.1.ZXhhbXBsZV9pZF8xMjM"
}
},
"mailbox": {
"status": "enabled",
"messageCount": 3543
},
"providerStatus": "active",
"lastSyncedAt": "2026-01-01T00:00:00.000Z",
"groups": {
"meta": {
"totalCount": 1,
"limit": 1,
"hasMore": true,
"nextCursor": "text"
},
"items": [
{
"id": "grp.1.ZXhhbXBsZV9pZF8xMjM",
"name": "Engineering"
}
]
}
}
]
}Applies up to 200 group update operations in one request, best-effort with per-item results in request order (results[i] corresponds to operations[i]). A well-formed envelope always returns 200; individual failures are reported in results[].
Material Security API key
Successful response
Per-operation result, in the same order as the request.
Bad request: invalid parameters or request body
Unauthorized: missing or invalid API key
Forbidden: the API key doesn't have permission to perform this action
Not found: the requested resource doesn't exist
Too many requests: the client has exceeded a rate limit and should retry later
Internal server error
POST /api/v1/groups/bulk HTTP/1.1
Host: your-instance.on.material.security
x-material-client-secret: YOUR_API_KEY
Content-Type: application/json
Accept: */*
Content-Length: 430
{
"operations": [
{
"method": "text",
"id": "grp.1.ZXhhbXBsZV9pZF8xMjM",
"body": {
"licenses": {
"values": [
"advanced"
]
},
"settings": {
"emailSync": "on",
"fileSync": "on",
"emailThreatRemediation": "on",
"fileRemediation": "on",
"sensitiveEmailRedaction": "on",
"passwordResetProtection": "on",
"oauthAppRemediation": "on",
"emailBombProtection": "enabled"
},
"roles": {
"assign": [
{
"id": "analyst",
"tenants": [
"tnt.1.ZXhhbXBsZV9pZF8xMjM"
]
}
],
"remove": [
"analyst"
]
}
}
}
]
}{
"results": [
{
"status": "text",
"index": 1,
"id": "text",
"group": {
"id": "grp.1.ZXhhbXBsZV9pZF8xMjM",
"type": "google_group",
"name": "Engineering",
"description": "All engineering staff",
"email": "engineering@example.com",
"aliases": [],
"memberCount": 42,
"roles": [
{
"id": "analyst",
"tenants": [
"tnt.1.ZXhhbXBsZV9pZF8xMjM"
]
}
],
"settings": [
{
"tenant": "tnt.1.ZXhhbXBsZV9pZF8xMjM",
"settings": {
"emailSync": {
"enabled": true,
"source": "group"
},
"fileSync": {
"enabled": true,
"source": "group"
},
"emailThreatRemediation": {
"enabled": true,
"source": "group"
},
"fileRemediation": {
"enabled": true,
"source": "group"
},
"sensitiveEmailRedaction": {
"enabled": true,
"source": "group"
},
"passwordResetProtection": {
"enabled": true,
"source": "group"
},
"oauthAppRemediation": {
"enabled": true,
"source": "group"
},
"emailBombProtection": {
"mode": "enabled",
"source": "group"
}
},
"licenses": {
"values": [
"advanced"
],
"source": "group"
}
}
],
"lastUpdatedAt": "2026-01-01T00:00:00.000Z"
}
}
],
"meta": {
"succeeded": 1,
"failed": 1
}
}Last updated
Was this helpful?

