Prevent Posts in the Trash from Being Updated via REST API

This is a very specific post so it may not be useful for many of you guys, but on the other hand I didn’t even find I hint about anything like this across the internet, so, for those of you who need it, this tutorial is a gem. I hope 🙂

Let’s say that you have my Simple WP Crossposting plugin installed on your main site (Site 1) or it could be any custom functionality or a plugin that uses a post update REST API endpoint {WP url}/wp-json/wp/v2/posts/{post ID}. So basically we’re syncing changes between the same posts on “Site 1” and “Site 2”.

And our goal is to prevent syncing changes we made on “Site 1” when a post copy on “Site 2” has been moved to the trash. Please note that here I mean not only restoring a post from the trash (changing the post status) but any changes.

We can go different ways here:

  1. We can send an additional REST API request before updating a post to check whether it is in the trash on “Site 2” or not.
  2. Or we can use a simple code snippet on “Site 2” to just prevent the post from being updated in case it is in the trash.

Of course the 2nd way wins in performance! So we’re going to use it. But you can use the first way of course if you wish, in that case before every REST API update request you need to send an extra GET request to /wp/v2/posts?slug={your post slug}.

Right now we need a hook before posting via REST API! And I decided to use rest_pre_insert_{post type}. If you think that there is a better hook for that, please let me know in the comments section below.

// for Posts
add_filter( 'rest_pre_insert_post', 'rudr_prevent_trashed_post_updates' );
// for Pages
add_filter( 'rest_pre_insert_page', 'rudr_prevent_trashed_post_updates' );
// repeat it for any custom post type you want it to use
function rudr_prevent_trashed_posts_updates( $prepared_post ) {

	// do nothing if we're not updating (but publishing) a specific post
	if( ! isset( $prepared_post->ID ) ) {
		return $prepared_post;

	if( 'trash' === get_post_status( $prepared_post->ID ) ) {
		return new WP_Error( 'misha_err2', 'Updating posts in the trash is not a good idea.' );
	return $prepared_post;


Ok, it is time to deconstruct the code above:

And when sending a request like this and getting an error we can process it the following way:

if( 200 !== wp_remote_retrieve_response_code( $response ) ) { // 500 by the way
	$response_body = json_decode( wp_remote_retrieve_body( $request ), true );
	print_r( $response_body );
	    [code] => misha_err2
	    [message] => Updating posts in the trash is not a good idea.
	    [data] => 

Prevent Trashed and Private Posts from Being Updated via WordPress REST API

This is an interesting example because if you’re just about to add a private post status to check into the previous code snippet, be ready to get an error like this on the “Site 2” every time you update your private posts:

updating private posts is not allowed Gutenberg error message
By the way, the error message you see here “Private posts and posts in the…” is our custom text we set when created a WP_Error message.

So, that’s how our new code snippet is going to look like for both trashed and private posts:

add_filter( 'rest_pre_insert_post', 'rudr_prevent_trashed_and_private_post_updates', 25, 2 );

function rudr_prevent_trashed_and_private_post_updates( $prepared_post, $request ) {

	// do nothing if we're not updating (but publishing) a specific post
	if( ! isset( $prepared_post->ID ) ) {
		return $prepared_post;
	// let's check the User-Agent header
	if( false === strpos( $request->get_header( 'user_agent' ), '' ) ) {
		// do nothing if not a REST API request from the "Site 1" (in this case not from
		return $prepared_post;
	if( in_array( get_post_status( $prepared_post->ID ), array( 'trash', 'private' ) ) ) {
		return new WP_Error( 'misha_err3', 'Private posts and posts in the trash are not allowed for updates.' );
	return $prepared_post;


Some notes:

Misha Rudrastyh

Misha Rudrastyh

Hey guys and welcome to my website. For more than 10 years I've been doing my best to share with you some superb WordPress guides and tips for free.

Need some developer help? Contact me

Follow me on X