Why WordPress API Returns 404: Fix It Step by Step
This guide explains the common reasons behind WordPress API 404 errors, helping you identify if the issue is with routing, server configuration, or authentication.

You open a WordPress API URL in your browser, call it from PHP, or request it from a JavaScript app, and get “404 Not Found” instead of data. The endpoint looks right, but the request seems to disappear before WordPress can explain what went wrong. That usually points to request routing, so check how WordPress reaches the REST API before focusing on the post or resource you expected.
Most WordPress API 404s don't mean the content is missing. The route may not be registered, rewrite handling may be failing, the server may be altering the request, or your PHP URL construction and JavaScript path may point somewhere else. Authentication can also muddy the result, but a missing route and a bad credential don't fail in the same way.
Follow the checks in order, with a visible pass or fail at each step. Start with the REST index, then test server handling before credentials. ShieldThemes can help when a custom theme, hosting stack, or maintenance issue complicates the diagnosis, but many routing problems are visible in the first response.
A WordPress REST API 404 Usually Means the Request Never Reached the Route
When your REST request returns 404, the endpoint wasn’t found at the URL your server handled. The request may never have reached the intended WordPress route, so changing a password or bearer token can waste time.
Separate routing failures from authentication and server failures first. That distinction tells you which layer to test, even when a fresh WordPress installation appears broken.

What error code 404 means in a WordPress request
A 404 means the requested API path wasn’t found, but it doesn’t prove that WordPress generated the response. A September 2023 WordPress.org forum report described 404 responses for both /wp-json/ and /wp-json/posts from Apache, according to WordPress.org.
“Requests to both endpoints returned 404 Not Found responses from Apache,” a WordPress.org forum report stated.
Check the response body and server signature. An Apache or Nginx HTML page points toward rewrite rules, document roots, or virtual-host handling. A WordPress JSON error shows that WordPress received the request and produced a structured response.
A 401 means authentication failed. A 403 means WordPress or the server understood the request but denied permission. A 500 points to a server-side PHP or application failure, while a 503 usually indicates temporary unavailability. These responses need different fixes, so treating every status as a credential problem sends you in the wrong direction.
The first layer to test before changing PHP or credentials
Test the REST index before editing application code. If /wp-json/ fails with an Apache or Nginx page, inspect routing and permalink handling first. A reported WordPress 6.6.1 case also showed how Plain permalinks can create confusion, although permalinks aren’t the cause of every API 404.
Practical rule: If the REST index returns a server-generated HTML 404, test the URL, rewrite handling, and virtual host before changing credentials or client code.
Once routing passes, investigate authentication with this guide to how to authenticate the WordPress REST API. ShieldThemes can trace these layers when a custom theme or hosting stack obscures the first failure, but you can identify many routing problems from the initial response alone.
Choose the Debugging Route That Matches the 404 Response
You can usually identify why the WordPress API returns 404 by checking who produced the response. An Apache or Nginx HTML page points to server handling, while a WordPress JSON error shows that the request reached the application.
Use the response origin as your decision point rather than working through a list of guesses. The request moves from the client to the web server, then through WordPress routing, authentication, and the registered endpoint.

Server-generated 404 versus WordPress JSON 404
If you see an HTML 404 for /wp-json/, the request may not have passed through WordPress at all. Check rewrite pass-through, the virtual host, and the permalink structure before inspecting credentials.
Weak setting: Your WordPress site uses “Plain” permalinks while the server expects rewritten routes.
Strong setting: Your site uses “Post name” permalinks, you save the setting, and your server passes unknown paths to WordPress.
A JSON 404 takes you down a different path. WordPress handled the URL but couldn’t match the requested namespace or route. A protected endpoint more commonly returns 401 or 403, although some custom permission callbacks can deliberately return 404.
| symptom | likely cause | first fix |
|---|---|---|
| Apache or Nginx HTML 404 for /wp-json/ | Permalink or rewrite pass-through is not reaching WordPress | Set a rewrite-based permalink structure, save it, and verify server rewrite handling |
| WordPress JSON 404 for a custom namespace | The namespace or route is misspelled, unregistered, or registered too late | Inspect route registration and compare the requested path with the registered namespace and route |
| 401 or 403 response on a protected endpoint | Authentication or permission callback mismatch | Confirm the authentication method and test the permission callback after routing works |
| PHP or JavaScript request fails while the REST index works | Malformed base URL, path, trailing slash, method, or client-side handling | Inspect the exact network request and compare it with a known working route |
Built-in endpoint versus custom namespace route
Test a built-in route such as /wp-json/wp/v2/posts before debugging custom code. If it works, inspect your namespace, route pattern, HTTP method, or registration timing.
Weak route: /wp-json/store/v1/products when the code registered shop/v1/products.
Strong route: Request /wp-json/shop/v1/products after registering that namespace on rest_api_init.
PHP request versus JavaScript fetch request
When the REST index works but your application fails, compare the actual request with the working URL. PHP may build the wrong site base, while JavaScript may omit wp-json, use the wrong method, or parse an HTML error as JSON.
A request-testing workflow can help you compare headers, methods, and response bodies. This guide to the best WordPress API testing tools fits that process. ShieldThemes can trace these layers during ongoing maintenance, although a developer with server and WordPress access can often isolate the first broken layer quickly.
Collect the URL, Route, and Server Details Before Changing Anything
Before changing permalinks, plugins, or server rules, record the failed request. Your browser, PHP script, and JavaScript application may not send the same URL or HTTP method, so memory isn’t reliable.
Use one working comparison and one failing comparison. For a broader check of rewrite failures, see our WordPress 404 troubleshooting guide. You’ll then know whether the server, WordPress route registration, client code, or authentication produced the 404.
Why the WordPress REST API may not be working
Compare the REST index, a built-in route, and your custom route in that order. A WordPress.org forum report dated September 22, 2023 describes a user who had already saved the Permalinks screen with Post name selected before investigating other causes. Record that setting, but don’t assume it fixed rewrites.
Capture the exact request and response
Record the complete scheme and host, installation subdirectory, REST path, namespace, route, HTTP method, query parameters, status, body, and response headers. Check the browser developer tools, curl output, and the calling PHP or JavaScript code.
- Request URL: Done means you have the exact address, such as example.com/wp-json/acme/v1/orders, including any subdirectory.
- Route details: Done means you have the namespace, route, method, and query string written separately.
- Response evidence: Done means you saved the status, body, headers, and the layer that displayed the error.
- Client source: Done means you know whether PHP, JavaScript, a browser, Apache, or Nginx issued or returned the response.
Weak request: “The orders API returns 404.”
Exact request: You recorded GET example.com/wp-json/acme/v1/orders?status=open, the HTML response body, and the server headers.
Verify the route registration and namespace
Compare /wp-json/, /wp-json/wp/v2/posts, and your failing custom route. If the index fails, investigate the server and permalink handling. If the index works but the built-in route fails, inspect rewrites or WordPress loading. If both built-in checks work, verify that your custom namespace and route register during the current request.
Weak route check: You test only /wp-json/acme/v1/orders from the application.
Known-route check: You test /wp-json/, /wp-json/wp/v2/posts, and /wp-json/acme/v1/orders separately.
Check WordPress, PHP, and rewrite prerequisites
Confirm the WordPress Permalinks setting, web-server type, rewrite configuration, PHP version, and authentication method before changing code. Record whether the request needs cookies, an application password, a bearer token, or no authentication.
Diagnostic card: You should have one browser developer-tools capture, one curl response, and one WordPress Permalinks screen capture. This gives you a compact record of what your client sent, what your server returned, and how WordPress is configured.
Fix the REST API 404 in the Order WordPress Processes the Request
Use the record you collected to test each layer in order. You need a JSON response from WordPress before inspecting custom code or authentication.
Each result narrows the fault. A failed check tells you which layer still blocks the request, so you can fix the cause instead of changing unrelated settings.

How to fix a 404 error in an API
Start with the REST index at /wp-json/. A working result returns JSON describing the site and available namespaces, not an Apache, Nginx, or theme-generated HTML error page.
- REST index: Open your site’s /wp-json/ URL and confirm that WordPress returns JSON.
- Failure meaning: Treat an HTML 404 as a rewrite, document-root, or front-controller problem before checking custom routes.
- Method check: Use GET for the index and keep the request method unchanged during later endpoint tests.
Reset the permalink and rewrite path
Replace Plain permalinks with a rewrite-based structure such as Post name, then save the Permalinks screen. This refreshes WordPress rewrite rules without requiring you to edit files blindly.
Weak setting: Your site uses Plain permalinks, and your client requests /wp-json/acme/v1/orders as though rewrite rules already exist.
Post name enabled: Your WordPress Permalinks screen uses Post name, you save the setting, and /wp-json/ is tested again immediately.
Saving permalinks is a diagnostic step, not proof that your server rewrite layer is configured.
Confirm the route exists before debugging access
When the index works, inspect the custom namespace, route, HTTP method, callback, and permission callback. Registration should expose the route during the WordPress request lifecycle.
On Apache, check the virtual host, rewrite module, document root, and front-controller handoff to index.php. On Nginx, check the server block, document root, location rules, and configuration that sends non-file requests to WordPress.
Weak route: Your code registers acme/v1/order, but the client requests acme/v1/orders.
Matching route: Your registered namespace, path, method, callback, and requested URL all match before authentication is added.
Retest the endpoint with the same method and URL
Retest the custom endpoint using the same URL and HTTP method from the original request, but leave authentication disabled temporarily. Credentials can’t repair a route that isn’t registered or reachable.
If the route now returns JSON, add the required cookies, application password, or bearer token and test again. If it still returns 404, return to the first failed check. For complex hosting or custom-theme stacks, ShieldThemes can provide ongoing maintenance, although an on-site team still needs to control server credentials and deployment access.
Trace PHP and JavaScript Requests Without Mistaking Client Errors for Route Errors
Once route and rewrite checks pass, the client becomes the next suspect. You can still see a 404 when PHP builds the wrong URL, JavaScript drops the WordPress base path, or the request uses the wrong method.
The fastest test is simple: compare the final request from PHP or the browser with the URL that returned the REST index. If the paths differ, fix construction first. If the REST index itself returns 404, client edits won’t repair routing.

PHP requests that return 404
A PHP request that returns 404 usually points to the final URL, method, or response handling. Build the endpoint from your configured site base, preserve /wp-json/, and account for installations such as https://example.com/store/wp-json/.
Weak: PHP appends /wp-json/ to a hard-coded domain and sends a trailing-slash-sensitive route with POST.
Strong: PHP reads the site base, creates /store/wp-json/acme/v1/orders/, uses GET as registered, and logs the status plus raw response body before decoding JSON.
JavaScript requests that return 404
A JavaScript request that returns 404 is often caused by a fetch path that omits the localized WordPress base URL. The browser Network panel shows the final URL, redirects, method, status, and response. Inspect that request rather than the source string.
Weak: JavaScript fetches /wp-json/acme/v1/orders from a site installed under /store.
Strong: JavaScript fetches the injected base plus /wp-json/acme/v1/orders/, then checks response.status before parsing the body.
What works
- Central base: You generate PHP and JavaScript URLs from one configured site value.
- Visible diagnostics: You log the method, final URL, status, redirects, and raw body.
- Method matching: You send GET, POST, or another method exactly as your route registration expects.
What fails
- Hard-coded origin: You break requests after moving WordPress into a subdirectory or staging domain.
- Blind decoding: You treat an HTML server error as JSON and hide the useful response.
- Path guessing: You edit fetch code while the REST index still returns 404.
Keep route registration separate from request authentication
Authentication can’t fix a missing route. First establish a reachable REST index and registered endpoint. Then test cookies, application passwords, or bearer tokens, including same-origin rules and authorization headers in your browser or PHP client.
Handle subdirectory installs and generated base URLs
If your WordPress installation lives below the domain root, use its generated site URL rather than the server origin. Centralized construction reduces drift. Hard-coded paths are safe only when you control every deployment and client.
Use the Symptom to Apply the First Fix, Not a Random WordPress Change
Your first fix should match the response you can see. If you change authentication, plugins, and permalinks at once, you lose the evidence showing where the WordPress API request failed.
The table below gives you a narrow first action for each common failure. A server-generated HTML page, a WordPress JSON response, and a client-side URL error point to different layers.

The response is an Apache or Nginx HTML 404
When you receive an HTML 404, check routing before credentials. The web server may not be passing the request to WordPress at all.
| symptom | likely cause | first fix |
|---|---|---|
| Every REST URL, including /wp-json/, returns 404 | Plain permalinks or rewrite rules are not routing requests to WordPress | Choose a rewrite-based permalink structure, save it, and verify server rewrite support |
| The web server returns an HTML 404 page | Apache or Nginx is not passing the request to the WordPress front controller | Check the virtual host, document root, rewrite module or rules, and front-controller pass-through |
| The REST index works but a custom endpoint returns JSON 404 | The namespace or route does not match the registered path | Compare the exact URL with the registered namespace, route, method, and callback |
| A custom route is absent after plugins load | The route is registered too late or its permission callback is incorrectly configured | Register it during the REST API initialization flow and verify the permission callback |
| PHP receives 404 while the same URL works in a browser | The PHP base URL, subdirectory, slash, method, or encoded path is wrong | Log and compare the exact PHP request URL and method with the working request |
| JavaScript fetch receives 404 while direct testing works | The fetch base path or localized site URL is incorrect | Inspect the browser Network panel and correct the final generated URL before checking authentication |
Weak: Your permalink setting uses “Plain,” so your server receives query-style requests without the rewrite path your API needs.
Strong: Your permalink setting uses “Post name,” you save it, and you then retest /wp-json/ after confirming Apache or Nginx rewrite support.
How to fix a 404 error in WordPress
Identify whether the server, route registration, or client created the failing URL, then change only that layer. Don’t treat every 404 as an authentication problem.
- Server HTML 404: Check the document root, virtual host, rewrite rules, and WordPress front-controller pass-through first.
- Unregistered route: Compare your requested namespace and path with the route registered by your plugin or theme.
- Authentication signal: Treat 401 as an authentication failure and 403 as a permission failure. A 404 usually needs route or URL investigation first.
The response is a WordPress REST JSON 404
A JSON 404 usually means WordPress handled the request but couldn’t match the requested route. The namespace, route, HTTP method, or registration timing may be wrong.
Weak: Your PHP code requests /wp-json/acme/v1/orders while your plugin registers acme/v1/order.
Strong: Your PHP code requests /wp-json/acme/v1/order, matching the registered namespace, route, method, and callback.
Register the custom route during the REST API initialization flow, and verify that its permission callback returns an intentional Boolean result. A route registered after discovery, or one blocked by unsuitable registration logic, will mislead your testing.
The route works directly but fails from PHP or JavaScript
When direct testing works, inspect the final client URL before changing WordPress. The PHP request may omit a subdirectory or slash, while the JavaScript fetch may use the domain root instead of the localized WordPress base path.
Weak: Your script fetches /wp-json/acme/v1/order from a site installed at /store.
Strong: Your script fetches https://example.com/store/wp-json/acme/v1/order, and the browser Network panel confirms that final URL.
Log the complete PHP URL and method, then inspect the browser’s final fetch URL. This focused check keeps production debugging accountable without turning every 404 into a random WordPress change.
Prove the Fix with a Known Route, a Custom Route, and the Real Client
A page loading in your browser doesn’t prove that the WordPress API works. You need layered evidence: the rewrite path must reach WordPress, the route must exist, and your PHP or JavaScript client must send the intended request.
Test each layer separately, then repeat the original failure without changing its inputs. That shows whether you have a complete fix or only a partial one.
Verify the rewrite layer before the route layer
Start with the REST index or another built-in endpoint. You should see an HTTP success status, a JSON content type, and a JSON object containing REST information. If the index remains 404 after you save permalinks, inspect the response body. An Apache or Nginx HTML page points toward server routing, the wrong virtual host, a subdirectory mismatch, or unapplied rewrite rules.
Weak: https://example.com/wp-json/ when WordPress runs at /store.
Strong: https://example.com/store/wp-json/ returns JSON from the same installation you administer.
Use server logs and the browser Network panel to confirm that the request reaches the correct host and final path. Saving permalinks helps only when the request is already reaching the correct WordPress installation.
Confirm the expected response body and status
Once the built-in route works, request your custom namespace directly. You should receive the status your route defines, such as 200 for a successful read or 201 after a successful create, with the expected fields in the JSON body. A generic page, empty body, or different status means the route still needs investigation.
Verification view: REST index: success status, JSON, route data. Custom route: expected status, namespace response, required fields. Real client: identical URL, method, headers, parameters, and body.
- Index: Your built-in endpoint returns JSON from the correct WordPress installation.
- Namespace: Your custom route returns its intended status and response fields.
- Authentication: Your protected route returns its designed authorization response, not an unexplained 404.
- Logs: Your server and WordPress logs show the request reaching the expected application.
Repeat the original client request without changing its inputs
Finally, rerun the exact PHP or JavaScript request that first failed. Keep its method, headers, authentication, query parameters, body, and final URL unchanged. If the direct route works but the client fails, compare the client’s final URL and method first. A changed input means you’re testing a different request, not proving the fix.
FAQ
How to fix 404 error in API
Start by requesting the API’s base or index URL directly and record the full response. A 404 means the server couldn't find the requested resource, but the cause may be a wrong path, missing rewrite rule, unregistered route, or incorrect HTTP method. Compare the failing URL with a known working route before changing authentication or application code.
How can I fix the 404 error in WordPress
Open https://your-domain.com/wp-json/ and check whether WordPress returns JSON. If it doesn't, save a non-Plain permalink structure in WordPress, then test again. A persistent 404 points to rewrite handling, the installation path, or server configuration. Apache needs the correct .htaccess rules, while Nginx must pass unknown paths to index.php.
Why isn't my WordPress REST API working
If the REST index works but a custom endpoint returns 404, check the namespace, route name, HTTP method, and registration timing in register_rest_route(). Then compare the final URL created by your PHP or JavaScript client with a direct request. A mismatch in the site path, trailing slash, query string, or method can make a valid route appear missing.
What is API error code 404
API error code 404 indicates that the server received a request for a resource or route it couldn't find. It doesn't usually prove that the API is down. Check the domain, path, version prefix, route registration, rewrite rules, and request method. In WordPress, test /wp-json/ first, then inspect the custom route that fails.
Start with the REST Index, Then Follow the Failure to Its First Broken Layer
You can waste hours changing plugins when the first broken layer is a rewrite rule or an incorrect site path. A short, ordered test gives you evidence before you touch authentication, custom code, or client logic.
Start with the request WordPress exposes by default. Once you know whether that response works, each later failure points toward a smaller set of causes.
Run the seven-check sequence
- Capture the failure: Save the exact URL, method, headers, body, status code, and response body so you can repeat the same request.
- Test the REST index: Open https://your-domain.com/wp-json/ and record whether WordPress returns JSON or a server-generated 404 page.
- Refresh permalinks: In WordPress, select a non-Plain structure, save it, then test the index again.
- Check rewrite pass-through: Confirm Apache uses the WordPress .htaccess rules or Nginx forwards unknown paths to index.php.
- Verify route registration: Confirm your namespace, route name, HTTP method, and register_rest_route() timing match the request.
- Inspect client construction: Compare the PHP or JavaScript final URL, method, headers, query string, and response handling with the working direct request.
- Investigate authentication last: Check cookies, nonces, application passwords, capabilities, and permission callbacks only after the route itself responds.
Weak setting: Plain permalinks with no rewrite refresh after migration.
Strong setting: Post name permalinks saved in WordPress, followed by a fresh request to /wp-json/.
Start with the WordPress REST index
The REST index is the smallest useful starting task. If it fails, follow the installation path, permalink structure, Apache or Nginx rules, and WordPress bootstrap before inspecting custom endpoints.
If the index returns JSON but your custom route fails, inspect its namespace and registration. A working direct route with a failing application request shifts attention to URL construction, method, headers, or response parsing.
Escalate only after the first broken layer is identified
Your next fix should match the first failed test, not the most familiar WordPress setting. ShieldThemes can support ongoing maintenance, hosting, security, and custom integrations, although an external team still needs access to your server and deployment records.
For a startup or growing business, that evidence creates an accountable escalation path. Start with the REST index and its response body. That single page tells you which branch deserves your time.
If you want help managing this diagnosis, ShieldThemes builds and maintains WordPress sites, secure hosting, custom integrations, and software for startups and growing businesses. The ShieldThemes blog feed for WordPress and development insights supports ongoing technical work.



