REST API Controllers Reference
WP Sell Services registers 25 REST controllers plus a set of generic utility routes. WP Sell Services Pro adds 9 more. Everything lives under one namespace:
/wp-json/wpss/v1/Every route below is generated from the 1.4.0 source. Path parameters are shown
as WordPress route regex ((?P<id>[\d]+)) so you can match them exactly.
For authentication, pagination, error shapes, and the generic endpoints, see REST API Overview.
POST/PUT/PATCHmeans the route is registered asEDITABLE, so WordPress accepts all three verbs on it.
Two namespaces – and only one of them is the API
Section titled “Two namespaces – and only one of them is the API”There are two namespaces, and the split is not the one the names suggest.
| Namespace | What is on it |
|---|---|
wpss/v1 |
Everything. All 25 free controllers and all 10 Pro controllers. Pro extends the API; it does not run a parallel one. |
wpss-pro/v1 |
Exactly four cart-adapter routes, and only while the matching cart plugin is active. |
The four wpss-pro/v1 routes are:
| Method | Route | Present when |
|---|---|---|
| GET | /wpss-pro/v1/fluentcart/products |
FluentCart is active |
| GET | /wpss-pro/v1/fluentcart/orders |
FluentCart is active |
Build every client against wpss/v1. Prefixing a Pro endpoint with
wpss-pro/v1 returns rest_no_route on every single one.
Route presence is conditional
Section titled “Route presence is conditional”Two things change which routes exist on a given site, so enumerate rather than assume:
- The active e-commerce rail.
/payments/*– in free and Pro – registers only whenwpss_uses_standalone_payments()is true, i.e. no cart plugin has claimed payments. Activate WooCommerce, EDD or FluentCart and those routes stop registering entirely; a call to them answers404 rest_no_routefrom WordPress core. That is by design: when a cart plugin is enabled it owns all payment, and the plugin does not offer a second way in. - Pro + a valid license. The 10 Pro controllers register on
wpss_loaded.
To see the truth for a site, read the index: GET /wp-json/wpss/v1.
Free controllers
Section titled “Free controllers”Generic utility routes
Section titled “Generic utility routes”Registered by the API bootstrap rather than a dedicated controller.
| Method | Route | Purpose |
|---|---|---|
| GET | / |
Namespace index – the WordPress-generated route list for wpss/v1. The authoritative answer to “what exists on this site”. |
| GET | /categories |
Service categories |
| GET | /tags |
Service tags |
| GET | /settings |
Public marketplace settings |
| GET | /me |
Current user summary |
| GET | /dashboard |
Dashboard payload for the current user |
| GET | /search |
Cross-entity search |
| POST | /batch |
Batch several reads into one request |
| POST | /tour/complete |
Mark the guided onboarding tour finished for the current user. Called by the bundled tour; persists per-user so the tour does not replay. |
Services
Section titled “Services”| Method | Route |
|---|---|
| GET, POST | /services |
| GET | /services/grid |
| GET | /services/limits |
| GET, POST/PUT/PATCH, DELETE | /services/(?P<id>[\d]+) |
| GET | /services/(?P<id>[\d]+)/packages |
| GET | /services/(?P<id>[\d]+)/faqs |
| GET | /services/(?P<id>[\d]+)/reviews |
| GET, POST | /services/(?P<id>[\d]+)/addons |
| POST/PUT/PATCH, DELETE | /services/(?P<id>[\d]+)/addons/(?P<addon_id>[\d]+) |
/services/grid returns the lighter payload used by the catalog grid. Prefer it
over /services when you only need cards.
/services/limits returns the ceilings a single service may not exceed, so a
client can build its create-service form without discovering each one by being
rejected. Public read; no authentication needed.
{ "max_packages": 3, "max_gallery": 4, "max_videos": 1, "max_extras": 3, "max_faq": 5, "max_requirements": 5}-1 means unlimited. The numbers above are the Free defaults; Pro raises
max_gallery, max_extras, max_faq and max_requirements to -1 and leaves
max_packages and max_videos where they are. Each value passes through its own
wpss_service_max_* filter, so a site can set its own ceilings - read the route
rather than hard-coding these numbers.
Orders
Section titled “Orders”| Method | Route |
|---|---|
| GET | /orders |
| GET, POST/PUT/PATCH | /orders/(?P<id>[\d]+) |
| GET, POST | /orders/(?P<id>[\d]+)/messages |
| GET, POST | /orders/(?P<id>[\d]+)/deliverables |
| GET | /orders/(?P<id>[\d]+)/files/(?P<file_id>[A-Za-z0-9\-]+) |
| POST | /orders/(?P<id>[\d]+)/(?P<action>…) |
| GET, POST | /orders/(?P<id>[\d]+)/requirements |
| POST | /orders/(?P<id>[\d]+)/requirements/skip |
| DELETE | /orders/(?P<id>[\d]+)/requirements/files/(?P<file_id>[\d]+) |
| GET | /orders/(?P<id>[\d]+)/sub-orders |
| GET | /orders/(?P<id>[\d]+)/receipts |
| GET | /orders/(?P<id>[\d]+)/timeline |
| POST | /orders/(?P<id>[\d]+)/pay |
Order transitions all go through one action route rather than a verb per
transition. (?P<action>…) accepts exactly:
start | deliver | complete | revision | cancel | disputehold | resume | accept-cancellation | reject-cancellationChanged in 1.4.0:
acceptandrejectwere removed. They had no handler behind them and returned a misleading success on some paths, so a client built against them was never actually transitioning anything. There is no replacement – an order is accepted by being paid.delivernow routes throughDeliveryServicerather than writing the status directly, so a delivery made over REST produces the same records and notifications as one made in the dashboard.
curl -X POST https://yoursite.com/wp-json/wpss/v1/orders/42/deliver \ -H "X-WP-Nonce: $NONCE"/sub-orders lists the milestone, tip, and extension sub-orders attached to a
parent order – see Sub-Order Pattern.
GET /orders/{id}/timeline (new in 1.4.0) returns the merged, chronological
event history for one order – status transitions, deliveries, revisions,
milestone and extension events, and payment events – as a single list. It is
what an order-detail screen renders instead of stitching four endpoints
together.
Paying an order or a phase
Section titled “Paying an order or a phase”POST /orders/{id}/pay and POST /milestones/{id}/pay do not take money.
They resolve where the buyer must go to pay, and enforce the milestone
lock-step guard while doing so.
POST /orders/{id}/pay – 200:
{ "success": true, "order_id": 42, "checkout_url": "https://yoursite.com/checkout/order-pay/1042/?key=wc_order_…", "platform": "milestone"}platform is the sub-order type when the row is one (milestone, tip,
extension) and an empty string for a normal order.
POST /milestones/{id}/pay – 200:
{ "success": true, "milestone_id": 57, "checkout_url": "https://yoursite.com/checkout/order-pay/1043/?key=wc_order_…"}Errors on both:
| Status | Code | When |
|---|---|---|
| 404 | wpss_order_not_found / wpss_milestone_not_found |
No such row, or the row is not a milestone |
| 409 | wpss_order_not_payable / wpss_milestone_not_payable |
The row is not in pending_payment |
| 409 | wpss_milestone_locked |
An earlier phase is still open |
Section titled “checkout_url is a BROWSER url, not an API endpoint”
checkout_urlis a BROWSER url, not an API endpointThis is the single most common way to get this wrong.
checkout_urlis a page for a human, resolved through thewpss_ensure_pay_orderfilter by whatever e-commerce rail is active. Do not fetch it, do not parse it, do not reconstruct it. A native client must open it in a webview (or the system browser) and watch for the return URL.On the WooCommerce rail it is a WooCommerce order-pay page (
/checkout/order-pay/{wc_id}/?key=…), rendered by WooCommerce with whatever gateways the store has enabled. There is no JSON behind it.Side effect on Woo: generating this URL creates a real WooCommerce order. Pro’s
WCPayOrderResolvercreates (or reuses) an unpaid WC order for the amount owed so the link survives an email with no cart session. It is idempotent – the WC order id is stored on the WPSS row aswc_pay_order_idand reused while the order still needs payment – but calling/payspeculatively on a site with Woo active still puts a pending order in the store. Call it when the buyer is actually about to pay.On the standalone rail it is
…/checkout/?pay_order={id}and nothing is created.On the FluentCart rail it is a FluentCart checkout URL for an order that rail minted, with the same side effect and the same idempotence: Pro’s
FluentCartPayOrderResolvercreates or reuses one FluentCart order carrying a single fee line. FluentCart is a beta rail, off untilwpss_pro_beta_railsreturns true.EDD has no pay-order rail. It hooks neither half of the seam, so
wpss_can_pay_single_order()is false andcheckout_urlis an empty string – there is no Pay button to offer. See Pay-order support by rail for the one support table.
Milestones
Section titled “Milestones”| Method | Route |
|---|---|
| GET, POST | /orders/(?P<order_id>[\d]+)/milestones |
| GET, DELETE | /milestones/(?P<id>[\d]+) |
| POST | /milestones/(?P<id>[\d]+)/pay |
| POST | /milestones/(?P<id>[\d]+)/submit |
| POST | /milestones/(?P<id>[\d]+)/approve |
| POST | /milestones/(?P<id>[\d]+)/decline |
| POST | /milestones/(?P<id>[\d]+)/request-revision |
The terminal actions are approve and decline (not “reject”) – the same vocabulary as the milestone hooks.
request-revision is the buyer’s third option on a submitted phase: it takes a
reason, returns the phase to revision_requested so the seller can resubmit,
and posts the reason into the parent contract’s conversation. A phase has no
conversation of its own. Only the buyer may call it, and only while the phase
is pending_approval.
Extensions and tips
Section titled “Extensions and tips”| Method | Route |
|---|---|
| GET, POST | /orders/(?P<order_id>[\d]+)/extensions |
| POST | /orders/(?P<order_id>[\d]+)/extension |
| POST | /extensions/(?P<id>[\d]+)/decline |
| GET, POST | /orders/(?P<order_id>[\d]+)/tip |
| GET | /vendors/(?P<vendor_id>[\d]+)/tips |
| GET | /vendors/(?P<vendor_id>[\d]+)/tips/total |
Vendors
Section titled “Vendors”| Method | Route |
|---|---|
| GET | /vendors |
| GET | /vendors/(?P<id>[\d]+) |
| GET, POST/PUT/PATCH | /vendors/me |
| POST/PUT/PATCH | /vendors/me/vacation |
| GET | /vendors/(?P<id>[\d]+)/services |
| GET | /vendors/(?P<id>[\d]+)/reviews |
| GET | /vendors/(?P<id>[\d]+)/stats |
| POST | /vendors/register |
Seller levels
Section titled “Seller levels”| Method | Route |
|---|---|
| GET | /seller-levels |
| GET | /seller-levels/(?P<level>[a-z_]+) |
| GET | /vendors/me/level |
| GET | /vendors/(?P<vendor_id>[\d]+)/level |
Portfolio
Section titled “Portfolio”| Method | Route |
|---|---|
| GET | /vendors/(?P<vendor_id>[\d]+)/portfolio |
| GET, POST | /portfolio |
| GET, POST/PUT/PATCH, DELETE | /portfolio/(?P<id>[\d]+) |
| POST | /portfolio/(?P<id>[\d]+)/featured |
| POST | /portfolio/reorder |
Reviews
Section titled “Reviews”| Method | Route |
|---|---|
| GET, POST | /reviews |
| GET, POST/PUT/PATCH, DELETE | /reviews/(?P<id>[\d]+) |
| POST | /orders/(?P<order_id>[\d]+)/review |
| POST | /reviews/(?P<id>[\d]+)/reply |
| POST | /reviews/(?P<id>[\d]+)/helpful |
| GET | /services/(?P<service_id>[\d]+)/reviews/summary |
| GET | /vendors/(?P<vendor_id>[\d]+)/reviews/summary |
Buyer requests and proposals
Section titled “Buyer requests and proposals”| Method | Route |
|---|---|
| GET, POST | /buyer-requests |
| GET | /buyer-requests/mine |
| GET, POST/PUT/PATCH, DELETE | /buyer-requests/(?P<id>[\d]+) |
| GET, POST | /buyer-requests/(?P<id>[\d]+)/proposals |
| POST | /buyer-requests/(?P<id>[\d]+)/proposals/(?P<proposal_id>[\d]+)/accept |
| POST | /buyer-requests/(?P<id>[\d]+)/proposals/(?P<proposal_id>[\d]+)/reject |
| GET, POST | /proposals |
| GET, POST/PUT/PATCH | /proposals/(?P<id>[\d]+) |
| POST | /proposals/(?P<id>[\d]+)/withdraw |
| GET | /proposals/stats |
Request attachments. PUT /buyer-requests/{id} accepts attachments, an
array of media IDs uploaded with POST /media and context=request. The array
replaces the list; leave the field out to keep the attachments as they are.
While the request has no proposal, a file left out of the list is deleted.
Once any proposal exists, files already on the request stay whatever the
array says, new IDs are added, and DELETE /media/{id} on such a file answers
409 wpss_file_in_use.
Conversations
Section titled “Conversations”| Method | Route |
|---|---|
| GET | /conversations |
| GET | /conversations/(?P<id>[\d]+) |
| GET, POST | /conversations/(?P<id>[\d]+)/messages |
| POST | /conversations/(?P<id>[\d]+)/read |
| GET | /conversations/unread-count |
| GET | /orders/(?P<order_id>[\d]+)/conversation |
| POST | /orders/(?P<order_id>[\d]+)/conversation/messages |
Disputes
Section titled “Disputes”| Method | Route |
|---|---|
| GET | /disputes |
| GET | /disputes/(?P<id>[\d]+) |
| GET, POST | /orders/(?P<order_id>[\d]+)/dispute |
| POST | /disputes/(?P<id>[\d]+)/respond |
| GET, POST | /disputes/(?P<id>[\d]+)/evidence |
| GET | /disputes/(?P<id>[\d]+)/timeline |
| POST | /disputes/(?P<id>[\d]+)/escalate |
| POST | /disputes/(?P<id>[\d]+)/cancel |
| POST | /disputes/(?P<id>[\d]+)/resolve |
| POST | /disputes/(?P<id>[\d]+)/assign |
| GET | /disputes/options |
resolve and assign require dispute-management capability. See
Admin Mediation.
Earnings and withdrawals
Section titled “Earnings and withdrawals”| Method | Route |
|---|---|
| GET | /earnings/summary |
| GET | /earnings/history |
| GET | /wallet/transactions |
| GET, POST | /withdrawals |
| POST/PUT/PATCH | /withdrawals/(?P<id>[\d]+) |
| DELETE | /withdrawals/(?P<id>[\d]+) (vendor cancels their own pending request) |
| GET, PUT | /withdrawals/profile (the vendor’s payout profile) |
| GET | /withdrawals/methods |
Payments (free) – standalone rail only
Section titled “Payments (free) – standalone rail only”| Method | Route |
|---|---|
| GET | /payments/methods |
| POST | /payments/create-intent |
| POST | /payments/confirm |
These are the standalone checkout payment routes shipped in free. Pro replaces them with a wider, gateway-specific set – see Payments (Pro).
POST /payments/create-intent takes service_id, package_id (stable id or
legacy index), quantity and addons (ids, or {id, quantity, option, text}
objects), or pay_order for an existing order, plus gateway. It is priced on
the server exactly like the web checkout - package, quantity, add-ons and tax -
and never reads a price from the request.
These routes do not exist on every site. As of 1.4.0 the whole controller is skipped unless
wpss_uses_standalone_payments()is true (src/API/PaymentController.php). With WooCommerce, EDD, FluentCart or FluentCart enabled, that rail owns all payment and these routes are never registered – a client calling them gets404 rest_no_route. Do not treat that as an error to retry: checkGET /wpss/v1(orGET /settings) and send the buyer to the rail’s own checkout instead.Switching rails never rewrites past orders – an order paid through a gateway keeps its record, and that gateway’s webhooks keep working.
| Method | Route |
|---|---|
| GET | /cart |
| POST | /cart/add |
| DELETE | /cart/(?P<item_key>[a-z0-9]+) |
| POST | /cart/checkout |
Cart items are addressed by item_key, not by service id – one service can
appear more than once with different packages and add-ons.
GET /cart prices every line the way checkout will charge it. Since 1.8.0
each line also carries unavailable (boolean) and unavailable_reason
(string). A line is unavailable when its service was deleted, unpublished or
paused after it was added. Such a line is returned at 0 and is left out of
subtotal, tax and total; show the reason and offer to remove it.
Authentication
Section titled “Authentication”Authentication ships in the free plugin, not Pro.
| Method | Route |
|---|---|
| POST | /auth/login |
| POST | /auth/register |
| POST | /auth/logout |
| GET | /auth/me |
| POST | /auth/forgot-password |
| POST | /auth/change-password |
| GET, POST | /auth/devices |
| DELETE | /auth/devices/(?P<device_id>[a-zA-Z0-9_-]+) |
| GET, DELETE | /auth/sessions |
| DELETE | /auth/sessions/(?P<uuid>[a-zA-Z0-9\-]+) |
/auth/devices registers a device for push notifications – what a mobile
client calls after login.
/auth/sessions is a different thing and deliberately a separate route: it
lists and revokes the app tokens a member holds. DELETE /auth/sessions ends
them all; the {uuid} form ends one. They are not on /auth/devices because
that route already means push tokens.
Favorites, media, notifications, moderation, audit log
Section titled “Favorites, media, notifications, moderation, audit log”| Method | Route |
|---|---|
| GET | /favorites |
| POST, DELETE | /favorites/(?P<service_id>[\d]+) |
| GET | /services/(?P<service_id>[\d]+)/favorited |
| GET, POST | /media |
| GET, DELETE | /media/(?P<id>[\d]+) |
| GET | /notifications |
| GET | /notifications/unread-count |
| POST | /notifications/(?P<id>[\d]+)/read |
| POST | /notifications/read-all |
| DELETE | /notifications/(?P<id>[\d]+) |
| GET | /moderation/pending |
| GET | /moderation/count |
| GET | /moderation/(?P<service_id>[\d]+) |
| POST | /moderation/(?P<service_id>[\d]+)/approve |
| POST | /moderation/(?P<service_id>[\d]+)/reject |
| GET | /audit-log |
Reporting and blocking
Section titled “Reporting and blocking”Both ship in the free plugin. A store submitting a marketplace app needs them: App Store Guideline 1.2 asks for a way to report content and a way to block the person who posted it.
| Method | Route |
|---|---|
| GET, POST | /reports |
| POST | /reports/(?P<id>[\d]+)/resolve |
| GET | /blocks |
| POST, DELETE | /blocks/(?P<user_id>[\d]+) |
POST /reports files a report against any target type; the vocabulary of
target types is filterable, so the same controller serves services, orders,
vendors and messages. GET /reports is the owner’s queue and is admin-only.
On the website, members reach POST /reports through the Report link on the
service page and the vendor profile; see
Member Reports.
Reporting asks the owner to act. Blocking lets a member act immediately, which is the one that actually ends a bad interaction, so the two are separate routes rather than one moderation surface. Blocks are stored in user meta, and enforcement lives at the points where two members can reach each other rather than in the controller.
Realtime
Section titled “Realtime”| Method | Route |
|---|---|
| POST | /realtime/auth |
Private-channel authorization for the realtime (WebSocket) layer. The plugin speaks the Pusher protocol, so this works with Pusher.com or any self-hosted Pusher-compatible server (e.g. Soketi). Client connection settings (key, host, cluster, port, TLS) are exposed under the realtime key of GET /settings; the app secret never leaves the server.
POST /realtime/auth
Section titled “POST /realtime/auth”Authorize a private-channel subscription per the Pusher auth contract. Called automatically by the bundled wpss-realtime.js client (with the X-WP-Nonce header); external clients can call it with any supported authentication method.
Authentication Required: Yes (logged-in user)
Parameters:
socket_id(string, required) - Pusher socket ID of the connecting client (format123.456)channel_name(string, required) - Private channel to subscribe to
Allowed channels:
private-wpss-user-{ID}- Only the user themselfprivate-wpss-order-{ID}- The order’s customer, its vendor, or administrators
Response (200):
{ "auth": "app_key:hmac_sha256_signature"}Errors:
401 rest_not_logged_in- Not authenticated403 wpss_realtime_forbidden- Channel not owned by the current user (any channel outside the two shapes above is also refused)404 wpss_realtime_disabled- Realtime is not enabled/configured on this site
Example:
curl -X POST \ https://yoursite.com/wp-json/wpss/v1/realtime/auth \ -u "username:xxxx xxxx xxxx xxxx" \ -d "socket_id=1234.5678" \ -d "channel_name=private-wpss-user-45"Events published by the plugin:
notification.createdonprivate-wpss-user-{ID}- payload{ id, type }message.createdonprivate-wpss-order-{ID}and the recipient’sprivate-wpss-user-{ID}- payload{ order_id, sender_id, message_id, excerpt }
Pro controllers [PRO]
Section titled “Pro controllers [PRO]”Available only when WP Sell Services Pro is active with a valid license.
Payments (Pro)
Section titled “Payments (Pro)”| Method | Route |
|---|---|
| GET | /payments/methods |
| POST | /payments/stripe/create-intent |
| POST | /payments/stripe/confirm |
| POST | /payments/paypal/create-order |
| POST | /payments/paypal/capture |
| POST | /payments/razorpay/create-order |
| POST | /payments/razorpay/verify |
| POST | /payments/offline/submit |
| GET | /payments/(?P<order_id>[\d]+)/status |
Wallet
Section titled “Wallet”| Method | Route |
|---|---|
| GET | /wallet/balance |
| GET | /wallet/transactions |
| POST | /wallet/withdraw |
| GET | /wallet/withdrawals |
| GET | /wallet/providers |
Stripe Connect
Section titled “Stripe Connect”| Method | Route |
|---|---|
| POST | /stripe-connect/onboard |
| GET | /stripe-connect/status |
| POST | /stripe-connect/disconnect |
| GET | /stripe-connect/accounts |
| GET | /stripe-connect/accounts/(?P<vendor_id>[\d]+) |
| GET, POST/PUT/PATCH | /stripe-connect/settings |
PayPal mass payouts
Section titled “PayPal mass payouts”| Method | Route |
|---|---|
| GET, POST | /paypal-payouts/batches |
| GET | /paypal-payouts/batches/(?P<id>[\d]+) |
| POST | /paypal-payouts/batches/(?P<id>[\d]+)/sync |
| GET | /paypal-payouts/pending |
| GET, POST/PUT/PATCH | /paypal-payouts/profile |
/pending is what an owner exports to pay vendors manually; sync reconciles a
submitted batch back against the wallet ledger.
Commission rules
Section titled “Commission rules”| Method | Route |
|---|---|
| GET, POST | /commission-rules |
| GET | /commission-rules/preview |
| GET, POST/PUT/PATCH, DELETE | /commission-rules/(?P<id>[\d]+) |
preview resolves which rule would apply to a given vendor/category/amount
without persisting anything – use it to explain a rate in your own UI.
Vendor subscription plans
Section titled “Vendor subscription plans”| Method | Route |
|---|---|
| GET, POST | /subscription-plans |
| GET, POST/PUT/PATCH, DELETE | /subscription-plans/(?P<id>[\d]+) |
| GET | /subscription-plans/my-subscription |
| POST, DELETE | /subscription-plans/subscribe |
Recurring services
Section titled “Recurring services”| Method | Route |
|---|---|
| GET, POST | /recurring-services |
| GET | /recurring-services/(?P<id>[\d]+) |
| GET | /recurring-services/my-subscriptions |
| GET | /recurring-services/vendor-subscriptions |
| POST | /recurring-services/(?P<id>[\d]+)/cancel |
| POST | /recurring-services/(?P<id>[\d]+)/pause |
| POST | /recurring-services/(?P<id>[\d]+)/resume |
Recurring services sit behind a default-off feature flag in 1.3.0. The routes register, but the feature’s UI is hidden until you opt in – see Recurring Services.
Analytics
Section titled “Analytics”| Method | Route | Scope |
|---|---|---|
| GET | /analytics/overview |
Marketplace-wide – admin only |
| GET | /analytics/revenue |
Marketplace-wide – admin only |
| GET | /analytics/vendor/overview |
The calling vendor |
| GET | /analytics/vendor/revenue |
The calling vendor |
| GET | /analytics/vendor/orders |
The calling vendor |
| GET | /analytics/vendor/services |
The calling vendor |
| POST | /analytics/export |
Queue a data export |
The two un-prefixed routes (/analytics/overview, /analytics/revenue) are the
platform-owner numbers and were previously undocumented; the /vendor/* ones
are scoped to whoever is calling. /analytics/export is POST, not GET –
it starts an export rather than returning one.
/analytics/revenue takes period, one of 7days | 30days (default) |
90days | 12months.
Both admin routes register even on an unlicensed site, deliberately: an
unlicensed call answers 403 wpss_pro_license_required rather than
404 rest_no_route, so a client can tell “you need a license” apart from “this
build does not have that endpoint”. Anonymous callers get 401 rest_not_logged_in;
a logged-in non-admin gets 403.
White label
Section titled “White label”| Method | Route |
|---|---|
| GET, POST/PUT/PATCH | /white-label |
Returns the active branding (name, logo, colors) so a headless or mobile client can render the same identity as the site.
Related Documentation
Section titled “Related Documentation”- REST API Overview - Authentication, error handling, pagination, CORS
- Hooks and Filters - Available action and filter hooks
- Custom Integrations - Building custom controllers
- Money Flow - How the payment routes settle

