WordPress REST API fix

Send X-WP-Nonce for logged-in WordPress REST API requests.

The nonce pattern is for same-origin browser requests made by a logged-in WordPress user. It is not the right auth model for external scripts.

When to use this fix

  • A logged-in admin/editor screen calls a REST route from JavaScript.
  • The response mentions rest_cookie_invalid_nonce.
  • The route works after refresh but fails when the cached page gets old.
  • The request is same-origin and should use the WordPress browser session.

When not to use this fix

  • Zapier, Make, mobile apps, cron jobs, and server scripts should use Application Passwords or another explicit auth model.
  • Public GET endpoints should not require a logged-in nonce unless the data is private.
  • Webhooks should use signatures or shared secrets, not a browser nonce.
  • Cross-origin frontends need a full auth design, not a copied nonce value.

Before and after JavaScript

Before

fetch('/wp-json/agency/v1/save', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(payload)
});

After

fetch(IFK_REST.root + 'agency/v1/save', {
  method: 'POST',
  credentials: 'same-origin',
  headers: {
    'Content-Type': 'application/json',
    'X-WP-Nonce': IFK_REST.nonce
  },
  body: JSON.stringify(payload)
});

PHP enqueue pattern

// Pattern to verify in your environment.
add_action('wp_enqueue_scripts', function () {
    wp_enqueue_script(
        'agency-app',
        get_stylesheet_directory_uri() . '/assets/agency-app.js',
        [],
        '1.0',
        true
    );

    wp_localize_script('agency-app', 'IFK_REST', [
        'root' => esc_url_raw(rest_url()),
        'nonce' => wp_create_nonce('wp_rest'),
    ]);
});

Verification checklist

  • Confirm the nonce is generated on the page load used for the request.
  • Confirm the request includes browser credentials for same-origin cookies.
  • Confirm the response is not a cached page with an old nonce.
  • Confirm the route still enforces a real capability in permission_callback.