# 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):

* [AUTH101: sign in again](#sign-in-again)
* [AUTH201: ask an administrator to check the role](#check-the-role)
* [SYNC341: update the app](#update-the-app)

## Diagnosing Failures[​](#diagnosing-failures "Diagnosing Failures के लिए सीधा लिंक")

### Sign in again (AUTH101)[​](#sign-in-again "Sign in again (AUTH101) के लिए सीधा लिंक")

The app says **"Request still unauthorized after token refresh - please log in again"**.

1. WCPOS opens the WordPress sign-in window by itself. Sign in there as the same cashier.
2. If you closed the window, the app says **"Please log in to continue"**. Press **Login** on that message to open the window again.
3. 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](/hi-IN/error-codes/AUTH101.md) 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](/hi-IN/error-codes/AUTH301.md)).

### Ask an administrator to check the role (AUTH201)[​](#check-the-role "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](/hi-IN/manage-store/staff-permissions.md). They can follow [AUTH201](/hi-IN/error-codes/AUTH201.md) 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)[​](#update-the-app "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](/hi-IN/error-codes/SYNC341.md) page.
* **Desktop:** install the update the app offers, then reopen the app. If none is offered, [download the latest desktop build](/hi-IN/getting-started/installation.md#app-requirements) for Windows, Mac (Intel or Apple silicon) or Linux.
* **iPhone and iPad:** update WCPOS from its [TestFlight beta](https://testflight.apple.com/join/JGBdVRrW).
* **Android:** update WCPOS from its [Google Play beta](https://play.google.com/apps/testing/com.wcpos.main).

[SYNC341](/hi-IN/error-codes/SYNC341.md) 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[​](#permission-failure-vs-token-failure "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 as `rest_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 as `woocommerce_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[​](#related-documentation "Related Documentation के लिए सीधा लिंक")

[Staff AccessGrant or remove what each role can do.](/hi-IN/manage-store/staff-permissions.md)

[SessionsSigned-in devices and ending a session.](/hi-IN/settings/sessions.md)

[Error codesEvery code the app can show, with fixes.](/hi-IN/error-codes.md)

## For administrators and developers[​](#summary "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](/hi-IN/manage-store/staff-permissions.md).

### What each default role can reach[​](#what-each-role-can-reach "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 WordPress `install_plugins` capability.
* **`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[​](#how-the-server-checks "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.

1. **App protocol** (most v2 routes). Fails with `426`, code `wcpos_update_required`. The app shows [SYNC341](/hi-IN/error-codes/SYNC341.md): update the app.
2. **Access token.** Fails with `401`, code `woocommerce_pos_rest_unauthorized`, no user signed in. The app refreshes the token once and retries; if the retry fails too, it shows [AUTH101](/hi-IN/error-codes/AUTH101.md): Session expired.
3. **POS access.** A signed-in user without `access_woocommerce_pos` gets `403`, code `woocommerce_pos_rest_forbidden`. The app shows [AUTH201](/hi-IN/error-codes/AUTH201.md): Insufficient role.
4. **The route's own check.** Fails with `403`, for example `rest_forbidden`. The app shows [AUTH201](/hi-IN/error-codes/AUTH201.md) 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's `manage_woocommerce` instead; 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)[​](#sync-endpoints "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[​](#free-plugin-endpoint-access-matrix "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 open
* `GET /wcpos/v1/cashier/{id}`: the signed-in cashier
* `GET /wcpos/v1/cashier/{id}/stores`: stores this cashier may use
* `GET /wcpos/v1/products`, `/products/variations`: catalogue
* `GET /wcpos/v1/products/categories`, `/tags`, `/brands`: catalogue filters
* `GET /wcpos/v1/coupons`: coupon lookup
* `GET /wcpos/v1/orders`: order history
* `POST /wcpos/v1/orders`: selling
* `PATCH /wcpos/v1/orders/{id}`: completing an order
* `GET` and `POST /wcpos/v1/orders/{id}/checkout`: taking payment
* `GET /wcpos/v1/receipts/{order_id}`: receipt rendering
* `GET /wcpos/v1/data/order_statuses`: status names
* `GET /wcpos/v1/customers`: customer search
* `POST /wcpos/v1/customers`: add a customer
* `PATCH /wcpos/v1/customers/{id}`: edit a customer
* `GET /wcpos/v1/taxes`, `/taxes/classes`: tax rates and classes
* `GET /wcpos/v1/shipping_methods`: shipping lines
* `GET /wcpos/v1/payment-gateways`: payment options
* `POST /wcpos/v1/payment-gateways/{id}/bootstrap`: payment setup
* `GET /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 screen
* `GET /wcpos/v1/settings/checkout`: Checkout settings screen
* `GET /wcpos/v1/settings/tax_ids`: Tax ID settings screen
* `GET /wcpos/v1/settings/payment-gateways`: Payment gateway settings screen
* `GET /wcpos/v1/extensions`: Extensions list
* `GET /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[​](#pro-plugin-endpoint-access-matrix "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 editing
* `POST /wcpos/v1/stores`: add a store
* `PATCH /wcpos/v1/stores/{id}`: save a store
* `POST /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[​](#token-expiry-coverage "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](/hi-IN/error-codes/AUTH101.md)). 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`, code `woocommerce_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](/hi-IN/error-codes/AUTH101.md)).

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.
