# Group webhooks, group reads, and pause for Directory Sync

[Directory Sync](https://clerk.com/docs/guides/configure/auth-strategies/enterprise-connections/directory-sync.md) has three new capabilities: webhooks for group changes, Backend API reads for a group and its members, and a pause switch for directories. Group pushes from the identity provider also produce fewer events than before.

## Group webhooks

Directory Sync keeps Organization memberships and Roles in step with your identity provider, but until now the groups themselves were hard to observe. That matters most when your application maps identity provider groups onto its own objects, such as teams or projects, rather than onto Clerk Organizations alone. The only signal was the `user.updated` event Directory Sync fires for each member it touches. Your webhook handler fetched the user, read their current groups, and worked out what changed. When an IT admin deleted a group in the identity provider, that produced the same events as every member leaving at once, and nothing in them told the two apart.

Six webhook events now report group changes directly:

- `directoryGroup.created`: the identity provider created a group.
- `directoryGroup.updated`: the identity provider renamed a group. The payload carries the new `display_name`.
- `directoryGroup.deleted`: the identity provider deleted a group, or it stopped appearing in a pull sync. The payload carries the last known name.
- `directoryGroup.synced`: the identity provider pushed a group in full, whether or not anything changed. Okta sends that push on **Push now** and on its periodic re-push of unchanged groups, so the event fires once per group per push. It isn't sent for pull-synced directories such as Google Workspace.
- `directoryGroupMembership.created`: a user was added to a group.
- `directoryGroupMembership.deleted`: a user was removed from a group. `cause` says why: `member_removed` when the provider took the user out, `group_deleted` when the whole group went away.

Every payload names the `directory_id` and the group's `id` and `display_name`. Membership payloads also carry the member's `directory_user_id` and the `user_id` of the Clerk user they're linked to, which is `null` until that user has been provisioned.

Webhooks can arrive out of order. When two events describe the same group or membership, keep the one with the later `updated_at`, which is when the directory recorded the change.

## Read a group and its members

Two reads join the [Directories](https://clerk.com/docs/reference/backend-api/tag/directories) endpoints:

- [`GET /v1/directories/{directory_id}/groups/{group_id}`](https://clerk.com/docs/reference/backend-api/tag/directories/GET/directories/%7Bdirectory_id%7D/groups/%7Bgroup_id%7D) returns one group as the identity provider reported it, and `404` once the provider has deleted it.
- [`GET /v1/directories/{directory_id}/groups/{group_id}/members`](https://clerk.com/docs/reference/backend-api/tag/directories/GET/directories/%7Bdirectory_id%7D/groups/%7Bgroup_id%7D/members) lists the group's members with cursor pagination, up to 500 per page. Each member carries the `user_id` of its Clerk user, or `null` if that user hasn't been provisioned yet.

A webhook handler that receives a `directoryGroup.*` event can fetch the group's current state with these reads instead of keeping its own copy of the directory.

## Fewer `user.updated` events on group pushes

Since October 20, a group push from the identity provider records only the members who joined or left. The per-user events a push produces, such as `directoryGroupMembership.created` and `user.updated`, cover those users alone. The group-level events don't depend on who changed: a rename sends `directoryGroup.updated`, and every push sends `directoryGroup.synced`, so a push with nothing changed sends that one event and nothing else. Before, every push rewrote the whole group, so every member counted as changed on every push, and large groups that Okta re-pushes every few minutes timed out.

If you relied on that fan-out to replay a group, for example by asking a customer to **Push now** in Okta so your application could rebuild its memberships, listen for `directoryGroup.synced` instead and page through the group with the members endpoint. That's one event per group per push, however many members the group has.

## Pause a directory

A directory can now be paused, from its page in the Clerk Dashboard or by sending `paused` to [`PATCH /v1/directories/{directory_id}`](https://clerk.com/docs/reference/backend-api/tag/directories/PATCH/directories/%7Bdirectory_id%7D). Directory responses include the flag. A paused directory rejects provisioning requests and skips scheduled syncs, but keeps the memberships it granted. After you resume a SCIM directory, trigger a resync from the identity provider so it pushes its current state. Requests it sent while the directory was paused were rejected, not queued. A pull-synced directory catches up on its next sync. Disabling a directory [withdraws the access it granted](https://clerk.com/docs/guides/configure/auth-strategies/enterprise-connections/directory-sync.md#directory-lifecycle-changes) instead, so pause when you want changes to stop landing for a while without touching anyone's access.
