Tutorial

An Overview of the WordPress JSON API

** UPDATED POST FOR WP-API V2 HERE

WordPress has had no formal REST API. There is the crude XMLRPC, but we won’t go into the gory details of the past.

As part of Google Summer of Code (GSOC), Ryan McCue submitted a proposal for creating a formal JSON API to be included in WordPress core and therefore available to every WordPress.org install.

For those who may not know what a REST API is; it stands for Representational State Transfer. In short, it separates client from the server. Each request from any client contains all the information necessary to service the request, and session state is held in the client.

There is no “official” standard for RESTful web API’s. This is because REST is an architectural style. You can use HTML, XML or JSON. JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write, it’s very easy for machines to parse and generate. This is largely in part the reason it has become the de facto choice when creating REST API’s, and also the reason JSON data is the response format of the forthcoming API.

JSON API OVERVIEW

Currently, you can use the WordPress JSON API on your site via a plugin you install from the WordPress repository; the functionality in this plugin will eventually be included in the core WordPress software. Activate it and you now have a REST API for your site’s content. The plugin exposes your data in JSON format in the following content types:

  • Posts
  • Pages
  • Users
  • Media
  • Taxonomies
  • Custom Post Types

The response data is like what you would get in the WordPress loop, only the format is JSON. This allows you to display it in any way you wish. You can even filter the API calls in a similar fashion to the loop.

Want to get your site’s posts? Simply send a GET request to url.com/wp-json/posts. Update user with ID 4? Send a POST request to url.com/wp-json/users/4. Get all posts with the search term “awesome”? GET url.com/wp-json/posts?filter[s]=awesome. It’s that easy.

Let’s look at some of the JSON responses from WP-API developer @RachelBaker‘s site:

This is just a small example of the wide range of data you are able to request from the API.

Some API calls require authentication, just like WordPress requires authentication to access wp-admin, or to create new posts. Most GET requests do not require authentication, this allows you to display content via the API on the front of your site, or in an external app without a user needing to log in.

Here is an example AJAX call to filter the posts API endpoint response:

$.ajax({
    url: 'http://url.com/wp-json/posts',
    data: {
        filter: {
        'posts_per_page': 5
        }
    },
    dataType: 'json',
    type: 'GET',
    success: function(data) {
        // success code
    },
    error: function() {
        // error code
    }
});

Most anything you can filter get_posts you can use to filter the posts JSON response. The other API endpoints are filtered in much the same way.

Also, you can use authenticated API calls to PUT or DELETE content. To edit a post you send a PUT request to the API at url.com/wp-json/posts/id where id is the post id you wish to edit. To add meta to a post send a Post request to url.com/wp-json/posts/id/meta and in your ajax supply a key and value in the data parameter. This really could not be any more simple.

In a lot of cases, people choose WordPress as their CMS because it’s very easy to add new content types. Another benefit of the JSON API is it works well with Custom Post Types (CPT). To access a CPT you add a type parameter to the API request (url.com/wp-json/posts?type=cpt); and you can add any other get post filters as well.

There is one gotcha with posts, and that is custom meta, it’s not added for you. If you want to include custom meta it is easy to add with a filter to json_prepare_post.

Example function to add meta to posts:

function custom_json_api_prepare_post( $post_response, $post, $context ) {

    $meta = get_post_meta( $post['ID'] );
    $post_response[‘meta_field_name’] = $meta;

    return $post_response;
}
add_filter( 'json_prepare_post', 'custom_json_api_prepare_post', 10, 3 );

There is also some great documentation for the API, read through them and even check out issues on Github to get a better handle on current state of the API.

API USAGE

You may be asking why you need a JSON API in WordPress. There are many reasons, but the main reason is to allow access to data without any constraints on its usage. This allows developers to create unique experiences, one of them being custom applications. Also, plugins and themes can access the data on your site and display the content more efficiently than reloading the entire page. Sections of a site can be updated live or with user interaction.

Maybe you have a Multisite install, and each site is a store. You may want to display all of the sales items from each site on the network that are tagged “Halloween”. The API makes these types of data mash-ups very easy to implement.

Maybe you want to post to your WordPress site from a web connected device. Smart devices are gaining momentum, apps from these devices can access your API, and your site will handle the request.

I could list a hundred more ideas for usage but the point of why we need and API in WordPress is this…

If every WordPress site is running a similar API data structure, and the sites data is open, amazing things can be created.

This post is the first in a series where I will go deeper into all aspects of the API, keep an eye out.

Some Additional Resources Worth Checking Out

http://wp-api.org
https://wordpress.org/plugins/json-rest-api
http://apppresser.com/using-wordpress-rest-api-mobile-app
http://wordpress.tv/2014/07/06/rachel-baker-put-your-content-to-rest-with-wp-api
http://wordpress.tv/2014/10/13/andrew-nacin-post-modern-wordpress

35 thoughts on “An Overview of the WordPress JSON API

  1. If you want to see an example of the JSON API in true action, SheReadsTruth (a women’s online bible study site – http://www.shereadstruth.com) has both their WordPress site and their iOS app running using the JSON API with amazing results. Even without the “native” JSON in core yet, the API is extremely usable, and the app is very responsive.

  2. If I am using the function to get the all custom meta of the post its only show the custom meta and remove the content and other things, please advice.

  3. HI, I really love your post. I am really stuck here yoursite.com/wp-json/post/123 do you know how to get the next and prev post link?

      1. Thanks for the quick response! Do you have any example how to do it? Do I need to bind that in function.php?

  4. Maybe you could help me. How can I use the WP-API inside of my plugin? I mean, create just one plugin to avoid to force the user to install two plugins?

    1. if you include it it could cause problems with inclusion in core. If you develop a plugin make sure to remove it when it is in core.

  5. I used your snippet below this text: “Example function to add meta to posts:”
    and I do see what I named “custom_field” show up in Postman but how do I access them?

    From Postman it looks like this…

    “custom_field”: {
    “_edit_last”: [
    “1”
    ],
    “_edit_lock”: [
    “1428095186:1”
    ],
    “lat”: [
    “35.859751”
    ],
    “age”: [
    “20”
    ]
    }


    I’ve been working with…

    $http.get(‘wp-json/metadata?filter[custom_field]=’ + $routeParams.ID).success(function(res){
    if ( res.length > 1 ) {
    $scope.media = res;
    $scope.age = res.age;
    }
    });

  6. Is there anyway to get multiple tags together?

    E.g. Instead of:
    /api/?json=get_tag_posts&tag_slug=tag1

    Use:
    /api/?json=get_tag_posts&tag_slug=tag1,tag2

    Which could bring back posts from both tags?

  7. I am getting the response as text/html instead of JSON.
    What can be the reason? Please suggest

  8. Hello Ryan! I’m having some issues with the custom meta data… I have NO idea where I have to put that code.

    Inside: class-wp-json-posts.php????

    And if so… where inside of that??? I’m getting constants errors.

  9. Thank you for the article!
    I do have one question though…
    You talk about adding metadata to the posts with a sweet function, however, you never told us where to put that function… If you could elaborate, that’d be great!
    Thanks

  10. Thank you so much for the info in this post, also I really appreciate the info on `json_prepare_post`. I was lost but know I see…

    @Jino, @mariano, I’m placing mine in a plugin I created for custom post types, at the bottom with a little `set it and forget it` setting where I pick up the custom meta as ‘additional.meta_name’.


    function custom_json_api_prepare_post( $post_response, $post, $context ) {

    // add meta details in here
    $meta = get_post_meta( $post['ID'] );
    $post_response["additional"] = $meta;

    return $post_response;
    }
    add_filter( 'json_prepare_post', 'custom_json_api_prepare_post', 10, 3 );

  11. Great tutorial! Any ideas on how to return more custom post types? Default value is 10 posts when i pull in from “tempoonline.com.ng/wp-json/posts”

    i want to be able to pull more posts to implement an infinite scroll

    1. In my jQuery example you see the filter for posts per page.

      url.com/wp-json/posts?filter[posts_per_page]=20

      1. thanks for the snappy reply.. Much appreciated.. you have no idea how youve saved me..

        is there a way i can append more posts automatically to the already imported post as i scroll down the page.. like an infinite scroll

        Thanks again

  12. Ryan, this is a very helpful article. I’m just getting my head around what a REST API and this plugin can do. The impression I get is that this plugin is only one-way; that is you can only pull data from your website to be used externally.

    But is it possible (using the plugin) to go the other way? Specifically, I want to grab data from a JSON feed and use that data on my site. Specifically, I want to pull a list of “listings” with relevant data attached, have each listing become a custom post type (Listing) and populate custom fields using the attached data for each.

    Is this possible using this plugin? (I’m using the Types plugin by OnTheGo Systems to create the post type/fields, so there may be a conflict).

    1. Is the listings on your site? If not you can use php curl to get json to create custom posts. The WP-API plugin can post to a site but requires authentication

  13. Hi Ryan…
    i read your blog it’s very helpful for everyone..
    actually i am making a web-services in wordpress using json api plugin
    and made own custom controller for showing page content,,, all is right
    but i want to show only page content title and page url in json response
    how can i will filter those thing from json response you can prefer this json api method code below
    public function get_page() {
    global $json_api;
    extract($json_api->query->get(array(‘id’, ‘slug’, ‘page_id’, ‘page_slug’, ‘children’)));
    if ($id || $page_id) {
    if (!$id) {
    $id = $page_id;
    }
    $posts = $json_api->introspector->get_posts(array(
    ‘page_id’ => $id
    ));
    } else if ($slug || $page_slug) {
    if (!$slug) {
    $slug = $page_slug;
    }
    $posts = $json_api->introspector->get_posts(array(
    ‘pagename’ => $slug
    ));
    } else {
    $json_api->error(“Include ‘id’ or ‘slug’ var in your request.”);
    }

    // Workaround for https://core.trac.wordpress.org/ticket/12647
    if (empty($posts)) {
    $url = $_SERVER[‘REQUEST_URI’];
    $parsed_url = parse_url($url);
    $path = $parsed_url[‘path’];
    if (preg_match(‘#^http://[^/]+(/.+)$#’, get_bloginfo(‘url’), $matches)) {
    $blog_root = $matches[1];
    $path = preg_replace(“#^$blog_root#”, ”, $path);
    }
    if (substr($path, 0, 1) == ‘/’) {
    $path = substr($path, 1);
    }
    $posts = $json_api->introspector->get_posts(array(‘pagename’ => $path));
    }

    if (count($posts) == 1) {
    if (!empty($children)) {
    $json_api->introspector->attach_child_posts($posts[0]);
    }
    return array(
    ‘page’ => $posts[0]
    );
    } else {
    $json_api->error(“Not found.”);
    }

    }

    please suggest me i am new in web-services

  14. Ryan, thanks for the article. I’m hoping you can point me in the right direction. I’m told one of my sites has a few different broken links but I can’t seem to find them. And they all use the wp-json in the path. http://bostonconstructionllc.com/wp-json/ and http://bostonconstructionllc.com/wp-json/oembed/1.0/embed?url=http://bostonconstructionllc.com/custom-homes-carl-and-kim/

    Where should i go to locate the wp-json ??? Thanks for any information you can give me.

    1. Looks like you are trying to use jetpack API with WP-API, these are two separate APIs that do not work together

      1. Ryan, thanks so much for your help. I have never used jetpack so my guess is I can remove those lines altogether. I really appreciate you taking the time. Debbie N.

Comments are closed.

accessibilityadminaggregationanchorbackupsbookmarksbuddypresscachingcalendarcaret-downcartunifiedcrediblecustommigrationdesigndevecomfriendsgoodgroupsgrowthhostingideasinternationalizationiphoneloyaltymailhealthmessagingArtboard 1migrationsmultiple-sourcesmultisitenotificationsperformancephoneprofilesresearcharrowscalablescrapingsecuresharearrowarrowsourcestreamsupportunifiedupdatesvaultwebsitewordpress