How to Eliminate WordPress REST API “403 Forbidden” Errors (Complete Fix)?

The WordPress REST API (accessed via the /wp-json/ namespace) is the architectural backbone for the Block Editor (Gutenberg), headless decoupled applications, mobile apps, and third-party SaaS integrations like Zapier. A 403 Forbidden error on this endpoint means your server successfully received the HTTP request, understood the payload, but actively refused to authorize it. Unlike a 404 Not Found (which indicates broken routing), a 403 is a deliberate, security-driven termination.

This authorization failure occurs for three primary reasons: an aggressive WordPress security plugin blocking the API to prevent user enumeration, a server-side Web Application Firewall (WAF) flagging the JSON payload as a false positive, or an internal server routing failure stripping the necessary authentication headers from the request. This technical guide outlines the precise steps to diagnose the restriction, whitelist the necessary JSON endpoints, and restore full programmatic access to your WordPress architecture without compromising your server’s security posture.

Prerequisites Before You Begin

Before altering firewall rules and security protocols, ensure you have the following diagnostic tools and access levels ready:

  • API Testing Client: Desktop software like Postman, Insomnia, or command-line cURL to fire direct GET and POST requests to your [https://yourdomain.com/wp-json/wp/v2/](https://yourdomain.com/wp-json/wp/v2/) endpoint. Testing via a standard browser caches results and strips necessary headers.

  • Administrator Dashboard Access: Standard wp-admin credentials to modify security plugin configurations and flush rewrite rules.

  • Hosting Control Panel Access: Direct login to cPanel, Plesk, or your specific managed WordPress dashboard to manipulate ModSecurity or WAF settings.

  • Server Log Access: Ability to read the raw Apache error_log, Nginx error.log, or ModSecurity modsec_audit.log via SSH or SFTP.

  • File Transfer Client / Code Editor: SFTP access to modify .htaccess (Apache) or nginx.conf routing directives.

Step-by-Step Solutions

Method 1: Auditing Endpoint Security and Firewall Plugins (The Application Layer)

Most 403 Forbidden REST API errors are intentionally triggered by WordPress security plugins. Features designed to stop “User Enumeration” (hackers scraping author IDs) routinely lock down the entire /wp-json/wp/v2/users endpoint.

Step 1: Disable REST API Restrictions in Wordfence If you utilize Wordfence, navigate to your WordPress dashboard. Click Wordfence > All Options. Scroll down to the Brute Force Protection section. Look for the setting labeled Prevent discovery of usernames through ‘/?author=N’ scans, the wp-json/wp/v2/users API. If this is toggled ON, Wordfence returns a hard 403 for any unauthenticated request to the users endpoint. Toggle this OFF, then click Save Changes in the top right corner. To verify this step was successful, open Postman and fire a GET request to [yourdomain.com/wp-json/wp/v2/users](https://yourdomain.com/wp-json/wp/v2/users). You should receive a 200 OK status with a JSON array of users.

Step 2: Adjust Solid Security (Formerly iThemes) Tweaks If you run Solid Security, navigate to Security > Settings > Advanced > WordPress Tweaks. Locate the REST API dropdown menu. By default, security-conscious admins set this to “Restricted Access,” which throws a 403 for non-logged-in requests, breaking third-party SaaS integrations. Change this dropdown to Default Access. Click Save. To verify this step was successful, test an external integration (like a Zapier webhook) to confirm it can now read your post types without being rejected.

Step 3: Isolate Rogue Plugins via Deactivation If neither of the above applies, another plugin (like Disable REST API, Perfmatters, or a custom function in your theme) is blocking the endpoint. Deactivate all plugins except your core integration. If the 403 disappears, reactivate them one by one, sending a Postman request after each activation, until the 403 returns. To verify this step was successful, you will have identified the exact plugin bottlenecking the architecture.

Method 2: Bypassing Server-Side Web Application Firewalls (The Server Layer)

If you disabled all WordPress plugins and the 403 persists, the block is occurring before the request ever hits PHP. Server-side Web Application Firewalls (WAF) like ModSecurity often flag REST API POST and PUT requests as SQL injection (SQLi) or Cross-Site Scripting (XSS) attacks because they contain large, unescaped JSON data payloads.

Step 1: Temporarily Disable ModSecurity (Diagnostic Test) Log into your cPanel account. Under the Security section, click on ModSecurity. You will see a list of your domains. Toggle the status to Off for the domain experiencing the REST API error. To verify this step was successful, wait 60 seconds for the Apache graceful restart, then resend your API payload. If it succeeds with a 200 or 201 status, ModSecurity is confirmed as the culprit. Do not leave ModSecurity off permanently.

Step 2: Identify the Specific ModSecurity Rule ID Turn ModSecurity back On. You must find exactly which rule is triggering the false positive. Access your server via SSH or use cPanel’s Errors interface. Open the Apache error log (/var/log/apache2/error.log or /usr/local/apache/logs/error_log). Search for the term “403” and “wp-json”. You will see an entry that looks like: [client 192.168.1.1] ModSecurity: Access denied... [id "941160"]. To verify this step was successful, copy the specific numerical ID (e.g., 941160) generated by the firewall.

Step 3: Whitelist the Rule ID via .htaccess or WHM If you have WHM (root) access, navigate to ModSecurity Tools > Hits List, find the hit, and click Disable Rule. If you only have cPanel/FTP access, open your .htaccess file and inject the following Apache directive above the # BEGIN WordPress line to safely whitelist that single rule:

Apache

<IfModule mod_security2.c>
  SecRuleRemoveById 941160
</IfModule>

To verify this step was successful, run your API test again. The payload should pass through the firewall successfully while the rest of the site remains protected.

Method 3: Regenerating Routing Rules and Validating .htaccess Directives (The Core Layer)

The REST API relies heavily on WordPress’s internal routing engine (Permalinks). If your .htaccess file is corrupted, or if FastCGI is stripping authentication headers, the server will misroute the API call or reject the token, returning a 403.

Step 1: Flush WordPress Rewrite Rules If the REST API routes are out of sync with the database, endpoints will fail to authenticate properly. Navigate to your WordPress dashboard. Click Settings > Permalinks. You do not need to change any radio buttons; simply scroll to the very bottom of the page and click the blue Save Changes button. This action forces WordPress to flush and regenerate the wp_options rewrite array. To verify this step was successful, test a simple GET request to /wp-json/. It should return a massive JSON index of all available routes.

Step 2: Strip and Rebuild the .htaccess File Custom .htaccess security snippets often block PHP execution in specific directories or block HTTP Authorization headers. Connect via FTP, locate the .htaccess file in your public_html root, and open it in a code editor. Rename it to .htaccess_backup. Create a new .htaccess file and paste the default WordPress core routing rules:

Apache

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

To verify this step was successful, save the file back to the server and retry your authenticated API call.

Step 3: Force CGI to Pass Authorization Headers If you are passing a Bearer Token or Application Password via the API and still receiving a 403, your server’s FastCGI daemon is likely stripping the Authorization header before PHP can read it. Inside your .htaccess file, at the very top, add this single line: CGIPassAuth On. To verify this step was successful, fire a POST request with your authorization token. The 403 should be replaced with a 200 OK or 201 Created.

Troubleshooting Common Pitfalls

If you deviate from the standard architecture or encounter secondary errors after applying the fixes above, refer to this diagnostic table:

If you see this error Do this to fix it
403 Forbidden via Cloudflare Cloudflare’s edge WAF is blocking the JSON payload. Log into Cloudflare, go to Security > Events, find the blocked API request, and click Create Exception for the /wp-json/* URI path.
rest_cookie_invalid_nonce Your frontend application is passing an expired X-WP-Nonce. Nonces expire every 12 to 24 hours. You must write a JavaScript function to dynamically fetch and refresh the nonce via wp_create_nonce('wp_rest') before sending the POST request.
CORS Policy Block (Cross-Origin) The browser console shows a CORS 403. You are trying to hit the API from a different domain. Add Header set Access-Control-Allow-Origin "*" to your .htaccess file, or hook into rest_api_init to define allowed origins in PHP.

3 Common Mistakes Users Make During This Process

  1. Disabling the REST API Completely: Many outdated tutorials tell users to disable the API to “save resources.” Doing this breaks the Gutenberg Block Editor entirely, prevents password resets, and cripples core functionality like Contact Form 7 submissions.

  2. Leaving ModSecurity Disabled Permanently: Turning off your server’s WAF to fix a single REST API integration exposes your entire database to SQL injection attacks. Always take the time to find the specific rule ID and whitelist it individually.

  3. Testing API Endpoints in a Web Browser: Navigating to an endpoint in Chrome sends standard browser headers without authentication tokens. Always use Postman or cURL to explicitly pass Application Passwords, Bearer tokens, or Nonces to ensure you are receiving an accurate HTTP status code.

Final Thoughts

Eliminating REST API 403 errors requires a systematic approach to isolating the application layer from the server layer. By methodically auditing security plugins, fine-tuning ModSecurity rules to allow JSON payloads, and ensuring your .htaccess file successfully passes HTTP authorization headers, you secure your infrastructure while maintaining robust programmatic access.

Leave a Comment