01.software Docs

Customers SDK

Customer identity, hosted sessions and source-aware groups.

Customers SDK

For a complete task, start with the Customers guide. This reference keeps the public SDK boundary; use SDK basics for imports and peers.

Source-aware customer groups

Trusted server workflows can list the authoritative reasons for Customer Group membership and add or revoke only the manual source:

import { createServerClient } from '@01.software/sdk/server'

type Server = ReturnType<typeof createServerClient>

export async function grantManualMembership(
  server: Server,
  input: { groupId: string; customerId: string; reason: string },
) {
  await server.customerGroups.grantMember(input)
  return server.customerGroups.listMembers({
    groupId: input.groupId,
    limit: 100,
  })
}

export async function revokeManualMembership(
  server: Server,
  input: { groupId: string; customerId: string },
) {
  await server.customerGroups.revokeMember(input)
  return server.customerGroups.listMembers({
    groupId: input.groupId,
    limit: 100,
  })
}

Call grantManualMembership to retain the manual source. Call the separate revokeManualMembership only after an explicit decision to remove that source; granting does not automatically revoke it.

An active Membership source remains effective after a manual source is revoked. Treat customers.groups as a read-compatible projection; do not write it directly after source-authority activation.

Customer Auth

Hosted customer OAuth is the default path for new storefronts. Configure the browser-safe client with the workspace publishable key plus customer auth issuer and client id:

import { createClient } from '@01.software/sdk'

// Consume this client in trusted routes with a server-owned token store.
export function createHostedCustomerClient(
  publishableKey: string,
  issuer: string,
  clientId: string,
) {
  return createClient({
    publishableKey,
    customer: { persist: false, oauth: { issuer, clientId } },
  })
}

In a trusted route handler, first guard that client.customer.oauth is configured, then call createAuthorizationUrl() to start PKCE. Exchange the callback code server-side and store access, refresh, and transient OAuth state in HttpOnly cookies or another server-owned session store. Do not place hosted customer OAuth tokens in browser JavaScript, localStorage, or client-readable cookies.

client.customer.auth.login() and register() remain available for legacy direct email/password compatibility, but new ecommerce templates should expose that path only behind explicit legacy routes. For a direct session, call await client.customer.auth.logoutAsync() to revoke its refresh-token family. It clears local credentials even if revocation fails; handle a rejected promise as incomplete server logout. The older synchronous logout() only clears local state. useCustomerLogout() waits for revocation and clears authenticated customer query data on either outcome. An already issued access token may remain valid for up to 15 minutes. Workspace admins can disable new password registrations in Console Customer Authentication settings. register() then returns 403 registration_disabled; existing password login and reset remain available.

For those direct local-auth integrations, client.customer.auth.forgotPassword(email) supports either signed workspace webhook delivery or platform-managed reset email. Choose the delivery mode and configure the absolute storefront reset URL under the Console customer authentication settings. Platform delivery appends the token query parameter and uses the verified workspace sender when available. The SDK does not accept an arbitrary redirect URL for this call.

Self-withdrawal

Call client.customer.auth.withdraw(currentPassword) with a signed-in password account. Success clears SDK credentials; also clear application-owned cookies and caches. Handle active_membership_exists and reauthentication_unavailable (409), and account_locked (423). See the SDK README for the full account, error and retention behavior.

Hosted session methods

customer.oauth is optional; guard configuration before calling createAuthorizationUrl, parseCallback, exchangeCode, refresh or logout. parseCallback must receive the stored expectedState; exchange uses the original PKCE verifier and registered redirect URI. After exchange, set the access token in the trusted client and call customer.auth.me() for identity readback. Serialize rotation and preserve one server-owned access/refresh pair.

Hosted logout success means the request was accepted, not that a sweep is observable. A recognized unexpired refresh token for the same workspace/client triggers a sweep even after rotation or family revocation. Absent, expired or differently client-bound tokens do not. The app cannot distinguish these outcomes. Sweep covers that customer's clients in the workspace, including legacy-direct; only internal retries of the same durable intent preserve post-fence families. Follow the complete sign-in/logout task for cookie cleanup and revocation_unconfirmed handling; cleanup failures must not replace the primary error.

Next Actions

On this page