I have tried every which way to authenticate a post request.

  1. WP User Plugin - As per the docs, I've logged in at wp-json/wpuser/v1/user/login and received my token. I've passed that token as a header called "Authorization" (also tried "authorization") with my POST request to wp-json/wp/v2/job-listings/ I get 401: rest_cannot_create. I also tried this with authorization as a parameter, as well as h:authorization, and with an uppercase "A" as well.

  2. JSON API Plugin - Generate nonce with get_nonce/?controller=auth&method=generate_auth_cookie, generate a cookie with auth/generate_auth_cookie using the nonce and credentials, tried to POST with, alternatively, the cookie and the nonce as the value of an X-WP-Nonce header. Both return 403: rest_cookie_invalid_nonce

  3. Tried adding RewriteCond %{HTTP:Authorization} ^(.*) RewriteRule .* - [e=HTTP_AUTHORIZATION:%1] to my .htacces file and tried the above.

I don't want to use the Basic Auth plugin because of its security issues (and believe me, I've tried it in the past to no avail).

Please, whatever you do, do not simply link to me to the WP REST API handbook. I have read it and I can't figure out where to get the nonce from, so I'd welcome an actual explanation on that but please don't just link me to that page.

I'm happy to add some server code if necessary, but these plugins imply that I shouldn't have to.

Please help. Thank you.

2 Answers 2


You don't need plugins for authentication unless you're making a cross domain request, and to get the nonce, you just create it as you would any other nonce.

As the handbook states:

For developers making manual Ajax requests, the nonce will need to be passed with each request. The API uses nonces with the action set to wp_rest. These can then be passed to the API via the _wpnonce data parameter (either POST data or in the query for GET requests), or via the X-WP-Nonce header. If no nonce is provided the API will set the current user to 0, turning the request into an unauthenticated request, even if you’re logged into WordPress.

So lets do that:

$nonce = wp_create_nonce( 'wp_rest' );

There's nothing special about how the nonce gets created, it's created the same way as every other nonce in WordPress. You would use the same function to put nonces on your action buttons and in your forms to improve security.

Now we just put it in our doc in a way javascript can access it. Luckily the handbook gives us a working code example:


wp_localize_script( 'wp-api', 'wpApiSettings', array(
    'root' => esc_url_raw( rest_url() ),
    'nonce' => wp_create_nonce( 'wp_rest' )
) );

Followed by a working example of using the nonce in jQuery for an authenticated POST request:

$.ajax( {
    url: wpApiSettings.root + 'wp/v2/posts/1',
    method: 'POST',
    beforeSend: function ( xhr ) {
        xhr.setRequestHeader( 'X-WP-Nonce', wpApiSettings.nonce );
        'title' : 'Hello Moon'
} ).done( function ( response ) {
    console.log( response );
} );

If you enqueue the built in backbone based REST library, it will automatically generate the nonce using the same code above.

This will work when combined with a cookie for a logged in user, however, it will not work for requests across domains.

If you're trying to make a REST API request from another website, a CLI app, mobile app, a Node application, etc etc you will need a custom authentication plugin. You will need to consult with their documentation and support avenues though as 3rd party plugin dev support is offtopic on this stack


If anyone is looking for a solution with Fetch:

.fetch(`${scriptVars.endpoint}`, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-WP-Nonce': scriptVars.nonce
  credentials: 'same-origin',
  body: JSON.stringify(postData)
.then(() => window.alert('success'));

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.