Documentation

Client API overview

Customer-facing endpoints under /client/* and /client-data/*.

The Client API is the half of AppEngine that your customers' apps talk to — order history pages in a customer portal, "manage subscriptions" screens, the storefront's wishlist, the gig-worker app's job feed. It runs alongside the staff/operator API but uses a separate auth model and a separate URL prefix.

Two principal types, two URL trees

AppEngine separates the people who run an app (Users) from the people who use it (Customers). The URL prefix tells you which audience an endpoint serves:

PrefixAudienceAuth
/profile/customer/*Customer auth flowsPublic
/client-data/*Customer's own profile and accountCustomer JWT
/client/community/*Customer's social/community surfaceCustomer JWT
/client/finance/*Customer wallets and payoutsCustomer JWT
/client/events/*Customer ticket purchase and check-inCustomer JWT
/client/logistics/*Customer order tracking and gig-worker portalCustomer JWT
/client/affiliate/*Affiliate partner portalCustomer JWT
/client-app/*Multi-tenant client app managementStaff JWT
/storefront/*Public commerce surfaceMostly public

A customer-facing app uses the customer JWT obtained from POST /profile/customer/signin. The same orgid header rules apply — customer auth is org-scoped just like staff auth.

Auth pattern

Every authenticated client endpoint resolves the principal via @CurrentCustomerOrUser(). This decorator accepts either a customer JWT or a user JWT, but client endpoints that handle PII or money explicitly check that the principal is a customer (or that the user has impersonation rights).

const customerJwt = await fetch('/api/profile/customer/signin', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json', orgid: ORG_ID },
  body: JSON.stringify({ email, password }),
}).then(r => r.json()).then(d => d.token);

const orders = await fetch('/api/client-data/orders', {
  headers: {
    orgid: ORG_ID,
    Authorization: `Bearer ${customerJwt}`,
  },
}).then(r => r.json());

What the Client API does not do

  • It does not expose write access to other customers' data — every read and write is implicitly scoped to the authenticated customer's sk.
  • It does not include staff endpoints. If you need to manage someone else's order, that's the operator API (e.g. POST /storefront/order/process/:orderNumber).
  • It does not bypass the catalog auth model. Public storefront browsing endpoints (GET /storefront/products) are unauthenticated; "my orders" requires the customer JWT.

Pages in this section