Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .last-synced-sha
Original file line number Diff line number Diff line change
@@ -1 +1 @@
92db0495807c86fbbc4d45bd266a6c1f5bcbb59c
f908f520f9fcd63dfd42ed35b7f141a65b61609b
21 changes: 20 additions & 1 deletion .oagen-manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"version": 2,
"language": "dotnet",
"generatedAt": "2026-04-28T16:33:51.142Z",
"generatedAt": "2026-04-30T20:02:34.086Z",
"files": [
"src/WorkOS.net/Client/Utilities/EventSchemaDiscriminatorConverter.cs",
"src/WorkOS.net/Client/WorkOSClient.Generated.cs",
Expand Down Expand Up @@ -158,6 +158,9 @@
"src/WorkOS.net/Entities/DsyncGroupUserAdded.cs",
"src/WorkOS.net/Entities/DsyncGroupUserAddedData.cs",
"src/WorkOS.net/Entities/DsyncGroupUserRemoved.cs",
"src/WorkOS.net/Entities/DsyncTokenCreated.cs",
"src/WorkOS.net/Entities/DsyncTokenCreatedData.cs",
"src/WorkOS.net/Entities/DsyncTokenDeleted.cs",
"src/WorkOS.net/Entities/DsyncUserCreated.cs",
"src/WorkOS.net/Entities/DsyncUserDeleted.cs",
"src/WorkOS.net/Entities/DsyncUserUpdated.cs",
Expand Down Expand Up @@ -302,6 +305,7 @@
"src/WorkOS.net/Entities/UserManagementLoginRequest.cs",
"src/WorkOS.net/Entities/UserObject.cs",
"src/WorkOS.net/Entities/UserOrganizationMembershipBaseListData.cs",
"src/WorkOS.net/Entities/UserOrganizationMembershipBaseWithUser.cs",
"src/WorkOS.net/Entities/UserUpdated.cs",
"src/WorkOS.net/Entities/ValidateApiKey.cs",
"src/WorkOS.net/Entities/VaultByokKeyVerificationCompleted.cs",
Expand Down Expand Up @@ -466,6 +470,9 @@
"test/WorkOSTests/testdata/api_key_revoked_data_owner.json",
"test/WorkOSTests/testdata/api_key_revoked_nulls.json",
"test/WorkOSTests/testdata/api_key_validation_response.json",
"test/WorkOSTests/testdata/api_key_validation_response_api_key.json",
"test/WorkOSTests/testdata/api_key_validation_response_api_key_nulls.json",
"test/WorkOSTests/testdata/api_key_validation_response_api_key_owner.json",
"test/WorkOSTests/testdata/api_key_validation_response_nulls.json",
"test/WorkOSTests/testdata/api_key_with_value.json",
"test/WorkOSTests/testdata/api_key_with_value_nulls.json",
Expand Down Expand Up @@ -752,6 +759,14 @@
"test/WorkOSTests/testdata/dsync_group_user_removed.json",
"test/WorkOSTests/testdata/dsync_group_user_removed_data.json",
"test/WorkOSTests/testdata/dsync_group_user_removed_nulls.json",
"test/WorkOSTests/testdata/dsync_token_created.json",
"test/WorkOSTests/testdata/dsync_token_created_data.json",
"test/WorkOSTests/testdata/dsync_token_created_data_nulls.json",
"test/WorkOSTests/testdata/dsync_token_created_nulls.json",
"test/WorkOSTests/testdata/dsync_token_deleted.json",
"test/WorkOSTests/testdata/dsync_token_deleted_data.json",
"test/WorkOSTests/testdata/dsync_token_deleted_data_nulls.json",
"test/WorkOSTests/testdata/dsync_token_deleted_nulls.json",
"test/WorkOSTests/testdata/dsync_user_created.json",
"test/WorkOSTests/testdata/dsync_user_created_nulls.json",
"test/WorkOSTests/testdata/dsync_user_deleted.json",
Expand Down Expand Up @@ -914,6 +929,7 @@
"test/WorkOSTests/testdata/list_empty_user_invite.json",
"test/WorkOSTests/testdata/list_empty_user_organization_membership.json",
"test/WorkOSTests/testdata/list_empty_user_organization_membership_base_list_data.json",
"test/WorkOSTests/testdata/list_empty_user_organization_membership_base_with_user.json",
"test/WorkOSTests/testdata/list_empty_user_sessions_list_item.json",
"test/WorkOSTests/testdata/list_empty_webhook_endpoint_json.json",
"test/WorkOSTests/testdata/list_event_schema.json",
Expand All @@ -925,6 +941,7 @@
"test/WorkOSTests/testdata/list_user_invite.json",
"test/WorkOSTests/testdata/list_user_organization_membership.json",
"test/WorkOSTests/testdata/list_user_organization_membership_base_list_data.json",
"test/WorkOSTests/testdata/list_user_organization_membership_base_with_user.json",
"test/WorkOSTests/testdata/list_user_sessions_list_item.json",
"test/WorkOSTests/testdata/list_webhook_endpoint_json.json",
"test/WorkOSTests/testdata/magic_auth.json",
Expand Down Expand Up @@ -1145,6 +1162,8 @@
"test/WorkOSTests/testdata/user_organization_membership.json",
"test/WorkOSTests/testdata/user_organization_membership_base_list_data.json",
"test/WorkOSTests/testdata/user_organization_membership_base_list_data_nulls.json",
"test/WorkOSTests/testdata/user_organization_membership_base_with_user.json",
"test/WorkOSTests/testdata/user_organization_membership_base_with_user_nulls.json",
"test/WorkOSTests/testdata/user_organization_membership_nulls.json",
"test/WorkOSTests/testdata/user_sessions_impersonator.json",
"test/WorkOSTests/testdata/user_sessions_impersonator_nulls.json",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ public override object ReadJson(Newtonsoft.Json.JsonReader reader, Type objectTy
case "dsync.group.created": target = new DsyncGroupCreated(); break;
case "dsync.group.deleted": target = new DsyncGroupDeleted(); break;
case "dsync.group.updated": target = new DsyncGroupUpdated(); break;
case "dsync.token.created": target = new DsyncTokenCreated(); break;
case "dsync.token.deleted": target = new DsyncTokenDeleted(); break;
case "dsync.group.user_added": target = new DsyncGroupUserAdded(); break;
case "dsync.user.created": target = new DsyncUserCreated(); break;
case "dsync.user.deleted": target = new DsyncUserDeleted(); break;
Expand Down
2 changes: 1 addition & 1 deletion src/WorkOS.net/Entities/ApiKey.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace WorkOS
using System;
using System.Collections.Generic;

/// <summary>The API Key object if the value is valid, or `null` if invalid.</summary>
/// <summary>Represents an api key.</summary>
public class ApiKey
{

Expand Down
2 changes: 1 addition & 1 deletion src/WorkOS.net/Entities/ApiKeyCreatedDataOwner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
namespace WorkOS
{

/// <summary>The owner of the API key.</summary>
/// <summary>Represents an api key created data owner.</summary>
public class ApiKeyCreatedDataOwner
{

Expand Down
3 changes: 3 additions & 0 deletions src/WorkOS.net/Entities/DirectoryUser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ public class DirectoryUser
/// <summary>The last name of the user.</summary>
public string? LastName { get; set; }

/// <summary>The full name of the user.</summary>
public string? Name { get; set; }

/// <summary>A list of email addresses for the user.</summary>
[System.Obsolete("This field is deprecated.")]
public List<DirectoryUserEmail>? Emails { get; set; }
Expand Down
7 changes: 5 additions & 2 deletions src/WorkOS.net/Entities/DirectoryUserWithGroups.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ public class DirectoryUserWithGroups
/// <summary>The last name of the user.</summary>
public string? LastName { get; set; }

/// <summary>The full name of the user.</summary>
public string? Name { get; set; }

/// <summary>A list of email addresses for the user.</summary>
[System.Obsolete("This field is deprecated.")]
public List<DirectoryUserEmail>? Emails { get; set; }
Expand Down Expand Up @@ -69,8 +72,8 @@ public class DirectoryUserWithGroups
/// <summary>An ISO 8601 timestamp.</summary>
public DateTimeOffset UpdatedAt { get; set; }

/// <summary>The directory groups the user belongs to. Use the List Directory Groups endpoint with a user filter instead.</summary>
[System.Obsolete("This field is deprecated.")]
/// <summary>The directory groups the user belongs to. Deprecated: starting May 1, 2026, this field returns an empty array by default for newly created teams. Existing teams currently depending on this field should migrate to the new access pattern for better throughput performance — the field is unbounded by user, so users with many group memberships produce large, slow response payloads. Use the List Directory Groups endpoint with a `user` filter to fetch a user's group memberships.</summary>
[System.Obsolete("Deprecated. starting May 1, 2026, this field returns an empty array by default for newly created teams.")]
public List<DirectoryGroup> Groups { get; set; } = default!;

/// <summary>
Expand Down
15 changes: 15 additions & 0 deletions src/WorkOS.net/Entities/DsyncTokenCreated.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// This file is auto-generated by oagen. Do not edit.

namespace WorkOS
{
using System;

/// <summary>Represents a dsync token created.</summary>
public class DsyncTokenCreated : EventSchema
{

/// <summary>The event payload.</summary>
public new DsyncTokenCreatedData Data { get; set; } = default!;
public new EventContext? Context { get; set; }
}
}
32 changes: 32 additions & 0 deletions src/WorkOS.net/Entities/DsyncTokenCreatedData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// This file is auto-generated by oagen. Do not edit.

namespace WorkOS
{
using System;

/// <summary>The event payload.</summary>
public class DsyncTokenCreatedData
{

/// <summary>Distinguishes the directory token object.</summary>
public string Object { get; internal set; } = "directory_token";

/// <summary>Unique identifier of the directory token.</summary>
public string Id { get; set; } = default!;

/// <summary>The ID of the directory the token authenticates to.</summary>
public string DirectoryId { get; set; } = default!;

/// <summary>The ID of the organization the directory belongs to.</summary>
public string? OrganizationId { get; set; }

/// <summary>The trailing characters of the bearer token, for identification only. The full token value is never included in events.</summary>
public string TokenSuffix { get; set; } = default!;

/// <summary>An ISO 8601 timestamp.</summary>
public DateTimeOffset CreatedAt { get; set; }

/// <summary>The timestamp at which the token expires, or null for tokens without a scheduled expiration. Used during rotation to indicate the grace window for the outgoing token.</summary>
public DateTimeOffset? ExpiresAt { get; set; }
}
}
15 changes: 15 additions & 0 deletions src/WorkOS.net/Entities/DsyncTokenDeleted.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// This file is auto-generated by oagen. Do not edit.

namespace WorkOS
{
using System;

/// <summary>Represents a dsync token deleted.</summary>
public class DsyncTokenDeleted : EventSchema
{

/// <summary>The event payload.</summary>
public new DsyncTokenCreatedData Data { get; set; } = default!;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 DsyncTokenDeleted.Data typed as DsyncTokenCreatedData

DsyncTokenDeleted reuses DsyncTokenCreatedData for its Data property. While both events share the same directory-token payload shape today, naming the delete event's data type after the create event is misleading — callers inspecting event.Data.GetType() or reading the property signature will see DsyncTokenCreatedData, which could cause confusion or misdirection when the schemas diverge in the future.

A dedicated DsyncTokenDeletedData class (or at minimum a shared DirectoryTokenData base) would make the intent clearer, consistent with how the rest of the SDK models paired event types (e.g., separate Data types per event class).

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

public new EventContext? Context { get; set; }
}
}
3 changes: 3 additions & 0 deletions src/WorkOS.net/Entities/DsyncUserUpdatedData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ public class DsyncUserUpdatedData
/// <summary>The last name of the user.</summary>
public string? LastName { get; set; }

/// <summary>The full name of the user.</summary>
public string? Name { get; set; }

/// <summary>A list of email addresses for the user.</summary>
[System.Obsolete("This field is deprecated.")]
public List<DirectoryUserEmail>? Emails { get; set; }
Expand Down
3 changes: 3 additions & 0 deletions src/WorkOS.net/Entities/OrganizationMembership.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ public class OrganizationMembership
/// <summary>The primary role assigned to the user within the organization.</summary>
public AddRolePermission Role { get; set; } = default!;

/// <summary>The user that belongs to the organization through this membership.</summary>
public User User { get; set; } = default!;
Comment on lines +49 to +50
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Non-nullable User may silently be null

User User { get; set; } = default! uses the null-forgiving operator to suppress compiler warnings, but if any existing endpoint that returns OrganizationMembership doesn't embed the user object (e.g., older API responses, or endpoints that don't expand user data), accessing .User will throw a NullReferenceException at runtime with no compile-time warning.

If the API only conditionally includes user, the property should be declared nullable (User? User). If it is always present, this is fine — but even then, the _nulls test fixture (organization_membership_nulls.json) now also always includes a fully populated user object, meaning the null case for this field isn't covered by any test.


/// <summary>
/// Typed accessor for <see cref="CustomAttributes"/>. Returns the value stored under
/// <paramref name="key"/> coerced to <typeparamref name="T"/>, or the default
Expand Down
3 changes: 3 additions & 0 deletions src/WorkOS.net/Entities/Profile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ public class Profile
/// <summary>The user's last name.</summary>
public string? LastName { get; set; }

/// <summary>The user's full name.</summary>
public string? Name { get; set; }

/// <summary>The role assigned to the user within the organization, if applicable.</summary>
public AddRolePermission? Role { get; set; }

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// This file is auto-generated by oagen. Do not edit.

namespace WorkOS
{
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using STJS = System.Text.Json.Serialization;

/// <summary>Represents an user organization membership base with user.</summary>
public class UserOrganizationMembershipBaseWithUser
{

/// <summary>Distinguishes the organization membership object.</summary>
public string Object { get; internal set; } = "organization_membership";

/// <summary>The unique ID of the organization membership.</summary>
public string Id { get; set; } = default!;

/// <summary>The ID of the user.</summary>
public string UserId { get; set; } = default!;

/// <summary>The ID of the organization which the user belongs to.</summary>
public string OrganizationId { get; set; } = default!;

/// <summary>The status of the organization membership. One of `active`, `inactive`, or `pending`.</summary>
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
[STJS.JsonIgnore(Condition = STJS.JsonIgnoreCondition.WhenWritingDefault)]
public OrganizationMembershipCreatedDataStatus Status { get; set; }

/// <summary>Whether this organization membership is managed by a directory sync connection.</summary>
public bool DirectoryManaged { get; set; }

/// <summary>The name of the organization which the user belongs to.</summary>
public string? OrganizationName { get; set; }

/// <summary>An object containing IdP-sourced attributes from the linked [Directory User](https://workos.com/docs/reference/directory-sync/directory-user) or [SSO Profile](https://workos.com/docs/reference/sso/profile). Directory User attributes take precedence when both are linked.</summary>
public Dictionary<string, object>? CustomAttributes { get; set; }

/// <summary>An ISO 8601 timestamp.</summary>
public DateTimeOffset CreatedAt { get; set; }

/// <summary>An ISO 8601 timestamp.</summary>
public DateTimeOffset UpdatedAt { get; set; }

/// <summary>The user that belongs to the organization through this membership.</summary>
public User User { get; set; } = default!;

/// <summary>
/// Typed accessor for <see cref="CustomAttributes"/>. Returns the value stored under
/// <paramref name="key"/> coerced to <typeparamref name="T"/>, or the default
/// value when the key is missing or the value is not convertible.
/// </summary>
/// <typeparam name="T">Expected value type.</typeparam>
/// <param name="key">The key to look up.</param>
public T? GetCustomAttributesAttribute<T>(string key)
{
if (this.CustomAttributes == null)
{
return default;
}

if (!this.CustomAttributes.TryGetValue(key, out var value))
{
return default;
}

if (value is T typed)
{
return typed;
}

if (value is Newtonsoft.Json.Linq.JToken token)
{
return token.ToObject<T>();
}

if (value is System.Text.Json.JsonElement element)
{
return System.Text.Json.JsonSerializer.Deserialize<T>(element.GetRawText());
}

return default;
}
}
}
2 changes: 2 additions & 0 deletions src/WorkOS.net/Enums/EventContextActorSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ public enum EventContextActorSource
Api,
[EnumMember(Value = "dashboard")]
Dashboard,
[EnumMember(Value = "admin_portal")]
AdminPortal,
[EnumMember(Value = "system")]
System,
}
Expand Down
Loading