Skip to content

feat(backend): Add directory group webhook event types - #10378

Open
mauricioabreu wants to merge 1 commit into
mainfrom
mauricio-antunes/directory-group-webhook-types
Open

mauricioabreu wants to merge 1 commit into
mainfrom
mauricio-antunes/directory-group-webhook-types

Conversation

@mauricioabreu

@mauricioabreu mauricioabreu commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

Description

Directory Sync sends directoryGroup.created, .updated, .deleted and directoryGroupMembership.created, .deleted, but WebhookEvent has no members for them, so verifyWebhook() cannot narrow them and handlers have to cast the payload.

Adds DirectoryGroupWebhookEvent and DirectoryGroupMembershipWebhookEvent to the union, with their payload types. The deleted membership carries cause (group_deleted or member_removed). The membership payload has no id, so it declares id?: never to keep event.data.id typed as string | undefined across the union, which an existing type test guards.

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

@changeset-bot

changeset-bot Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 5452ee4

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 11 packages
Name Type
@clerk/backend Minor
@clerk/astro Patch
@clerk/express Patch
@clerk/fastify Patch
@clerk/hono Patch
@clerk/nextjs Patch
@clerk/nuxt Patch
@clerk/react-router Patch
@clerk/tanstack-react-start Patch
@clerk/testing Patch
@clerk/swingset Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel

vercel Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
clerk-js-sandbox Ready Ready Preview Oct 23, 2026 1:28am UTC
swingset Ready Ready Preview Oct 23, 2026 1:28am UTC

Request Review

@coderabbitai

coderabbitai Bot commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Source mode: Auto
  • Repository: clerk/javascript
  • Branch: main
  • File: .coderabbit.yaml
  • Commit: 42664a9
  • Layers: Repository YAML (base), Organization UI (inherited)
  • Review profile: ASSERTIVE
  • Plan: Team
  • Run ID: a9210ca4-1b13-45da-8752-7c9195c0ffd4
📥 Commits

Reviewing files that changed from the base of the PR and between 42664a9 and 5452ee4.

📒 Files selected for processing: 5
  • .changeset/directory-group-webhook-events.md
  • packages/backend/src/__tests__/directory-group-webhooks.test.ts
  • packages/backend/src/api/resources/JSON.ts
  • packages/backend/src/api/resources/Webhooks.ts
  • packages/backend/src/index.ts
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

Included review availability: This review used your included allowance. 5 included reviews remain after this review. Your included PR review attempts over the past 7 days set your current allowance at 6 reviews per hour.

📝 Walkthrough

The backend adds payload interfaces and webhook event types for directory groups and directory group memberships. The event types join the WebhookEvent union, and the new payload and event types are exported from the package. Type-level tests check event membership and payload fields, including deletion causes and nullable user IDs.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested reviewers: jescalan

Merge Risk: ⚪ Minimal · up to 5452e

The new webhook types, exports, and type-level tests have no identified merge-blocking issue; the change is ready for normal checks.

Pre-merge checks: Passed 5
Check name Status Explanation
Title check Passed The title clearly identifies the addition of Directory Group webhook event types, which is the main change.
Description check Passed The description explains the new webhook event types, payload behavior, and stated test and build results.
Docstring Coverage Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 4…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 4 files. (1 skipped: 1 unsupported.)

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Warning

Linked repositories: Some configured repositories could not be included in this review. Cross-repository analysis may be incomplete. Please check linked-repository access and settings.

Comment @coderabbitai help to get the list of available commands.

@pkg-pr-new

pkg-pr-new Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

@clerk/astro

npm i https://pkg.pr.new/@clerk/astro@10378

@clerk/backend

npm i https://pkg.pr.new/@clerk/backend@10378

@clerk/chrome-extension

npm i https://pkg.pr.new/@clerk/chrome-extension@10378

@clerk/clerk-js

npm i https://pkg.pr.new/@clerk/clerk-js@10378

@clerk/electron

npm i https://pkg.pr.new/@clerk/electron@10378

@clerk/electron-passkeys

npm i https://pkg.pr.new/@clerk/electron-passkeys@10378

@clerk/eslint-plugin

npm i https://pkg.pr.new/@clerk/eslint-plugin@10378

@clerk/expo

npm i https://pkg.pr.new/@clerk/expo@10378

@clerk/expo-biometrics

npm i https://pkg.pr.new/@clerk/expo-biometrics@10378

@clerk/expo-google-signin

npm i https://pkg.pr.new/@clerk/expo-google-signin@10378

@clerk/expo-native-components

npm i https://pkg.pr.new/@clerk/expo-native-components@10378

@clerk/expo-passkeys

npm i https://pkg.pr.new/@clerk/expo-passkeys@10378

@clerk/express

npm i https://pkg.pr.new/@clerk/express@10378

@clerk/fastify

npm i https://pkg.pr.new/@clerk/fastify@10378

@clerk/hono

npm i https://pkg.pr.new/@clerk/hono@10378

@clerk/localizations

npm i https://pkg.pr.new/@clerk/localizations@10378

@clerk/mosaic

npm i https://pkg.pr.new/@clerk/mosaic@10378

@clerk/nextjs

npm i https://pkg.pr.new/@clerk/nextjs@10378

@clerk/nuxt

npm i https://pkg.pr.new/@clerk/nuxt@10378

@clerk/react

npm i https://pkg.pr.new/@clerk/react@10378

@clerk/react-router

npm i https://pkg.pr.new/@clerk/react-router@10378

@clerk/shared

npm i https://pkg.pr.new/@clerk/shared@10378

@clerk/tanstack-react-start

npm i https://pkg.pr.new/@clerk/tanstack-react-start@10378

@clerk/testing

npm i https://pkg.pr.new/@clerk/testing@10378

@clerk/ui

npm i https://pkg.pr.new/@clerk/ui@10378

@clerk/upgrade

npm i https://pkg.pr.new/@clerk/upgrade@10378

@clerk/vue

npm i https://pkg.pr.new/@clerk/vue@10378

commit: 5452ee4

The directoryGroup.* and directoryGroupMembership.* events Directory Sync sends are now in the public webhook reference, but verifyWebhook() could not narrow them because WebhookEvent had no members for them. The membership payload declares an optional id it never sets, so event.data.id keeps its type across the union.
@github-actions

Copy link
Copy Markdown
Contributor

API Changes Report

Generated by Break Check on 2026-10-23T02:10:46.141Z

Summary

Metric Count
Packages analyzed 20
Packages with changes 1
🔴 Breaking changes 0
🟡 Non-breaking changes 2
🟢 Additions 20

🤖 This report was reviewed by claude-sonnet-4-6.


@clerk/backend

Current version: 3.26.1
Recommended bump: MINOR → 3.27.0

Subpath .

🟡 Non-breaking Changes (1)

Modified: WebhookEvent
- export type WebhookEvent = UserWebhookEvent | SessionWebhookEvent | EmailWebhookEvent | EmailDeliveryWebhookEvent | SMSWebhookEvent | OrganizationWebhookEvent | OrganizationDomainWebhookEvent | OrganizationMembershipWebhookEvent | OrganizationInvitationWebhookEvent | OrganizationInvitationAcceptedWebhookEvent | RoleWebhookEvent | PermissionWebhookEvent | WaitlistEntryWebhookEvent | BillingPaymentAttemptWebhookEvent | BillingSubscriptionWebhookEvent | BillingSubscriptionItemWebhookEvent;
+ export type WebhookEvent = UserWebhookEvent | SessionWebhookEvent | EmailWebhookEvent | EmailDeliveryWebhookEvent | SMSWebhookEvent | DirectoryGroupWebhookEvent | DirectoryGroupMembershipWebhookEvent | OrganizationWebhookEvent | OrganizationDomainWebhookEvent | OrganizationMembershipWebhookEvent | OrganizationInvitationWebhookEvent | OrganizationInvitationAcceptedWebhookEvent | RoleWebhookEvent | PermissionWebhookEvent | WaitlistEntryWebhookEvent | BillingPaymentAttemptWebhookEvent | BillingSubscriptionWebhookEvent | BillingSubscriptionItemWebhookEvent;

Static analyzer: Breaking change in type alias WebhookEvent: Type changed: import("@clerk/backend").BillingPaymentAttemptWebhookEvent|import("@clerk/backend").BillingSubscriptionItemWebhookEvent… → import("@clerk/backend").BillingPaymentAttemptWebhookEvent|import("@clerk/backend").BillingSubscriptionItemWebhookEvent…

🤖 AI review (reclassified as non-breaking) (95%): Adding new union members (DirectoryGroupWebhookEvent and DirectoryGroupMembershipWebhookEvent) to WebhookEvent is non-breaking for consumers: verifyWebhook returns Promise<WebhookEvent> (output position), so widening the return type only requires consumers to handle additional variants, and exhaustive switch consumers will need to add cases but their existing code still compiles; no existing well-typed consumer code stops compiling.

🟢 Additions (18)

Click to expand 18 changes
Added: DeletedDirectoryGroupMembershipWebhookEventJSON
+ export interface DeletedDirectoryGroupMembershipWebhookEventJSON extends DirectoryGroupMembershipWebhookEventJSON

Added interface DeletedDirectoryGroupMembershipWebhookEventJSON

Added: DeletedDirectoryGroupMembershipWebhookEventJSON.cause
+ cause: 'group_deleted' | 'member_removed';

Added property DeletedDirectoryGroupMembershipWebhookEventJSON.cause

Added: DirectoryGroupMembershipWebhookEvent
+ export type DirectoryGroupMembershipWebhookEvent = Webhook<'directoryGroupMembership.created', DirectoryGroupMembershipWebhookEventJSON> | Webhook<'directoryGroupMembership.deleted', DeletedDirectoryGroupMembershipWebhookEventJSON>;

Added type alias DirectoryGroupMembershipWebhookEvent

Added: DirectoryGroupMembershipWebhookEventJSON
+ export interface DirectoryGroupMembershipWebhookEventJSON

Added interface DirectoryGroupMembershipWebhookEventJSON

Added: DirectoryGroupMembershipWebhookEventJSON.directory_id
+ directory_id: string;

Added property DirectoryGroupMembershipWebhookEventJSON.directory_id

Added: DirectoryGroupMembershipWebhookEventJSON.directory_user_id
+ directory_user_id: string;

Added property DirectoryGroupMembershipWebhookEventJSON.directory_user_id

Added: DirectoryGroupMembershipWebhookEventJSON.group
+ group: {
+         object: typeof ObjectType.DirectoryGroup;
+         id: string;
+         display_name: string;
+     };

Added property DirectoryGroupMembershipWebhookEventJSON.group

Added: DirectoryGroupMembershipWebhookEventJSON.id
+ id?: never;

Added property DirectoryGroupMembershipWebhookEventJSON.id

Added: DirectoryGroupMembershipWebhookEventJSON.object
+ object: typeof ObjectType.DirectoryGroupMembership;

Added property DirectoryGroupMembershipWebhookEventJSON.object

Added: DirectoryGroupMembershipWebhookEventJSON.updated_at
+ updated_at: number;

Added property DirectoryGroupMembershipWebhookEventJSON.updated_at

Added: DirectoryGroupMembershipWebhookEventJSON.user_id
+ user_id: string | null;

Added property DirectoryGroupMembershipWebhookEventJSON.user_id

Added: DirectoryGroupWebhookEvent
+ export type DirectoryGroupWebhookEvent = Webhook<'directoryGroup.created' | 'directoryGroup.updated' | 'directoryGroup.deleted', DirectoryGroupWebhookEventJSON>;

Added type alias DirectoryGroupWebhookEvent

Added: DirectoryGroupWebhookEventJSON
+ export interface DirectoryGroupWebhookEventJSON

Added interface DirectoryGroupWebhookEventJSON

Added: DirectoryGroupWebhookEventJSON.directory_id
+ directory_id: string;

Added property DirectoryGroupWebhookEventJSON.directory_id

Added: DirectoryGroupWebhookEventJSON.display_name
+ display_name: string;

Added property DirectoryGroupWebhookEventJSON.display_name

Added: DirectoryGroupWebhookEventJSON.id
+ id: string;

Added property DirectoryGroupWebhookEventJSON.id

Added: DirectoryGroupWebhookEventJSON.object
+ object: typeof ObjectType.DirectoryGroup;

Added property DirectoryGroupWebhookEventJSON.object

Added: DirectoryGroupWebhookEventJSON.updated_at
+ updated_at: number;

Added property DirectoryGroupWebhookEventJSON.updated_at

Subpath ./webhooks

🟡 Non-breaking Changes (1)

Modified: WebhookEvent
- export type WebhookEvent = UserWebhookEvent | SessionWebhookEvent | EmailWebhookEvent | EmailDeliveryWebhookEvent | SMSWebhookEvent | OrganizationWebhookEvent | OrganizationDomainWebhookEvent | OrganizationMembershipWebhookEvent | OrganizationInvitationWebhookEvent | OrganizationInvitationAcceptedWebhookEvent | RoleWebhookEvent | PermissionWebhookEvent | WaitlistEntryWebhookEvent | BillingPaymentAttemptWebhookEvent | BillingSubscriptionWebhookEvent | BillingSubscriptionItemWebhookEvent;
+ export type WebhookEvent = UserWebhookEvent | SessionWebhookEvent | EmailWebhookEvent | EmailDeliveryWebhookEvent | SMSWebhookEvent | DirectoryGroupWebhookEvent | DirectoryGroupMembershipWebhookEvent | OrganizationWebhookEvent | OrganizationDomainWebhookEvent | OrganizationMembershipWebhookEvent | OrganizationInvitationWebhookEvent | OrganizationInvitationAcceptedWebhookEvent | RoleWebhookEvent | PermissionWebhookEvent | WaitlistEntryWebhookEvent | BillingPaymentAttemptWebhookEvent | BillingSubscriptionWebhookEvent | BillingSubscriptionItemWebhookEvent;

Static analyzer: Breaking change in type alias WebhookEvent: Type changed: import("@clerk/backend").BillingPaymentAttemptWebhookEvent|import("@clerk/backend").BillingSubscriptionItemWebhookEvent… → import("@clerk/backend").BillingPaymentAttemptWebhookEvent|import("@clerk/backend").BillingSubscriptionItemWebhookEvent…

🤖 AI review (reclassified as non-breaking) (95%): WebhookEvent is only used as an output type (the resolved value of Promise<WebhookEvent> returned by verifyWebhook); adding two new union members (DirectoryGroupWebhookEvent and DirectoryGroupMembershipWebhookEvent) widens the output type, which is safe for existing consumers who pattern-match on known discriminants and simply won't encounter the new variants.

🟢 Additions (2)

Added: DirectoryGroupMembershipWebhookEvent
+ export type DirectoryGroupMembershipWebhookEvent = Webhook<'directoryGroupMembership.created', DirectoryGroupMembershipWebhookEventJSON> | Webhook<'directoryGroupMembership.deleted', DeletedDirectoryGroupMembershipWebhookEventJSON>;

Added type alias DirectoryGroupMembershipWebhookEvent

Added: DirectoryGroupWebhookEvent
+ export type DirectoryGroupWebhookEvent = Webhook<'directoryGroup.created' | 'directoryGroup.updated' | 'directoryGroup.deleted', DirectoryGroupWebhookEventJSON>;

Added type alias DirectoryGroupWebhookEvent


Report generated by Break Check

Last ran on 5452ee4.

This branch was successfully deployed

2 active deployments
Preview – swingset — 5452ee48 Deployed Oct 23, 2026 by vercel[bot]
Preview – clerk-js-sandbox — 5452ee48 Deployed Oct 23, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant