Title: rest-api – Make WordPress Core

---

#  Tag Archives: rest-api

 [  ](https://profiles.wordpress.org/kadamwhite/) [K. Adam White](https://profiles.wordpress.org/kadamwhite/)
4:28 pm _on_ October 11, 2022     
Tags: [core-restapi ( 34 )](https://make.wordpress.org/core/tag/core-restapi/),
[dev-notes ( 616 )](https://make.wordpress.org/core/tag/dev-notes/), [dev-notes-6.1 ( 37 )](https://make.wordpress.org/core/tag/dev-notes-6-1/),
rest-api   

# 󠀁[Miscellaneous REST API improvements in WordPress 6.1](https://make.wordpress.org/core/2022/10/11/miscellaneous-rest-api-improvements-in-wordpress-6-1/)󠁿

## Search REST resources by ID across subtypes

WordPress 6.1 includes an enhancementenhancement Enhancements are simple improvements
to WordPress, such as the addition of a hook, a new feature, or an improvement to
an existing feature. to the search controller, [#56546](https://core.trac.wordpress.org/ticket/56546),
which makes it possible to retrieve a term or post object over the REST APIREST 
API The REST API is an acronym for the RESTful Application Program Interface (API)
that uses HTTP requests to GET, PUT, POST and DELETE data. It is how the front end
of an application (think “phone app” or “website”) can communicate with the data
store (think “database” or “file system”) [https://developer.wordpress.org/rest-api/](https://developer.wordpress.org/rest-api/)
without knowing anything but that resource’s ID and object type.

`get_post` can retrieve a post of any post type so long as you know the post’s numeric
ID, and `get_term` can retrieve a term from any taxonomyTaxonomy A taxonomy is a
way to group things together. In WordPress, some common taxonomies are category,
link, tag, or post format. [https://codex.wordpress.org/Taxonomies#Default_Taxonomies](https://codex.wordpress.org/Taxonomies#Default_Taxonomies)..
Because REST objects are segregated by post type-specific endpoints, however, there
has not been a clear way to get a Post with ID 78 if you don’t know whether it is
a `page`, `post`, or `my-cpt`.

The coreCore Core is the set of software required to run WordPress. The Core Development
Team builds WordPress. `/search` endpoint now supports `?include` and `?exclude`
parameters which take a list of IDs, and limit results to posts matching those IDs.

Examples:

 * To get post 78 when you don’t know its post type,
    - `/wp/v2/search?include=78`
 * To get posts 78 and 79 only if they are in the `page` post type,
    - `/wp/v2/search?include=78,79&subtype=page`
 * To search posts excluding post 78,
    - `/wp/v2/search?exclude=78`
 * To get term 87,
    - `/wp/v2/search?type=term&include=78`
 * To get term 87 only if it is a categoryCategory The 'category' taxonomy lets 
   you group posts / content together that share a common bond. Categories are pre-
   defined and broad ranging.,
    - `/wp/v2/search?type=term&include=78&subtype=category`
 * To search terms excluding terms 87 and 88,
    - `/wp/v2/search?exclude=87,88`

The search endpoint supports the `_embed` metaMeta Meta is a term that refers to
the inside workings of a group. For us, this is the team that works on internal 
WordPress sites like WordCamp Central and Make WordPress. parameter, so developers
can therefore use the search endpoint to retrieve a full post or term response object
in one request knowing only those object’s IDs.

As an example of how this could be used, imagine a custom blockBlock Block is the
abstract term used to describe units of markup that, composed together, form the
content or layout of a webpage using the WordPress editor. The idea combines concepts
of what in the past may have achieved with shortcodes, custom HTML, and embed discovery
into a single consistent API and user experience. which relates to a specific post.
As of WordPress 6.1 developers can implement that block knowing only the related
post’s ID, and could then create a hook to search for that post by ID and retrieve
it using the Block Editor’s existing entity system:

    ```notranslate
    /**
     * Dictionary of requested items: keep an in-memory list of the type (if known)
     * for each requested ID, to limit unnecessary API requests.
     */
    const typeById = {};
    ​
    /**
     * Query for a post entity resource without knowing its post type.
     *
     * @param {number} id Numeric ID of a post resource of unknown subtype.
     * @returns {object|undefined} The requested post object, if found and loaded.
     */
    function usePostById( id ) {
        const type = typeById[ id ];
    ​
        useEffect( function() {
            if ( ! id || typeById[ id ] ) {
                return;
            }
    ​
            apiFetch( {
                path: `/wp/v2/search?type=post&include=${ id }&_fields=id,subtype`,
            } ).then( ( result ) => {
                if ( result.length ) {
                    typeById[ id ] = result[0].subtype;
                }
            } );
        }, [ id ] );
    ​
        return useSelect( function( select ) {
            if ( ! id || ! type ) {
                return undefined;
            }
            return select( 'core' ).getEntityRecord( 'postType', type, id );
        }, [ id, type ] );
    }
    ```

## Pretty-printing REST endpoint JSONJSON JSON, or JavaScript Object Notation, is a minimal, readable format for structuring data. It is used primarily to transmit data between a server and web application, as an alternative to XML. responses

WordPress 6.1 also introduces support for returning pre-formatted JSON from the 
REST API. [#41998](https://core.trac.wordpress.org/ticket/41998) lets developers
request formatted JSON using a new `_pretty` query parameter or a filterFilter Filters
are one of the two types of Hooks [https://codex.wordpress.org/Plugin_API/Hooks](https://codex.wordpress.org/Plugin_API/Hooks).
They provide a way for functions to modify data of other functions. They are the
counterpart to Actions. Unlike Actions, filters are meant to work in an isolated
manner, and should never have side effects such as affecting global variables and
output., particularly useful when querying via curl or other tools which do not 
provide an option to format responses.

To format the JSON returned from a specific endpoint request, append the `?_pretty`
query parameter to the endpoint URLURL A specific web address of a website or web
page on the Internet, such as a website’s URL www.wordpress.org.

To instruct WordPress to pretty-print all REST response bodies, a developer can 
use the `rest_json_encode_options` filter:

    ```notranslate
    function myproject_pretty_print_rest_responses( $options ) {
            $options |= JSON_PRETTY_PRINT;
    ​
            return $options;
    }
    add_filter( 'rest_json_encode_options', 'myproject_pretty_print_rest_responses', 10 );
    ```

A developer or site owner may also disable pretty-printing globally using the same
filter:

    ```notranslate
    function myproject_disable_rest_pretty_printing( $options ) {
            $options &= ~JSON_PRETTY_PRINT;
    ​
            return $options;
    }
    add_filter( 'rest_json_encode_options', 'myproject_disable_rest_pretty_printing', 10 );
    ```

Filters are applied after, and can override, the `_pretty` query parameter.

_Thanks to _[@spacedmonkey](https://profiles.wordpress.org/spacedmonkey/)_ for peer
review._

[#core-restapi](https://make.wordpress.org/core/tag/core-restapi/), [#dev-notes](https://make.wordpress.org/core/tag/dev-notes/),
[#dev-notes-6-1](https://make.wordpress.org/core/tag/dev-notes-6-1/), [#rest-api](https://make.wordpress.org/core/tag/rest-api/)

 [  ](https://profiles.wordpress.org/spacedmonkey/) [Jonny Harris](https://profiles.wordpress.org/spacedmonkey/)
2:26 pm _on_ October 10, 2022     
Tags: [6.1 ( 94 )](https://make.wordpress.org/core/tag/6-1/),
[core-restapi ( 34 )](https://make.wordpress.org/core/tag/core-restapi/), [dev-notes ( 616 )](https://make.wordpress.org/core/tag/dev-notes/),
[dev-notes-6.1 ( 37 )](https://make.wordpress.org/core/tag/dev-notes-6-1/), [performance ( 404 )](https://make.wordpress.org/core/tag/performance/),
rest-api   

# 󠀁[Performance improvements to the REST API](https://make.wordpress.org/core/2022/10/10/performance-improvements-to-the-rest-api/)󠁿

WordPress 6.1 brings a number of key improvements to the REST APIREST API The REST
API is an acronym for the RESTful Application Program Interface (API) that uses 
HTTP requests to GET, PUT, POST and DELETE data. It is how the front end of an application(
think “phone app” or “website”) can communicate with the data store (think “database”
or “file system”) [https://developer.wordpress.org/rest-api/](https://developer.wordpress.org/rest-api/)
to increase performance. These improvements decrease the number of database queries
that are run on each REST API request. 

## Avoid unnecessarily preparing item links

Prior to WordPress 6.1, the `prepare_links` method in the REST API was called in
all controllers. If the `_fields` parameter is passed to the REST API request, it
might mean that the links field is not requested and would never be returned in 
the response. This is wasteful, as `prepare_links` can contain database calls or
other complex logic that would be run even if it never returned the response. 

In 6.1 `prepare_links` are only called if requested in the response, when links 
are requested in fields or the `_embedded` parameter is passed. As part of this 
work, the taxonomyTaxonomy A taxonomy is a way to group things together. In WordPress,
some common taxonomies are category, link, tag, or post format. [https://codex.wordpress.org/Taxonomies#Default_Taxonomies](https://codex.wordpress.org/Taxonomies#Default_Taxonomies).
and post type controllers have now been updated to implement said `prepare_links`
method to bring them in line with other REST API controllers. 

This is the code example of implementing this change in custom REST API controllers.

**Before**

    ```notranslate
    $response = rest_ensure_response( $data );
    $links = $this->prepare_links( $post );
    $response->add_links( $links );

    return $response;
    ```

**After**

    ```notranslate
    $response = rest_ensure_response( $data );

    if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) {
      $links = $this->prepare_links( $post );
      $response->add_links( $links );
    }

    return $response;
    ```

This logic conditionally calls prepare_links _only_ if `_links` or `_embedded` is
requested. This logic only applies when using the `_fields` query parameter. When
not using `_fields`, links are included in the response as normal. 

For more info see TracTrac An open source project by Edgewall Software that serves
as a bug tracker and project management tool for WordPress. ticketticket Created
for both bug reports and feature development on the bug tracker.: [#52992](https://core.trac.wordpress.org/ticket/52992),
[#56019](https://core.trac.wordpress.org/ticket/56019), [#56020](https://core.trac.wordpress.org/ticket/56020)

## Improvement to the Posts controller

When running profiling tools against the responses of REST API requests, it was 
discovered that post controllers request a lot of linked data to each post. For 
example, when returning a post in a REST API response, linked data such as author(
user), featured imageFeatured image A featured image is the main image used on your
blog archive page and is pulled when the post or page is shared on social media.
The image can be used to display in widget areas on your site or in a summary list
of posts., and parent post were all requested. As these linked items were not primed
in caches, it could mean that for each post in the REST API response there would
be 3 separate database queries: one for the user, one for the featured image, and
another for the parent post. 

In WordPress 6.1 all the caches are primed in a single database query and there 
are new helper functions to enable this:

`update_post_author_caches`

Takes an array of posts and primes users caches in a single query. 

`update_post_parent_caches`

Takes an array of posts and primes post parents in a single query. 

`update_menu_item_cache`

Takes an array of posts and primes post / terms link to menu items single query.

The existing function `update_post_thumbnail_cache` was used to prime featured image
caches. These functions are also being rolled out to other parts of the coreCore
Core is the set of software required to run WordPress. The Core Development Team
builds WordPress. that can benefit from priming caches in a single place. 

For more info see Trac tickets: [#55592](https://core.trac.wordpress.org/ticket/55592),
[#55593](https://core.trac.wordpress.org/ticket/55593), [#55620](https://core.trac.wordpress.org/ticket/55620)

## Improvements to other controllers

The comments and user controllers have also been improved: User controller now primes
user metaMeta Meta is a term that refers to the inside workings of a group. For 
us, this is the team that works on internal WordPress sites like WordCamp Central
and Make WordPress. in a single query and the comments controller now primes the
linked post cache in a single query. Improvements were made to the post search controller
to improve database performance along with the media controller. 

For more info see Trac tickets: [#55674](https://core.trac.wordpress.org/ticket/55674),
[#56272](https://core.trac.wordpress.org/ticket/56272), [#55677](https://core.trac.wordpress.org/ticket/55677),
[#55716](https://core.trac.wordpress.org/ticket/55716)

_Props to _[@flixos90](https://profiles.wordpress.org/flixos90/)_ and _[@milana_cap](https://profiles.wordpress.org/milana_cap/)_
for peer review and [@mxbclang](https://profiles.wordpress.org/mxbclang/) and [@webcommsat](https://profiles.wordpress.org/webcommsat/)
for proofreading. _

[#6-1](https://make.wordpress.org/core/tag/6-1/), [#core-restapi](https://make.wordpress.org/core/tag/core-restapi/),
[#dev-notes](https://make.wordpress.org/core/tag/dev-notes/), [#dev-notes-6-1](https://make.wordpress.org/core/tag/dev-notes-6-1/),
[#performance](https://make.wordpress.org/core/tag/performance/), [#rest-api](https://make.wordpress.org/core/tag/rest-api/)

 [  ](https://profiles.wordpress.org/spacedmonkey/) [Jonny Harris](https://profiles.wordpress.org/spacedmonkey/)
11:37 am _on_ January 24, 2022     
Tags: [5.9 ( 104 )](https://make.wordpress.org/core/tag/5-9/),
[dev-notes ( 616 )](https://make.wordpress.org/core/tag/dev-notes/), rest-api   

# 󠀁[Menus endpoints in WordPress 5.9](https://make.wordpress.org/core/2022/01/24/menus-endpoints-in-wordpress-5-9/)󠁿

WordPress 5.9 adds three new REST APIREST API The REST API is an acronym for the
RESTful Application Program Interface (API) that uses HTTP requests to GET, PUT,
POST and DELETE data. It is how the front end of an application (think “phone app”
or “website”) can communicate with the data store (think “database” or “file system”)
[https://developer.wordpress.org/rest-api/](https://developer.wordpress.org/rest-api/)
endpoints to manage menus and menu locations. These menus endpoints are used the
in new [navigation block](https://make.wordpress.org/core/2022/01/07/the-new-navigation-block/).

> [The new Navigation block](https://make.wordpress.org/core/2022/01/07/the-new-navigation-block/)

Before discussing menu endpoints, it’s worth noting how menus are currently stored.
Navigation menus are stored using the `nav_menu` taxonomyTaxonomy A taxonomy is 
a way to group things together. In WordPress, some common taxonomies are category,
link, tag, or post format. [https://codex.wordpress.org/Taxonomies#Default_Taxonomies](https://codex.wordpress.org/Taxonomies#Default_Taxonomies).
and the `nav_menu_item` post type. A menu is stored as a term and acts like a container
for a number of menu items. Menu items are stored as posts. Menus and menu items
also have custom fields stored in metaMeta Meta is a term that refers to the inside
workings of a group. For us, this is the team that works on internal WordPress sites
like WordCamp Central and Make WordPress. and in various options.

### Menus

Accessible via `/wp/v2/menus`, the menus endpoint allows for performing CRUDCRUD
Create, read, update and delete, the four basic functions of storing data. (More
on [Wikipedia](http://en.wikipedia.org/wiki/Create,_read,_update_and_delete).) operations
on menu data. This endpoint extends the `WP_REST_Terms_Controller` class, mapping
fields to the menus and adding functionality like `auto_add`, that automatically
adds new pages to menus when created. A `GET` request includes the list of menus,
but does not contain the list of menu items. To get this data, the menu items endpoint
can be used.

Example output from request:

    ```notranslate
    {
        "auto_add": false
        "description": "",
        "id": 36,
        "locations": ['wporg_header_subsite_nav', 'primary'],
        "meta": [],
        "name": "Navigation",
        "slug": "navigation",
    }
    ```

### Menu items

Accessible via `/wp/v2/menu-items`, the menu items endpoint allows for performing
CRUD operations on menu items and assigning them to menus. This endpoint extends
the `WP_REST_Posts_Controller` class, mapping fields and adding custom functionality.
Menu items can only be assigned to one menu at a time unlike other taxonomies.

Many menu items have an associated object that the menu item links to. For instance,
a link to a page will have the `object` set to `page` and the `object_id` set to
the WordPress Post ID of that page. When using this endpoint, it may be useful to
get information about that linked object. For example the page’s title. This information
is not included in the response by default, but the REST API has a feature to embed
this information by using the `_embed` query parameter. For example, making a `GET`
request to `/wp/v2/menu-item/8874?_embed=true` will result in the following response:

    ```notranslate
    {
         "attr_title": "",
         "classes": [''],
         "description": "",
         "id": 8874,
         "invalid": false,
         "menu_order": 1,
         "menus": 363,
         "meta": {},
         "object": "page",
         "object_id": 8823,
         "parent": 0,
         "status": "publish",
         "target": "",
         "title": {rendered: 'Tickets'},
         "type": "post_type",
         "type_label": "Page",
         "url": "https://make.wordpress.org/core/reports/",
         "xfn": [""],
         "_embedded": {
                  wp:menu-item-object: [
                       {
                          "author": 5286302,
                          "date": "2014-01-29T19:49:26",
                          "featured_media": 0,
                          "id": 8823,
                          "link": "https://make.wordpress.org/core/reports/",
                          "slug": "reports",
                          "title": { "rendered": "Bug Reports"},
                          "type": "page",
                       }
                  ],
                  wp:term: [
                        {
                           "id": 363,
                           "name": "Navigation",
                           "slug": "navigation"
                        }
                  ]
        },
    }
    ```

### Menu Locations

Accessible via `/wp/v2/menu-locations`, the menu locations endpoint returns a list
of menu locations registered with the [`register_nav_menus`](https://developer.wordpress.org/themes/functionality/navigation-menus/)
function. To assign a menu to a particular location, use the menus endpoint, by 
passing an array of menu location keys.

Example output from request:

    ```notranslate
    {
         "description": "Desktop Horizontal Menu"
         "menu": 90
         "name": "primary"
    }
    ```

### Batching requests

Both the menu and menu item endpoints, both support the batching of requests, [introduced in WordPress 5.6.](https://make.wordpress.org/core/2020/11/20/rest-api-batch-framework-in-wordpress-5-6/)
This means that more than one menu / menu item can be updates / created in a simple
request to the APIAPI An API or Application Programming Interface is a software 
intermediary that allows programs to interact with each other and share data in 
limited, clearly defined ways..

### Access Control

To access data from any of the menus endpoints, requests must be made by a logged
in user with the `edit_theme_options` capabilitycapability A **capability** is permission
to perform one or more types of task. Checking if a user has a capability is performed
by the `current_user_can` function. Each user of a WordPress site might have some
permissions but not others, depending on their role. For example, users who have
the Author role usually have permission to edit their own posts (the “edit_posts”
capability), but not permission to edit other users’ posts (the “edit_others_posts”
capability).. By default, only users with the `Administrator` role have this capability.
This means that menu data is not publically exposed via the REST API. Ticketticket
Created for both bug reports and feature development on the bug tracker. [#54304](https://core.trac.wordpress.org/ticket/54304)
provides a means for developers to opt-in to exposing this data publicly. The REST
API team hopes to implement this feature in a near future release of WordPress.

These endpoints were first developed as a feature pluginFeature Plugin A plugin 
that was created with the intention of eventually being proposed for inclusion in
WordPress Core. See [Features as Plugins](https://make.wordpress.org/core/handbook/about/release-cycle/features-as-plugins/)
on [GitHub](https://github.com/WP-API/menus-endpoints). For those using this pluginPlugin
A plugin is a piece of software containing a group of functions that can be added
to a WordPress website. They can extend functionality or add new features to your
WordPress websites. WordPress plugins are written in the PHP programming language
and integrate seamlessly with WordPress. These can be free in the WordPress.org 
Plugin Directory [https://wordpress.org/plugins/](https://wordpress.org/plugins/)
or can be cost-based plugin from a third-party., after upgrading to WordPress 5.9,
the plugin can be deactivated and removed as all of it’s functionality is now included
in WordPress CoreCore Core is the set of software required to run WordPress. The
Core Development Team builds WordPress..

_Props to _[@timothyblynjacobs](https://profiles.wordpress.org/timothyblynjacobs/)
_for peer review_.

[#5-9](https://make.wordpress.org/core/tag/5-9/), [#dev-notes](https://make.wordpress.org/core/tag/dev-notes/),
[#rest-api](https://make.wordpress.org/core/tag/rest-api/)

 [  ](https://profiles.wordpress.org/timothyblynjacobs/) [Timothy Jacobs](https://profiles.wordpress.org/timothyblynjacobs/)
4:59 am _on_ June 29, 2021     
Tags: [5.8 ( 99 )](https://make.wordpress.org/core/tag/5-8/),
[dev-notes ( 616 )](https://make.wordpress.org/core/tag/dev-notes/), rest-api   

# 󠀁[REST API Changes in WordPress 5.8](https://make.wordpress.org/core/2021/06/29/rest-api-changes-in-wordpress-5-8/)󠁿

The following is a snapshot of some of the changes to the REST APIREST API The REST
API is an acronym for the RESTful Application Program Interface (API) that uses 
HTTP requests to GET, PUT, POST and DELETE data. It is how the front end of an application(
think “phone app” or “website”) can communicate with the data store (think “database”
or “file system”) [https://developer.wordpress.org/rest-api/](https://developer.wordpress.org/rest-api/)
in WordPress 5.8. For more details, see the full list of [closed tickets](https://core.trac.wordpress.org/query?component=REST+API&milestone=5.8&or&focuses=~rest-api&milestone=5.8&or&component=Application+Passwords&milestone=5.8&col=id&col=summary&col=owner&col=type&col=status&col=priority&col=version&order=priority).

## Widgets

WordPress 5.8 sees the introduction of a new blockBlock Block is the abstract term
used to describe units of markup that, composed together, form the content or layout
of a webpage using the WordPress editor. The idea combines concepts of what in the
past may have achieved with shortcodes, custom HTML, and embed discovery into a 
single consistent API and user experience.-based widgets editor and with it the 
creation of several REST API endpoints dedicated to widgetWidget A WordPress Widget
is a small block that performs a specific function. You can add these widgets in
sidebars also known as widget-ready areas on your web page. WordPress widgets were
originally created to provide a simple and easy-to-use way of giving design and 
structure control of the WordPress theme to the user. management. Before diving 
in to how the new endpoints operate, I’d like to provide some background about how
widgets work that should make the following sections more clear.

#### Instance Widgets

The predominant way to create widgets is to subclass the `WP_Widget` base class 
and register the widget with `register_widget`. These are referred to as “multi”
widgets. These widgets have multiple instances that are identified by their `number`,
an incrementing integer for each widget type.

Each instance has its own setting values. These are stored and fetched by `WP_Widget`
which allows for the REST API to include these values. However, since a widget’s
instance can contain arbitrary data, for example a `DateTime` object, the REST API
cannot always serialize a widget to JSONJSON JSON, or JavaScript Object Notation,
is a minimal, readable format for structuring data. It is used primarily to transmit
data between a server and web application, as an alternative to XML.. As such, a
widget’s data is always serialized using the PHPPHP The web scripting language in
which WordPress is primarily architected. WordPress requires PHP 7.4 or higher `
serialize` function and then base64 encoded. This data is also exposed with a `hash`
value which is a `wp_hash` signature of this value to prevent clients from sending
arbitrary data to be deserialized with `unserialize`.

For widgets that can be safely accept and expose their instance data as JSON, pass
the `show_instance_in_rest` flag in the `$widget_options` parameter.

    ```notranslate
    class ExampleWidget extends WP_Widget {
        ...
        /**
         * Sets up the widget
         */
        public function __construct() {
            $widget_ops = array(
                // ...other options here
                'show_instance_in_rest' => true,
                // ...other options here
            );
            parent::__construct( 'example_widget', 'ExampleWidget', $widget_ops );
        }
        ...
    }
    ```

#### Reference Widgets

Far less common, but still supported, are widgets that are registered using `wp_register_sidebar_widget`
and `wp_register_widget_control` directly. These are referred to as “reference”,“
function-based”, or “non-multi” widgets. These widgets can store their data in an
arbitrary location. As such, their instance values are never included in the REST
API.

### Widget Types

Accessible via `/wp/v2/widget-types`, the widget types endpoint describes the different
widget types that are registered on the server. The endpoint is accessible to users
who have permission to `edit_theme_options`. By default, this is limited to Administrator
users.

#### Response Format

    ```notranslate
    {
      "id": "pages",
      "name": "Pages",
      "description": "A list of your site’s Pages.",
      "is_multi": true,
      "classname": "widget_pages",
      "_links": {
        "collection": [
          {
            "href": "https://trunk.test/wp-json/wp/v2/widget-types"
          }
        ],
        "self": [
          {
            "href": "https://trunk.test/wp-json/wp/v2/widget-types/pages"
          }
        ]
      }
    }
    ```

### Encode Endpoint

Multi widgets have access to the `/wp/v2/widget-types/<widget>/encode` endpoint.
This endpoint is used to convert htmlHTML HyperText Markup Language. The semantic
scripting language primarily used for outputting content in web browsers. form data
for the widget to the next `instance` for the widget, render the widget form, and
render the widget preview.

For example, let’s say we want to interact with the MetaMeta Meta is a term that
refers to the inside workings of a group. For us, this is the team that works on
internal WordPress sites like WordCamp Central and Make WordPress. widget. First,
we’ll want to request the widget form from the server.

    ```wp-block-code
    POST /wp/v2/widget-types/meta/encode
    ```

    ```notranslate
    {
      "instance": {},
      "number": 1
    }
    ```

For now, let’s assume we’re working with a new widget. The `instance` is empty because
this is a new widget, so we’ll be rendering an empty form. The `number` argument
can be omitted, but including one is recommended to provide stable input ids. You’ll
receive a response similar to this. _The widget preview has been snipped for brevity._

    ```notranslate
    {
      "form": "<p><label for=\"widget-meta-1-title\">Title:</label><input class=\"widefat\" id=\"widget-meta-1-title\" name=\"widget-meta[1][title]\" type=\"text\" value=\"\" /></p>",
      "preview": "<div class=\"widget widget_meta\">...</div>",
      "instance": {
        "encoded": "YToxOntzOjU6InRpdGxlIjtzOjA6IiI7fQ==",
        "hash": "77e9f20acb54fa4f77de5a865333c0e6",
        "raw": {
          "title": ""
        }
      }
    }
    ```

The provided form can then be rendered and edited by the user. When you want to 
render a new preview or are ready to begin saving, call the `encode` endpoint again
with the url encoded form data and the `instance` value returned from the first 
response.

    ```wp-block-code
    POST /wp/v2/widget-types/meta/encode
    ```

    ```notranslate
    {
      "instance": {
        "encoded": "YToxOntzOjU6InRpdGxlIjtzOjA6IiI7fQ==",
        "hash": "77e9f20acb54fa4f77de5a865333c0e6",
        "raw": {
          "title": ""
        }
      },
      "number": 1,
      "form_data": "widget-meta%5B1%5D%5Btitle%5D=Site+Info"
    }
    ```

The REST API will call the widget’s update function to calculate the new instance
based on the provided form data. The `instance` object can then be used to save 
a widget via the widgets endpoint.

    ```notranslate
    {
      "form": "<p><label for=\"widget-meta-1-title\">Title:</label><input class=\"widefat\" id=\"widget-meta-1-title\" name=\"widget-meta[1][title]\" type=\"text\" value=\"Site Info\" /></p>",
      "preview": "<div class=\"widget widget_meta\">...</div>",
      "instance": {
        "encoded": "YToxOntzOjU6InRpdGxlIjtzOjk6IlNpdGUgSW5mbyI7fQ==",
        "hash": "0e9a5bff2d28cba322c8cd27cd4e77af",
        "raw": {
          "title": "Site Info"
        }
      }
    }
    ```

### Widgets Endpoint

The widgets endpoint is used for performing CRUDCRUD Create, read, update and delete,
the four basic functions of storing data. (More on [Wikipedia](http://en.wikipedia.org/wiki/Create,_read,_update_and_delete).)
operations on the saved widgets. Like the widget types endpoint, the widgets endpoints
required the `edit_theme_options` capabilitycapability A **capability** is permission
to perform one or more types of task. Checking if a user has a capability is performed
by the `current_user_can` function. Each user of a WordPress site might have some
permissions but not others, depending on their role. For example, users who have
the Author role usually have permission to edit their own posts (the “edit_posts”
capability), but not permission to edit other users’ posts (the “edit_others_posts”
capability). to access.

 To retrieve widgets, make a `GET` request to the `/wp/v2/widgets` endpoint. The`
sidebar` parameter can be used to limit the response to widgets belonging to the
requested sidebarSidebar A sidebar in WordPress is referred to a widget-ready area
used by WordPress themes to display information that is not a part of the main content.
It is not always a vertical column on the side. It can be a horizontal rectangle
below or above the content area, footer, header, or any where in the theme..

To create a widget, for instance the widget from our previous example, make a `POST`
request to the `/wp/v2/widgets` endpoint. The `instance` is the same value returned
from the `encode` endpoint. The `id_base` is the unique identifier for the widget
type and `sidebar` is the id of the sidebar to assign the widget to. Both are required.

    ```wp-block-code
    POST /wp/v2/widgets
    ```

    ```notranslate
    {
    	"instance": {
    		"encoded": "YToxOntzOjU6InRpdGxlIjtzOjk6IlNpdGUgSW5mbyI7fQ==",
    		"hash": "0e9a5bff2d28cba322c8cd27cd4e77af",
    		"raw": {
    			"title": "Site Info"
    		}
    	},
    	"sidebar": "sidebar-1",
    	"id_base": "meta"
    }
    ```

The endpoint will return information about the newly created widget.

    ```notranslate
    {
      "id": "meta-1",
      "id_base": "meta",
      "sidebar": "sidebar-1",
      "rendered": "<div class=\"widget widget_meta\">...</div>",
      "rendered_form": "<p><label for=\"widget-meta-1-title\">Title:</label><input class=\"widefat\" id=\"widget-meta-1-title\" name=\"widget-meta[1][title]\" type=\"text\" value=\"Site Info\" /></p>",
      "instance": {
        "encoded": "YToxOntzOjU6InRpdGxlIjtzOjk6IlNpdGUgTWV0YSI7fQ==",
        "hash": "dac44c3ebfa0428fed61829fa151e4e8",
        "raw": {
          "title": "Site Info"
        }
      },
      "_links": {
        "self": [
          {
            "href": "https://trunk.test/wp-json/wp/v2/widgets/meta-1"
          }
        ],
        "collection": [
          {
            "href": "https://trunk.test/wp-json/wp/v2/widgets"
          }
        ],
        "about": [
          {
            "embeddable": true,
            "href": "https://trunk.test/wp-json/wp/v2/widget-types/meta"
          }
        ],
        "wp:sidebar": [
          {
            "href": "https://trunk.test/wp-json/wp/v2/sidebars/sidebar-1/"
          }
        ],
        "curies": [
          {
            "name": "wp",
            "href": "https://api.w.org/{rel}",
            "templated": true
          }
        ]
      }
    }
    ```

Since the meta widget (and all other built-in widgets) is registered with `show_instance_in_rest`
enabled you could bypass the `encode` endpoint and use `instance.raw` instead. For
example, if we wanted to update the widget to have a new title, we could make the
following `PUT` request to `/wp/v2/widgets/meta-1`.

    ```wp-block-code
    PUT /wp/v2/widgets/meta-1
    ```

    ```notranslate
    {
    	"instance": {
    		"raw": {
    			"title": "Site Meta"
    		}
    	}
    }
    ```

A `PUT` request can also be made to update the sidebar assigned to a widget by passing
a new `sidebar` id in the request.

To delete a widget, send a `DELETE` request to the individual widget route. By default,
deleting a widget will move a widget to the Inactive Widgets area. To permanently
delete a widget, use the `force` parameter. For example: `DELETE /wp/v2/widgets/
meta-1?force=true`.

### Sidebars Endpoints

Found under `/wp/v2/sidebars`, the sidebars endpoint is used to manage a site’s 
registered sidebars (widget areas) and their assigned widgets. For example, the 
following is the response for the first footer area in the Twenty Twenty theme.

    ```notranslate
    {
      "id": "sidebar-1",
      "name": "Footer #1",
      "description": "Widgets in this area will be displayed in the first column in the footer.",
      "class": "",
      "before_widget": "<div class=\"widget %2$s\"><div class=\"widget-content\">",
      "after_widget": "</div></div>",
      "before_title": "<h2 class=\"widget-title subheading heading-size-3\">",
      "after_title": "</h2>",
      "status": "active",
      "widgets": [
        "recent-posts-2",
        "recent-comments-2",
        "meta-1"
      ],
      "_links": {
        "collection": [
          {
            "href": "https://trunk.test/wp-json/wp/v2/sidebars"
          }
        ],
        "self": [
          {
            "href": "https://trunk.test/wp-json/wp/v2/sidebars/sidebar-1"
          }
        ],
        "wp:widget": [
          {
            "embeddable": true,
            "href": "https://trunk.test/wp-json/wp/v2/widgets?sidebar=sidebar-1"
          }
        ],
        "curies": [
          {
            "name": "wp",
            "href": "https://api.w.org/{rel}",
            "templated": true
          }
        ]
      }
    }
    ```

The `widgets` property contains an ordered list of widget ids. While all other properties
are readonly, the `widgets` property can be used to reorder a sidebar’s assigned
widgets. Any widget ids omitted when updating the sidebar will be assigned to the
Inactive Widgets sidebar area.

For example, making a `PUT` request to `/wp/v2/sidebars/sidebar-1` with the following
body will remove the Recent Comments widget, and move the Meta widget to the top
of the sidebar.

    ```wp-block-code
    PUT /wp/v2/sidebars/sidebar-1
    ```

    ```notranslate
    {
      "widgets": [
        "meta-1",
        "recent-posts-2"
      ]
    }
    ```

For more information about the changes to widgets in 5.8, check out the Block-based
Widgets Editor dev notedev note Each important change in WordPress Core is documented
in a developers note, (usually called dev note). Good dev notes generally include
a description of the change, the decision that led to this change, and a description
of how developers are supposed to work with that change. Dev notes are published
on Make/Core blog during the beta phase of WordPress release cycle. Publishing dev
notes is particularly important when plugin/theme authors and WordPress developers
need to be aware of those changes.In general, all dev notes are compiled into a 
Field Guide at the beginning of the release candidate phase..

> [Block-based Widgets Editor in WordPress 5.8](https://make.wordpress.org/core/2021/06/29/block-based-widgets-editor-in-wordpress-5-8/)

## Additional Changes

### Posts Collection Tax Query Accepts `operator`

By default, a post must contain at least one of the requested terms to be included
in the response. As of [[51026]](https://core.trac.wordpress.org/changeset/51026),
the REST API accepts a new `operator` property that can be set to `AND` to require
a post to contain all of the requested terms.

For example, `/wp/v2/posts?tags[terms]=1,2,3&tags[operator]=AND` will return posts
that have tags with the ids of 1, 2, and 3.

See [#41287](https://core.trac.wordpress.org/ticket/41287) for more details.

_Props to [@noisysocks](https://profiles.wordpress.org/noisysocks/) for reviewing._

[#5-8](https://make.wordpress.org/core/tag/5-8/), [#dev-notes](https://make.wordpress.org/core/tag/dev-notes/),
[#rest-api](https://make.wordpress.org/core/tag/rest-api/)

 [  ](https://profiles.wordpress.org/timothyblynjacobs/) [Timothy Jacobs](https://profiles.wordpress.org/timothyblynjacobs/)
7:59 pm _on_ February 23, 2021     
Tags: [5.7 ( 67 )](https://make.wordpress.org/core/tag/5-7/),
[dev-notes ( 616 )](https://make.wordpress.org/core/tag/dev-notes/), rest-api   

# 󠀁[REST API Changes in WordPress 5.7](https://make.wordpress.org/core/2021/02/23/rest-api-changes-in-wordpress-5-7/)󠁿

The following is a snapshot of some of the changes to the REST APIREST API The REST
API is an acronym for the RESTful Application Program Interface (API) that uses 
HTTP requests to GET, PUT, POST and DELETE data. It is how the front end of an application(
think “phone app” or “website”) can communicate with the data store (think “database”
or “file system”) [https://developer.wordpress.org/rest-api/](https://developer.wordpress.org/rest-api/)
in WordPress 5.7. For more details, see the full list of [closed tickets](https://core.trac.wordpress.org/query?component=REST+API&milestone=5.7&or&focuses=~rest-api&milestone=5.7&or&component=Application+Passwords&milestone=5.7&col=id&col=summary&col=status&col=owner&col=type&col=priority&col=version&order=priority).

## Endpoint Changes

### Posts Collection Tax Query Accepts `include_children`

Introduced in [50157](https://core.trac.wordpress.org/changeset/50157), the REST
API posts collection endpoints have been updated to allow a more complex syntax 
for specifying the `tax_query` used when querying posts. Each taxonomyTaxonomy A
taxonomy is a way to group things together. In WordPress, some common taxonomies
are category, link, tag, or post format. [https://codex.wordpress.org/Taxonomies#Default_Taxonomies](https://codex.wordpress.org/Taxonomies#Default_Taxonomies).’
s query parameters can now both accept a list of term ids or an object with a `terms`
property. 

Hierarchical taxonomies support an `include_children` property alongside `terms`.
By default it’s disabled, but if set to `true` the flag is enabled for the generated
[`tax_query`](https://developer.wordpress.org/reference/classes/wp_query/#taxonomy-parameters)
to enable searching for posts that have the given terms or terms that are children
of the given terms.

    ```notranslate
    import { addQueryArgs } from '@wordpress/url';
    import apiFetch from '@wordpress/api-fetch';

    const query = {
    	categories: {
    		terms: [ 3, 5, 7 ],
    		include_children: true,
    	},
    };
    apiFetch( { path: addQueryArgs( '/wp/v2/posts', query ) } );
    ```

See [#39494](https://core.trac.wordpress.org/ticket/39494) for more details.

### Support `modified_before` and `modified_after` Query Parameters

Introduced in [50024](https://core.trac.wordpress.org/changeset/50024) the REST 
API posts collection endpoints now accept `modified_before` and `modified_after`
query parameters to query posts based on the post modified date instead of the post
published date.

    ```notranslate
    import { addQueryArgs } from '@wordpress/url';
    import apiFetch from '@wordpress/api-fetch';

    const query = {
    	modified_after: '2020-12-01T00:00:00Z',
    	modified_before: '2020-12-31T23:59:59Z',
    };
    apiFetch( { path: addQueryArgs( '/wp/v2/posts', query ) } );
    ```

As a result of this change, the posts controller now uses a `date_query` with a 
separate clause for each date related query parameter instead of a single clause
with the `before` and `after` flags set.

See [#50617](https://core.trac.wordpress.org/ticket/50617) for more details.

### Multiple MetaMeta Meta is a term that refers to the inside workings of a group. For us, this is the team that works on internal WordPress sites like WordCamp Central and Make WordPress. Values for a Key Can Be Deleted by Sending an Empty Array

Previously, to remove all values for a specific meta key, passing `null` as the 
value for that meta key was required. After [49966](https://core.trac.wordpress.org/changeset/49966)
an empty array can be passed instead.

    ```notranslate
    register_post_meta( 'post', 'my_meta_key', array( 
    	'type' => 'string',
    	'show_in_rest' => true,
    ) );
    ```

    ```notranslate
    import apiFetch from '@wordpress/api-fetch';

    const data = {
    	meta: {
    		my_meta_key: [],
    	}
    };
    apiFetch( { data, method: 'PUT', path: '/wp/v2/posts/1' } );
    ```

See [#50790](https://core.trac.wordpress.org/ticket/50790) for more details.

### All Themes are Returned via the Themes Controller

As of [49925](https://core.trac.wordpress.org/changeset/49925), the themes endpoint
now returns all themes installed on the site, not just the active theme. By default,
the endpoint returns both `active` and `inactive` themes, but the `status` query
parameter can be used to limit the list to themes with the desired status.

Note, the `theme_supports` value is only exposed for the `active` theme. The field
is omitted for `inactive` themes since declaring the supported theme features requires
calls to `add_theme_support` which can only be done if the theme is active.

When querying solely for `active` themes, the only permission required is to be 
able to edit posts of any `show_in_rest` post type. However when querying for `inactive`
themes the `switch_themes` or `manage_network_themes` capabilitycapability A **capability**
is permission to perform one or more types of task. Checking if a user has a capability
is performed by the `current_user_can` function. Each user of a WordPress site might
have some permissions but not others, depending on their role. For example, users
who have the Author role usually have permission to edit their own posts (the “edit_posts”
capability), but not permission to edit other users’ posts (the “edit_others_posts”
capability). is required.

In addition to the changes to the collection endpoint, a new single theme endpoint
is available. For example, `/wp/v2/themes/twentytwentyone` will return information
about Twenty Twenty One. For convenience, a link is also added to the currently 
active theme in the REST API Index if the current user has the requisite permissions.
This is the recommended way for applications to discover the currently active theme.

    ```notranslate
    {
      "name": "WordPress Develop",
      "_links": {
        "help": [
          {
            "href": "http://v2.wp-api.org/"
          }
        ],
        "wp:active-theme": [
          {
            "href": "https://wordpress.test/wp-json/wp/v2/themes/twentytwentyone"
          }
        ],
        "curies": [
          {
            "name": "wp",
            "href": "https://api.w.org/{rel}",
            "templated": true
          }
        ]
      }
    }
    ```

Lastly, the `page`, `per_page`, `search` and `context` query parameters are no longer
exposed in the index as they are not supported by this endpoint.

See [#50152](https://core.trac.wordpress.org/ticket/50152) for more details.

### Image Editor Accepts a List of Modifiers

The `/wp/v2/media/<id>/edit` endpoint [introduced in WordPress 5.5](https://make.wordpress.org/core/2020/07/16/new-and-modified-rest-api-endpoints-in-wordpress-5-5/#image-editing)
came with a limited APIAPI An API or Application Programming Interface is a software
intermediary that allows programs to interact with each other and share data in 
limited, clearly defined ways. that accepted top-level rotation and crop declarations.
In [50124](https://core.trac.wordpress.org/changeset/50124) this API was made more
powerful and flexible by accepting an array of modifications in the new `modifiers`
request parameter.

    ```notranslate
    import apiFetch from '@wordpress/api-fetch';

    const data = {
    	modifiers: [
    		{
    			type: 'crop',
    			args: {
    				left  : 0,
    				top   : 0,
    				width : 80,
    				height: 80
    			}
    		},
    		{
    			type: 'rotate',
    			args: {
    				angle: 90
    			}
    		}
    	]
    };
    apiFetch( { data, method: 'POST', path: '/wp/v2/media/5/edit' } );
    ```

The previous query parameters have been marked as deprecated, but will continue 
to function as normal and do not currently issue deprecation warnings. Clients are
encouraged to switch to the new syntax.

To alleviate server resources, whenever possible, clients should simplify redundant
modifications before sending the request.

See [#52192](https://core.trac.wordpress.org/ticket/52192) for more details.

## Parameter Validation

### Non-String Enums

In [50010](https://core.trac.wordpress.org/changeset/50010) support for type coercion
was added to the `enum` JSONJSON JSON, or JavaScript Object Notation, is a minimal,
readable format for structuring data. It is used primarily to transmit data between
a server and web application, as an alternative to XML. Schema keyword. Previously,
the `enum` keyword was validated by perform a strict equality check. For `string`
types this is generally ok, but it prevented using alternative types like `number`
when rich type support isn’t available.

Now the same level of type coercion/sanitization is applied when validating enum
as all other validation checks. This means that a value of `"1"` will be accepted
for an enum of `[ 0, 1 ]`. Additionally, `object` types now properly ignore key 
order when checking for equality.

See [#51911](https://core.trac.wordpress.org/ticket/51911) for more details.

### Validation Error Codes

As of [50007](https://core.trac.wordpress.org/changeset/50007), the `rest_validate_value_from_schema`
function now returns specific error codes for each validation failure instead of
the generic `rest_invalid_param`. For instance, if more array items are given than
allowed by `maxItems`, the `rest_too_many_items`error code will be returned.

See [#52317](https://core.trac.wordpress.org/ticket/52317) for more details.

### Return Detailed Error Information from Request Validation

Previously when a parameter failed validation only the first error message specified
in the `WP_Error` instance was returned to the user. Since [50150](https://core.trac.wordpress.org/changeset/50150)
the REST API will now return detailed error information as part of the `details`
error data key.

    ```notranslate
    {
      "code": "rest_invalid_param",
      "message": "Invalid parameter(s): enum_a, enum_b",
      "data": {
        "status": 400,
        "params": {
          "enum_a": "enum_a is not one of a, b, c.",
          "enum_b": "enum_b is not one of d, e, f."
        },
        "details": {
          "enum_a": {
            "code": "rest_not_in_enum",
            "message": "enum_a is not one of a, b, c.",
            "data": {
              "enum": ["a", "b", "c"]
            }
          },
          "enum_b": {
            "code": "rest_not_in_enum",
            "message": "enum_b is not one of d, e, f.",
            "data": {
              "enum": ["d", "e", "f"]
            }
          }
        }
      }
    }
    ```

See [#50617](https://core.trac.wordpress.org/ticket/50617) for more details.

## Application Passwords

### Fine Grained Capabilitiescapability A **capability** is permission to perform one or more types of task. Checking if a user has a capability is performed by the `current_user_can` function. Each user of a WordPress site might have some permissions but not others, depending on their role. For example, users who have the Author role usually have permission to edit their own posts (the “edit_posts” capability), but not permission to edit other users’ posts (the “edit_others_posts” capability).

When the Application Passwords REST API controllers were introduced, the `edit_user`
meta capability was used for all permission checks. As of [50114](https://core.trac.wordpress.org/changeset/50114),
the REST API now uses specific meta capabilities for each action type.

 * `create_app_password`
 * `list_app_passwords`
 * `read_app_password`
 * `edit_app_password`
 * `delete_app_password`
 * `delete_app_passwords`

By default, these capabilities all map to `edit_user` however they can now be customized
by using the `map_meta_cap` filterFilter Filters are one of the two types of Hooks
[https://codex.wordpress.org/Plugin_API/Hooks](https://codex.wordpress.org/Plugin_API/Hooks).
They provide a way for functions to modify data of other functions. They are the
counterpart to Actions. Unlike Actions, filters are meant to work in an isolated
manner, and should never have side effects such as affecting global variables and
output..

See [#51703](https://core.trac.wordpress.org/ticket/51703) for more details.

### Introspection Endpoint

[50065](https://core.trac.wordpress.org/changeset/50065) introduces a new Application
Passwords endpoint for introspecting the app password being currently used for authentication.
This endpoint is accessible via `/wp/v2/users/me/application-passwords/introspect`
and will return the same information as the other endpoints. This allows for an 
application to disambiguate between multiple installations of their application 
which would all share the same `app_id`.

Clients can use this information to provide UIUI User interface hints about how 
the user is authenticated, for instance by displaying the App Passwords’s label.
Or when their application is uninstalled by the user, they can automatically clean
up after themselves by deleting their App Password.

See [#52275](https://core.trac.wordpress.org/ticket/52275) for more details.

### Unique Application Names

As of [50030](https://core.trac.wordpress.org/changeset/50030) the Application Passwords
API enforces that each App Password has a unique name that cannot consist solely
of whitespace characters. Additionally, invalidinvalid A resolution on the bug tracker(
and generally common in software development, sometimes also _notabug_) that indicates
the ticket is not a bug, is a support request, or is generally invalid. characters
are stripped from the provided application name.

See [#51941](https://core.trac.wordpress.org/ticket/51941) for more details.

_Props to [@flixos90](https://profiles.wordpress.org/flixos90/), [@desrosj](https://profiles.wordpress.org/desrosj/)
for proofreading._

[#5-7](https://make.wordpress.org/core/tag/5-7/), [#dev-notes](https://make.wordpress.org/core/tag/dev-notes/),
[#rest-api](https://make.wordpress.org/core/tag/rest-api/)

 [  ](https://profiles.wordpress.org/timothyblynjacobs/) [Timothy Jacobs](https://profiles.wordpress.org/timothyblynjacobs/)
12:48 pm _on_ December 8, 2020     
Tags: [5.6 ( 85 )](https://make.wordpress.org/core/tag/5-6/),
[dev-notes ( 616 )](https://make.wordpress.org/core/tag/dev-notes/), rest-api   

# 󠀁[REST API Changes in WordPress 5.6](https://make.wordpress.org/core/2020/12/08/rest-api-changes-in-wordpress-5-6/)󠁿

WordPress 5.6 introduces a number of changes to the REST APIREST API The REST API
is an acronym for the RESTful Application Program Interface (API) that uses HTTP
requests to GET, PUT, POST and DELETE data. It is how the front end of an application(
think “phone app” or “website”) can communicate with the data store (think “database”
or “file system”) [https://developer.wordpress.org/rest-api/](https://developer.wordpress.org/rest-api/),
some of which have been covered in other dev notesdev note Each important change
in WordPress Core is documented in a developers note, (usually called dev note).
Good dev notes generally include a description of the change, the decision that 
led to this change, and a description of how developers are supposed to work with
that change. Dev notes are published on Make/Core blog during the beta phase of 
WordPress release cycle. Publishing dev notes is particularly important when plugin/
theme authors and WordPress developers need to be aware of those changes.In general,
all dev notes are compiled into a Field Guide at the beginning of the release candidate
phase..

> [Application Passwords: Integration Guide](https://make.wordpress.org/core/2020/11/05/application-passwords-integration-guide/)

> [REST API Batch Framework in WordPress 5.6](https://make.wordpress.org/core/2020/11/20/rest-api-batch-framework-in-wordpress-5-6/)

> [Site Health Check changes in 5.6](https://make.wordpress.org/core/2020/11/15/site-health-check-changes-in-5-6/)

> [New action wp_after_insert_post in WordPress 5.6.](https://make.wordpress.org/core/2020/11/20/new-action-wp_after_insert_post-in-wordpress-5-6/)

Below are some other noteworthy changes that deserve a call out.

## Search

The `wp/v2/search` endpoint introduced in WordPress 5.0 provides a unified interface
for searching across multiple content types. WordPress 5.6 adds a terms and post
formats search handler. For example, to search across terms in all taxonomies, make
the following request: `https://example.org/wp-json/wp/v2/search?type=term&search
=my-term`. To search post-formats, use the `post-format` type: `https://example.
org/wp-json/wp/v2/search?type=post-format&search=aside`.

Additionally, the REST API search infrastructure no longer requires that the `id`
for each item is an integer. Strings are now an acceptable `id` type.

See [#51458](https://core.trac.wordpress.org/ticket/51458), [#51459](https://core.trac.wordpress.org/ticket/51459),
[#51131](https://core.trac.wordpress.org/ticket/51131).

## JSONJSON JSON, or JavaScript Object Notation, is a minimal, readable format for structuring data. It is used primarily to transmit data between a server and web application, as an alternative to XML. Schema

### `multipleOf` keyword

The `multipleOf` keyword allows for asserting that an `integer` or `number` type
is a multiple of the given number. For example, this schema will only accept even
integers.

    ```notranslate
    {
      "type": "integer",
      "multipleOf": 2
    }
    ```

`multipleOf` also supports decimals. For example, this schema could be used to accept
a percentage with a maximum of 1 decimal point.

    ```notranslate
    {
      "type": "number",
      "minimum": 0,
      "maximum": 100,
      "multipleOf": 0.1
    }
    ```

See [#51022](https://core.trac.wordpress.org/ticket/51022).

### `minProperties` and `maxProperties`

The `minItems` and `maxItems` keywords can be used for the `array` type. The `minProperties`
and `maxProperties` introduces this same functionality for the `object` type. This
is helpful when using `additionalProperties` to have a list of objects with unique
keys.

This schema requires an object that specifies at least 1, and at most 3, colors.

    ```notranslate
    {
      "type": "object",
      "additionalProperties": {
        "type": "string",
        "format": "hex-color"
      },
      "minProperties": 1,
      "maxProperties": 3
    }
    ```

    ```notranslate
    {
      "primary": "#52accc",
      "secondary": "#096484"
    }
    ```

See [#51023](https://core.trac.wordpress.org/ticket/51023).

### `patternProperties`

The `patternProperties` keyword is similar to the `additionalProperties` keyword,
but allows for asserting that the property matches a regex pattern. The keyword 
is an object where each property is a regex [pattern](https://developer.wordpress.org/rest-api/extending-the-rest-api/schema/#pattern)
and its value is the JSON Schema used to validate properties that match that pattern.

For example, this schema requires that each value is a hex color and the property
must only contain “word” characters.

    ```notranslate
    {
      "type": "object",
      "patternProperties": {
        "^\\w+$": {
          "type": "string",
          "format": "hex-color"
        }
      },
      "additionalProperties": false
    }
    ```

When the REST API validates the `patternProperties` schema, if a property doesn’t
match any of the patterns, the property will be allowed and not have any validation
applied to its contents. This behaves the same as the `properties` keyword. If this
logic isn’t desired, add `additionalProperties` to the schema to disallow non-matching
properties. See [#51024](https://core.trac.wordpress.org/ticket/51024).

### `oneOf` and `anyOf`

These are advanced keywords that allow for the JSON Schema validator to choose one
of _many_ schemas to use when validating a value. The `anyOf` keyword allows for
a value to match at least one of the given schemas. Whereas, the `oneOf` keyword
requires the value match _exactly_ one schema.

For example, this schema allows for submitting an array of “operations” to an endpoint.
Each operation can either be a “crop” or a “rotation”.

    ```notranslate
    {
      "type": "array",
      "items": {
        "oneOf": [
          {
            "title": "Crop",
            "type": "object",
            "properties": {
              "operation": {
                "type": "string",
                "enum": [
                  "crop"
                ]
              },
              "x": {
                "type": "integer"
              },
              "y": {
                "type": "integer"
              }
            }
          },
          {
            "title": "Rotation",
            "type": "object",
            "properties": {
              "operation": {
                "type": "string",
                "enum": [
                  "rotate"
                ]
              },
              "degrees": {
                "type": "integer",
                "minimum": 0,
                "maximum": 360
              }
            }
          }
        ]
      }
    }
    ```

The REST API will loopLoop The Loop is PHP code used by WordPress to display posts.
Using The Loop, WordPress processes each post to be displayed on the current page,
and formats it according to how it matches specified criteria within The Loop tags.
Any HTML or PHP code in the Loop will be processed on each post. [https://codex.wordpress.org/The_Loop](https://codex.wordpress.org/The_Loop)
over each schema specified in the `oneOf` array and look for a match. If exactly
one schema matches, then validation will succeed. If more than one schema matches,
validation will fail. If no schemas match, then the validator will try to find the
closest matching schema and return an appropriate error message.

> operations[0] is not a valid Rotation. Reason: operations[0][degrees] must be 
> between 0 (inclusive) and 360 (inclusive)

See [#51025](https://core.trac.wordpress.org/ticket/51025).

### Expose all JSON Schema keywords in the index

When making an `OPTIONS` request to an endpoint, the REST API will return the `args`
that the route accepts. Previously, only a limited subset of JSON Schema keywords
were exposed. In WordPress 5.6, now the full list of JSON Schema keywords that the
REST API supports will be exposed. See [#51020](https://core.trac.wordpress.org/ticket/51020).

#### More specific validation error codes

When the `type` of a value is incorrect, `rest_validate_value_from_schema` now returns`
rest_invalid_type` instead of the generic `rest_invalid_param`. The validation error
code is not currently exposed to REST API clients. This would only effect direct
usages of the validation function.

## Miscellaneous

The `apiRequest` library now supports using the `PUT` and `DELETE` HTTPHTTP HTTP
is an acronym for Hyper Text Transfer Protocol. HTTP is the underlying protocol 
used by the World Wide Web and this protocol defines how messages are formatted 
and transmitted, and what actions Web servers and browsers should take in response
to various commands. methods with servers that didn’t support those methods. This
is done by making the request a `POST` request and passing the original HTTP method
in the `X-HTTP-Method-Override` headerHeader The header of your site is typically
the first thing people will experience. The masthead or header art located across
the top of your page is part of the look and feel of your website. It can influence
a visitor’s opinion about your content and you/ your organization’s brand. It may
also look different on different screen sizes.. [#43605](https://core.trac.wordpress.org/ticket/43605).

The comments controller now uses the `rest_get_route_for_post` function introduced
in WordPress 5.5 to generate the `up` response link. This function is filterable
to allow for [custom controllers to properly define](https://developer.wordpress.org/rest-api/extending-the-rest-api/adding-rest-api-support-for-custom-content-types/#registering-a-custom-post-type-with-rest-api-support)
their REST API route. [#44152](https://core.trac.wordpress.org/ticket/44152).

The REST API now supports a broader range of JSON media types. Previously, only `
application/json` was supported which prevented using subtypes like `application/
activity+json`. The REST API will now `json_decode` the body of requests using a
JSON subtype `Content-Type`. Additionally, `wp_die()` now properly sends the error
as JSON when a JSON subtype is specified in the `Accept` header. [#49404](https://core.trac.wordpress.org/ticket/49404).

_Props [@m\_butcher](https://profiles.wordpress.org/m_butcher/) for reviewing._

[#5-6](https://make.wordpress.org/core/tag/5-6/), [#dev-notes](https://make.wordpress.org/core/tag/dev-notes/),
[#rest-api](https://make.wordpress.org/core/tag/rest-api/)

 [  ](https://profiles.wordpress.org/timothyblynjacobs/) [Timothy Jacobs](https://profiles.wordpress.org/timothyblynjacobs/)
4:37 pm _on_ November 20, 2020     
Tags: [5.6 ( 85 )](https://make.wordpress.org/core/tag/5-6/),
[dev-notes ( 616 )](https://make.wordpress.org/core/tag/dev-notes/), rest-api   

# 󠀁[REST API Batch Framework in WordPress 5.6](https://make.wordpress.org/core/2020/11/20/rest-api-batch-framework-in-wordpress-5-6/)󠁿

WordPress 5.6 introduces a framework for making a series of REST APIREST API The
REST API is an acronym for the RESTful Application Program Interface (API) that 
uses HTTP requests to GET, PUT, POST and DELETE data. It is how the front end of
an application (think “phone app” or “website”) can communicate with the data store(
think “database” or “file system”) [https://developer.wordpress.org/rest-api/](https://developer.wordpress.org/rest-api/)
calls in one request to the server. At its simplest, this is a helpful performance
optimization when a large number of write operations need to be made. It also optionally
offers basic concurrency controls.

## Registration

In order to be used in a batch request, routes must first declare support for the
feature during their registration. For example:

    ```notranslate
    register_rest_route( 'my-ns/v1', 'my-route', array(
    	'methods'             => WP_REST_Server::CREATABLE,
    	'callback'            => 'my_callback',
    	'permission_callback' => 'my_permission_callback',
    	'allow_batch'         => array( 'v1' => true ),
    ) );
    ```

If the REST API route was implemented using best practices, declaring support should
be sufficient for the route to be writable via the batch endpoint. Specifically,
these are the things to look out for:

 1. Routes must use the `WP_REST_Request` object to get all request data. In other 
    words, it shouldn’t access the `$_GET`, `$_POST` or `$_SERVER` variables to get
    parameters or headers.
 2. Routes must return data. This could be a `WP_REST_Response` object, a `WP_Error`
    object or any kind of JSONJSON JSON, or JavaScript Object Notation, is a minimal,
    readable format for structuring data. It is used primarily to transmit data between
    a server and web application, as an alternative to XML. serializable data. This
    means the route must not directly echo the response and `die()`. For example by
    using `wp_send_json()` or `wp_die()`.
 3. Routes must be re-entrant. Be prepared for the same route to be called multiple
    times in a batch.

## Making a Request

To send a batch, make a `POST` request to `https://yoursite.test/wp-json/batch/v1`
with an array of the desired requests. For example, the simplest batch request looks
like this.

    ```notranslate
    {
      "requests": [
        {
          "path": "/my-ns/v1/route"
        }
      ]
    }
    ```

### Request Format

Each request is an object that can accept the following properties.

    ```notranslate
    {
      "method": "PUT",
      "path": "/my-ns/v1/route/1?query=param",
      "headers": {
        "My-Header": "my-value",
        "Multi": [ "v1", "v2" ]
      },
      "body": {
        "project": "Gutenberg"
      }
    }
    ```

 * `method` is the HTTPHTTP HTTP is an acronym for Hyper Text Transfer Protocol.
   HTTP is the underlying protocol used by the World Wide Web and this protocol 
   defines how messages are formatted and transmitted, and what actions Web servers
   and browsers should take in response to various commands. method to use for the
   request. If omitted, the `POST` method is used.
 * `path` is the REST API route to call. Query parameters can be included. This 
   property is required.
 * `headers` is an object of headerHeader The header of your site is typically the
   first thing people will experience. The masthead or header art located across
   the top of your page is part of the look and feel of your website. It can influence
   a visitor’s opinion about your content and you/ your organization’s brand. It
   may also look different on different screen sizes. names to a header values. 
   If the header has multiple values, it can be passed as an array.
 * `body` is the parameters to pass to the route. It is filled in the `POST` parameter
   type.

### Discovering Max Requests

By default, the REST API accepts up to 25 requests in a single batch. However, this
value is filterable so it can be scaled up or down based on server resources.

    ```notranslate
    function my_prefix_rest_get_max_batch_size() {
    	return 50;
    }

    add_filter( 'rest_get_max_batch_size', 'my_prefix_rest_get_max_batch_size' );
    ```

As such, clients are strongly encouraged to make a preflight request to discover
the limit. For example, making an `OPTIONS` request to `batch/v1` will return the
following response.

    ```notranslate
    {
      "namespace": "",
      "methods": [ "POST" ],
      "endpoints": [
        {
          "methods": [ "POST" ],
          "args": {
            "validation": {
              "type": "string",
              "enum": [ "require-all-validate", "normal" ],
              "default": "normal",
              "required": false
            },
            "requests": {
              "type": "array",
              "maxItems": 25,
              "items": {
                "type": "object",
                "properties": {
                  "method": {
                    "type": "string",
                    "enum": [ "POST", "PUT", "PATCH", "DELETE" ],
                    "default": "POST"
                  },
                  "path": {
                    "type": "string",
                    "required": true
                  },
                  "body": {
                    "type": "object",
                    "properties": [],
                    "additionalProperties": true
                  },
                  "headers": {
                    "type": "object",
                    "properties": [],
                    "additionalProperties": {
                      "type": [ "string", "array" ],
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                }
              },
              "required": true
            }
          }
        }
      ],
      "_links": {
        "self": [
          {
            "href": "http://trunk.test/wp-json/batch/v1"
          }
        ]
      }
    }
    ```

The limit is specified in the `endpoints[0].args.requests.maxItems` property.

## Response Format

The batch endpoint will return a `207` status code and the responses of each request
in the same order as they were requested. For example:

    ```notranslate
    {
      "responses": [
        {
          "body": {
            "id": 1,
            "_links": {
              "self": [
                {
                  "href": "http://trunk.test/wp-json/my-ns/v1/route/1"
                }
              ]
            }
          },
          "status": 201,
          "headers": {
            "Location": "http://trunk.test/wp-json/my-n1/v1/route/1",
            "Allow": "GET, POST"
          }
        }
      ]
    }
    ```

Internally, the REST API [envelopes](https://developer.wordpress.org/rest-api/using-the-rest-api/global-parameters/#_envelope)
each response before including it in the `responses` array.

## Validation Modes

By default, each request is processed in isolation. This means that a batch response
can contain some requests that were successful, and some that failed. Sometimes 
it’s desired to only process a batch if all the requests are valid. For instance,
in GutenbergGutenberg The Gutenberg project is the new Editor Interface for WordPress.
The editor improves the process and experience of creating new content, making writing
rich content much simpler. It uses ‘blocks’ to add richness rather than shortcodes,
custom HTML etc. [https://wordpress.org/gutenberg/](https://wordpress.org/gutenberg/)
we don’t want to save some menu items, ideally all would be saved or none would.

To accomplish this, the REST API allows for passing a `validation` mode of `require-
all-validate`. When this is set, the REST API will first check that each request
is valid according to `WP_REST_Request::has_valid_params()` and `WP_REST_Request::
sanitize_params()`. If any request fails validation, then the entire batch is rejected.

In this example, a batch of two requests is made and the second one has failed validation.
Since the order of `responses` is still the same as the order of `requests`, `null`
is used to indicate that the request didn’t fail validation.

    ```notranslate
    {
      "failed": "validation",
      "responses": [
        null,
        {
          "body": {
            "code": "error_code",
            "message": "Invalid request data",
            "data": { "status": 400 }
          },
          "status": 400,
          "headers": {}
        }
      ]
    }
    ```

**Note:** Using `require-all-validate` is not a guarantee that all requests will
be successful. A route callback may still return an error.

### Validate Callback

Those `WP_REST_Request` methods use the `validate_callback` and `sanitize_callback`
specified for each parameter when the route is registered. In most cases, this will
mean the schema based validation.

Any validation done inside the route, for instance in the `prepare_item_for_database`
method, will not cause the batch to be rejected. If this is a concern, it is recommended
to move as much validation as possible into the `validate_callback` for each individual
parameter. This can be built on top of the existing schema based validation, for
instance.

    ```notranslate
    'post' => array(
    	'type'        => 'integer',
    	'minimum'     => 1,
    	'required'    => true,
    	'arg_options' => array(
    		'validate_callback' => function ( $value, $request, $param ) {
    			$valid = rest_validate_request_arg( $value, $request, $param );

    			if ( is_wp_error( $valid ) ) {
    				return $valid;
    			}

    			if ( ! get_post( $value ) || ! current_user_can( 'read_post', $value ) ) {
    				return new WP_Error( 'invalid_post', __( 'That post does not exist.' ) );
    			}

    			return true;
    		}
    	)
    )
    ```

Sometimes when performing validation, the full context of the request is needed.
Typically, this validation would have been done in `prepare_item_for_database`, 
but WordPress 5.6 introduces an alternative. When registering a route, a top-level`
validate_callback` can now be specified. It will receive the full `WP_REST_Request`
object and can return a `WP_Error` instance or `false`. The callback won’t be executed
if parameter-level validation did not succeed.

    ```notranslate
    register_rest_route( 'my-ns/v1', 'route', array(
    	'callback'            => '__return_empty_array',
    	'permission_callback' => '__return_true',
    	'validate_callback'   => function( $request ) {
    		if ( $request['pass1'] !== $request['pass2'] ) {
    			return new WP_Error(
    				'passwords_must_match',
    				__( 'Passwords must match.' ),
    				array( 'status' => 400 )
    			);
    		}

    		return true;
    	}
    ) );
    ```

**Note:** Request validation happens _before_ permission checks take place. Keep
this in mind when considering whether to moving logic to a `validate_callback`.

## Limitations

No built-in routes currently allow batching. This will be added in a future release,
most likely starting immediately with WordPress 5.7.

`GET` requests are not supported. Developers are instead encouraged to use [linking and embedding](https://developer.wordpress.org/rest-api/using-the-rest-api/linking-and-embedding/)
or utilize parallel requests for the time being.

### Further Reading

See [#50244](https://core.trac.wordpress.org/ticket/50244), [[49252]](https://core.trac.wordpress.org/changeset/49252),
[[48947]](https://core.trac.wordpress.org/changeset/48947), [[48945]](https://core.trac.wordpress.org/changeset/48945).

_Props [@kadamwhite](https://profiles.wordpress.org/kadamwhite/), [@m\_butcher](https://profiles.wordpress.org/m_butcher/),
[@jeffmatson](https://profiles.wordpress.org/jeffmatson/) for reviewing._

[#5-6](https://make.wordpress.org/core/tag/5-6/), [#dev-notes](https://make.wordpress.org/core/tag/dev-notes/),
[#rest-api](https://make.wordpress.org/core/tag/rest-api/)

 [  ](https://profiles.wordpress.org/georgestephanis/) [George Stephanis](https://profiles.wordpress.org/georgestephanis/)
8:29 pm _on_ November 5, 2020     
Tags: [5.6 ( 85 )](https://make.wordpress.org/core/tag/5-6/),
[application-passwords ( 4 )](https://make.wordpress.org/core/tag/application-passwords/),
[authentication ( 4 )](https://make.wordpress.org/core/tag/authentication/), [core-passwords ( 2 )](https://make.wordpress.org/core/tag/core-passwords/),
[dev-notes ( 616 )](https://make.wordpress.org/core/tag/dev-notes/), rest-api, [two-factor ( 12 )](https://make.wordpress.org/core/tag/two-factor/)

# 󠀁[Application Passwords: Integration Guide](https://make.wordpress.org/core/2020/11/05/application-passwords-integration-guide/)󠁿

WordPress 5.6 will finally see the introduction of a new system for making authenticated
requests to various WordPress APIs — Application Passwords.

The existing cookie-based authentication system is not being removed, and any custom
authentication solutions provided by plugins should continue to operate normally.

For any sites using the [Application Passwords feature plugin](https://github.com/wordpress/application-passwords),
it is recommended to deactivate the pluginPlugin A plugin is a piece of software
containing a group of functions that can be added to a WordPress website. They can
extend functionality or add new features to your WordPress websites. WordPress plugins
are written in the PHP programming language and integrate seamlessly with WordPress.
These can be free in the WordPress.org Plugin Directory [https://wordpress.org/plugins/](https://wordpress.org/plugins/)
or can be cost-based plugin from a third-party. after upgrading to WordPress 5.6.
However, sites won’t experience any errors if the plugin remains active. The current
plan is to use the plugin for future prototyping.

## Application Password Format

Application Passwords are [**24**-characters long](https://github.com/WordPress/wordpress-develop/blob/87ff38532d8f4d9f48e67e3af171ea1a88798f6d/src/wp-includes/class-wp-application-passwords.php#L25-L32),
generated by `[wp_generate_password()](https://github.com/WordPress/wordpress-develop/blob/87ff38532d8f4d9f48e67e3af171ea1a88798f6d/src/wp-includes/class-wp-application-passwords.php#L49)`
without the use of special characters — so they consist exclusively of upper-case,
lower-case, and numeric characters. For the cryptographically curious, that comes
to [over **142 bits** of entropy](https://github.com/WordPress/application-passwords/pull/34/commits/71f5e9a66f9fa552e07bb11cf981ee1f648e3516).

When presented to the user for entering into an application, they are displayed 
[**chunked** for ease of use](https://github.com/WordPress/wordpress-develop/blob/87ff38532d8f4d9f48e67e3af171ea1a88798f6d/src/wp-includes/class-wp-application-passwords.php#L305-L317),
like so:

    ```notranslate
    abcd EFGH 1234 ijkl MNOP 6789
    ```

Application passwords can be used **with or without the spaces** — if included, 
spaces will just be stripped out before the password is hashed and verified.

### Data Store

WordPress will be storing a user’s application passwords as an array in user metaMeta
Meta is a term that refers to the inside workings of a group. For us, this is the
team that works on internal WordPress sites like WordCamp Central and Make WordPress.,
similar to how interactive login sessions (via `WP_Session_Tokens`) are stored already.

[The `WP_Application_Passwords` class](https://github.com/WordPress/wordpress-develop/blob/master/src/wp-includes/class-wp-application-passwords.php)
has all the methods for storing and retrieving records. Records include a number
of attributes about them — including assigned name for the application, a timestamp
for when it was created, and data on their last usage such as, date and IP address.
[Each application password is also assigned a uuid for reference](https://github.com/WordPress/wordpress-develop/blob/e4fadc6f4db4306374f5717fccef82df5c6ac4e8/src/wp-includes/class-wp-application-passwords.php#L53),
in case you’d like to build infrastructure for additional properties and store them
in an alternate location.

## Getting Credentials

### Generating Manually

From the Edit User page, you can generate new, and view or revoke existing application
passwords. [The form](https://github.com/WordPress/wordpress-develop/blob/530493396b324f5bed518a494e2843e7fdb020f1/src/wp-admin/user-edit.php#L723-L730)
and [the list table](https://github.com/WordPress/wordpress-develop/blob/530493396b324f5bed518a494e2843e7fdb020f1/src/wp-admin/includes/class-wp-application-passwords-list-table.php)
are both fully extensibleExtensible This is the ability to add additional functionality
to the code. Plugins extend the WordPress core software. to allow for overloading
to store additional data (more on this later, in “Authentication Scoping”).

[⌊The Application Passwords section of Edit User screen, after a new application
password has been created.⌉⌊The Application Passwords section of Edit User screen,
after a new application password has been created.⌉[

The Edit User screen, after a new application password has been created.

Once a given password has been used, it will keep track of where and when it has
been used – the “Last Used” column is accurate to within 24 hours (so that WordPress
isn’t writing to the database on every usage — only if it’s a new day). This can
be incredibly useful for identifying passwords that are no longer in use, so that
they can be safely revoked.

### Authorization Flow

To ensure that application password functionality is available, fire off a request
to the REST APIREST API The REST API is an acronym for the RESTful Application Program
Interface (API) that uses HTTP requests to GET, PUT, POST and DELETE data. It is
how the front end of an application (think “phone app” or “website”) can communicate
with the data store (think “database” or “file system”) [https://developer.wordpress.org/rest-api/](https://developer.wordpress.org/rest-api/)
root URLURL A specific web address of a website or web page on the Internet, such
as a website’s URL www.wordpress.org, and look at [the `authentication` key in the response data](https://github.com/WordPress/wordpress-develop/blob/530493396b324f5bed518a494e2843e7fdb020f1/src/wp-includes/rest-api.php#L1099-L1119).
If this key is empty, then application passwords are not available (perhaps because
the request is not over `https://` or it has been intentionally disabled).

If, however, `response.authentication` is an object with a key of `application-passwords`
it will offer a URL to send a user to complete the authentication flow. (You could
just guess at the URL, but this gives us more of the relevant information in one
go, as well as confirming that application passwords are available and enabled.)

The `response.authentication['application-passwords'].endpoints.authorization` url
will likely look something like this:

`https://example.com/wp-admin/authorize-application.php`

Instead of just sending the user there to generate an application password, it would
then be up to the user to reliably re-enter it into your application. So instead,
some additional `GET` parameters are accepted along with the request:

 * `app_name` (_required_) – The human readable identifier for your app. This will
   be the name of the generated application password, so structure it like … “WordPress
   Mobile App on iPhone 12” for uniqueness between multiple versions.
   Whatever name
   you suggest can be edited by the user if they choose before the application is
   created. While you can choose to not pre-populate it for the user, it is required
   to create a password, so they will then be forced to create their own, and could
   select a non-intuitive option.
 * `app_id` (_recommended_) – [a UUID formatted identifier](https://github.com/WordPress/wordpress-develop/blob/e3f28a9a11fd2c6eea7862a616738ace01d09d26/src/wp-includes/functions.php#L6990-L7038).
   The `app_id` allows for identifying instances of your application, it has no 
   special meaning in and of itself. As a developer, you can use the `app_id` to
   locate all Application Passwords created for your application.
   In the event of
   a data breach, your `app_id` could be distributed to void credentials generated
   with it, or if a site wants to allow only a given `app_id` or set of `app_id`
   s to register, this would enable that. However, it is strictly on the honor system—
   there is nothing to stop applications from generating new uuids with every authorization.
 * `success_url` (_recommended_) – The URL that you’d like the user to be sent to
   if they approve the connection. Three `GET` variables will be appended when they
   are passed back (`site_url`, `user_login`, and `password`); these credentials
   can then be used for APIAPI An API or Application Programming Interface is a 
   software intermediary that allows programs to interact with each other and share
   data in limited, clearly defined ways. calls.
   If the `success_url` variable is
   omitted, a password will be generated and displayed to the user instead, to manually
   enter into their application.
 * `reject_url` (_optional_) – If included, the user will get sent there if they
   reject the connection. If omitted, the user will be sent to the `success_url`,
   with `?success=false` appended to the end.
   If the `success_url` is omitted, the
   user just will be sent to their WordPress dashboard.

[⌊A screenshot of the new Authorize Application screen in the WP-Admin. A button
is displayed to approve the connection, and one to reject the connection.⌉⌊A screenshot
of the new Authorize Application screen in the WP-Admin. A button is displayed to
approve the connection, and one to reject the connection.⌉[

A screenshot of what the authorization flow will look like to a user.

As the parameters are all passed in via GET variables, if the user needs to log 
in first, they will all be preserved through the redirect parameter, so the user
can then continue with authorization.

It is also worth noting that the `success_url` and `redirect_url` parameters will
generate an error if they use a `http://` rather than `https://` protocol — however
other application protocols **are** acceptable! So if you have a `myapp://` link
that opens your [Android](https://developer.android.com/training/app-links), [iOS / MacOS](https://developer.apple.com/documentation/xcode/allowing_apps_and_websites_to_link_to_your_content),
or [Windows](https://blogs.windows.com/windowsdeveloper/2016/10/14/web-to-app-linking-with-appurihandlers/)—
_those will work!_

[Here is an example of a simple javascript application (under 100 lines of code) that uses this to authenticate to a WordPress site](https://gist.github.com/georgestephanis/44d16dfdd17bd18b9c45d1d5e6d7ec7b).
Though not the tidiest code, it was created in under two hours one evening, but 
it goes through the proper flows and can make authenticated requests.

### Programmatically through the REST API

If you have previously been using a different system to access the REST API and 
would prefer to switch over to using application passwords, it’s easy! [You can generate yourself a new application password via a `POST` request to the new `/wp/v2/users/me/application-passwords` endpoint.](https://github.com/WordPress/wordpress-develop/blob/master/src/wp-includes/rest-api/endpoints/class-wp-rest-application-passwords-controller.php)
Once you’ve got the new application password in the response data, you can delete
any old credentials and just use the coreCore Core is the set of software required
to run WordPress. The Core Development Team builds WordPress. implementation instead—
but please consider using something like [libsodium](https://github.com/jedisct1/libsodium)(
which [has a library bundled with WordPress already](https://github.com/WordPress/wordpress-develop/tree/master/src/wp-includes/sodium_compat)—
[here’s an implementation example](https://github.com/WordPress/two-factor/pull/389))
or [Vault](https://www.vaultproject.io/) to store the credentials encrypted, rather
than in plaintext.

## Using Credentials

### REST API

The credentials can be passed along to REST API requests served over `https://` 
using [Basic Auth](https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication#basic_authentication_scheme)/
[RFC 7617](https://tools.ietf.org/html/rfc7617), which is nearly ubiquitous in its
availability — [here’s the documentation for how to use it with cURL](https://ec.haxx.se/http/auth.html).

For a simple command-line script example, just swap out `USERNAME`, `PASSWORD`, 
and `HOSTNAME` in this with their respective values:

    ```notranslate
    curl --user "USERNAME:PASSWORD" https://HOSTNAME/wp-json/wp/v2/users?context=edit
    ```

### XML-RPC API

To use a generated application password with the legacy XML-RPC API, you can just
use it directly in lieu of the account’s real password.

For a simple command-line script example, again just swap out `USERNAME`, `PASSWORD`,
and `HOSTNAME` in this with their respective values:

    ```notranslate
    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>' https://HOSTNAME/xmlrpc.php
    ```

### Future 🔮 APIs

The application passwords authentication scheme can also be applied to future APIs
for WordPress as they become available. For example, if GraphQL or other systems
are enabled in WordPress, application passwords will provide them with a solid, 
established authentication infrastructure to build off of out of the box.

As an example of this, [with a trivial code addition identifying whether the current load is an api request](https://github.com/wp-graphql/wp-graphql/pull/1529),
[WPGraphQL](https://www.wpgraphql.com/) will now be able to accept authenticated
requests without the need of an ancillary plugin, using just the application passwords
functionality that has merged into core.

### Using an Application Password on `wp-login.php`

You can’t. 😅 The _point_ of application passwords are that they are to be used 
programmatically for applications, and not by humans for interactive sessions.

## Feature Availability

By default, Application Passwords is available to all users on sites served over
SSLSSL Secure Sockets Layer. Provides a secure means of sending data over the internet.
Used for authenticated and private actions./HTTPSHTTPS HTTPS is an acronym for Hyper
Text Transfer Protocol Secure. HTTPS is the secure version of HTTP, the protocol
over which data is sent between your browser and the website that you are connected
to. The 'S' at the end of HTTPS stands for 'Secure'. It means all communications
between your browser and the website are encrypted. This is especially helpful for
protecting sensitive data like banking information.. This can be customized using
the `wp_is_application_passwords_available` and `wp_is_application_passwords_available_for_user`
filters.

For example, to completely disable Application Passwords add the following code 
snippet to your site.

    ```notranslate
    add_filter( 'wp_is_application_passwords_available', '__return_false' );
    ```

Without SSL, it is possible for the Application Password to be seen by an attacker
on your networknetwork (versus site, blog) or the network between your site and 
the authorized application. If you are ok with this risk, you can force availability
with the following code snippet.

    ```notranslate
    add_filter( 'wp_is_application_passwords_available', '__return_true' );
    ```

If desired, it is possible to restrict what users on your site can use the Application
Passwords feature. For example, to restrict usage to administrator users, use the
following code snippet.

    ```notranslate
    function my_prefix_customize_app_password_availability(
    	$available,
    	$user
    ) {
    	if ( ! user_can( $user, 'manage_options' ) ) {
    		$available = false;
    	}

    	return $available;
    }

    add_filter(
    	'wp_is_application_passwords_available_for_user',
    	'my_prefix_customize_app_password_availability',
    	10,
    	2
    );
    ```

## Future Development

### Authentication Scoping

In future versions, the expectation is to include the ability to scope a given application
password to limit its access. The intention is to work on building this in plugin-
land until it’s ready for a core proposal.

What might password scoping look like? Here’s some methods being considered:

 * In a multisitemultisite Used to describe a WordPress installation with a network
   of multiple blogs, grouped by sites. This installation type has shared users 
   tables, and creates separate database tables for each blog (wp_posts becomes 
   wp_0_posts). See also **network**, **blog**, **site** environment, either restrict
   the credentials to a subset of the user’s blogs, or restrict it to only operate
   in a normal “blogblog (versus network, site) adminadmin (and super admin)” context,
   and not a “network admin” context.
 * Restrict functionality to only manage content — posts, pages, comments, custom
   post types — and disallow infrastructure management functionality like managing
   plugins, themes, and users.
 * Restrict the role that credentials can allow an application to operate as. For
   example, an Editor may restrict a set of credentials to only operate as though
   they had Author or Contributor permissions.

However this is done, implementing additional functionality to enforce the [principle of least privilege](https://en.wikipedia.org/wiki/Principle_of_least_privilege)
on an application-by-application basis is a worthwhile expansion on the included
functionality.

### Fine-grained Capabilitiescapability A **capability** is permission to perform one or more types of task. Checking if a user has a capability is performed by the `current_user_can` function. Each user of a WordPress site might have some permissions but not others, depending on their role. For example, users who have the Author role usually have permission to edit their own posts (the “edit_posts” capability), but not permission to edit other users’ posts (the “edit_others_posts” capability).

Right now, a user’s application passwords can be managed by any user who has permission
to `edit_user` them. The ability to customize this behavior using a new set of more
fine-grained capabilities is currently [planned for 5.7](https://core.trac.wordpress.org/ticket/51703).

### Eventually Two-Factor Authentication?

Another useful bit of application passwords is that it will removes an obstacle 
for the inclusion of multi-factor authentication on interactive logins.

Previously, if you enabled an interactive step — whether captcha or second factor
validation — on login pages, you would be in a bind with other non-interactive authentications,
for example the legacy XML-RPC system. After all, if a bad actor can just brute 
force or use social engineering to discern the user’s password, it would be trivially
usable via XML-RPC, where there is no ability to include an interactive prompt, 
and that functionality would need to be disabled entirely.

With that use case now being provided for via application passwords, there is additional
flexibility for the normal browser-based `wp-login.php` system to evolve.

### Further Resources

 * Core Ticketticket Created for both bug reports and feature development on the
   bug tracker.: [#42790](https://core.trac.wordpress.org/ticket/42790)
 * [Merge Proposal](https://make.wordpress.org/core/2020/09/23/proposal-rest-api-authentication-application-passwords/)
 * [Example Client](https://gist.github.com/georgestephanis/44d16dfdd17bd18b9c45d1d5e6d7ec7b)
 * [Feature Plugin](https://github.com/wordpress/application-passwords). Further
   development of App Passwords will be prototyped in this repo.

For bugbug A bug is an error or unexpected result. Performance improvements, code
optimization, and are considered enhancements, not defects. After feature freeze,
only bugs are dealt with, with regressions (adverse changes from the previous version)
being the highest priority. reports or enhancements, open a [Trac ticket](https://core.trac.wordpress.org/newticket?component=Login+and+Registration&focuses=rest-api)
in the new _App Passwords_ component with the _rest-api_ focus.

_Props [@timothyblynjacobs](https://profiles.wordpress.org/timothyblynjacobs/), 
[@m\_butcher](https://profiles.wordpress.org/m_butcher/), [@desrosj](https://profiles.wordpress.org/desrosj/),
[@jeffmatson](https://profiles.wordpress.org/jeffmatson/), for helping to write,
review, and proofread._

[#5-6](https://make.wordpress.org/core/tag/5-6/), [#application-passwords](https://make.wordpress.org/core/tag/application-passwords/),
[#authentication](https://make.wordpress.org/core/tag/authentication/), [#core-passwords](https://make.wordpress.org/core/tag/core-passwords/),
[#dev-notes](https://make.wordpress.org/core/tag/dev-notes/), [#rest-api](https://make.wordpress.org/core/tag/rest-api/),
[#two-factor](https://make.wordpress.org/core/tag/two-factor/)

 [  ](https://profiles.wordpress.org/georgestephanis/) [George Stephanis](https://profiles.wordpress.org/georgestephanis/)
4:29 am _on_ September 23, 2020     
Tags: [application-passwords ( 4 )](https://make.wordpress.org/core/tag/application-passwords/),
[authentication ( 4 )](https://make.wordpress.org/core/tag/authentication/), rest-
api, [two-factor ( 12 )](https://make.wordpress.org/core/tag/two-factor/)   

# 󠀁[Proposal: REST API Authentication / Application Passwords](https://make.wordpress.org/core/2020/09/23/proposal-rest-api-authentication-application-passwords/)󠁿

## Problem statement: no way to authenticate third-party access to REST APIREST API The REST API is an acronym for the RESTful Application Program Interface (API) that uses HTTP requests to GET, PUT, POST and DELETE data. It is how the front end of an application (think “phone app” or “website”) can communicate with the data store (think “database” or “file system”) 󠀁[https://developer.wordpress.org/rest-api/](https://developer.wordpress.org/rest-api/)󠁿

Ever since the REST API infrastructure merged via[ #33982](https://core.trac.wordpress.org/ticket/33982)
and shipped in[ WordPress 4.4](https://wordpress.org/support/wordpress-version/version-4-4/)
in December 2015, it’s been gaining momentum and been used in more and more places—
throughout WordPress’s adminadmin (and super admin), via plugins and themes, and
enabled deep, robust interactions powering new functionality such as the GutenbergGutenberg
The Gutenberg project is the new Editor Interface for WordPress. The editor improves
the process and experience of creating new content, making writing rich content 
much simpler. It uses ‘blocks’ to add richness rather than shortcodes, custom HTML
etc. [https://wordpress.org/gutenberg/](https://wordpress.org/gutenberg/) blockBlock
Block is the abstract term used to describe units of markup that, composed together,
form the content or layout of a webpage using the WordPress editor. The idea combines
concepts of what in the past may have achieved with shortcodes, custom HTML, and
embed discovery into a single consistent API and user experience. editor.

However, the functionality has been limited in that the only way to make authenticated
requests to the APIAPI An API or Application Programming Interface is a software
intermediary that allows programs to interact with each other and share data in 
limited, clearly defined ways. in coreCore Core is the set of software required 
to run WordPress. The Core Development Team builds WordPress. has been through Cookie&
Nonce-based authentication—there is no good way for third-party applications to 
communicate with WordPress in an authenticated fashion, apart from the legacy XML-
RPC API.

This has resulted in frustration for our[ Mobile teams](https://make.wordpress.org/mobile/)
especially as they’re working to integrate Gutenberg support, which relies on the
REST API. After some time having to store username/password to spoof a cookie and
interactive session to scrape a nonce from the wp-admin DOM, and then to use an 
endpoint to get it instead via[ [46253]](https://core.trac.wordpress.org/changeset/46253).
All of which is a tremendously messy and awkward usage that completely falls apart
if someone uses a variant of a two-factor authentication system.

Spoofing an interactive session just to make API requests is bad form and needlessly
complex.

> **We’d like to propose integrating [Application Passwords](https://github.com/WP-API/authentication/issues/13)
> into Core.**

There have been [many systems considered](https://github.com/WP-API/authentication/),
including everything from multiple incarnations of OAuth, JWT, and even some solutions
that are combinations of the two. Some called for a centralized app repository, 
some had open registration, but all were complex and none of them could build sufficient
traction to come to fruition.

[[

Broad conceptual overview of varying methods (See: [WP-API/authentication#15](https://github.com/WP-API/authentication/issues/15))

A simpler alternative to [Application Passwords](https://github.com/WP-API/authentication/issues/13)
is pure [Basic Authentication](https://core.trac.wordpress.org/ticket/42790) and
detailed in[ #42790](https://core.trac.wordpress.org/ticket/42790). However, Application
Passwords is more comprehensive, and a far superior of a choice for the reasons 
that follow.

### Benefit: **Ease of API Requests**

Given a login and an application password, making an API request is as simple as

    ```notranslate
    curl --user "USERNAME:APPLICATION_PASSWORD" -X POST -d "title=New Title" https://my.wordpress.site/wp-json/wp/v2/posts/POST_ID
    ```

It uses the standard HTTPHTTP HTTP is an acronym for Hyper Text Transfer Protocol.
HTTP is the underlying protocol used by the World Wide Web and this protocol defines
how messages are formatted and transmitted, and what actions Web servers and browsers
should take in response to various commands. authorization headers. Everything supports
this trivially.

### Benefit: **Ease of Revoking Credentials**

![](https://make.wordpress.org/core/files/2020/09/434fcd60-ff2f-11e6-938f-5a49609fff4b-
1024x658.png)

Application Passwords makes it easy to revoke any individual application password,
or wholesale void all of a user’s application passwords. Application Passwords also
lists the date a password was last used and the IP it was used from to help track
down inactive credentials or bad actors using them from unexpected locations.

### Benefit: Ease of Requesting API Credentials

While it is possible for a user to go to their user profile page and generate a 
new application password, for example if they are creating a command line tool for
themselves, the ideal workflow looks something like this:

![](https://make.wordpress.org/core/files/2020/09/4350f5c8-ff2f-11e6-9399-8bbbe3fb44b5-
1024x580.png)

To request a password for your application, redirect users to:

    ```notranslate
    https://example.com/wp-admin/authorize-application.php
    ```

The URLURL A specific web address of a website or web page on the Internet, such
as a website’s URL www.wordpress.org is included in the REST API index to facilitate
automated discovery.

    ```notranslate
    {
      "name": "Trunk",
      "authentication": {
        "application-passwords": {
          "endpoints": {
            "authorization": "http://example.com/wp-admin/authorize-application.php"
          }
        }
      }
    }
    ```

and use the following `GET` request parameters to specify:

 * `app_name` (_required_) – The human readable identifier for your app. This will
   be the name of the generated application password, so structure it like … “WordPress
   Mobile App on iPhone 12” for uniqueness between multiple versions. If omitted,
   the user will be required to provide an application name.
 * `success_url` (_recommended_) – The URL that you’d like the user to be sent to
   if they approve the connection. Two `GET` variables will be appended when they
   are passed back (`user_login` and `password`); these credentials can then be 
   used for API calls. If the `success_url` variable is omitted, a password will
   be generated and displayed to the user, to manually enter into your application.
 * `reject_url` (_optional_) – If included, the user will get sent there if they
   reject the connection. If omitted, the user will be sent to the `success_url`,
   with `?success=false` appended to the end. If the `success_url` is omitted, the
   user will be sent to their WordPress dashboard.

If the user is logged out, they’ll be redirected to the WordPress Login page. After
logging in, they’ll be immediately redirected back to the Authorize Application 
screen.

In discussions with [@timothyblynjacobs](https://profiles.wordpress.org/timothyblynjacobs/)
we’re unsure about whether to add a `state` parameter (which is just stored and 
passed back to the application to prevent CSRF attacks). Realistically apps could
just include it on their own in the `success_url` or a `site_url` parameter (which
could remind the application what site the returned credentials are for). Requiring
apps to pass a `state` parameter could encourage best practices, but we wouldn’t
be able to enforce that they validate its contents.

It’s also worth noting that the `success_url` and `reject_url` are both explicitly
designed that apps can pass in custom protocols for the return URLs. That is, they
could set them to be `wordpress://authentication` so that the user’s phone automatically
redirects them back from their web browser, directly into the application with the
credentials appended to the query. You may have seen this previously with other 
applications where you “Login with Facebook” in your browser and then Facebook sends
you directly back into your app. Or with how your web browser can open Zoom directly
on your laptop, pre-populating the room ID and password.

### Benefit: Login Security

Unlike pure basic auth that requires entering in credentials directly into the application,
Application Passwords allows for an _interactive_ authentication flow. This means
that login security features like Two Factor or reCAPTCHA can continue to protect
user accounts.

One of the reasons XML-RPC is so often recommended to be disabled is that it allows
brute forcing user’s passwords since those additional security protections can’t
be implemented. A risk of implementing pure basic auth is that sites will be forced
to disable it because it can’t be interactive.

## Proposed solution: merge Application Passwords to core

While there is a [standalone plugin for Application Passwords](https://wordpress.org/plugins/application-passwords/)
that’s developed in a [GitHub repo](https://github.com/wordpress/application-passwords),
[PR#540 to WordPress-develop](https://github.com/WordPress/wordpress-develop/pull/540)
is the official work we’re proposing to be merged into core. The pull request is
based off of the original feature pluginFeature Plugin A plugin that was created
with the intention of eventually being proposed for inclusion in WordPress Core.
See [Features as Plugins](https://make.wordpress.org/core/handbook/about/release-cycle/features-as-plugins/)’
s codebase. We welcome comments on this proposal post, contributions to [Application Passwords](https://github.com/wordpress/application-passwords)
itself, and even more so review and feedback on the [existing merge proposal pull request](https://github.com/WordPress/wordpress-develop/pull/540).

_Props to _[@timothyblynjacobs](https://profiles.wordpress.org/timothyblynjacobs/)_
for help on the content of this post, _[@jeffpaul](https://profiles.wordpress.org/jeffpaul/)_
for help on the structure of this post, and the many many people who have contributed
to the analysis behind this proposal and to Application Passwords._

[#application-passwords](https://make.wordpress.org/core/tag/application-passwords/),
[#authentication](https://make.wordpress.org/core/tag/authentication/), [#rest-api](https://make.wordpress.org/core/tag/rest-api/),
[#two-factor](https://make.wordpress.org/core/tag/two-factor/)

 [  ](https://profiles.wordpress.org/timothyblynjacobs/) [Timothy Jacobs](https://profiles.wordpress.org/timothyblynjacobs/)
4:20 pm _on_ September 7, 2020     
Tags: [agenda ( 1,124 )](https://make.wordpress.org/core/tag/agenda/),
rest-api   

# 󠀁[REST API Meeting Agenda for September 10](https://make.wordpress.org/core/2020/09/07/rest-api-meeting-agenda-for-september-10/)󠁿

After a hiatus following the release of WordPress 5.5, the REST APIREST API The 
REST API is an acronym for the RESTful Application Program Interface (API) that 
uses HTTP requests to GET, PUT, POST and DELETE data. It is how the front end of
an application (think “phone app” or “website”) can communicate with the data store(
think “database” or “file system”) [https://developer.wordpress.org/rest-api/](https://developer.wordpress.org/rest-api/)
weekly component chat will occur this week at **[September 10, 2020 18:00 UTC](https://www.timeanddate.com/worldclock/fixedtime.html?iso=20200910T1800)**
in the `#core-restapi` SlackSlack Slack is a Collaborative Group Chat Platform [https://slack.com/](https://slack.com/).
The WordPress community has its own Slack Channel at [https://make.wordpress.org/chat/](https://make.wordpress.org/chat/)
channel.

Agenda Items:

 * Batch Requests
 * Menus
 * Widgets
 * 5.6 Priorities
 * Open Floor

All agenda items are welcome, from all teams and contributors; please post them 
as comments below or let us know by joining the meeting.

[#agenda](https://make.wordpress.org/core/tag/agenda/), [#rest-api](https://make.wordpress.org/core/tag/rest-api/)

# Post navigation

[← Older posts](https://make.wordpress.org/core/tag/rest-api/page/2/?output_format=md)