WordPress REST API Disabled: Broken vs. Blocked on Purpose

This post contains affiliate links. If you buy something through one of them, Veravix may earn a commission at no extra cost to you.

Checked for accuracy and updated on October 20, 2026. If a blocked REST API turns out to be a symptom of an infected site, How to Scan a Website for Malware, and What 69 Remote Scans Showed explains the checks to run first.

If you’ve landed here, one of two things is true. Either something on your site broke and the cause turned out to be the REST API, or you’re deliberately trying to turn it off and want to do it without breaking anything else. The fix is different depending on which one you are, so start by figuring out which situation you’re actually in.

How to check if the REST API is actually disabled

Visit yoursite.com/wp-json/ directly in a browser. A working REST API returns a block of JSON describing your site’s routes and namespaces. If you get a 404, a 403, or a blank white screen instead, something is blocking it. Try yoursite.com/wp-json/wp/v2/posts too. A 401 there specifically means authentication is being enforced, which is a narrower and usually intentional restriction, not a full disable.

This distinction matters because “disabled” covers a range of behavior. A full block returns a 404 for every route. An authentication requirement returns a 401 only for requests that aren’t logged in. Confusing the two leads to overcorrecting, either forcing the whole API back open when only login-gating was needed, or trying to gate logins on a site where the API is actually just broken.

Run the test twice: once while you’re logged in to WordPress, and once in a private window where you’re not. If /wp-json/ loads when you’re logged in but fails in the private window, the API isn’t broken, it’s gated, and something is restricting anonymous requests on purpose or by accident. Read the response code, not just whether the page loads. WordPress’s own “route does not exist” error is rest_no_route with a 404. A 401 or 403 means the route exists and is refusing the request, which points at a plugin, a snippet or a firewall rather than a broken install.

The cause people miss: plain permalinks

If Settings, Permalinks is set to Plain, the pretty /wp-json/ address returns a 404 even though the REST API itself is fine. WordPress can still serve it through the query-string form, so test yoursite.com/?rest_route=/. If that returns JSON, the API is working and the permalink structure is the problem. Switch to any structure other than Plain (Post name is the usual choice) and save.

Treat the ?rest_route= address as a test only. Plugins, apps and the block editor expect /wp-json/, so they keep failing until the permalinks are fixed. If the permalinks are already set to something else and /wp-json/ still returns a 404, saving the Permalinks screen again rebuilds the rewrite rules, and it’s worth confirming on Apache that the .htaccess rules are still in place, or on Nginx that requests for /wp-json/ are being passed to index.php.

The error messages that usually point back to this

Most people don’t search for “REST API disabled” in the abstract. They hit a message inside another tool and trace it back. Three are common, and they don’t all mean the same thing.

Elementor. When the editor won’t load, Elementor’s own help documentation lists a disabled REST API as a known cause, and names plugins that can switch it off: Disable REST API, REST API Toolbox, Perfmatters, Clearfy Pro and iThemes Security (now Solid Security). Server-side firewalls such as ModSecurity can also reject the editor’s requests, which looks identical from the outside.

WooCommerce. The mobile app and payment setup can show “Your store is not driven by WordPress or REST API is disabled.” That message is not proof the API is off. It has been reported with a broken Jetpack connection, and in at least one reported case the store’s /wp-json/wc/v3 endpoint returned JSON normally while the site sat behind Cloudflare. Run the direct /wp-json/ check first, then look at the Jetpack connection and any CDN or firewall rules.

Site Health. WordPress’s own Tools, Site Health screen reports the problem as “The REST API encountered an unexpected result” or “The REST API encountered an error.” Hosting guides tie both to the same short list: a conflicting plugin or theme, security tools blocking access, and caching misconfiguration. That list is the rest of this article.

If it broke and you didn’t do it

The REST API doesn’t disable itself, so something changed. Before you start switching plugins off on a live site, make sure you have a recent backup and know how you’d get back, which is covered in how to restore a WordPress backup. Then work through these in order, since they’re ranked by how often they’re actually the cause:

Security and performance plugins. Plenty of plugins carry a REST API switch, and it’s easy to enable one during a hardening pass and forget it. Shield Security has a “Disable Anonymous REST API” option with a namespace exclusion list, and its own documentation warns that enabling it may break plugins that use the REST API for your visitors. Perfmatters has a “Disable REST API” section under Settings, General, with a “Disable for Non-Admins” choice and a “Disable When Logged Out” choice. Dedicated plugins such as Disable REST API and REST API Toolbox do the same job, and Solid Security (formerly iThemes Security) appears on Elementor’s list of plugins that can turn it off. Check each active plugin’s settings for anything mentioning “REST API,” “JSON API,” or “XML-RPC” (a different feature, but often toggled in the same settings panel and easy to confuse).

Wordfence is often blamed for this, but Wordfence’s own support staff have said publicly that it has no feature that blocks the REST API, so look at the other plugins first. Also check any plugin that hides your login URL or rewrites site paths: one reported case had a hide-login plugin’s rewrite rules block the REST API and break the Elementor editor.

A leftover code snippet. Older WordPress security tutorials (many predating the block editor, which depends on the REST API) recommend adding a snippet like this to functions.php or a custom plugin:

add_filter( 'rest_authentication_errors', function( $result ) {
    if ( ! empty( $result ) ) {
        return $result;
    }
    if ( ! is_user_logged_in() ) {
        return new WP_Error( 'rest_disabled', 'REST API restricted', array( 'status' => rest_authorization_required_code() ) );
    }
    return $result;
} );

This particular snippet only blocks unauthenticated access, which is usually fine. A more aggressive version removes the rest_api_init action entirely, which blocks everything, including the block editor itself. Search your theme’s functions.php, any custom or “site-specific” plugin, and a code-snippets plugin if you use one, for rest_authentication_errors or rest_api_init to find it.

Host-level and CDN firewall rules. Some managed hosts, CDNs and web application firewalls block /wp-json/ or the editor’s requests by default as a security baseline, independent of anything in WordPress itself. If switching every plugin off changes nothing, this is next. Give your host the exact URL that fails and the response code you see, and ask them to check the firewall log for it. A Site Health warning about a failed loopback request alongside the REST API one points the same way, because it means the server can’t reach its own address either.

If you’re disabling it on purpose

Full REST API removal is rarely the right move on a modern WordPress site, and the reason is specific: since WordPress 5.0, the block editor (Gutenberg) reads and writes post content through the REST API. Disable the API outright and the editor stops saving, autosaves stop working, and the post list screen can throw errors. Perfmatters’ own documentation warns that fully disabling it breaks the block editor with an “Updating failed” message. Jetpack, most page builders’ front-end editors, and any mobile app connection to your site rely on it too.

What you’re usually actually trying to prevent is unauthenticated access, not the API’s existence. The rest_authentication_errors filter shown above does that: logged-in users and legitimate admin-side requests keep working, while anonymous requests to your data get rejected. That closes the real risk, information disclosure to anyone who requests /wp-json/wp/v2/users and enumerates the usernames of your authors, without touching anything the editor needs.

The plugins that offer this switch usually give you the same two choices, and they are not equal. Blocking only logged-out visitors is the safer one if you have authors or contributors, because they need the API inside the editor. Blocking everyone who isn’t an admin is stricter, and it will break those accounts. Most of these tools also let you exempt specific namespaces, and you will probably need that for a contact form plugin, WooCommerce or Jetpack, since they call the API on behalf of anonymous visitors.

If a specific integration needs authenticated API access from outside the browser (a mobile app, a headless front end, a Zapier-style automation), use WordPress’s built-in application passwords (Users, Profile, Application Passwords) rather than reopening the whole API to anonymous requests. They are available over HTTPS by default. An application password scopes access to one user account and can be revoked individually without touching the REST API’s global availability.

If you’re tightening a site more broadly, the REST API is only one of several things worth checking. Checking your security headers covers a different layer that needs no plugin to inspect.

The one thing not to disable

Regardless of which security plugin’s settings page you’re in, leave the core wp/v2 namespace itself alone and restrict access with a filter instead of a route removal. Removing the namespace entirely rather than gating it is what breaks the editor, since the editor can’t distinguish “intentionally restricted” from “not there.” A 401 is something the admin dashboard already knows how to handle gracefully; a missing route generally isn’t.