WordPress is moving towards becoming a fully-fledged application framework, and we need new APIs. This project was born to create an easy-to-use, easy-to-understand and well-tested framework for creating these APIs, plus creating APIs for core.

This plugin provides an easy to use REST API, available via HTTP. Grab your site’s data in simple JSON format, including users, posts, taxonomies and more. Retrieving or updating data is as simple as sending a HTTP request.

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

The WordPress REST API exposes a simple yet easy interface to WP Query, the posts API, post meta API, users API, revisions API and many more. Chances are, if you can do it with WordPress, the API will let you do it.

The REST API also includes an easy-to-use JavaScript API based on Backbone models, allowing plugin and theme developers to get up and running without needing to know anything about the details of getting connected.

Check out our documentation for information on what’s available in the API and how to use it. We’ve also got documentation on extending the API with extra data for plugin and theme developers!

All tickets for the project are being tracked on GitHub. You can also take a look at the recent updates for the project.

Install the WP REST API via the plugin directory, or by uploading the files manually to your server.

For full-flavoured API support, you’ll need to be using pretty permalinks to use the plugin, as it uses custom rewrite rules to power the API.

2.0 Beta 15.0 (October 07, 2016)

Introduce support for Post Meta, Term Meta, User Meta, and Comment Meta in
their parent endpoints.

For your meta fields to be exposed in the REST API, you need to register
them. WordPress includes a register_meta() function which is not usually
required to get/set fields, but is required for API support.

To register your field, simply call register_meta and set the show_in_rest
flag to true. Note: register_meta must be called separately for each meta
key.

This mirrors our existing support for ?{taxonomy}= filtering in the posts
controller (which allows querying for only records with are associated with
any of the provided term IDs for the specified taxonomy) by adding an
equivalent _exclude variant to list IDs of terms for which associated posts
should NOT be returned.

2.0 Beta 13.0 (March 29, 2016)

BREAKING CHANGE: Fix Content-Disposition header parsing.

Allows regular form submissions from HTML forms, as well as properly formatted HTTP requests from clients. Note: this breaks backwards compatibility, as previously, the header parsing was completely wrong.

Support lodash, plus older and newer underscore: add an alias for _.contains

Add args and options on the model/collection prototypes

Rework category/tag mixins to support new API structure

Add workaround for the null/empty values returned by the API when creating a new post * these values are not accepted for subsequent updates/saves, so explicitly excluding them. See https://github.com/WP-API/WP-API/pull/2393

Better handling of the (special) me endpoint

Schema parsing cleanup

Introduce wp.api.loadPromise so developers can ensure api load complete before using

2.0 Beta 12.0 (February 9, 2016)

BREAKING CHANGE: Removes meta endpoints from primary plugin.

If your project depends on post meta endpoints, please install WP REST API Meta Endpoints. For the gory history of meta, read #1425 and linked issues. At this time, we recommend using register_rest_field() to expose meta (docs).

BREAKING CHANGES: Moves to consistent use of context throughout controllers.

Contexts limit the data present in the response. Here’s how to think of them: embed correlates with sidebar representation, view represents the primary public view, and edit is the data expected for an editor.

Introduces a register_api_field() function for backwards compat, which calls _doing_it_wrong(). However, register_api_field() won’t ever be committed to WordPress core, so you should update your function calls.

2.0 Beta 5.0 (October 23, 2015)

Now api-core has been merged into WordPress trunk (for 4.4) we should no longer load the infrastructure code when it’s already available. This also fixes a fatal error for users who were on trunk.

(props @rmccue)

Switch to new mysql_to_rfc3339

(props @rmccue)

Double-check term taxonomy

(props @rmccue)

Load admin functions

This was removed from the latest beta of WordPress in the REST API infrastructure, a more long term fix is planned.

(props @joehoyle)

Add Add compat shim for renamed rest_mysql_to_rfc3339()

(props @danielbachhuber)

Compat shim for wp_is_numeric_array()

(props @danielbachhuber)

Revert Switch to register_post_type_args filter

(props @joehoyle)

2.0 Beta 4.0 (August 14, 2015)

Show public user information through the user controller.

In WordPress as of r32683 (scheduled for 4.3), WP_User_Query now has support for getting users with published posts.

To match current behaviour in WordPress themes and feeds, we now expose this public user information. This includes the avatar, description, user ID, custom URL, display name, and URL, for users who have published at least one post on the site. This information is available to all clients; other fields and data for all users are still only available when authenticated.

Rather than using separate /schema endpoints, the schema for items is now available through an OPTIONS request to the route. This means that full documentation is now available for endpoints through an OPTIONS request; this includes available methods, what data you can pass to the endpoint, and the data you’ll get back.

This data is now also available in the main index and namespace indexes. Simply request the index with context=help to get full schema data. Warning: this response will be huge. The schema for single endpoints is also available in the collection’s OPTIONS response.

This breaks backwards compatibility for clients relying on schemas being at their own routes. These clients should instead send OPTIONS requests.

Custom endpoints can register their own schema via the schema option on the route. This option should live side-by-side with the endpoints (similar to relation in WP’s meta queries), so your registration call will look something like:

Our fantastic JavaScript API from version 1 is now available for version 2, refreshed with the latest and greatest changes.

As a refresher: if you want to use it, simply make your script depend on wp-api when you enqueue it. If you want to enqueue the script manually, add wp_enqueue_script( 'wp-api' ) to a callback on wp_enqueue_scripts.

Previously when fetching a collection of items, you only received the items themselves. To fetch the links as well via embedding, you needed to make a request to the single item with _embed set.

No longer! You can now request a collection with embeds enabled (try /wp/v2/posts?_embed). This will embed links inside each item, allowing you to build interface items much easier (for example, post archive pages can get featured image data at the same time).

This also applies to custom endpoints. Any endpoint that returns a list of objects will automatically have the embedding applied to objects inside the list.

Requests from other origins could potentially run code on the API domain, allowing cross-origin access to authentication cookies or similar.

Reported by @xknown on 2015-07-23.

Move /postsWP_Query vars back to filter param.

In version 1, we had internal WP_Query vars available via filter (e.g. filter[s]=search+term). For our first betas of version 2, we tried something different and exposed these directly on the endpoint. The experiment has now concluded; we didn’t like this that much, so filter is back.

We plan on adding nicer looking arguments to collections in future releases, with a view towards being consistent across different collections. We also plan on opening up the underlying query vars via filter for users, comments, and terms as well.

By extension of the fact that getting any individual post yields a forbidden context error when the context=edit and the user is not authorized, the user should also not be permitted to list any post items when unauthorized.

Previously, when pretty permalinks were enabled, the API URL during autodiscovery looked like /wp-json, whereas the non-pretty permalink URL looked like ?rest_route=/. These are now consistent, and always end with a slash character to simplify client URL building.

Previously, the schema was merely a decorative element for documentation inside the comments controller. To bring it inline with our other controllers, the schema is now used internally for validation.

Previously, the Location header was sent when updating resources due to some inadvertent copypasta. This header should only be sent when creating to direct clients to the new resource, and isn’t required when you’re already on the correct resource.

Since the first versions of the API, we’ve been building attachment URLs via str_replace. Who knows why we were doing this, but it caused problems with custom attachment URLs (such as CDN-hosted images). This now correctly uses the internal functions and filters.

2.0 Beta 2.0 (May 28, 2015)

Load the WP REST API before the main query runs.

The rest_api_loaded function now hooks into the parse_request action.
This change prevents the main query from being run on every request and
allows sites to set WP_USE_THEMES to false. Previously, the main query
was always being run (SELECT * FROM wp_posts LIMIT 10), even though the
result was never used and couldn’t be cached.

The index (/wp-json by default) now contains a list of the available
namespaces. This allows for simple feature detection. You can grab the index
and check namespaces for wp/v3 or pluginname/v2, which indicate the
supported endpoints on the site.

** Version 1.4 now supports whitelisting of individual routes within the REST API **

The engine for the API has existed in WordPress since v4.4, but additional functionality and endpoints are a
continual project. While this is very exciting news for many reasons – and many plugins, themes, and even pieces of
WordPress core are already beginning to use the REST API – it is also not functionality that every site admin is going
to want enabled on their website if not necessary.

As of WordPress 4.7, the filters provided for disabling the REST API were removed. To compensate, this plugin will
forcibly return an authentication error to any API requests from sources who are not logged into your website, which
will effectively still prevent unauthorized requests from using the REST API to get information from your website.

For WordPress versions 4.4, 4.5 and 4.6, this plugin makes use of the rest_enabled filter provided by the API to
disable the API functionality. However, it is strongly recommended that all site owners run the most recent version
of WordPress except where absolutely necessary.

Upload the disable-json-api directory to the /wp-content/plugins/ directory via FTP

Alternatively, upload the disable-json-api_v#.#.zip file to the ‘Plugins->Add New’ page in your WordPress admin
area

Activate the plugin through the ‘Plugins’ menu in WordPress

Installation Instructions

Upload the disable-json-api directory to the /wp-content/plugins/ directory via FTP

Alternatively, upload the disable-json-api_v#.#.zip file to the ‘Plugins->Add New’ page in your WordPress admin
area

Activate the plugin through the ‘Plugins’ menu in WordPress

How do I know if this plugin is working?

While logged into WordPress as any user, the REST API will function as intended. Because of this, you must use a new
browser – or Chrome’s incognito mode – to test your website with a clean session. Go to yourdomain.com/wp-json/ (or
yourdomain.com/?rest_route=/ if you have pretty permalinks disabled) while NOT LOGGED IN to test the results. You will
see an authentication error returned if the plugin is active. “DRA: Only authenticated users can access the REST API.”

Does this plugin disable all REST API’s installed?

This plugin is ONLY meant to disable endpoints accessible via the default REST API that is part of WordPress itself. If
a plugin or theme chooses to register its namespace with the core REST API, its endpoints will – by default – by
disabled so long as this plugin is active. Namespaces and routes may be whitelisted via this plugin’s Settings page.

1.4.1

Fixed echo of text URL to primary Plugins page in WP Dashboard

1.4

Tested for WP v4.8

Tested for PHP 5.3+

Added settings screen

Site Admins may now whitelist routes that they wish to allow unauthenticated access to

Added dra_allow_rest_api filter to the is_logged_in() check, so developers can get more granular with permissions

Props to @tangrufus for all of the help that went into this release

1.3

Tested for WP v4.7

Adding new functionality to raise authentication errors in 4.7+ for non-logged-in users

Notice: This is the deprecated Version 1 of the WP REST API. It’s no longer supported beyond security fixes. Please consider WP REST API v2 for your website, although there are considerations to be aware of. If you activate both v1 and v2 on your website, then v1 will take priority and v2 will be inaccessible.

WordPress is moving towards becoming a fully-fledged application framework, and
we need new APIs. This project was born to create an easy-to-use,
easy-to-understand and well-tested framework for creating these APIs, plus
creating APIs for core.

This plugin provides an easy to use REST API, available via HTTP. Grab your
site’s data in simple JSON format, including users, posts, taxonomies and more.
Retrieving or updating data is as simple as sending a HTTP request.

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

WP API exposes a simple yet easy interface to WP Query, the posts API, post meta
API, users API, revisions API and many more. Chances are, if you can do it with
WordPress, WP API will let you do it.

WP API also includes an easy-to-use Javascript API based on Backbone models,
allowing plugin and theme developers to get up and running without needing to
know anything about the details of getting connected.

Check out our documentation for information on what’s available in the
API and how to use it. We’ve also got documentation on extending the API with
extra data for plugin and theme developers!

All tickets for the project are being tracked on GitHub. You can also take a
look at the recent updates for the project.

Drop this directory in and activate it. You need to be using pretty permalinks
to use the plugin, as it uses custom rewrite rules to power the API.

1.2.5

Ensure media of private posts are private too.

Reported by @danielbachhuber on 2016-01-08.

1.2.4

Compatibilty with WordPress 4.4

Because WordPress 4.4 also registers rewrite rules for /wp-json/, WP-API v1 needs to register its rewrite rules with higher priority to continue to function as expected.

(props @danielbachhuber)

1.2.3

Fix potential XSS vulnerability.

Requests from other origins could potentially run code on the API domain, allowing cross-origin access to authentication cookies or similar.

Reported by @xknown on 2015-07-23.

1.2.2

Fix user access security vulnerability.

Authenticated users were able to escalate their privileges bypassing the
expected capabilities check.

Reported by @kacperszurek on 2015-05-16.

1.2.1

Fix information disclosure security vulnerability.

Unauthenticated users could access revisions of published and unpublished posts. Revisions are now only accessible to authenticated users with permission to edit the revision’s post.

Reported by @chredd on 2015-04-09.

1.2

Preflighted requests (using the OPTIONS method) include the headers
Access-Control-Allow-Origin, Access-Control-Allow-Methods, and
Access-Control-Allow-Credentials in the response, if the HTTP origin is
set.

Previously JSONP requests sent the incorrect application/json Content-Type
header with the response. This would result in an error if strict MIME
checking was enabled. The Content-Type header was corrected to
application/javascript for JSONP responses.

Corrected the edit and create posts code examples in the Getting Started
section. The new post example was updated to include the required
content_raw parameter. The new and edit posts examples were updated to use
a correct date parameter.

1.1

Taxonomies and terms have now been moved from the /posts/types/<type>
namespace to global routes: /taxonomies, /taxonomies/<tax>,
/taxonomies//terms and /taxonomies/<tax>/terms/<term>

Test coverage for taxonomy endpoints has also been increased to 100%.

Deprecation warning: The /posts/types/<type>/taxonomies endpoint (and
sub-endpoints with the same prefix) have been deprecated in favour of the new
endpoints. These deprecated endpoints will now return a
X-WP-DeprecatedFunction header indicating that the endpoint should not be
used for new development, but will continue to work in the future.

Posts without excerpts could previously return nonsense strings, excerpts from
other posts, or cause internal PHP errors. Posts without excerpts will now
always return an excerpt, typically automatically generated from the post
content.

The excerpt_raw field was added to the edit context on posts. This field
contains the raw excerpt data saved for the post, including empty
string values.

Password-protected posts could previously be exposed to all users, however
could also have broken behaviour with excerpts. Password-protected posts are
now hidden to unauthenticated users, while content and excerpts are shown
correctly for the edit context.

(Note that hiding password-protected posts is intended to be a temporary
measure, and will likely change in the future.)

WP_JSON_Server::get_timezone(), WP_JSON_Server::get_date_with_gmt(),
WP_JSON_Server::get_avatar_url() and “WP_JSON_Server::parse_date()` have
all been moved into the global namespace to decouple them from the server
class.

Deprecation warning: These methods have been deprecated. The new
json_get_timezone(), json_get_date_with_gmt(), json_get_avatar_url() and
json_parse_date() methods should now be used instead.

1.0

Add user endpoints.

Creating, reading, updating and deleting users and their data is now possible
by using the /users endpoints. /users/me can be used to determine the
current user, and returns a 401 status for non-logged in users.

Note that the format of post authors has changed, as it is now an embedded
User entity. This should not break backwards compatibility.

Creating, reading, updating and deleting post meta is now possible by using
the /posts/<id>/meta endpoints. Post meta is now correctly embedded into
Post entities.

Meta can be updated via the Post entity (e.g. PUT to /posts/<id>) or via
the entity itself at /posts/<id>/meta/<mid>. Meta deletion must be done via
a DELETE request to the latter.

Only non-protected and non-serialized meta can be accessed or manipulated via
the API. This is not predicted to change in the future; clients wishing to
access this data should consider alternative approaches.

Post types can now indicate their availability via the API using the
show_in_json argument passed to register_post_type. This value defaults to
the publicly_queryable argument (which itself defaults to the
public argument).

This breaks backwards compatibility for clients using Basic
authentication. Clients are encouraged to switch to using OAuth
authentication. The Basic Authentication plugin can be
installed for backwards compatibility and local development, however should
not be used in production.

Add json_ensure_response function to ensure either a
WP_JSON_ResponseInterface or a WP_Error object is returned.

When extending the API, the json_ensure_response function can be used to
ensure that any raw data returned is wrapped with a WP_JSON_Response object.
This allows using get_status/get_data easily, however WP_Error must
still be checked via is_wp_error.

Endpoints that need to set headers or response codes should now return a
WP_JSON_Response rather than using the server methods.
WP_JSON_ResponseInterface may also be used for more flexible use of the
response methods.

Deprecation warning: Calling WP_JSON_Server::header,
WP_JSON_Server::link_header and WP_JSON_Server::query_navigation_headers
is now deprecated. This will be removed in 1.0.

0.8

Add compatibility layer for JsonSerializable. You can now return arbitrary
objects from endpoints and use the jsonSerialize() method to return the data
to serialize instead of just using the properties of the object.

0.7

The response handler object is now passed into the endpoint objects via the
constructor, allowing you to avoid excess global state where possible. It’s
recommended to use this where possible rather than the global object.

Return all term metadata, rather than just the last one
(props @afurculita, #13)

Access post metadata from cache where possible – Note, this is a backwards
compatibility break, as the format of the metadata has changed. This may
change again in the near future, so don’t rely on it until 1.0.
(props @afurculita, #14)

0.6

Add generic CPT class – Plugins are now encouraged to extend
WP_JSON_CustomPostType and get free hooking for common actions. This
removes most of the boilerplate that you needed to write for new CPT-based
routes and endpoints (#380)

Use defined filter priorities for endpoint registration – It’s now easier to
inject your own endpoints at a defined point

Update the schema – Now includes documentation on the Media entity, plus more
(#264)

Add better taxonomy support – You can now query for taxonomies and terms
directly. The routes here might seem strange
(/posts/types/post/taxonomies/category for example), but the intention is
to future-proof them
as much as possible(#275)

0.3

Add initial comment endpoints to get comments for a post, and get a single
comment (#320)

Return a Post entity when updating a post, rather than wrapping it with
useless text (#329)

Allow filtering the output as well as input. You can now use the
json_dispatch_args filter for input as well as the json_serve_request
filter for output to serve up alternative formats (e.g. MsgPack, XML (if
you’re insane))

Include a profile link in the index, to indicate the JSON Schema that the
API conforms to. In the future, this will be versioned.

0.2

Allow all public query vars to be passed to WP Query – Some private query vars
can also be passed in, and all can if the user has edit_posts
permissions (#311)

Pagination can now be handled by using the page argument without messing
with WP Query syntax (#266)

0.0.4

Hyperlinks now available in most constructs under the ‘meta’ key. At the
moment, the only thing under this key is ‘links’, but more will come
eventually. (Try browsing with a browser tool like JSONView; you should be
able to view all content just by clicking the links.)

Accessing / now gives an index which briefly describes the API and gives
links to more (also added the HIDDEN_ENDPOINT constant to hide from this).

Post collections now contain a summary of the post, with the full post
available via the single post call. (prepare_post() has fields split into
post and post-extended)

Post entities have dropped post_ prefixes, and custom_fields has changed to
post_meta.

Now supports JSONP callback via the _jsonp argument. This can be disabled
separately to the API itself, as it’s only needed for
cross-origin requests.

Internal: No longer extends the XMLRPC class. All relevant pieces have been
copied over. Further work still needs to be done on this, but it’s a start.

This plugin uses the OAuth 1.0a protocol to allow delegated authorization; that is, to allow applications to access a site using a set of secondary credentials. This allows server administrators to control which applications can access the site, as well as allowing users to control which applications have access to their data.

This is a feature plugin that is a spinoff of the main Two-Factor Authentication plugin, found at https://github.com/georgestephanis/two-factor/.

With Application Passwords you are able to authenticate a user without providing that user’s password directly, instead you will use a base64 encoded string of their username and a new application password.

Creating a New Application Password

Go the User Profile page of the user that you want to generate a new application password for. To do so, click Users on the left side of the WordPress admin, then click on the user that you want to manage.

Scroll down until you see the Application Passwords section. This is typically at the bottom of the page.

Within the input field, type in a name for your new application password, then click Add New.Note: The application password name is only used to describe your password for easy management later. It will not affect your password in any way. Be descriptive, as it will lead to easier management if you ever need to change it later.

Once the Add New button is clicked, your new application password will appear. Be sure to keep this somewhere safe, as it will not be displayed to you again. If you lose this password, it cannot be obtained again.

Testing an Application Password

WordPress REST API

This test uses the technologies listed below, but you can use any REST API request.

Now that you have your new password, you will need to base64 encode it using a terminal window as well as your username to use it with the REST API.
The command you will use is as follows:shell
echo -n "USERNAME:PASSWORD" | base64
Within this, you will replace USERNAME:PASSWORD with your username and newly generated application password. For example:shell
echo -n "admin:mypassword123" | base64

Once your username and password are base64 encoded, you are now able to make a simple REST API call using the terminal window to update a post. Because you are performing a POST request, you will need to authorize the request using your newly created base64 encoded access token. If authorized correctly, you will see the post title update to “New Title.”shell
curl --header "Authorization: Basic ACCESS_TOKEN" -X POST -d "title=New Title" http://LOCALHOST/wp-json/wp/v2/posts/POST_ID}
When running this command, be sure to replace ACCESS_TOKEN with your newly generated access token, LOCALHOST with the location of your local WordPress installation, and POST_ID with the ID of the post that you want to edit.

XML-RPC

This test uses the technologies listed below, but you can use any XML-RPC request.

XML-RPC enabled within WordPress

cURL

Mac OSX or Linux

A Mac or Linux terminal

Local development environment (e.g. MAMP, DesktopServer, Vagrant) running on localhost

Once you have created a new application password, it’s time to send a request to test it. Unlike the WordPress REST API, XML-RPC does not require your username and password to be base64 encoded. To begin the process, open a terminal window and enter the following:shell
curl -H 'Content-Type: text/xml' -d '<methodCall><methodName>wp.getUsers</methodName><params><param><value>1</value></param><param><value>USERNAME</value></param><param><value>PASSWORD</value></param></params></methodCall>' LOCALHOST
In the above example, replace USERNAME with your username, and PASSWORD with your new application password. This should output a response containing all users on your site.

Who make this plugin?

Support

To save time so that we can spend it on development, please read the plugin’s FAQs first.
Before requesting support, and ensure that you have updated Sunny and WordPress to the latest released version and installed PHP 7 or later.

You can filter on nested properties with a ‘.’ like ‘title.rendered’. Not sure if this also works on arrays. Existing issues or Submit issue

Does this also work for my custom posttype?

Yes, we picked 20 as priority (default = 10) for activating.
This mean this plugin is probably activated last, so all custom post types should already be loaded.
But this only works if you made it public for the api.
See Adding REST API Support for Custom Content Types for more information.

Upload the wp-rest-api-log directory to the /wp-content/plugins/ directory

Activate the plugin through the ‘Plugins’ menu in WordPress

Go to Settings -> REST API Log to enable or disable logging

Go to Tools -> REST API Log to start viewing log entries

Installation Instructions

Upload the wp-rest-api-log directory to the /wp-content/plugins/ directory

Activate the plugin through the ‘Plugins’ menu in WordPress

Go to Settings -> REST API Log to enable or disable logging

Go to Tools -> REST API Log to start viewing log entries

How do I use ElasticPress logging?

ElasticPress is a plugin than interfaces WordPress to the ElasticSearch search service. Because ElasticSearch has its own REST API for indexing and searching data, it was a natural fit to extend logging support via this REST API Logging plugin.

You can go into Settings > ElasticPress to enable logging for requests & responses. You can also disable REST API logging if you only need ElasticPress logging.

v1.6.5 July 26, 2017

Fixed some escaping issues in admin and new-line characters when saving to database (props davidanderson)

Updated highlight.js and clipboard.js versions

v1.6.4 May 26, 2017

Fixed an issue with the URL in the settings tabs (props davidanderson)