REST API 403 {"error":"permission denied"} After a Successful OAuth2 Token Exchange
What it means
The OAuth2 Authorization Code Grant flow completes and hands back a valid access_token, so the client credentials themselves are fine. The 403 happens on the very next call because the API Client's OAuth scope (the functional areas it was registered with, such as Staffing or Time Off and Leave) does not cover the resource the call is actually hitting, like GET /workers or GET /currencies.
Troubleshooting
- Confirm the access_token was issued successfully and is not expired, this rules out a 401/authentication problem and isolates the failure to authorization.
- Open the API Client registration in the tenant and list the functional areas (scope) it was granted at setup.
- Identify which functional area actually covers the endpoint you are calling. Endpoints like /workers or /currencies live under areas such as System or Staffing, not every functional area exposes every endpoint.
- Compare the endpoint's required functional area against the client's granted scope list. A mismatch here is the cause whenever a valid token still returns 403 with a permission denied body rather than a 401.
Add the specific functional area that covers the failing endpoint to the API Client's OAuth scope, then re-run the request with the existing access_token (no need to re-auth).
When registering a new API Client, map out every endpoint the integration will actually call and grant the full set of functional areas up front, rather than adding scope reactively every time a new endpoint hits a 403.