Customers are the end users of a tenant's site or app. They are a separate datatype (customer) with their own endpoints, their own token flavor, and no access to the operator surface.
A customer token carries datatype: "customer", which is how CurrentUserMiddleware decides to populate request.currentCustomer.
Sign-up and sign-in
/profile/customer/signupNo auth/profile/customer/signinNo auth/profile/customer/refreshNo authSuccessful sign-in returns the customer record plus tokens:
{ "customer": { "sk": "…", "datatype": "customer", "data": { … } },
"orgId": "acme", "token": "…", "refreshToken": "…" }Unlike users, customers self-register.
Password management
/profile/customer/password/forgot/:email/:redirectUrl?No auth/profile/customer/password/validate-tokenNo auth/profile/customer/password/resetNo auth/profile/customer/password/changeJWTforgot takes an optional redirectUrl so the reset email can return the customer to the page they started from. validate-token lets the reset form check the token before asking for a new password.
Social login
/profile/customer/social-loginNo auth/profile/customer/google/tokenNo authsocial-login validates a provider token and issues a customer session. The Google endpoint exchanges a Google ID token directly — the flow a mobile app uses after a native Google sign-in.
Profile
/profile/customer/updateJWT/profile/customer/profile/:emailOrUsernameJWT/profile/customer/exist/:emailOrUsernameNo auth/profile/customers/:attr/:valueJWT/profile/customer/profile/:emailOrUsernameJWT/profile/customer/selfJWTcustomer/exist is public so a sign-up form can tell the visitor an account already exists before submitting.
Subscriptions
/profile/customer/subscribeNo auth/profile/customer/unsubscribeNo authMarketing opt-in and opt-out, writing to the subscriber datatype. Unsubscribe is public because it has to work from an email link with no session.
Customer dashboards
/profile/customer/dashboard/auth/:authOrgIdNo authAuthenticates a customer into a dashboard belonging to a specific org — used where one storefront's customer needs access to a related org's portal.
Guests
/profile/guest/authNo authReturns { guest, token, refreshToken } for an anonymous guest customer, so a cart or booking can exist before the visitor creates an account.
Acting on a customer's behalf
Server-side code holding a System user token can act as a customer by adding the customer's token:
Authorization: Bearer <system-user-token>
x-client-authorization: Bearer <customer-token>
orgid: acmeThe middleware loads the customer into currentCustomer, JwtAuthGuard evaluates repository writes against the customer, and created records are stamped with the customer's sk as author.
A System-role user calling repository/create|update|delete without x-client-authorization gets 401 — No customer found - x-client-authorization header is missing. Server-side integrations must carry the end user's token, not just their own.
Client-facing modules
Customer-facing apps should prefer the /client/* controllers, which expose a narrower surface intended for customer tokens:
/client/events · /client/community · /client/content-studio · /client/finance · /client/forms · /client/giftcards · /client/broadcast · /client/logistics · /client/affiliate · /client/stowbo · /client-data · /affiliate/public