docs
/
AppEngine API

Customer authentication

Sign-up, sign-in, password reset and social login for the end users of a tenant.

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

POST/profile/customer/signupNo auth
POST/profile/customer/signinNo auth
POST/profile/customer/refreshNo auth

Successful sign-in returns the customer record plus tokens:

{ "customer": { "sk": "…", "datatype": "customer", "data": { … } },
  "orgId": "acme", "token": "…", "refreshToken": "…" }

Unlike users, customers self-register.

Password management

GET/profile/customer/password/forgot/:email/:redirectUrl?No auth
POST/profile/customer/password/validate-tokenNo auth
POST/profile/customer/password/resetNo auth
POST/profile/customer/password/changeJWT

forgot 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

POST/profile/customer/social-loginNo auth
POST/profile/customer/google/tokenNo auth

social-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

POST/profile/customer/updateJWT
GET/profile/customer/profile/:emailOrUsernameJWT
GET/profile/customer/exist/:emailOrUsernameNo auth
GET/profile/customers/:attr/:valueJWT
DELETE/profile/customer/profile/:emailOrUsernameJWT
DELETE/profile/customer/selfJWT

customer/exist is public so a sign-up form can tell the visitor an account already exists before submitting.

Subscriptions

POST/profile/customer/subscribeNo auth
POST/profile/customer/unsubscribeNo auth

Marketing 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

POST/profile/customer/dashboard/auth/:authOrgIdNo auth

Authenticates 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

POST/profile/guest/authNo auth

Returns { 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: acme

The 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.

System users cannot write as themselves

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