WordPress REST API Introduction
The WordPress REST API lets other programs talk to your site with HTTP requests, and the answer comes as JSON. A mobile app, a JavaScript front end (React, Vue), another website or a simple script can read and write your content without the theme. It is also the base of the block editor, which uses it to save your posts.
The base URL
Every WordPress site has the API on the address /wp-json/. The root shows details about the site and all the available routes:
$ curl -s http://example.com/wp-json/ | jq '{name, description, url, namespaces}'
{
"name": "Demo Site",
"description": "",
"url": "http://example.com",
"namespaces": [
"oembed/1.0",
"wp/v2",
"wp-site-health/v1",
"wp-block-editor/v1",
"wp-abilities/v1"
]
}
If the pretty permalinks are not on, you can use the plain form /?rest_route=/, which works on every site:
$ curl -s "http://example.com/?rest_route=/" | jq -r .name
Demo Site
Namespaces, routes and endpoints
| Word | Meaning | Example |
|---|---|---|
| Namespace | The group and version of the API, so plugins do not clash | wp/v2 |
| Route | A URL path inside the namespace | /wp/v2/posts |
| Endpoint | A route with one HTTP method and its function | GET /wp/v2/posts |
See the main routes
$ curl -s http://example.com/wp-json/ | jq -r '.routes | keys[]' | grep "^/wp/v2" | grep -v "(" | head -20
/wp/v2
/wp/v2/block-directory/search
/wp/v2/block-patterns/categories
/wp/v2/block-patterns/patterns
/wp/v2/block-types
/wp/v2/blocks
/wp/v2/categories
/wp/v2/comments
/wp/v2/font-collections
/wp/v2/font-families
/wp/v2/icon-collections
/wp/v2/icons
/wp/v2/media
/wp/v2/menu-items
/wp/v2/menu-locations
/wp/v2/menus
/wp/v2/navigation
/wp/v2/pages
/wp/v2/pattern-directory/patterns
/wp/v2/plugins
HTTP methods
| Method | Used for | Example |
|---|---|---|
| GET | Read data | Get a list of posts |
| POST | Create data (also update) | Add a new post |
| PUT, PATCH | Update data | Change a post title |
| DELETE | Remove data | Delete a post |
Your first request
The posts route is public for published posts, so we can read it without a login. We make two posts first:
$ curl -s "http://example.com/wp-json/wp/v2/posts?_fields=id,slug,title" | jq -c '.[]'
{"id":6,"slug":"second-post","title":{"rendered":"Second post"}}
{"id":5,"slug":"first-post","title":{"rendered":"First post"}}
{"id":1,"slug":"hello-world","title":{"rendered":"Hello world!"}}
The _fields parameter returns only the fields you ask for, which keeps the response small. Without it, every post comes with the date, content, links and more.
Headers and status codes
$ curl -s -I "http://example.com/wp-json/wp/v2/posts" | grep -i -E "^(HTTP|content-type|x-wp-total|x-wp-totalpages)"
HTTP/1.1 200 OK
X-WP-Total: 3
X-WP-TotalPages: 1
Content-Type: application/json; charset=UTF-8
$ curl -s -o /dev/null -w "%{http_code}\n" http://example.com/wp-json/wp/v2/posts
200
$ curl -s -o /dev/null -w "%{http_code}\n" http://example.com/wp-json/wp/v2/nothing
404
| Code | Meaning |
|---|---|
| 200 | OK, the request worked |
| 201 | Created, a new item was made |
| 400 | Bad request, a parameter is wrong |
| 401 | Not logged in |
| 403 | Logged in, but not allowed |
| 404 | Route or item not found |
What can you get?
$ curl -s http://example.com/wp-json/wp/v2/types | jq -r 'keys[]'
attachment
nav_menu_item
page
post
wp_block
wp_font_face
wp_font_family
wp_global_styles
wp_navigation
wp_template
wp_template_part
Besides posts and pages, the API has routes for comments, media, users, categories, tags, taxonomies, settings and more. Custom post types and taxonomies appear there too, when you register them with show_in_rest => true.
| Exercises & Assignments |
|---|
| No Content Found. |
| Interview Questions & Answers |
|---|
| No Content Found. |