The Problem

The WordPress REST API endpoints (e.g., /wp-json/wp/v2/posts) return 404 errors because the custom permalink structure or .htaccess rules are intercepting the API requests.

Symptoms

  • /wp-json/wp/v2/posts returns 404
  • Headless WordPress frontends cannot fetch data
  • REST API works with default permalinks but not custom ones
  • Gutenberg editor fails to load posts or media
  • JSON response shows HTML 404 page instead of API data

Real Error Response

``` curl https://example.com/wp-json/wp/v2/posts

<!-- Returns HTML 404 page instead of JSON --> <!DOCTYPE html> <html> <head><title>Page Not Found</title></head> ... ```

Common Causes

Cause 1: Broken Rewrite Rules

After changing permalink settings, the rewrite rules may not be flushed.

Cause 2: .htaccess Missing WordPress Rules

apache
# .htaccess may be missing the WordPress rewrite block
# or have custom rules that intercept /wp-json/ requests

How to Fix It

Fix 1: Flush Rewrite Rules

```bash # Using WP-CLI wp rewrite flush --hard

# Or in WordPress admin: # Settings -> Permalinks -> Click "Save Changes" (no need to change anything) ```

Fix 2: Fix .htaccess

apache
# .htaccess should contain:
<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>

Fix 3: Verify mod_rewrite is Enabled

```bash # Apache apache2ctl -M | grep rewrite

# If not listed, enable it: sudo a2enmod rewrite sudo systemctl restart apache2 ```

Fix 4: Check Nginx Configuration

```nginx # If using Nginx, ensure try_files is configured: location / { try_files $uri $uri/ /index.php?$args; }

# Do NOT add rules that intercept /wp-json/ ```

Fix 5: Disable Conflicting Plugins

```bash # Temporarily disable all plugins wp plugin deactivate --all

# Test the API curl https://example.com/wp-json/wp/v2/posts

# If it works, re-enable plugins one by one wp plugin activate akismet ```

Common conflicting plugins: - Security plugins with firewall rules - Custom redirect plugins - Caching plugins with aggressive page caching

Fix 6: Bypass Cache for API Requests

nginx
# Nginx: Do not cache REST API responses
location /wp-json/ {
  try_files $uri $uri/ /index.php?$args;
  # Disable caching for API
  add_header Cache-Control "no-cache, no-store, must-revalidate";
}

Fix 7: Test with Authentication

```bash # Test authenticated API request curl -u admin:password https://example.com/wp-json/wp/v2/posts

# Or with application password curl -H "Authorization: Basic BASE64(user:app-password)" \ https://example.com/wp-json/wp/v2/posts ```