Role Endpoint Access
If you can't sign in, an action is blocked, or the POS asks you to update, find the code in the app's message and fix it here:
Diagnosing Failures
Sign in again (AUTH101)
The app says "Request still unauthorized after token refresh - please log in again".
- WCPOS opens the WordPress sign-in window by itself. Sign in there as the same cashier.
- If you closed the window, the app says "Please log in to continue". Press Login on that message to open the window again.
- Once you are back in, sales waiting to send go by themselves.
If the message comes back straight away, ask your site administrator for help and send them the AUTH101 page.
Sign-in failure details
The app got a 401, refreshed the token, and the retry was still a 401. This is the sign-in layer, not the role: a 403 never triggers a refresh. Something between the app and WordPress is dropping or refusing the token, often a security or authentication plugin (AUTH301).
Ask an administrator to check the role (AUTH201)
You are signed in, but your role does not allow this action. Ask your site administrator to check your access on Staff Access. They can follow AUTH201 to find the cause.
Role permission details
The server answered 403 to a signed-in user. Either the user lacks access_woocommerce_pos, or the route needs manage_woocommerce_pos or install_plugins. Find the endpoint in the lists below. If they say the user's role should reach it, the role has most likely been changed from the defaults: on the Access screen, where it shows Changed from the WCPOS defaults, by a role-editor plugin, or by custom code. An extra role on the user can also deny a capability.
If the endpoint is not in the lists, the tests behind them do not cover it: read that route's own permission check. WCPOS Pro can also refuse a user for a store they are not authorized for, for example 403 wcpos_display_store_forbidden ("You are not authorized for this store.").
Update the app (SYNC341)
The app says "Update the POS app on this device." The plugin on your site is newer than the app. Update the app, then reopen it:
- Web: reload the browser tab. If the message comes back: on a computer, hold Shift while reloading; on a phone or tablet, ask your site administrator for help and send them the SYNC341 page.
- Desktop: install the update the app offers, then reopen the app. If none is offered, download the latest desktop build for Windows, Mac (Intel or Apple silicon) or Linux.
- iPhone and iPad: update WCPOS from its TestFlight beta.
- Android: update WCPOS from its Google Play beta.
SYNC341 has the rest, including what a site administrator can do when no newer app exists yet.
App version details
The server answered 426 on a v2 route, because the app is older than the plugin's sync protocol.
Permission failure vs. token failure
AUTH201 means the user is signed in but not allowed: ask an administrator about the role. AUTH101 means the sign-in itself failed: sign in again.
How to tell them apart
403(AUTH201): the user is signed in but does not have permission for this action. Check the role's capabilities, and what the endpoint needs in the lists below.401(AUTH101, "Request still unauthorized after token refresh"): the server could not authenticate the app's request, and nobody is signed in. Sign in again; if it keeps coming back, check the token and anything between the app and WordPress that strips or refuses it.
Read the refused response in the browser's network panel, or in a server-side log. WP Admin > POS > Settings > Tools > Logs also records each 401 whose token was malformed or refused for a reason other than plain expiry. The status and the error code are in the response body. The signed-in user is not: read it on the server, for example with get_current_user_id() in a debug log while the request runs.
Role or capability failure:
- Status:
403 - Code:
woocommerce_pos_rest_forbidden, or the route's own, such asrest_forbidden - Signed-in user (server side): the cashier's WordPress user ID
Token or sign-in failure:
- Status:
401 - Code:
woocommerce_pos_rest_unauthorized data.reason: the token error, such aswoocommerce_pos_auth_token_expired- Signed-in user (server side):
0(nobody signed in)
A non-zero user points at capabilities. A user of 0 points at the token, or at something between the app and WordPress.
Related Documentation
For administrators and developers
Cashiers can stop reading here. The rest of this page is for site administrators and developers who need to know whether the sign-in, the user's role or the app version is the cause. It lists the WCPOS REST endpoints each default role can reach, and what the server answers when it says no. To change what a role may do, use Staff Access.
What each default role can reach
A cashier can do everything a sale needs, including refunds, and can read the Cloud Print printers to send receipts. Every other setting, the logs and store management need an administrator or shop manager.
What each default role can access
administrator: every endpoint on this page.shop_manager: every endpoint except Pro's extension install and update action, which needs the WordPressinstall_pluginscapability.cashier: everything the selling workflow uses, including refunds. No settings screens, logs, extensions or store management. The only settings it can read are the Cloud Print printers, so the POS can send receipts to them.
How these lists were checked
The lists come from the plugin's integration tests. Each test signs in with a WCPOS access token, the way the app does, and calls the endpoint as each role. In the Free tests an allowed endpoint must answer with a status below 400. The Pro tests also accept 400 or 404, because their fixtures are minimal: either answer still proves the user got past the permission check. A refused endpoint must answer 403 with the user still signed in.
How the server checks a request
Every request to the POS passes up to four checks: the app version, the sign-in, POS access, then the route's own rule. The first check that fails gives the answer.
The four checks, in order
A request to /wcpos/v1/ or /wcpos/v2/ passes these checks in order. The public sign-in routes and printer polling skip checks 2 and 3. Three sync maintenance routes skip check 3 for a user with WooCommerce's manage_woocommerce, and need that capability instead.
- App protocol (most v2 routes). Fails with
426, codewcpos_update_required. The app shows SYNC341: update the app. - Access token. Fails with
401, codewoocommerce_pos_rest_unauthorized, no user signed in. The app refreshes the token once and retries; if the retry fails too, it shows AUTH101: Session expired. - POS access. A signed-in user without
access_woocommerce_posgets403, codewoocommerce_pos_rest_forbidden. The app shows AUTH201: Insufficient role. - The route's own check. Fails with
403, for examplerest_forbidden. The app shows AUTH201 too.
The three capabilities, and which roles have them
The plugin grants its own two capabilities to the default roles when it is activated. An update grants only capabilities new in that release, so one removed on the Access screen stays removed. install_plugins is WordPress's own.
access_woocommerce_pos: administrator, shop manager and cashier. Required for every POS endpoint except the public sign-in routes, printer polling and three sync maintenance routes (/wcpos/v2/uuid/backfill,/orders/index/backfill,/integrity/rebuild), which need WooCommerce'smanage_woocommerceinstead; some also need one of the two below.manage_woocommerce_pos: administrator and shop manager. Opens settings, logs, the extensions list and Pro store management.install_plugins(WordPress): administrator only. Opens Pro's extension install and update.
Sync endpoints (v2)
The 2.0 app syncs through /wcpos/v2/. Every default role can reach every sync route the app uses.
Every role: the v2 sync routes
- Status:
GET /wcpos/v2/status - Catalogue:
GET /wcpos/v2/products,/variations,/products/categories,/products/tags,/products/brands - Customers, coupons, taxes:
GET /wcpos/v2/customers,/coupons,/taxes - Orders:
GET /wcpos/v2/orders,/orders/pull - Change feed:
GET /wcpos/v2/changes/sequence-log,/changes/revision-hash,/changes/range-checksum,/changes/config-fingerprint,/changes/tick - Integrity checks:
GET /wcpos/v2/digests,/integrity/scan,/integrity/bucket - Barcode lookup:
GET /wcpos/v2/resolve/barcode - Send a new order:
POST /wcpos/v2/push/orders
Free Plugin Endpoint Access Matrix
These /wcpos/v1/ routes serve sign-in, checkout, receipts and the settings screens. Every role can reach the routes a sale uses. The settings screens, logs and extensions list need an administrator or shop manager.
Every role (administrator, shop manager, cashier): 27 endpoints
GET /wcpos/v1/stores: stores the app can openGET /wcpos/v1/cashier/{id}: the signed-in cashierGET /wcpos/v1/cashier/{id}/stores: stores this cashier may useGET /wcpos/v1/products,/products/variations: catalogueGET /wcpos/v1/products/categories,/tags,/brands: catalogue filtersGET /wcpos/v1/coupons: coupon lookupGET /wcpos/v1/orders: order historyPOST /wcpos/v1/orders: sellingPATCH /wcpos/v1/orders/{id}: completing an orderGETandPOST /wcpos/v1/orders/{id}/checkout: taking paymentGET /wcpos/v1/receipts/{order_id}: receipt renderingGET /wcpos/v1/data/order_statuses: status namesGET /wcpos/v1/customers: customer searchPOST /wcpos/v1/customers: add a customerPATCH /wcpos/v1/customers/{id}: edit a customerGET /wcpos/v1/taxes,/taxes/classes: tax rates and classesGET /wcpos/v1/shipping_methods: shipping linesGET /wcpos/v1/payment-gateways: payment optionsPOST /wcpos/v1/payment-gateways/{id}/bootstrap: payment setupGET /wcpos/v1/templates,/templates/active,/templates/gallery: receipt templates
Every role can also read GET /wcpos/v1/settings/cloud-print, the Cloud Print printers, so the POS can send receipts to them. It needs only access_woocommerce_pos. It is not one of the 27: its own test checks a user who has that capability and no settings access.
Administrator and shop manager only: 6 endpoints
These need manage_woocommerce_pos; a cashier gets 403.
GET /wcpos/v1/settings/general: General settings screenGET /wcpos/v1/settings/checkout: Checkout settings screenGET /wcpos/v1/settings/tax_ids: Tax ID settings screenGET /wcpos/v1/settings/payment-gateways: Payment gateway settings screenGET /wcpos/v1/extensions: Extensions listGET /wcpos/v1/logs: Logs screen
/wcpos/v1/settings itself has no readable index: read a section such as /settings/general instead.
Pro Plugin Endpoint Access Matrix
WCPOS Pro adds these routes. Every role can refund an order. Store management and the license key need an administrator or shop manager, and installing an extension needs an administrator.
The Pro routes, by role
Every role:
POST /wcpos/v1/orders/{id}/refunds: refund an order
Administrator and shop manager only (needs manage_woocommerce_pos):
GET /wcpos/v1/stores/{id}/edit: open a store for editingPOST /wcpos/v1/stores: add a storePATCH /wcpos/v1/stores/{id}: save a storePOST /wcpos/v1/settings/license: save the license key
Administrator only (needs the WordPress install_plugins capability):
POST /wcpos/v1/extensions/action: install or update an extension
Token Expiry Coverage
By default the app's sign-in lasts 30 minutes and renews itself for up to 30 days from when the cashier signed in. After that, the cashier signs in again (AUTH101). A token that has run out is always a 401, never a 403, so it never looks like a role problem.
Token lifetimes and what each case returns
The app signs in with an access token that lasts 30 minutes and a refresh token that lasts 30 days. Code can change both with the wcpos_jwt_access_token_expire and wcpos_jwt_refresh_token_expire filters. The same tests cover what happens when each one runs out, for all three roles:
- Valid access token: the endpoint answers normally.
- Expired, missing or malformed access token:
401, codewoocommerce_pos_rest_unauthorized, no user signed in. The app refreshes the token once and retries. - Expired access token, valid refresh token: the refresh returns a new access token, and the retry succeeds.
- Expired refresh token: the refresh is refused with
woocommerce_pos_auth_token_expired, and the cashier signs in again (AUTH101).
An expired access token never signs a user in, so it never reaches a role check: it is always a 401, never a 403. The tests prove the same on the v2 routes for the cashier role.