The endpoints a client application uses, grouped by what you are doing. Paths are relative to the host; every one needs orgid.
Auth column: public — no customer needed · customer — needs x-client-authorization.
Authentication
| Method | Path | Auth | Purpose |
|---|---|---|---|
POST | profile/customer/signin | public | Email + password → token |
POST | profile/customer/signup | public | Create a customer |
POST | profile/customer/refresh | public | Exchange a refresh token |
GET | profile/logout | customer | End the session |
GET | profile/customer/profile | customer | The signed-in customer |
POST | profile/customer/update | customer | Update profile |
GET | profile/customer/exist | public | Is this email registered? |
GET | profile/magic-link | public | Send a passwordless link |
POST | profile/magic-link/redirect | public | Redeem one |
POST | profile/customer/social-login | public | Google / Facebook identity |
GET | profile/customer/password/forgot | public | Start a reset |
POST | profile/customer/password/reset | public | Complete a reset |
POST | profile/customer/password/validate-token | public | Check a reset token |
POST | profile/security/challenge/send | customer | Send an MFA challenge |
POST | profile/security/challenge/verify | customer | Verify it |
Catalog
| Method | Path | Auth | Purpose |
|---|---|---|---|
GET | storefront/products | public | Paged list. p, ps, categories, tags, brand, price, minPrice, maxPrice, sort |
GET | storefront/product/:slugOrSku | public | One product |
GET | storefront/product/category | public | Products in a category |
POST | storefront/search | public | Keyword search |
POST | storefront/find | public | Structured query |
GET | storefront/categories | public | Category list |
GET | storefront/brands | public | Brand list |
GET | storefront/collections | public | Collections |
Responses carry minMaxPrice alongside the paging fields, so a price filter can be rendered without a second call.
Pricing, shipping and discounts
| Method | Path | Auth | Purpose |
|---|---|---|---|
POST | storefront/pricing/calculate-cart | either | The money call. Items + address + coupon → full summary |
POST | storefront/discounts/apply | either | Validate a coupon on its own |
POST | shipping/options | either | Every way this cart can ship, cheapest first |
POST | shipping/calculate | either | One shipping figure for a cart |
POST | shipping/rates | either | Live carrier rates for a parcel |
GET | shipping/methods | either | Configured methods (GET, not POST) |
POST | shipping/product-cost | either | Shipping for a single product |
POST | shipping/verify-address | either | Address validation |
calculate-cart returns subtotal, discount, tax, total, deposit, productSubtotal, productDiscount, productTax, productShipping, productTotal, rentalSubtotal, rentalTotal, shippingMethod, shippingOptions, freeShipping, freeDelivery, depositWaived, discounts, valid, reason, message, cartId.
shipping/options returns { served, options[], currency, problems? }. served: false means no configuration covers that destination — it is an honest refusal, not a zero rate. served: true with an empty options means somewhere is covered but could not be priced right now; problems[] says why (carrier unreachable, no origin set, missing parcel dimensions, over a weight limit).
Checkout and orders
| Method | Path | Auth | Purpose |
|---|---|---|---|
POST | storefront/checkout-cart | either | Place an order |
POST | storefront/take-payment | either | Charge against an order |
GET | storefront/payment-gateways | public | Enabled gateways |
POST | storefront/stripe/intent | either | Stripe PaymentIntent |
POST | storefront/stripe/checkout-session | either | Stripe Checkout |
POST | storefront/stripe/subscription-session | either | Subscription checkout |
GET | storefront/verify-payment | either | Confirm a payment |
GET | storefront/order/get | customer | One order |
GET | storefront/orders/get | customer | The customer's orders |
GET | storefront/order/email | public | Look an order up by email |
POST | storefront/order/refund | customer | Request a refund |
GET | storefront/subscriptions/get | customer | Subscriptions |
POST | storefront/update-subscription | customer | Change one |
The client/* surface
Customer-scoped. Routes resolve "me" from x-client-authorization — you never pass a customer id. Every route that writes needs it; a few reads (the Content Player's) also answer without one.
| Method | Path | Purpose |
|---|---|---|
GET | client/affiliate/programs | Programs open to join |
POST | client/affiliate/join | Enrol |
GET | client/affiliate/me | Enrolments with stats and referral code |
GET | client/affiliate/me/link?program=… | Referral link (let the server build it) |
GET | client/affiliate/me/referrals?program=… | Referrals |
GET | client/affiliate/me/earnings?program=… | Earnings |
GET | client/finance/wallet | Wallet balance |
GET | client/finance/payouts | Payout history |
POST | client/finance/payouts/request | Request a payout |
GET/POST/PUT/DELETE | client/finance/payout-methods | Manage payout methods |
GET | client/events | Events |
POST | client/events/tickets/purchase | Buy tickets |
POST | client/events/tickets/confirm-order | Confirm |
GET | client/events/tickets/mine | The customer's tickets |
GET | client/events/participation/mine | Their participation |
Content Player — client/content-studio
Plays Content Studio posts (courses, applications, trainings, blog posts). Only published posts are served. Reading an unlocked page needs no customer token; saving needs one, and the first save enrolls the customer. An optional ?code= (access code or invitation) is passed through.
| Method | Path | Body / purpose |
|---|---|---|
GET | client/content-studio/mine | Everything the customer has started — status, %, next page, due date |
GET | client/content-studio/:post | The post, its outline (each item's status, lock reason, type, duration, step; chapters' done / total), my progress, and next |
POST | client/content-studio/:post/enroll | Start |
GET | client/content-studio/:post/items/:itemId | One page — content, prev / next, my progress and saved answer |
POST | client/content-studio/:post/items/:itemId/progress | { done, percent, score } |
POST | client/content-studio/:post/items/:itemId/answer | { values, done } — the page's answer; quizzes are marked 0–100 |
The staff side, content-studio/* (review queue, enrollments, review decisions, preview), is for signed-in business users only. It refuses the site's app token — never route it through a public proxy.
me/referrals, me/earnings and me/link require program as a query parameter. Omit it and you get 400 Program name is required.
Notes that save a debugging session
shipping/methodsis aGET. Everything around it is aPOST; posting to it 404s.- Referral codes are an array. An affiliate holds
codes[]— live, retired and disabled. The client responses resolve the live one ontodata.codefor you; do not walk the array yourself. forbidNonWhitelistedis on. Round-tripping a record —GET, change one field,POSTback — fails with a400because the read shape carries fields the write DTO does not accept. Send only what the write accepts.- Bodies are capped at 4 MB. Use the upload endpoints for files.
- Content Player answers upload their files first, to
client-data/files/upload(categorycontent-player), then send the answer with the file references. A proxy must allow that prefix.
Anything not listed here
This page covers the client-facing surface. AppEngine is much larger — see AppEngine API → Modules. From the browser runtime, any endpoint is reachable without a hand-written wrapper:
await appmint.api.post('shipping/options', { items, toAddress });