WordPress REST API error
WordPress REST API 403 Forbidden.
A 403 usually means the request reached a protected REST path, but WordPress, a permission callback, or a security layer refused the action.
Failure stage
Endpoint reached: WordPress or a security layer responded.
Authentication may exist: 403 is often after identity, not before it.
Failed first: capability, nonce/session, permission callback, or WAF rule rejected the request.
403 evidence matrix
| Evidence | Likely cause | First check |
|---|---|---|
rest_forbidden | Permission callback or capability failure | Check the current user capability used by the route. |
rest_cookie_invalid_nonce | Nonce/session failure | Fix nonce before editing permissions. |
| 403 HTML page, not JSON | Security plugin, WAF, or host block | Check security logs and request path rules. |
| GET works, POST fails | Write capability missing | Check method-specific permission_callback logic. |
| Admin user works, editor fails | Role/capability mismatch | Map the route to the exact capability required. |
Bad callback pattern
register_rest_route('ifk/v1', '/sync', [
'methods' => 'POST',
'callback' => 'ifk_sync',
'permission_callback' => '__return_true',
]);
This removes the 403 by removing protection. It is not a real fix for private write routes.
Corrected pattern
// Pattern to verify in your environment.
register_rest_route('ifk/v1', '/sync', [
'methods' => 'POST',
'callback' => 'ifk_sync',
'permission_callback' => function () {
return current_user_can('manage_options');
},
]);
What not to change yet
- Do not make private write routes public to silence 403.
- Do not change permalinks if the response is a JSON permission error.
- Do not switch auth methods until you know whether identity or capability failed.
- Do not disable all security tooling if the response code is a WordPress JSON error.