### Install WorkOS Go Library Source: https://github.com/workos/workos-go/blob/main/README.md Use this command to add the WorkOS Go library to your project. Requires Go version 1.23 or higher. ```bash go get github.com/workos/workos-go/v8 ``` -------------------------------- ### Paginate Through User Management List Source: https://github.com/workos/workos-go/blob/main/README.md Illustrates how to use the `Iterator` provided by list endpoints for automatic pagination. This example iterates through users and prints their email addresses. ```go iter := client.UserManagement().List(ctx, &workos.UserManagementListParams{}) for iter.Next() { user := iter.Current() fmt.Println(user.Email) } if err := iter.Err(); err != nil { log.Fatal(err) } ``` -------------------------------- ### Initialize WorkOS Client and Get Organization Source: https://github.com/workos/workos-go/blob/main/README.md Demonstrates how to create a new WorkOS client with your API key and client ID, and then retrieve an organization by its ID. Ensure you replace placeholder values with your actual credentials. ```go package main import ( "context" "log" "github.com/workos/workos-go/v8" ) func main() { client := workos.NewClient( "", workos.WithClientID(""), ) organization, err := client.Organizations().Get(context.Background(), "org_123") if err != nil { log.Fatal(err) } _ = organization } ``` -------------------------------- ### Get, Enable, Disable Feature Flags in Go Source: https://context7.com/workos/workos-go/llms.txt Demonstrates how to retrieve a specific feature flag by its slug, and how to enable or disable flags. ```go // Get a specific flag flag, err := client.FeatureFlags().Get(ctx, "dark-mode") // Enable / disable client.FeatureFlags().Enable(ctx, "dark-mode") client.FeatureFlags().Disable(ctx, "beta-feature") ``` -------------------------------- ### Handle Specific WorkOS API Errors Source: https://github.com/workos/workos-go/blob/main/README.md Shows how to inspect errors returned by the WorkOS client using `errors.As`. This example specifically checks for a `NotFoundError`. ```go result, err := client.Organizations().Get(ctx, "org_123") if err != nil { var notFound *workos.NotFoundError if errors.As(err, ¬Found) { log.Printf("Organization not found: %s", notFound.Message) } } ``` -------------------------------- ### Start and Poll AuthKit Device Authorization Source: https://context7.com/workos/workos-go/llms.txt Initiate a device flow with `client.AuthKitStartDeviceAuthorization` and then poll for completion using `client.AuthKitPollDeviceCode`. The user is prompted to visit a URL and enter a code on their device. ```go // Device flow deviceResp, err := client.AuthKitStartDeviceAuthorization(ctx) fmt.Printf("Visit %s and enter %s\n", deviceResp.VerificationURIComplete, deviceResp.UserCode) authResp, err = client.AuthKitPollDeviceCode(ctx, deviceResp.DeviceCode, int(deviceResp.ExpiresIn)) ``` -------------------------------- ### Error Handling Source: https://context7.com/workos/workos-go/llms.txt Explains how to handle API errors using Go's `errors.As` and provides examples for common WorkOS error types. ```APIDOC ## Error Handling All API errors implement the `error` interface and can be inspected via `errors.As`. Typed error types are `AuthenticationError` (401), `NotFoundError` (404), `UnprocessableEntityError` (422), `RateLimitExceededError` (429), `ServerError` (5xx), and `NetworkError`. Several authentication-flow-specific error types carry additional fields: `EmailVerificationRequiredError`, `MFAChallengeError`, `MFAEnrollmentError`, `OrganizationSelectionRequiredError`, `SSORequiredError`, and `OrganizationAuthenticationMethodsRequiredError`. ```go import ( "errors" "log" "github.com/workos/workos-go/v8" ) result, err := client.UserManagement().AuthenticateWithPassword(ctx, &workos.UserManagementAuthenticateWithPasswordParams{ Email: "user@example.com", Password: "hunter2", }, ) if err != nil { var notFound *workos.NotFoundError var mfaErr *workos.MFAChallengeError var orgSel *workos.OrganizationSelectionRequiredError var unproc *workos.UnprocessableEntityError switch { case errors.As(err, &mfaErr): // Prompt user for MFA code log.Printf("MFA required for user %s, factors: %v", mfaErr.User.ID, mfaErr.AuthenticationFactors) case errors.As(err, &orgSel): // Show org picker log.Printf("Pick org: %v", orgSel.Organizations) case errors.As(err, ¬Found): log.Printf("Not found: %s", notFound.Message) case errors.As(err, &unproc): log.Printf("Validation error: %s", unproc.Message) default: log.Fatal(err) } } _ = result ``` ``` -------------------------------- ### User Management: List, Get, Authenticate Users Source: https://context7.com/workos/workos-go/llms.txt Manage users within WorkOS, including listing users by organization, retrieving a specific user, and authenticating users via password or authorization code. Ensure correct parameters are used for each authentication method. ```go ctx := context.Background() // List and get users iter := client.UserManagement().ListUsers(ctx, &workos.UserManagementListUsersParams{ OrganizationID: workos.String("org_01ABC"), }) user, err := client.UserManagement().GetUser(ctx, "user_01XYZ") // Authenticate with password authResp, err := client.UserManagement().AuthenticateWithPassword(ctx, &workos.UserManagementAuthenticateWithPasswordParams{ Email: "alice@acme.com", Password: "s3cr3t!", }, ) fmt.Println(authResp.AccessToken, authResp.RefreshToken) // Authenticate with authorization code (SSO / AuthKit callback) authResp, err = client.UserManagement().AuthenticateWithCode(ctx, &workos.UserManagementAuthenticateWithCodeParams{ Code: "auth_code_from_callback", CodeVerifier: workos.String("pkce_verifier"), }, ) // Refresh token authResp, err = client.UserManagement().AuthenticateWithRefreshToken(ctx, &workos.UserManagementAuthenticateWithRefreshTokenParams{ RefreshToken: authResp.RefreshToken, OrganizationID: authResp.OrganizationID, }, ) ``` -------------------------------- ### Organizations Service: Create, Get, Update, List, Delete Source: https://context7.com/workos/workos-go/llms.txt Perform CRUD operations on WorkOS organizations, including creating with domain data and metadata, retrieving by ID or external ID, updating, listing with search, and deleting. Ensure context is provided for all operations. ```go ctx := context.Background() // Create org, err := client.Organizations().Create(ctx, &workos.OrganizationsCreateParams{ Name: "Acme Corp", DomainData: []*workos.OrganizationDomainData{{Domain: "acme.com", State: "verified"}}, Metadata: map[string]string{"plan": "enterprise"}, ExternalID: workos.String("customer-42"), }) // Get by ID org, err = client.Organizations().Get(ctx, "org_01ABC") // Get by external ID org, err = client.Organizations().GetByExternalID(ctx, "customer-42") // Update updated, err := client.Organizations().Update(ctx, "org_01ABC", &workos.OrganizationsUpdateParams{ Name: workos.String("Acme Corporation"), StripeCustomerID: workos.String("cus_xyz"), }) // List with search iter := client.Organizations().List(ctx, &workos.OrganizationsListParams{ Search: workos.String("acme"), }) for iter.Next() { fmt.Println(iter.Current().Name) } // Delete err = client.Organizations().Delete(ctx, "org_01ABC") // Get audit log configuration cfg, err := client.Organizations().GetAuditLogConfiguration(ctx, "org_01ABC") fmt.Println(cfg.RetentionPeriodInDays, cfg.State) ``` -------------------------------- ### Initialize WorkOS Client Source: https://github.com/workos/workos-go/blob/main/docs/V7_MIGRATION_GUIDE.md Replace package-level configuration with a single client instance. Use `workos.NewClient` and pass configuration options like `WithClientID`. ```go import ( "github.com/workos/workos-go/v6/pkg/directorysync" "github.com/workos/workos-go/v6/pkg/sso" ) func main() { sso.Configure("", "") directorysync.SetAPIKey("") } ``` ```go import "github.com/workos/workos-go/v6" func main() { client := workos.NewClient( "", workos.WithClientID(""), ) } ``` -------------------------------- ### Client Initialization Source: https://context7.com/workos/workos-go/llms.txt Demonstrates how to initialize the WorkOS client with basic and advanced options, including API key, client ID, base URL, and retry configurations. ```APIDOC ## Client Initialization `workos.NewClient` constructs the API client. `WithClientID` is required for authentication flows (SSO, AuthKit, UserManagement). Additional options include `WithBaseURL`, `WithHTTPClient`, `WithMaxRetries`, `WithLogger`, and `WithAppInfo`. ```go package main import ( "context" "log" "net/http" "time" "github.com/workos/workos-go/v8" ) func main() { // Basic client client := workos.NewClient( "sk_live_abc123", workos.WithClientID("client_abc123"), ) // Client with all options client = workos.NewClient( "sk_live_abc123", workos.WithClientID("client_abc123"), workos.WithBaseURL("https://api.workos.com"), workos.WithMaxRetries(5), workos.WithHTTPClient(&http.Client{Timeout: 30 * time.Second}), workos.WithLogger(log.Default()), workos.WithAppInfo("MyFramework", "1.0.0", "https://myframework.io"), ) org, err := client.Organizations().Get(context.Background(), "org_01ABCDEF") if err != nil { log.Fatal(err) } log.Println(org.Name) } ``` ``` -------------------------------- ### User Management: Create Invitation and List Memberships Source: https://context7.com/workos/workos-go/llms.txt Handle user invitations and manage organization memberships. Create invitations with user details and roles, and list organization memberships for a given user. Ensure the correct organization and user IDs are provided. ```go ctx := context.Background() // Send invite invite, err := client.UserManagement().CreateInvitation(ctx, &workos.UserManagementCreateInvitationParams{ Email: "bob@acme.com", OrganizationID: workos.String("org_01ABC"), RoleSlug: workos.String("member"), InviterUserID: workos.String("user_01XYZ"), }, ) fmt.Println(invite.AcceptInvitationURL) // List org memberships for a user memberIter := client.UserManagement().ListOrganizationMemberships(ctx, &workos.UserManagementListOrganizationMembershipsParams{ UserID: workos.String("user_01XYZ"), }, ) ``` -------------------------------- ### Get Session Logout URL Source: https://context7.com/workos/workos-go/llms.txt Generate a logout URL using `session.GetLogoutURL` to redirect the user to their identity provider for logout. This ensures that the user is logged out from WorkOS and any connected applications. ```go // Get logout URL logoutURL, err := session.GetLogoutURL(ctx, "https://app.example.com/logged-out") // Redirect user to logoutURL ``` -------------------------------- ### Generate Admin Portal Link for Directory Sync in Go Source: https://context7.com/workos/workos-go/llms.txt Generates a link to the Admin Portal for setting up Directory Sync. Requires the organization ID and a return URL. ```go // Generate portal link for Directory Sync dSyncResp, err := client.AdminPortal().GenerateLink(ctx, &workos.AdminPortalGenerateLinkParams{ Intent: "dsync", Organization: "org_01ABC", ReturnURL: workos.String("https://app.example.com/settings"), }, ) fmt.Println("DSync portal:", dSyncResp.Link) ``` -------------------------------- ### List Directories, Users, and Groups with Directory Sync in Go Source: https://context7.com/workos/workos-go/llms.txt Utilize `client.DirectorySync()` to manage directories, directory users, and directory groups synced from SCIM providers. Ensure you have the necessary context and parameters for listing operations. ```go ctx := context.Background() // List all directories for an org dirIter := client.DirectorySync().List(ctx, &workos.DirectorySyncListParams{ OrganizationID: workos.String("org_01ABC"), }) for dirIter.Next() { d := dirIter.Current() fmt.Println(d.ID, d.Type, d.State, d.Name) } // List users in a directory userIter := client.DirectorySync().ListUsers(ctx, &workos.DirectorySyncListUsersParams{ Directory: workos.String("directory_01XYZ"), }) for userIter.Next() { u := userIter.Current() fmt.Println(u.ID, *u.Email, u.State, u.Roles) } // List groups groupIter := client.DirectorySync().ListGroups(ctx, &workos.DirectorySyncListGroupsParams{ Directory: workos.String("directory_01XYZ"), }) for groupIter.Next() { g := groupIter.Current() fmt.Println(g.ID, g.Name) } // Get a specific directory user user, err := client.DirectorySync().GetUser(ctx, "directory_user_01XYZ") fmt.Println(user.CustomAttributes) ``` -------------------------------- ### Paginate List Endpoints with Iterator Source: https://context7.com/workos/workos-go/llms.txt Uses the `Iterator[T]` type to handle cursor-based pagination for list endpoints. Call `Next()` to advance, `Current()` to get the item, and `Err()` to check for errors after iteration. ```go import ( "context" "fmt" "log" "github.com/workos/workos-go/v8" ) ctx := context.Background() // Iterate all users iter := client.UserManagement().ListUsers(ctx, &workos.UserManagementListUsersParams{ Limit: workos.Int(50), }) for iter.Next() { user := iter.Current() fmt.Printf("User: %s <%s>\n", user.ID, user.Email) } if err := iter.Err(); err != nil { log.Fatal(err) } // Iterate organizations filtered by domain orgIter := client.Organizations().List(ctx, &workos.OrganizationsListParams{ Domains: []string{"acme.com"}, }) for orgIter.Next() { org := orgIter.Current() fmt.Println(org.ID, org.Name) } if err := orgIter.Err(); err != nil { log.Fatal(err) } ``` -------------------------------- ### Initialize WorkOS Client Source: https://context7.com/workos/workos-go/llms.txt Constructs the WorkOS API client with an API key and optional configurations like Client ID, Base URL, and retry settings. `WithClientID` is necessary for authentication flows. ```go package main import ( "context" "log" "net/http" "time" "github.com/workos/workos-go/v8" ) func main() { // Basic client client := workos.NewClient( "sk_live_abc123", workos.WithClientID("client_abc123"), ) // Client with all options client = workos.NewClient( "sk_live_abc123", workos.WithClientID("client_abc123"), workos.WithBaseURL("https://api.workos.com"), workos.WithMaxRetries(5), workos.WithHTTPClient(&http.Client{Timeout: 30 * time.Second}), workos.WithLogger(log.Default()), workos.WithAppInfo("MyFramework", "1.0.0", "https://myframework.io"), ) org, err := client.Organizations().Get(context.Background(), "org_01ABCDEF") if err != nil { log.Fatal(err) } log.Println(org.Name) } ``` -------------------------------- ### Update Organization Creation Method Source: https://github.com/workos/workos-go/blob/main/docs/V7_MIGRATION_GUIDE.md When creating an organization, use the new `client.Organizations().Create` method with a pointer to `workos.OrganizationsCreateParams`. ```go org, err := organizations.CreateOrganization(ctx, organizations.CreateOrganizationOpts{ Name: "Acme", }) ``` ```go org, err := client.Organizations().Create(ctx, &workos.OrganizationsCreateParams{ Name: "Acme", }) ``` -------------------------------- ### Import WorkOS Go SDK Source: https://github.com/workos/workos-go/blob/main/README.md Import the root 'workos' package for the Go SDK. This SDK uses a flat package layout. ```go import "github.com/workos/workos-go/v8" ``` -------------------------------- ### Customize Individual Requests with Options Source: https://context7.com/workos/workos-go/llms.txt Customize individual requests with functional options like timeout, idempotency key, and extra headers. Ensure the context is properly managed. ```go import ( "net/http" "time" "github.com/workos/workos-go/v8" ) // Per-request timeout, idempotency key, and extra headers org, err := client.Organizations().Create(ctx, &workos.OrganizationsCreateParams{ Name: "Acme Corp", DomainData: []*workos.OrganizationDomainData{ {Domain: "acme.com", State: "verified"}, }, Metadata: map[string]string{"plan": "enterprise"}, }, workos.WithTimeout(10*time.Second), workos.WithIdempotencyKey("create-acme-corp-v1"), workos.WithExtraHeaders(http.Header{"X-Correlation-ID": {"req-abc123"}}) ) ``` -------------------------------- ### Authenticate and Refresh User Sessions Source: https://github.com/workos/workos-go/blob/main/README.md Demonstrates how to manage user sessions using sealed cookies. Includes methods for authenticating a user and refreshing their session. ```go session := workos.NewSession(client, sealedCookie, cookiePassword) result, err := session.Authenticate() if err != nil { log.Fatal(err) } if result.Authenticated { fmt.Println("User:", result.User) fmt.Println("Org:", result.OrganizationID) } refreshed, err := session.Refresh(ctx) if err != nil { log.Fatal(err) } if refreshed.Authenticated { // Set refreshed.SealedSession as the new cookie value } ``` -------------------------------- ### Initiate SSO Logout Flow Source: https://context7.com/workos/workos-go/llms.txt Use `client.SSO().AuthorizeLogout` to initiate the logout flow and obtain a logout token. Then, use `client.SSO().GetLogoutURL` to construct the logout URL for the user's identity provider. ```go ctx := context.Background() // SSO logout flow logoutAuth, err := client.SSO().AuthorizeLogout(ctx, &workos.SSOAuthorizeLogoutParams{ ProfileID: "profile_01XYZ", }) logoutURL := client.SSO().GetLogoutURL(&workos.SSOGetLogoutURLParams{ Token: logoutAuth.LogoutToken, }) // Redirect user to logoutURL ``` -------------------------------- ### Update FGA/Authorization Service Access Source: https://github.com/workos/workos-go/blob/main/docs/V7_MIGRATION_GUIDE.md The `pkg/fga` package is now `Authorization`. Use `client.Authorization()` and note the parameter name change from `ResourceType` to `ResourceTypeSlug`. ```go import "github.com/workos/workos-go/v6/pkg/fga" fga.SetAPIKey("") resp, err := fga.ListResources(ctx, fga.ListResourcesOpts{ ResourceType: "project", }) ``` ```go import "github.com/workos/workos-go/v6" client := workos.NewClient("") resourceType := "project" iter := client.Authorization().ListResources(ctx, &workos.AuthorizationListResourcesParams{ ResourceTypeSlug: &resourceType, }) ``` -------------------------------- ### Create and Download Audit Log Export in Go Source: https://context7.com/workos/workos-go/llms.txt Initiates an audit log export for a specified date range and actions. The code then polls the export status until it's ready to download. ```go // Create an export for a date range export, err := client.AuditLogs().CreateExport(ctx, &workos.AuditLogsCreateExportParams{ OrganizationID: "org_01ABC", RangeStart: "2024-01-01T00:00:00Z", RangeEnd: "2024-06-30T23:59:59Z", Actions: []string{"document.viewed", "document.edited"}, }) // Poll until ready for export.State != "ready" { time.Sleep(2 * time.Second) export, err = client.AuditLogs().GetExport(ctx, export.ID) } fmt.Println("Download URL:", *export.URL) ``` -------------------------------- ### Generate AuthKit PKCE Authorization URL (Public Client) Source: https://context7.com/workos/workos-go/llms.txt For public or browser clients, use `workos.NewPublicClient` and its `GetAuthorizationURL` method. This method does not require an API key and returns the authorization URL, `CodeVerifier`, and `State`. ```go // Public/browser client (no API key needed) pub := workos.NewPublicClient("client_abc123") pkceResult, err := pub.GetAuthorizationURL(workos.AuthKitAuthorizationURLParams{ RedirectURI: "https://app.example.com/callback", }) fmt.Println(pkceResult.URL, pkceResult.CodeVerifier, pkceResult.State) ``` -------------------------------- ### List SSO Connections Source: https://context7.com/workos/workos-go/llms.txt Use `client.SSO().ListConnections` to retrieve a list of configured SSO connections for a given organization. The result is an iterator that allows you to loop through the connections. ```go ctx := context.Background() // List connections iter := client.SSO().ListConnections(ctx, &workos.SSOListConnectionsParams{ OrganizationID: workos.String("org_01ABC"), }) for iter.Next() { conn := iter.Current() fmt.Println(conn.ID, conn.ConnectionType, conn.State) } ``` -------------------------------- ### Build AuthKit PKCE Authorization URL (Server-Side) Source: https://context7.com/workos/workos-go/llms.txt Use `client.GetAuthKitPKCEAuthorizationURL` to generate a PKCE authorization URL for server-side flows. Remember to store the returned `CodeVerifier` and `State` in the user's session for later use. ```go ctx := context.Background() // Server-side: build PKCE authorization URL result, err := client.GetAuthKitPKCEAuthorizationURL(workos.AuthKitAuthorizationURLParams{ RedirectURI: "https://app.example.com/callback", OrganizationID: workos.String("org_01ABC"), ScreenHint: workos.String("sign-up"), }) // Store result.CodeVerifier and result.State in the session // Redirect user to result.URL ``` -------------------------------- ### AuthKit Helpers Source: https://context7.com/workos/workos-go/llms.txt Provides server-side PKCE flows for authentication. ```APIDOC ## AuthKit Helpers `client.GetAuthKitPKCEAuthorizationURL` and `client.AuthKitPKCECodeExchange` provide server-side PKCE flows. For browser or public clients, use `workos.NewPublicClient`. ### GetAuthKitPKCEAuthorizationURL Builds the authorization URL for the AuthKit PKCE flow. #### Parameters - **RedirectURI** (string) - Required - The URI to redirect the user to after authentication. - **OrganizationID** (string) - Required - The ID of the organization. - **ScreenHint** (string) - Optional - Hint for the authentication screen (e.g., 'sign-up', 'login'). #### Returns - **URL** - The authorization URL. - **CodeVerifier** - The code verifier to be stored in the session. - **State** - The state parameter to be stored in the session. ### AuthKitPKCECodeExchange Exchanges the authorization code and code verifier for authentication response. #### Parameters - **Code** (string) - Required - The authorization code received from the callback. - **CodeVerifier** (string) - Required - The code verifier stored during the authorization URL generation. #### Returns - **User** - User information. - **AccessToken** - The access token. ### NewPublicClient Creates a new public client for browser or public clients (no API key needed). #### Parameters - **ClientID** (string) - Required - The public client ID. ### GetAuthorizationURL (Public Client) Builds the authorization URL for the AuthKit PKCE flow using a public client. #### Parameters - **RedirectURI** (string) - Required - The URI to redirect the user to after authentication. #### Returns - **URL** - The authorization URL. - **CodeVerifier** - The code verifier to be stored in the session. - **State** - The state parameter to be stored in the session. ### AuthKitStartDeviceAuthorization Starts the AuthKit device authorization flow. #### Returns - **VerificationURIComplete** - The complete verification URI. - **UserCode** - The user code to be entered. - **DeviceCode** - The device code for polling. - **ExpiresIn** - The expiration time in seconds. ### AuthKitPollDeviceCode Polls the device code endpoint to check for authentication status. #### Parameters - **DeviceCode** (string) - Required - The device code obtained from `AuthKitStartDeviceAuthorization`. - **ExpiresIn** (int) - Required - The expiration time in seconds. ``` -------------------------------- ### Helper Utilities Source: https://context7.com/workos/workos-go/llms.txt The SDK provides generic pointer helpers for setting optional struct fields without declaring intermediate variables. ```APIDOC ## Helper Utilities (`Ptr`, `String`, `Bool`, `Int`) The SDK provides generic pointer helpers for setting optional struct fields without declaring intermediate variables. ```go import "github.com/workos/workos-go/v8" params := &workos.OrganizationsUpdateParams{ Name: workos.String("New Name"), AllowProfilesOutsideOrganization: workos.Bool(false), ExternalID: workos.String("ext-456"), Metadata: map[string]string{"tier": "gold"}, } // workos.Ptr is generic for any type limit := workos.Ptr(25) ``` ``` -------------------------------- ### Generate Admin Portal Link for SSO in Go Source: https://context7.com/workos/workos-go/llms.txt Creates an ephemeral link to the Admin Portal for configuring Single Sign-On (SSO). Specify the organization and the desired SSO provider type. ```go // Generate portal link for SSO setup portalResp, err := client.AdminPortal().GenerateLink(ctx, &workos.AdminPortalGenerateLinkParams{ Intent: "sso", Organization: "org_01ABC", ReturnURL: workos.String("https://app.example.com/settings"), IntentOptions: &workos.IntentOptions{ SSO: &workos.SSOIntentOptions{ ProviderType: workos.String("OktaSAML"), }, }, }, ) fmt.Println("Portal link:", portalResp.Link) // Redirect the admin user to portalResp.Link ``` -------------------------------- ### Stream WorkOS Platform Events Source: https://context7.com/workos/workos-go/llms.txt Streams WorkOS platform events with cursor-based pagination. Ensure you have the necessary context and client initialized. ```go ctx := context.Background() iter := client.Events().List(ctx, &workos.EventsListParams{ Events: []string{"user.created", "organization.created", "dsync.user.created"}, Limit: workos.Int(100), }) for iter.Next() { event := iter.Current() fmt.Printf("Event: %s at %s\n", event.Event, event.CreatedAt) } if err := iter.Err(); err != nil { log.Fatal(err) } ``` -------------------------------- ### Error Handling with errors.As (v6 vs v7) Source: https://github.com/workos/workos-go/blob/main/docs/V7_MIGRATION_GUIDE.md The SDK's error handling has been flattened in v7. Specific error types like MFAChallengeError from pkg/workos_errors are no longer exposed directly. Migration involves adapting to the new error structures or using generic error checking. ```go import "github.com/workos/workos-go/v6/pkg/workos_errors" var mfaErr *workos_errors.MFAChallengeError if errors.As(err, &mfaErr) { fmt.Println(mfaErr.PendingAuthenticationToken) } ``` -------------------------------- ### Manage Feature Flag Targets in Go Source: https://context7.com/workos/workos-go/llms.txt Allows adding or removing specific users as targets for a feature flag, controlling its rollout. ```go // Add/remove targets client.FeatureFlags().AddFlagTarget(ctx, "beta-feature", "user_01XYZ") client.FeatureFlags().RemoveFlagTarget(ctx, "beta-feature", "user_01XYZ") ``` -------------------------------- ### Generating Logout URL (v6 vs v7) Source: https://github.com/workos/workos-go/blob/main/docs/V7_MIGRATION_GUIDE.md Logout URL generation has been refactored. v6 used pkg/usermanagement, while v7 uses a Session object obtained from the client. The return type also changed from *url.URL to string. ```go u, err := usermanagement.GetLogoutURL(usermanagement.GetLogoutURLOpts{ SessionID: "session_abc", ReturnTo: "https://example.com/signed-out", }) ``` ```go session := workos.NewSession(client, sealedSession, cookiePassword) u, err := session.GetLogoutURL(ctx, "https://example.com/signed-out") ``` -------------------------------- ### Iterating Through Organizations with Pagination Source: https://github.com/workos/workos-go/blob/main/docs/V7_MIGRATION_GUIDE.md v7 introduces Iterator[T] for auto-fetching subsequent pages, removing the need for manual cursor management and List*Response types. Existing code using manual cursor management will need to be rewritten. ```go limit := 10 iter := client.Organizations().List(ctx, &workos.OrganizationsListParams{ PaginationParams: workos.PaginationParams{ Limit: &limit, }, }) for iter.Next() { fmt.Println(iter.Current().ID) } if err := iter.Err(); err != nil { return err } ``` -------------------------------- ### Generating SSO Authorization URL (v6 vs v7) Source: https://github.com/workos/workos-go/blob/main/docs/V7_MIGRATION_GUIDE.md The method for generating SSO authorization URLs has been updated. v6 used pkg/sso, while v7 uses the client.GetSSOAuthorizationURL method. The return type also changed from *url.URL to string. ```go import "github.com/workos/workos-go/v6/pkg/sso" sso.Configure("", "") u, err := sso.GetAuthorizationURL(sso.GetAuthorizationURLOpts{ RedirectURI: "https://example.com/callback", Organization: "org_123", }) ``` ```go import "github.com/workos/workos-go/v6" client := workos.NewClient( "", workos.WithClientID(""), ) organizationID := "org_123" u, err := client.GetSSOAuthorizationURL(workos.SSOAuthorizationURLParams{ RedirectURI: "https://example.com/callback", OrganizationID: &organizationID, }) ``` -------------------------------- ### Webhook Verification (v6 vs v7) Source: https://github.com/workos/workos-go/blob/main/docs/V7_MIGRATION_GUIDE.md Webhook signature verification has moved from pkg/webhooks to a dedicated WebhookVerifier. The entry point for verification has changed from webhooks.NewClient().ValidatePayload to workos.NewWebhookVerifier().VerifyPayload. Constructing an event is also a separate step. ```go import "github.com/workos/workos-go/v6/pkg/webhooks" client := webhooks.NewClient(secret) body, err := client.ValidatePayload(header, rawBody) ``` ```go import "github.com/workos/workos-go/v6" verifier := workos.NewWebhookVerifier(secret) body, err := verifier.VerifyPayload(header, rawBody) ``` ```go event, err := verifier.ConstructEvent(header, rawBody) ``` -------------------------------- ### Create Audit Log Event in Go Source: https://context7.com/workos/workos-go/llms.txt Use this to create a single audit log event. Ensure the OrganizationID and Event details are correctly populated. ```go ctx := context.Background() // Create an audit log event resp, err := client.AuditLogs().CreateEvent(ctx, &workos.AuditLogsCreateEventParams{ OrganizationID: "org_01ABC", Event: &workos.AuditLogEvent{ Action: "document.viewed", OccurredAt: "2024-06-01T12:00:00Z", Actor: &workos.AuditLogEventActor{ ID: "user_01XYZ", Type: "user", Name: workos.String("Alice"), }, Targets: []*workos.AuditLogEventTarget{ {ID: "doc-456", Type: "document"}, }, Context: &workos.AuditLogEventContext{ Location: "203.0.113.42", UserAgent: workos.String("Mozilla/5.0"), }, Metadata: map[string]interface{}{"document_title": "Q4 Report"}, }, }, workos.WithIdempotencyKey("audit-doc-view-001"), ) fmt.Println("Created:", resp.Success) ``` -------------------------------- ### Build SSO Authorization URL and Exchange Code Source: https://context7.com/workos/workos-go/llms.txt Use `client.SSO().GetAuthorizationURL` to build the SSO authorization URL without making an HTTP call. After the user is redirected back, use `client.SSO().GetProfileAndToken` to exchange the authorization code for user profile information and an access token. ```go ctx := context.Background() // Build authorization URL (no HTTP call) authURL := client.SSO().GetAuthorizationURL(&workos.SSOGetAuthorizationURLParams{ RedirectURI: "https://app.example.com/sso/callback", Organization: workos.String("org_01ABC"), LoginHint: workos.String("alice@acme.com"), }) // Redirect the user to authURL // Exchange code for profile + token tokenResp, err := client.SSO().GetProfileAndToken(ctx, &workos.SSOGetProfileAndTokenParams{ Code: "code_from_callback", }) profile := tokenResp.Profile fmt.Println(profile.Email, profile.ConnectionType, profile.OrganizationID) ``` -------------------------------- ### Update Organization Service Access Source: https://github.com/workos/workos-go/blob/main/docs/V7_MIGRATION_GUIDE.md Access organization-related services using `client.Organizations()` instead of the old `pkg/organizations` package. ```go import "github.com/workos/workos-go/v6/pkg/organizations" organizations.SetAPIKey("") org, err := organizations.GetOrganization(ctx, organizations.GetOrganizationOpts{ Organization: "org_123", }) ``` ```go import "github.com/workos/workos-go/v6" client := workos.NewClient("") org, err := client.Organizations().Get(ctx, "org_123") ``` -------------------------------- ### Authenticate Session from Cookie Source: https://context7.com/workos/workos-go/llms.txt On incoming requests, use `workos.NewSession` to create a session object from the sealed cookie and password. Then, call `session.Authenticate()` to validate the session locally without making an API call. This returns the authentication status, user details, and organization information. ```go // On each request: validate the cookie session := workos.NewSession(client, sealedCookie, cookiePassword) result, err := session.Authenticate() if err != nil { /* handle error */ } if result.Authenticated { fmt.Println("User:", result.User.Email) fmt.Println("Org:", result.OrganizationID) fmt.Println("Role:", result.Role) fmt.Println("Permissions:", result.Permissions) } else { fmt.Println("Auth failed:", result.Reason) // "no_session_cookie_provided", "invalid_jwt", etc. ``` -------------------------------- ### List User Feature Flags in Go Source: https://context7.com/workos/workos-go/llms.txt Fetches all feature flags that are enabled for a specific user. This is useful for personalized user experiences. ```go // List flags enabled for a specific user userFlagIter := client.FeatureFlags().ListUserFeatureFlags(ctx, "user_01XYZ", &workos.FeatureFlagsListUserFeatureFlagsParams{}, ) for userFlagIter.Next() { fmt.Println(userFlagIter.Current().Slug) } ``` -------------------------------- ### Read, Update, and Delete Object in WorkOS Vault in Go Source: https://context7.com/workos/workos-go/llms.txt Demonstrates reading a stored object by its ID, updating its value, and deleting it from the WorkOS Vault. ```go // Read it back read, err := client.Vault().ReadObject(ctx, obj.ID) fmt.Println("Value:", read.Value) // Update _, err = client.Vault().UpdateObject(ctx, obj.ID, &workos.VaultUpdateObjectParams{ Value: "sk_live_newsecret", }) // Delete err = client.Vault().DeleteObject(ctx, obj.ID) ``` -------------------------------- ### Customize WorkOS Requests with Functional Options Source: https://github.com/workos/workos-go/blob/main/README.md Customize individual WorkOS requests using functional options like WithTimeout, WithIdempotencyKey, and WithExtraHeaders. ```go result, err := client.Organizations().Get(ctx, "org_123", workos.WithTimeout(5 * time.Second), workos.WithIdempotencyKey("unique-key"), workos.WithExtraHeaders(http.Header{"X-Custom": {"value"}}), ) ``` -------------------------------- ### Generating AuthKit Authorization URL for Public Clients (v7) Source: https://github.com/workos/workos-go/blob/main/docs/V7_MIGRATION_GUIDE.md For browser/public PKCE flows, use the WorkOS PublicClient to generate the AuthKit authorization URL. This differs from the standard client which requires an API key. ```go publicClient := workos.NewPublicClient("") result, err := publicClient.GetAuthorizationURL(workos.AuthKitAuthorizationURLParams{ RedirectURI: "https://example.com/callback", }) ``` -------------------------------- ### Configure Webhook Endpoints Source: https://context7.com/workos/workos-go/llms.txt Provides CRUD operations for webhook endpoint configuration. This includes creating, listing, updating, and deleting webhook endpoints. ```go ctx := context.Background() // Create a webhook endpoint endpoint, err := client.Webhooks().CreateEndpoint(ctx, &workos.WebhooksCreateEndpointParams{ EndpointURL: "https://app.example.com/webhooks", Events: []string{ "user.created", "organization.created", "dsync.user.created", "dsync.user.updated", }, }, ) fmt.Println("Endpoint ID:", endpoint.ID, "Secret:", endpoint.Secret) // List endpoints iter := client.Webhooks().ListEndpoints(ctx, &workos.WebhooksListEndpointsParams{}) for iter.Next() { ep := iter.Current() fmt.Println(ep.EndpointURL, ep.Status, len(ep.Events), "events") } // Update events subscription client.Webhooks().UpdateEndpoint(ctx, endpoint.ID, &workos.WebhooksUpdateEndpointParams{ Events: []string{"*"}, // Subscribe to all events }, ) // Delete err = client.Webhooks().DeleteEndpoint(ctx, endpoint.ID) ``` -------------------------------- ### Perform Authorization Checks and Management in Go Source: https://context7.com/workos/workos-go/llms.txt Use `client.Authorization()` for fine-grained authorization, including permission checks, resource management, and role assignments. This service is essential for implementing RBAC and FGA patterns. ```go ctx := context.Background() // Check if a membership has a permission on a resource check, err := client.Authorization().Check(ctx, "om_01ABC", &workos.AuthorizationCheckParams{ PermissionSlug: "document:read", ResourceTarget: workos.AuthorizationResourceTargetByExternalID{ ResourceExternalID: "doc-456", ResourceTypeSlug: "document", }, }, ) fmt.Println("Authorized:", check.Authorized) // Create a resource resource, err := client.Authorization().CreateResource(ctx, &workos.AuthorizationCreateResourceParams{ ExternalID: "project-789", Name: "Q4 Report", ResourceTypeSlug: "project", OrganizationID: "org_01ABC", }) // Assign a role to a membership on a resource assignment, err := client.Authorization().AssignRole(ctx, "om_01ABC", &workos.AuthorizationAssignRoleParams{ RoleSlug: "editor", ResourceTarget: workos.AuthorizationResourceTargetByID{ResourceID: resource.ID}, }, ) fmt.Println("Assignment:", assignment.ID) // List resources accessible to a membership resourceIter := client.Authorization().ListResourcesForMembership(ctx, "om_01ABC", &workos.AuthorizationListResourcesForMembershipParams{ PermissionSlug: "document:read", ParentResource: workos.AuthorizationParentResourceByID{ID: resource.ID}, }, ) for resourceIter.Next() { fmt.Println(resourceIter.Current().ExternalID) } // Create an environment-level role with permissions role, err := client.Authorization().CreateEnvironmentRole(ctx, &workos.AuthorizationCreateEnvironmentRoleParams{ Slug: "viewer", Name: "Viewer", Description: workos.String("Read-only access"), }, ) client.Authorization().SetEnvironmentRolePermissions(ctx, role.Slug, &workos.AuthorizationSetEnvironmentRolePermissionsParams{ Permissions: []string{"document:read", "project:read"}, }, ) ``` -------------------------------- ### Use Pointer Helper Utilities for Optional Fields Source: https://context7.com/workos/workos-go/llms.txt Utilize generic pointer helpers like `String`, `Bool`, and `Int` to set optional struct fields without declaring intermediate variables. `workos.Ptr` is generic for any type. ```go import "github.com/workos/workos-go/v8" params := &workos.OrganizationsUpdateParams{ Name: workos.String("New Name"), AllowProfilesOutsideOrganization: workos.Bool(false), ExternalID: workos.String("ext-456"), Metadata: map[string]string{"tier": "gold"}, } // workos.Ptr is generic for any type limit := workos.Ptr(25) ``` -------------------------------- ### Generating AuthKit Authorization URL (v6 vs v7) Source: https://github.com/workos/workos-go/blob/main/docs/V7_MIGRATION_GUIDE.md The method for generating AuthKit authorization URLs has changed. v6 used pkg/usermanagement, while v7 uses the client.GetAuthKitAuthorizationURL method. The return type also changed from *url.URL to string. ```go import "github.com/workos/workos-go/v6/pkg/usermanagement" u, err := usermanagement.GetAuthorizationURL(usermanagement.GetAuthorizationURLOpts{ ClientID: "", RedirectURI: "https://example.com/callback", Provider: "authkit", }) ``` ```go import "github.com/workos/workos-go/v6" client := workos.NewClient( "", workos.WithClientID(""), ) provider := "authkit" u, err := client.GetAuthKitAuthorizationURL(workos.AuthKitAuthorizationURLParams{ RedirectURI: "https://example.com/callback", Provider: &provider, }) ``` -------------------------------- ### Exchange AuthKit PKCE Code Source: https://context7.com/workos/workos-go/llms.txt After the user completes the authorization flow and is redirected back, use `client.AuthKitPKCECodeExchange` with the provided code and the stored `CodeVerifier` to obtain user information and an access token. ```go // After callback: exchange code authResp, err := client.AuthKitPKCECodeExchange(ctx, workos.AuthKitPKCECodeExchangeParams{ Code: "code_from_callback", CodeVerifier: result.CodeVerifier, }) fmt.Println(authResp.User.Email, authResp.AccessToken) ``` -------------------------------- ### Manage Multi-Factor Authentication (MFA) Source: https://context7.com/workos/workos-go/llms.txt Manages TOTP and SMS authentication factors and challenges for MFA. This includes enrolling a TOTP factor, creating a challenge, and verifying the challenge. ```go ctx := context.Background() // Enroll a TOTP factor enrollResp, err := client.MultiFactorAuth().EnrollFactor(ctx, &workos.MultiFactorAuthEnrollFactorParams{ Type: "totp", Issuer: workos.String("MyApp"), User: workos.String("alice@acme.com"), }, ) fmt.Println("QR code:", enrollResp.AuthenticationFactor.TOTP.QrCode) // Create a challenge challenge, err := client.MultiFactorAuth().ChallengeAuthentication(ctx, &workos.MultiFactorAuthChallengeAuthenticationParams{ AuthenticationFactorID: enrollResp.AuthenticationFactor.ID, }, ) // Verify the challenge verifyResp, err := client.MultiFactorAuth().VerifyAuthentication(ctx, &workos.MultiFactorAuthVerifyAuthenticationParams{ AuthenticationChallengeID: challenge.ID, Code: "123456", }, ) fmt.Println("Valid:", verifyResp.Valid) ``` -------------------------------- ### Update Directory Sync Service Access Source: https://github.com/workos/workos-go/blob/main/docs/V7_MIGRATION_GUIDE.md Access Directory Sync services via `client.DirectorySync()` and note the change from `ListDirectoriesOpts` to `&workos.DirectorySyncListParams`. ```go import "github.com/workos/workos-go/v6/pkg/directorysync" directorysync.SetAPIKey("") resp, err := directorysync.ListDirectories(ctx, directorysync.ListDirectoriesOpts{}) ``` ```go import "github.com/workos/workos-go/v6" client := workos.NewClient("") iter := client.DirectorySync().List(ctx, &workos.DirectorySyncListParams{}) ``` -------------------------------- ### Admin Portal Service Source: https://context7.com/workos/workos-go/llms.txt Generate ephemeral links for the Admin Portal to configure SSO, Directory Sync, and domain verification. ```APIDOC ## Admin Portal Service `client.AdminPortal()` generates ephemeral links for the self-serve Admin Portal where customers configure SSO, Directory Sync, and domain verification. ### Generate Link (SSO) Generates a portal link for SSO setup. ```go portalResp, err := client.AdminPortal().GenerateLink(ctx, &workos.AdminPortalGenerateLinkParams{ Intent: "sso", Organization: "org_01ABC", ReturnURL: workos.String("https://app.example.com/settings"), IntentOptions: &workos.IntentOptions{ SSO: &workos.SSOIntentOptions{ ProviderType: workos.String("OktaSAML"), }, }, }, ) fmt.Println("Portal link:", portalResp.Link) // Redirect the admin user to portalResp.Link ``` ### Generate Link (Directory Sync) Generates a portal link for Directory Sync configuration. ```go dSyncResp, err := client.AdminPortal().GenerateLink(ctx, &workos.AdminPortalGenerateLinkParams{ Intent: "dsync", Organization: "org_01ABC", ReturnURL: workos.String("https://app.example.com/settings"), }, ) fmt.Println("DSync portal:", dSyncResp.Link) ``` ``` -------------------------------- ### List Organization Feature Flags in Go Source: https://context7.com/workos/workos-go/llms.txt Retrieves feature flags enabled for a given organization. This is useful for organization-wide feature rollouts. ```go // List flags enabled for an organization orgFlagIter := client.FeatureFlags().ListOrganizationFeatureFlags(ctx, "org_01ABC", &workos.FeatureFlagsListOrganizationFeatureFlagsParams{}, ) _ = flag ``` -------------------------------- ### Pagination (Iterator) Source: https://context7.com/workos/workos-go/llms.txt Illustrates how to use the `Iterator[T]` type for handling cursor-based pagination across list endpoints, including fetching the next item, current item, and checking for errors. ```APIDOC ## Pagination (Iterator) List endpoints return an `Iterator[T]` that lazily fetches pages using cursor-based pagination. Call `Next()` to advance, `Current()` to get the item, and `Err()` to check for errors after iteration. The `Cursor()` method returns the current pagination cursor for resuming iteration across process restarts. ```go import ( "context" "fmt" "log" "github.com/workos/workos-go/v8" ) ctx := context.Background() // Iterate all users iter := client.UserManagement().ListUsers(ctx, &workos.UserManagementListUsersParams{ Limit: workos.Int(50), }) for iter.Next() { user := iter.Current() fmt.Printf("User: %s <%s>\n", user.ID, user.Email) } if err := iter.Err(); err != nil { log.Fatal(err) } // Iterate organizations filtered by domain orgIter := client.Organizations().List(ctx, &workos.OrganizationsListParams{ Domains: []string{"acme.com"}, }) for orgIter.Next() { org := orgIter.Current() fmt.Println(org.ID, org.Name) } if err := orgIter.Err(); err != nil { log.Fatal(err) } ``` ```