API

Create a Simple JSON Endpoint in WordPress

As you may or may not know, the WordPress JSON REST API is on the horizon for a future version of WordPress. This will be one of the most important and influential additions to WordPress core we may see, especially for those using WordPress as a framework to create web and mobile applications. The inclusion of a standard, easy to use and extendable API for WordPress opens up a myriad of new possibilities on how we build applications with WordPress in the future

But what if you don’t want to wait for inclusion of the WP-API or use the official plugin version of the WP-API, where do you go? Maybe you just have a small bit of information that you would like to access in a JSON format. This could be needed for an AJAX call within your site or to allow a third-party to access some of your data. I will show you a quick way to set up your own endpoint and return your data in JSON format.

Set Up Our Example

For our example, we have the highly critical task of creating a place to store our animated GIFs and provide an easy way to access the links from a third-party. We want to access this by passing in a tag and all we need to get back is the link to the gif and a short description of it. For this, we will create a new CPT with just the featured image and title and a non-hierarchical taxonomy.

function wds_gif_cpt_and_tax() {

    $cpt_args = array(
        'label'   => 'GIFs',
        'show_ui' => true,
        'supports' => array( 'title', 'thumbnail' ),
    );
    register_post_type( 'wds_gif', $cpt_args );

    $tax_args = array(
        'label'   => 'GIF Tags',
    );
    register_taxonomy( 'wds_gif_tag', 'wds_gif', $tax_args );

}
add_action( 'init', 'wds_gif_cpt_and_tax' );

Create our Endpoint

Next we will use part of the WordPress rewrite API to properly register a rewrite tag and then add a rewrite rule so we can access this at http://example.com/gifs/tag/. For this, we use the functions add_rewrite_tag() and add_rewrite_rule(). As you can see, we use a simple regular expression to parse out the tag that is being passed to the endpoint URL. We will be using this tag later to query our GIFs custom post type.

function wds_gif_endpoint() {

    add_rewrite_tag( '%wds_gif%', '([^&]+)' );
    add_rewrite_rule( 'gifs/([^&]+)/?', 'index.php?wds_gif=$matches[1]', 'top' );

}
add_action( 'init', 'wds_gif_endpoint' );

Outputting the Data

Now we need to get the data out to our new endpoint so we can have access to those crucial animated GIFs. We are first going to call the $wp_query global so we can properly get find the rewrite tag from our URL. We are checking for the existence of the wds_gif query string, which we rewrote to /gifs/ in our URL. If this doesn’t exist, we will return and bail out of this function. If it works, we set up our array which we will be passing out in JSON format and then run a standard WP_Query loop for our new custom post type. We are going to be running a taxonomy query on this for the tag which was passed after /gifs/ in the URL.

Upon completion of the loop, we will send out the array of data in JSON format using wp_send_json(). This function will encode the array as JSON, echo it, and then run wp_die() to end any other actions that may happen later.

function wds_gif_endpoint_data() {

    global $wp_query;

    $gif_tag = $wp_query->get( 'wds_gif' );

    if ( ! $gif_tag ) {
        return;
    }

    $gif_data = array();

    $args = array(
        'post_type'      => 'wds_gif',
        'posts_per_page' => 100,
        'wds_gif_tag'    => esc_attr( $gif_tag ),
    );
    $gif_query = new WP_Query( $args );
    if ( $gif_query->have_posts() ) : while ( $gif_query->have_posts() ) : $gif_query->the_post();
        $img_id = get_post_thumbnail_id();
        $img = wp_get_attachment_image_src( $img_id, 'full' );
        $gif_data[] = array(
            'link'  => esc_url( $img[0] ),
            'title' => get_the_title(),
        );
    endwhile; wp_reset_postdata(); endif;

    wp_send_json( $gif_data );

}
add_action( 'template_redirect', 'wds_gif_endpoint_data' );

The Results

Now, you can enter your favorite animated GIFs into the WordPress admin under the new Custom Post Type and tag them with some proper keywords and you will be able to use an easy URL to access this data in JSON format by appending the slug of the tag in the URL. For example, you could use http://example.com/gifs/arrested-development to access all of your favorite GIFs of the Bluths. You will be presented with a nice array of JSON data as seen below.

Screen Shot 2015-07-06 at 3.20.20 PM

Why Use This Method?

Of course, this isn’t the only method to get your data. As stated above, the WP-API is on the horizon. That would open up a common API to all parts of WordPress that you can build upon and will be the standard in the future. Sometimes, though, you may need some quick and dirty data. This can be used to grant access to a third-party service or when you are making front-end AJAX calls on your own site.

You may ask, why wouldn’t you use admin-ajax.php to make those AJAX calls? When using admin-ajax.php, you are tapping into the WordPress admin and loading code that isn’t necessary. WordPress does not cache requests, for good reason, within wp-admin. If you have a high traffic site, or want the best possible performance, you definitely want to make use of caching whenever possible. Using admin-ajax.php on the front-end could potentially bring down a high traffic site if not used properly. When you create your own endpoint, you can feel free to add in your caching as you see fit.

In Summary

buster-bluth-omgThis is an easy method to get some JSON data from your WordPress site. We wrote a small API to our site that can output the data that we need. We used the WP Rewrite API to create an easy to remember URL to access the data and then ran a standard WP_Query and output this in JSON Format. This can be used as a quick method to provide just the data you need and allows for higher performance including the use of caching when using AJAX on the front-end.

15 thoughts on “Create a Simple JSON Endpoint in WordPress

  1. I know this is an older post, but I’ve got a very specific question about the code that might be useful to other people.

    Specifically, when employing the method above, we get a 404 error on the results pages. This is an issue for our javascript wizard that’s connecting with the API.

    Is there a way to send a valid header? One article I found suggested using admin-ajax.php, which you do not recommend.

    Help? Advice? Anything would be appreciated! 😉

    1. Answered my own question: adding status_header(200); just before the wp_send_json(); statement fixed the 404. Easy-peasy.

      1. Thanks for leaving your solution here, Jason. In my basic application, I wasn’t checking the status at all when getting the json data. Your solution would set the headers properly when your application does. Thanks for adding to the value of the post.

      2. Also, there was a CORS issue when I used status_header(). The solution was to add the following code to my plugin:

        add_action( ‘init’, ‘handle_preflight’ );
        function handle_preflight() {
        header(“Access-Control-Allow-Origin: *”);
        header(“Access-Control-Allow-Methods: GET”);
        }

      3. Thanks again. I was working on the same site. In that case, we wouldn’t have to worry about CORS.

      4. Thanks Man!
        You rescued me after few hours of banging my head against the wall. I got the correct JSON together with 404. All other answers in the internet where not relevant. None of the examples includes “status_header(200);”.
        IOU.

  2. Thank you for the helpful article on creating a custom endpoint in JSON.
    It helped me a lot to achieve something.

    However what’s the method you suggest to retrieve the data in the front end?

    wp_remote_get(), file_get_contents() and curl isn’t working for me.

    Can you please shed some light in it?

  3. i need to create a a form in my website that connect with this url api : https://api.beds24.com/json/createAccount to give the possibility who buy an our sub account to create it self.. i have seen the script api jason:
    {
    “authentication”: {
    “apiKey”: “apiKeyAsSetInAccountSettings”
    },
    “createAccount”: [
    {
    “username”: “username”,
    “password”: “password”,
    “apiKey”: “YourKeyToUseForTheNewAccount”,
    “email”: “mail@email.com”,
    “role”: “0”
    }
    ]
    }

    There is a sample PHP script here to modify property details: https://api.beds24.com/json/modifyProperty
    It could be modified to work with the createAccount function and my form.
    than i need also the response page from api translate in my web page

  4. i need to create a form in my web page where the custmer nedd to add 4 element:
    username”: “username”,
    “password”: “password”,
    “apiKey”: “YourKeyToUseForTheNewAccount”,
    “email”: “mail@email.com”,

    “role”: “0”

    the role is standard for hall and must be hide from the form
    so also my api key for example
    “authentication”: {
    “apiKey”: “apiKeyAsSetInAccountSettings”

    this code in the form need to point to this page https://office.bookinguide.cloud/api/json/createAccount

    and retur in other url wit the eco of the new value

    this i an action new sub account

    here the complete script jason

    {
    “authentication”: {
    “apiKey”: “apiKeyAsSetInAccountSettings”
    },
    “createAccount”: [
    {
    “username”: “username”,
    “password”: “password”,
    “apiKey”: “YourKeyToUseForTheNewAccount”,
    “email”: “mail@email.com”,
    “role”: “0”
    }
    ]
    }

  5. Pardon me if I’m misunderstanding. Lets say we put your endpoint function on some custom page or in functions.php. Now requests sent from javascript will be served from functions.php which is loaded after wp core stretches its muscles. Requires wp_options wp-config and wp-load etc or maybe more files.

    When sending request thru admin-ajax.php, Its a simple php file which also loads wp-load.php ajax-actions.php and later functions.php. Also wp-admin.php leaves the unwanted core files without loading. Whereas sending request to function residing anywhere in wordpress theme files will be loaded through whole wordpress environment?

  6. Hi, thanks for the cool post. I’m not sure if your post about admin-ajax.php is correct. In my previous research as I understood it, it is just poorly named. It is ok to use it for front and back end applications. Do you have any link to further information about that point?

Have a comment?

Your email address will not be published. Required fields are marked *

accessibilityadminaggregationanchorbackupsbookmarksbuddypresscachingcalendarcaret-downcartunifiedcrediblecustommigrationdesigndevecomfriendsgoodgroupsgrowthhostingideasinternationalizationiphoneloyaltymailhealthmessagingArtboard 1migrationsmultiple-sourcesmultisitenotificationsperformancephoneprofilesresearcharrowscalablescrapingsecuresharearrowarrowsourcestreamsupportunifiedupdatesvaultwebsitewordpress