Skip to main content
1 of 2

Show custom post type endpoint in REST API just if user has capability

I created a custom post type for WP, that should just be visitable for user that have a custom capability "read_cpt". Within templates and pre_get_posts I can run checks to include or exclude the CPT by using current_user_can().

I don't want the CPT, not even the endpoint, to show up within the REST API, to keep it top secret, as long as a user doesn't have the custom capability.

The only way I could figure out to hide the endpoints in the API to run this code.

Register post type for "classic" WP:

function add_post_type() {
    $args = array(
        [...]
        'public'                => false,
        'has_archive'           => false,
        'exclude_from_search'   => true,
        'publicly_queryable'    => false,
        'show_in_rest'          => false,
    );
    register_post_type( 'cpt', $args );
}
add_action( 'init', 'add_post_type', 0 );

and separately add it to the REST API:

add_action( 'init', 'cpt_rest_support', 25 );
function cpt_rest_support() {
    global $wp_post_types;

    if ( current_user_can( 'read_addresses' ) ) {
        //be sure to set this to the name of your post type!
        $post_type_name = 'address';
        if( isset( $wp_post_types[ 'cpt' ] ) ) {
            $wp_post_types[ 'cpt' ]->show_in_rest = true;
        }
    }
}

By creating a custom WP_REST_Posts_Controller class I couldn't find a way to hide the endpoint by modifying any of the *_permissions_check

Is there something like a "show_in_rest_permition_check" argument for register_post_type() or is the described way the only method?