Get a Free Quote

The WordPress REST API: A Complete Guide

The WordPress REST API turns your site into a data source that any application can read and write over HTTP, using clean JSON instead of PHP template tags. It ships in WordPress core, so every modern site already exposes it, whether you built for it or not.

That single fact changes what WordPress can be. It is no longer only a website engine. It is a content back end that can feed a React app, a mobile application, a set of static pages, or another server entirely. Understanding the API is the difference between fighting WordPress and building on top of it with confidence.

This guide walks through what the API is, how routes and endpoints fit together, the core endpoints you will reach for, every practical authentication method, how to send each type of request, and how to add your own endpoints in PHP. We cover headless builds, security, performance, and the errors that trip people up. If you want a decoupled or API driven WordPress build done properly, you can get a free quote and we will scope it with you.

What the WordPress REST API Is

The WordPress REST API is a built in interface that exposes your site content as data over HTTP. Instead of asking WordPress to render an HTML page, an application asks for the raw information, a post, a page, a user, a category, and gets it back as JSON. JSON is a plain text format that almost every programming language can read, which is why it has become the common tongue of the web.

Here is the mental shift that matters. Classic WordPress mixes content and presentation. A theme template loops through posts and prints HTML. The REST API splits those two jobs apart. WordPress becomes the place where content is stored, edited, and managed, and something else, a JavaScript app, a mobile client, another server, decides how to present it. Your content stops being trapped inside one theme.

You are already using this API even if you have never called it directly. The block editor talks to the REST API every time you save a post. Many plugins read and write through it. The mobile apps for WordPress use it. So the question is rarely whether to use the API, it is how deliberately you use it for the features you are building.

Why developers reach for it

The appeal comes down to a few concrete things. You keep the WordPress editing experience that clients already know, while gaining freedom in how the front end is built. You can serve the same content to a website, an app, and a partner integration from one source of truth. And because the format is standard JSON over standard HTTP, the skills transfer, any developer who has consumed an API can consume this one.

There is a cost too, and it is fair to name it. Going API first, especially in a headless build, means you take on work that a normal theme handles for you, such as routing, previews, and SEO output. We will get to that. For now, hold onto the core idea, the REST API is how WordPress content leaves the WordPress template layer and travels anywhere.

A short history worth knowing

The REST API did not always ship in core. For a few years it lived as a feature plugin while the team worked out the shape of the routes and the response format. The infrastructure landed in WordPress 4.4, and the full content endpoints for posts, pages, and the rest arrived in 4.7. That history matters for one practical reason, almost every actively maintained site now has the full API available, so you can rely on it being present without asking a client to install anything. When you read older tutorials that tell you to install a REST API plugin, that advice is out of date for the core content endpoints.

It also helps to know what REST means, because the name is not decoration. REST is a style of designing web interfaces around resources that you act on with standard HTTP methods. A post is a resource. You read it with GET, create it with POST, and remove it with DELETE. That consistency is why a developer who has never touched WordPress can still guess how the API behaves, the conventions are shared across most of the modern web.

Thinking about a new WordPress website?Get a free consultation and a fixed-scope quote. A senior engineer replies within 24 hours. No obligation.
Get a Free Quote

How It Works: Routes, Endpoints, JSON

Three words carry most of the meaning here, route, endpoint, and namespace. Get comfortable with them and the rest falls into place.

A route is a URL path the API responds to. A endpoint is a route combined with an HTTP method, so the same route can behave differently for a GET than for a POST. A namespace is a prefix that groups routes and versions them, which keeps different plugins and API versions from colliding.

Everything starts at the base URL. Append /wp-json/ to any WordPress site address and you reach the API root. Core content sits inside the wp/v2 namespace, so a real posts route looks like this:

https://example.com/wp-json/wp/v2/posts

Read that from left to right. The domain is your site. The /wp-json/ segment is the API base. The wp/v2 part is the core namespace and version. The posts part is the resource. Open that URL in a browser on any public WordPress site and you will see a JSON array of the latest posts. Open the bare /wp-json/ root and WordPress returns a discovery document that lists every route registered on the site, which is the fastest way to learn what a given site exposes.

Reading a JSON response

A single post comes back as a JSON object with fields for the id, the date, the slug, the title, the content, the excerpt, the author id, and more. Titles and content arrive as objects with a rendered property, because WordPress runs them through its filters before sending. Knowing that shape saves confusion, when you want the visible title you read title.rendered, not title.

Filtering with query parameters

The API is far more useful once you filter. Query parameters let you narrow, sort, and page through results without writing any server code. A few you will use constantly:

  • per_page and page control how many items you get and which page you are on. The maximum per page is 100.
  • search returns items matching a term.
  • categories and tags filter posts by taxonomy term ids.
  • orderby and order sort the results, for example by date descending.
  • _fields trims the response to only the fields you name, which is one of the easiest performance wins available.
  • _embed pulls in related resources such as the author and featured image so you avoid extra requests.

So a request for the five most recent posts, returning only the title and link, and embedding the featured image, is just a URL with the right parameters attached. No plugin, no custom code, and the response is small and fast.

Client app React, mobile, curl WordPress /wp-json route Database GET request JSON response query
Illustrative request and response flow between a client, WordPress, and the database.

Core Endpoints You Will Use

Core WordPress registers a set of endpoints under the wp/v2 namespace that cover the content types you already know. Once you learn the pattern, all of them read the same way, a collection route returns many items, and the same route with an id returns a single item.

Here are the endpoints you will use most, with their routes and a note on what each returns.

ResourceRouteReturns
Posts/wp-json/wp/v2/postsBlog posts, filterable by category, tag, author, and date.
Single post/wp-json/wp/v2/posts/<id>One post by its numeric id.
Pages/wp-json/wp/v2/pagesStatic pages, with parent and menu order fields.
Media/wp-json/wp/v2/mediaAttachments, including image sizes and source URLs.
Users/wp-json/wp/v2/usersAuthors and users, with public fields for unauthenticated reads.
Categories/wp-json/wp/v2/categoriesThe category taxonomy terms.
Tags/wp-json/wp/v2/tagsThe post tag taxonomy terms.
Comments/wp-json/wp/v2/commentsComments, readable publicly and writable when allowed.
Taxonomies/wp-json/wp/v2/taxonomiesThe taxonomies registered on the site.
Post types/wp-json/wp/v2/typesThe post types registered on the site.
Settings/wp-json/wp/v2/settingsSite settings, available only to authenticated admins.

Posts, pages, and media

Posts are the workhorse. You filter them by category id, tag id, author, search term, and date range, then page through the results. Pages behave almost identically but add a parent field, which matters when you build a nested navigation from page hierarchy. Media is where featured images and uploads live, and each media item exposes several rendered sizes, so a front end can pick the right one for the layout rather than shipping a giant original.

Users and taxonomies

The users endpoint returns public author information without authentication, and fuller data once you log in. Taxonomy endpoints, categories and tags out of the box, let you build filters and archives. Any custom taxonomy registered with show_in_rest set to true gets its own route in the same style, so a product catalogue with custom taxonomies is fully readable through the API.

Custom post types

This is the part that unlocks real projects. When you register a custom post type and pass show_in_rest => true, WordPress exposes it at /wp-json/wp/v2/your-type automatically, with the same query parameters as posts. That means a portfolio, a listings directory, or an events calendar becomes an API resource with no extra endpoint code. If you are planning that kind of build, our development services cover custom post types wired into an API front end, and you can request a quote to get it scoped.

Authentication Methods

Reading public content needs no login. The moment you want to create, update, or delete content, or read anything private, you must authenticate. WordPress checks the same capabilities it uses everywhere else, so a request can only do what the underlying user is allowed to do. There are four practical methods, and choosing the right one is mostly about where the request comes from.

Cookie authentication with a nonce

This is the method WordPress uses for requests made from inside the site while a user is logged in, the block editor being the obvious example. The browser already holds the login cookie. To prove the request is intentional and not forged, WordPress also requires a nonce, a short lived token, sent in the X-WP-Nonce header. If you are writing JavaScript that runs on your own WordPress pages, this is the correct approach and the easiest to set up. It does not work for outside applications, because they do not have the cookie.

Application passwords

Application passwords are built into WordPress core and are the right default for server to server and outside integrations. A user generates a dedicated password for a specific application from their profile screen. That password is sent with standard HTTP Basic authentication, and it never exposes the account main password. You can revoke a single application password without disturbing anything else. The one rule that is not negotiable, only ever send it over HTTPS, because Basic auth puts the credential in the request header.

JWT authentication

JSON Web Tokens suit front end applications that log a user in and then make many requests. A plugin adds a token endpoint, the client sends credentials once, receives a signed token, and then attaches that token in an Authorization: Bearer header on later requests. Tokens expire, which limits exposure if one leaks. JWT needs a plugin because it is not part of core, but it is a clean fit for a React or mobile app with real user sessions.

OAuth

OAuth is the choice when a third party application needs access on behalf of a user without ever seeing that user password, the pattern behind sign in with another service. It is the most involved to set up and usually calls for a plugin and careful configuration. Reach for it when you are granting access to software you do not control, not for your own internal tools.

MethodBest forNeeds a pluginHow the credential travels
Cookie and nonceSame site JavaScript, block editorNoLogin cookie plus X-WP-Nonce header
Application passwordsServer to server, outside integrationsNoHTTP Basic auth over HTTPS
JWTApp front ends with user sessionsYesBearer token in Authorization header
OAuthThird party access on behalf of a userYesAccess token after an authorization flow

If you are unsure which method fits your project, that is a normal question and the answer depends on who is calling the API and from where. We help teams pick and implement the right one. You can get a free quote and we will recommend an approach that matches your security needs.

Ready to bring your WordPress project to life?Get a free consultation and a fixed-scope quote. A senior engineer replies within 24 hours. No obligation.
Get a Free Quote

Making Requests: GET, POST, PUT, DELETE

The API maps neatly onto the four HTTP methods you have probably seen before. GET reads, POST creates, PUT updates, and DELETE removes. The same route handles several of these depending on the method and your permissions, which is exactly what the endpoint idea from earlier describes in practice.

  • GET retrieves one or many items and never changes anything. No authentication is needed for public data.
  • POST creates a new item, for example a new post. It requires authentication and the right capability.
  • PUT updates an existing item. In practice the WordPress API also accepts POST for updates, but PUT expresses intent clearly.
  • DELETE removes an item, moving it to trash by default, or permanently when you pass force.

A read request with fetch

From JavaScript in a browser or a Node process, the built in fetch function is all you need for reads. This example asks for the three most recent posts and pulls out the rendered title of each.

fetch('https://example.com/wp-json/wp/v2/posts?per_page=3&_fields=id,title,link')
  .then(function (response) {
    if (!response.ok) {
      throw new Error('Request failed: ' + response.status);
    }
    return response.json();
  })
  .then(function (posts) {
    posts.forEach(function (post) {
      console.log(post.id, post.title.rendered);
    });
  })
  .catch(function (error) {
    console.error(error);
  });

Notice the _fields parameter trimming the payload and the check on response.ok before reading the body. Both are small habits that make client code faster and less fragile.

A write request with curl

For a quick test from a terminal, or for a server side script, curl with an application password creates a post in one command. The user and application password go in the --user flag, and the body is JSON.

curl --user "editor:xxxx xxxx xxxx xxxx xxxx xxxx" \
  -X POST https://example.com/wp-json/wp/v2/posts \
  -H "Content-Type: application/json" \
  -d '{"title":"Posted through the API","content":"Hello from curl.","status":"draft"}'

Setting status to draft is a good instinct while you test, so nothing publishes by accident. Swap in publish when you mean it. To update that post later, send the same request to /wp-json/wp/v2/posts/<id> with the fields you want to change. To remove it, use -X DELETE on the same single item route.

Reading the response and status codes

Every response carries an HTTP status code, and reading it saves hours of guesswork. A 200 means success on a read, a 201 means something was created, a 400 means your input was malformed, a 401 means you are not authenticated, a 403 means you are authenticated but not allowed, and a 404 means the route or item does not exist. When something fails, WordPress returns a JSON object with a code and a message, which usually tells you exactly what went wrong.

Pagination headers you should read

Collection responses carry two headers that are easy to miss and genuinely useful. X-WP-Total holds the total number of items matching your query across all pages, and X-WP-TotalPages holds how many pages that works out to at your chosen per_page. Read those headers and you can build a correct pager without a second counting request. Ignore them and you end up guessing when to stop, or making extra calls you did not need. Most HTTP clients expose response headers alongside the body, so wiring this in is a few lines, not a rewrite.

Batching related work

When a page needs several pieces of content, resist the habit of firing a separate request for each one in a tight loop. Prefer a single filtered request where you can, use _embed to fold in authors and images, and consider the core batch endpoint for grouped writes. Fewer, larger requests almost always beat many small ones, both for speed and for staying within any rate limits the server enforces. This is the same instinct that keeps a database from drowning in tiny queries, applied one layer up.

Custom Endpoints with register_rest_route

The core endpoints cover content, but real projects need custom behaviour, a route that returns a filtered mix of data, triggers an action, or wraps a third party service. That is what register_rest_route is for. You hook into rest_api_init, declare a namespace and route, and provide a callback that returns the data.

Choose your own namespace rather than reusing wp/v2, so your routes never clash with core or another plugin. A common convention is a short plugin name plus a version, such as myplugin/v1.

<?php
add_action( 'rest_api_init', function () {
    register_rest_route( 'myplugin/v1', '/featured/(?P<count>\d+)', array(
        'methods'             => 'GET',
        'callback'            => 'myplugin_get_featured',
        'permission_callback' => '__return_true',
        'args'                => array(
            'count' => array(
                'validate_callback' => function ( $value ) {
                    return is_numeric( $value ) && (int) $value <= 20;
                },
            ),
        ),
    ) );
} );

function myplugin_get_featured( WP_REST_Request $request ) {
    $count = (int) $request['count'];

    $query = new WP_Query( array(
        'posts_per_page' => $count,
        'meta_key'       => 'featured',
        'meta_value'     => '1',
    ) );

    $data = array();
    foreach ( $query->posts as $post ) {
        $data[] = array(
            'id'    => $post->ID,
            'title' => get_the_title( $post ),
            'link'  => get_permalink( $post ),
        );
    }

    return rest_ensure_response( $data );
}

Walk through the important parts. The route pattern captures a numeric count from the URL. The args block validates that count before your callback ever runs, so bad input is rejected early. The callback receives a WP_REST_Request object, does its work, and returns through rest_ensure_response, which wraps plain data in a proper response object.

The permission callback is not optional

The single most important line above is permission_callback. This example uses __return_true because the data is public, but if your endpoint touches anything private or writes data, you must return a real capability check, for example current_user_can( 'edit_posts' ). Leaving the permission callback off, or setting it to always true on a sensitive route, is one of the most common and most serious mistakes in custom API code. WordPress will even warn about a missing permission callback for exactly this reason.

Validation and sanitization

Two callbacks guard your input. A validate_callback decides whether a value is acceptable and rejects it if not. A sanitize_callback cleans a value into a safe form before you use it. Use validation for numbers, enums, and formats, and sanitization for text and slugs. Together they keep unexpected input from reaching your queries. Never trust a parameter just because it arrived through your own route.

Returning proper errors

When something goes wrong inside your callback, do not return a bare string or let a fatal error leak. Return a WP_Error object with a machine readable code, a human message, and an HTTP status. WordPress turns that into a clean JSON error response with the right status code, which is exactly what a client expects. A callback that returns a well formed error is far easier to consume than one that returns a 200 with an error hidden in the body. Decide your error codes up front and document them alongside your routes, so the front end team can handle each case deliberately rather than guessing from the message text.

Schema and discoverability

A polished endpoint describes itself. Passing a schema callback to your route tells the API what fields it returns and what types they are, which shows up when a client sends an OPTIONS request to the route. You do not have to write a schema to ship a working endpoint, but on an API that other people will build against, it pays for itself in fewer support questions. It also lets the API validate output for you in some cases, which catches mistakes before they reach a client.

Extending existing responses

Sometimes you do not need a whole new route, you just want an extra field on an existing one. register_rest_field adds a field to a core response, for example attaching a computed reading time to every post. It keeps clients on the standard endpoints while giving them the data they need, which is often cleaner than inventing a parallel route.

Headless and Decoupled Front Ends

Headless WordPress is the architecture that made the REST API famous. The idea is to separate the body, the front end that visitors see, from the head, which here is the content management. WordPress keeps doing what it is best at, storing and editing content, and a separate application renders the site by pulling that content through the API.

In a decoupled build, the front end is usually a JavaScript framework such as React, Vue, or Next.js, or a static site generator that fetches content at build time. Editors still log into the familiar WordPress admin. Visitors never touch WordPress directly, they load the front end, which requests JSON from /wp-json and turns it into pages.

Why teams choose headless

  • Front end freedom. You build the interface with modern tooling and component libraries, unconstrained by the theme system.
  • One content source, many outputs. The same API feeds a website, a mobile app, and partner integrations at once.
  • Performance ceiling. A static or heavily cached front end can be extremely fast, since pages are prebuilt or served from the edge.
  • Separation of concerns. Front end and back end teams can work in parallel against a shared contract, the API.

The honest trade offs

Headless is powerful, and it is not free. Several things a normal theme gives you become your responsibility. Previewing unpublished content needs extra wiring, because the front end is separate from the editor. SEO output, meta tags, sitemaps, and structured data, has to be reproduced in the front end rather than handled by a plugin in the theme. Redirects, forms, and some plugins that assume a themed front end need rethinking. And you now run and deploy two systems instead of one.

None of that should scare you off, but it should shape the decision. Headless earns its keep on content rich sites that need a custom front end experience or that feed several channels. For a straightforward brochure or blog site, a well built classic or block theme is often the better call, and cheaper to maintain. If you want fast pages without going fully headless, our guide on how to speed up a WordPress website covers a lot of ground first.

Deciding between headless and a traditional build is exactly the kind of question worth a short conversation before you commit code. We do these builds and we will tell you honestly which one fits. You can request a quote and we will lay out both paths for your project.

Headless Mobile app Integrations Admin tools Static build high low
Illustrative comparison of common REST API use cases by relative adoption. Figures are illustrative only.
Want a clear plan and price for your website?Get a free consultation and a fixed-scope quote. A senior engineer replies within 24 hours. No obligation.
Get a Free Quote

Security Best Practices

The REST API is as secure as the way you use it. Core respects capabilities and permissions, so the platform is not the weak point. Problems come from configuration and custom code. Here is the list we hold our own builds to.

Serve everything over HTTPS

This is first for a reason. Application passwords and Basic auth put credentials in request headers, and JWT and OAuth pass tokens. Over plain HTTP, all of that is readable in transit. HTTPS is not a nice to have for an API, it is a requirement. If your site is not fully on HTTPS, fix that before you expose any authenticated endpoint.

Always set a real permission callback

As covered in the custom endpoints section, every route you register needs a permission_callback that reflects who should be allowed. For public reads, an explicit always true is fine and honest. For anything that writes or reads private data, check a real capability. Do not skip it and do not default it to true out of convenience.

Validate and sanitize every input

Treat all incoming parameters as untrusted, even on your own routes. Validate formats and ranges, sanitize text and slugs, and use prepared queries so nothing you receive can reach the database unescaped. This is the same discipline you apply anywhere in WordPress, and the API is no exception.

Limit what you expose

By default the users endpoint reveals author names and slugs to anyone, which some sites would rather not publish. You can restrict that, and you can require authentication for routes that do not need to be public. The goal is not to disable the API, the block editor needs it, but to expose only what your project actually requires.

Rate limit and monitor

A public write endpoint invites abuse. Rate limiting at the server or a security plugin slows brute force attempts and scraping. Logging failed authentication and unusual traffic gives you an early warning. On sites that matter, both are worth the small effort. If you want a security review of an API that is already live, our team can audit it, and you can get a free quote for that work.

Performance and Caching

An API that is correct but slow will still frustrate users, and the fixes are mostly straightforward. Performance work on the REST API falls into two buckets, sending less and caching more.

Send less data

The _fields parameter is the simplest win available. If a list view only needs the id, title, and link, ask for only those and skip the full content body on every item. Paginate with per_page rather than pulling hundreds of items at once. Use _embed thoughtfully, it saves round trips by including related data, but it also grows the response, so use it where it genuinely replaces extra requests.

Cache responses

Read heavy endpoints are ideal caching candidates because the same request returns the same data for many users. A few layers help, stacked from the outside in:

  • A CDN or edge cache in front of the site serves repeated GET requests without touching WordPress at all.
  • Full page or object caching on the server reduces database work for requests that do reach WordPress.
  • The WordPress object cache, backed by a persistent store, keeps expensive query results in memory between requests.

Set sensible cache lifetimes based on how often the content changes, and invalidate the cache when a post is saved so readers are not stuck with stale data. Getting invalidation right is the part that takes care, but the payoff is a fast API that shrugs off traffic spikes.

Honour caching headers

The API can work with the browser and any intermediate cache through standard HTTP headers. An ETag or a Last-Modified value lets a client ask whether anything has changed since last time, and receive a small not modified response when it has not, instead of the whole payload again. For a front end that polls for updates, that difference is large over a day of traffic. Set cache control headers that match how fresh each route needs to be, a rarely changing settings route can cache far longer than a live comments feed, and let the layers above WordPress do their job.

Watch your queries

Custom endpoints are only as fast as the queries behind them. Avoid unbounded loops, index the meta you filter on, and be wary of running queries inside a loop over another query. A profiler will show you the expensive calls quickly. The same performance mindset that keeps a normal WordPress site quick applies to the API, and our WordPress speed guide goes deeper on hosting, caching, and query tuning that helps here too.

Common Errors and Fixes

A handful of errors account for most of the time people lose with the REST API. Recognise them and you will move much faster.

rest_no_route (404)

WordPress does not recognise the route you requested. Usually the URL is wrong, a typo in the namespace, a missing version, or the plugin that registers the route is not active. Open the /wp-json/ root and confirm the route is actually listed. If you just registered it in code, make sure the plugin is active and that you hooked into rest_api_init.

rest_forbidden (401 or 403)

You are not allowed to do what you asked. A 401 means the request was not authenticated at all, so check that your credentials or token are being sent and that you are on HTTPS. A 403 means you are authenticated but the user lacks the capability, which points at either the wrong user or a permission callback doing its job. This is also the error you see when a nonce is missing or has expired on a same site request.

rest_cannot_create or rest_cannot_edit

The authenticated user does not have the capability for that write. Confirm the user role can perform the action, and that your custom route permission callback is not blocking it. This is often a role and capability question rather than an API bug. If you keep hitting it with a user you believe should have access, print the user roles and confirm the account you authenticated as is really the one you think it is, mismatched accounts are a frequent cause.

Malformed request (400)

Your input did not pass validation. Check that the JSON body is valid, that the Content-Type header is set to application/json on writes, and that required fields are present and correctly typed. The error message names the parameter at fault more often than people expect, so read it carefully.

CORS errors in the browser

If a front end on a different domain calls the API and the browser blocks it, that is a cross origin restriction, not a WordPress failure exactly. The API sends permissive headers for many cases, but authenticated cross origin requests need the right headers configured on the server. Plan your domains and headers early in a headless build so this does not surprise you near launch.

The API returns HTML instead of JSON

If a request returns an HTML error page rather than JSON, something is intercepting the request before the API runs, often a security plugin, a rewrite rule, or broken permalinks. Re saving permalinks in the WordPress admin fixes a surprising share of these. If that does not help, look at your 404 handling and any plugin that filters requests.

Where to go from here

The WordPress REST API rewards a little upfront learning with a lot of flexibility. Start by reading public endpoints in a browser, then try an authenticated write with an application password, then register a small custom route with a proper permission callback. From there, a headless front end or an app integration is a matter of scale, not a different skill.

If you want any of this built for you, a custom endpoint, a decoupled front end, an integration between WordPress and another system, or a security and performance review of an API you already run, that is our core work. You can see our services or get a free quote and we will scope it around your goals. For related reading, our guides on WordPress SEO and how to make a WordPress website pair well with an API driven build.

Hamza Hai

Hamza Hai writes about WordPress development, performance, and growth for businesses.

FAQ

Frequently asked questions

It lets applications read and write WordPress content over HTTP using JSON. Common uses include headless front ends built with React or Vue, mobile apps that pull posts, integrations that sync data with other systems, and admin tools that update content without loading the classic editor. The block editor itself uses the REST API to save your work.

The base is your site address followed by /wp-json/. Core content lives under /wp-json/wp/v2/, so posts are at /wp-json/wp/v2/posts and pages are at /wp-json/wp/v2/pages. You can open the base URL in a browser to see a discovery document that lists every registered route on the site.

For requests from within the same site, WordPress uses a logged in cookie plus a nonce. For outside requests, the built in option is application passwords, which you generate per user and send with HTTP Basic auth over HTTPS. JWT and OAuth are available through plugins when you need token based flows or third party access.

The API respects the same permission and capability checks as the rest of WordPress, so private data stays protected as long as you authenticate correctly and serve everything over HTTPS. Risk comes from weak authentication, custom endpoints that skip permission callbacks, and unvalidated input. Follow the security section in this guide and it holds up well.

You should not fully disable it, because the block editor and many core features depend on it. You can require authentication for requests, restrict specific routes, or limit what data is exposed. A more sensible approach is to lock down what needs locking down rather than switching the whole API off.

The REST API is the interface that serves your content as JSON. A headless build is an architecture that uses that interface. In a headless setup, WordPress handles content and the API, while a separate front end, often React, Next.js, or a static site generator, renders what visitors see. The API makes headless possible, but you can use the API without going headless.

Yes. When you register a custom post type, set show_in_rest to true and it appears under its own route. Custom fields can be exposed with register_post_meta and the right settings, or through register_rest_field for more control. Advanced Custom Fields can also surface fields in REST responses with the correct configuration.

No. The core API is built into WordPress and is active by default. You only add plugins for extra authentication methods such as JWT or OAuth, or to extend or restrict what the API exposes. For most reads and for application password authentication, core is all you need.

Have a project?

Let's Build Your Next WordPress Website

Get a free consultation and a fixed-scope quote. No obligations.

  • Free Consultation
  • No Hidden Costs
  • 100% Confidential

Request your free quote

Tell us what you are building. A senior engineer replies within 24 hours.

Please enter your name.

Please enter a valid email address.

Please tell us a little more about your project (10+ characters).

No obligation. Your details are only used to prepare your quote.

Click to call us +1 (365) 440-1786