WordPress REST API fix

Use Application Passwords for external WordPress REST API clients.

Application Passwords are the clean baseline for server scripts, Zapier-style automations, mobile apps, and external integrations that cannot rely on logged-in browser cookies.

When to use this fix

  • The client runs outside the WordPress browser session.
  • The request returns 401 because no valid identity reaches WordPress.
  • You are calling core endpoints such as /wp-json/wp/v2/posts.
  • You need a revocable credential per user or integration.

When not to use this fix

  • A same-origin admin screen already has a logged-in session and only needs X-WP-Nonce.
  • A route should be public read-only and has no private data or write action.
  • A security plugin or proxy strips Authorization; fix header forwarding first.
  • You need OAuth-style delegated user consent; Application Passwords are simpler credentials, not an OAuth flow.

Before and after request

Before

POST /wp-json/wp/v2/posts
Authorization: Bearer copied-from-random-plugin

Response: 401 Unauthorized

After

POST /wp-json/wp/v2/posts
Authorization: Basic base64(username:application_password)
Content-Type: application/json

Pattern to verify in your environment.

Implementation notes

  1. Create the Application Password under the WordPress user that should own the API action.
  2. Use the WordPress username, not an email alias if the server rejects it.
  3. Send the credential only over HTTPS.
  4. Test identity with /wp-json/wp/v2/users/me before testing writes.
  5. Confirm the same user has the capability required by the target route.

cURL pattern

# Pattern to verify in your environment.
curl -X GET "https://example.com/wp-json/wp/v2/users/me" \
  -u "wp_username:xxxx xxxx xxxx xxxx xxxx xxxx"

curl -X POST "https://example.com/wp-json/wp/v2/posts" \
  -u "wp_username:xxxx xxxx xxxx xxxx xxxx xxxx" \
  -H "Content-Type: application/json" \
  -d '{"title":"API draft","status":"draft"}'

Verification checklist

  • /users/me returns the intended user.
  • The Authorization header reaches PHP.
  • The target route returns 403 only after identity is accepted, if capability is missing.
  • The Application Password can be revoked without changing the user's normal login password.