Opens in a new tab
  1. Home
  2. Guides
  3. System
System guide

How WordPress advertises its REST API

Understand how WordPress exposes and advertises its REST API through api.w.org links, HTTP headers, RSD, resource-specific JSON links and the REST API itself.

  • Updated September 8, 2026
  • 19 min read
  • WordPress guide

WordPress does not simply provide a REST API at /wp-json/. It also actively advertises that API so browsers, JavaScript applications and external clients can discover where it is located and which frontend resources have corresponding REST representations.

A standard WordPress page can expose REST API discovery through several independent mechanisms:

  • an HTML <link> element inside the document head;
  • HTTP Link response headers;
  • resource-specific JSON discovery links;
  • RSD, or Really Simple Discovery;
  • the REST API root itself;
  • hypermedia links inside REST responses.

The most recognizable frontend signal is:

<link
    rel="https://api.w.org/"
    href="https://example.com/wp-json/"
/>

That line tells compatible software:

This website exposes a WordPress REST API.

Its root is here:

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

But removing that single line does not necessarily remove every REST discovery mechanism, and it certainly does not disable the REST API itself.

This distinction is important because:

REST API discovery
≠
REST API access
≠
REST API authorization

Discovery tells a client where an API exists.

Access determines whether the endpoint can be reached.

Authorization determines whether the requester may perform a particular operation.

This guide explains exactly how WordPress advertises its REST API, which core functions generate the discovery information, how resource-specific discovery works, how RSD fits into the system, and what actually happens when those discovery mechanisms are removed.

What is the WordPress REST API?

The WordPress REST API provides machine-readable access to WordPress resources through HTTP.

Instead of returning a complete HTML webpage, REST endpoints normally return JSON.

The primary API root is usually:

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

Core WordPress routes commonly exist under the:

wp/v2

namespace.

Examples include:

/wp-json/wp/v2/posts
/wp-json/wp/v2/pages
/wp-json/wp/v2/categories
/wp-json/wp/v2/tags
/wp-json/wp/v2/users
/wp-json/wp/v2/media

The official WordPress REST API Handbook describes the API as the interface through which applications can interact with WordPress by sending and receiving JSON data.

For its security model, see WordPress REST API Security Basics.

Why does WordPress advertise the REST API?

A software client should not always have to assume that:

/wp-json/

is the correct REST API root.

WordPress can run:

  • in a subdirectory;
  • behind proxies;
  • with different permalink configurations;
  • in multisite installations;
  • with custom URL filtering;
  • with installations where the public URL differs from the WordPress application URL.

WordPress therefore generates the appropriate REST API URL dynamically.

The official get_rest_url() documentation describes the core function used to retrieve the URL to a REST endpoint.

A client that follows WordPress’s advertised URL does not need to guess how that particular installation is configured.

The main REST API discovery mechanisms

WordPress currently exposes REST discovery through several layers.

A simplified architecture looks like:

Frontend WordPress page
│
├── HTML REST API root link
│   └── rel="https://api.w.org/"
│
├── HTML JSON resource link
│   └── rel="alternate"
│
├── HTTP Link header
│   ├── REST API root
│   └── current JSON resource
│
├── RSD
│   └── XML document advertising WP-API
│
└── Direct REST root
    └── /wp-json/
        ├── namespaces
        ├── routes
        └── hypermedia links

This explains why removing one discovery signal does not necessarily make the API undiscoverable.

REST API discovery in the HTML head

WordPress can insert the following element into the document <head>:

<link
    rel="https://api.w.org/"
    href="https://example.com/wp-json/"
/>

The relationship:

https://api.w.org/

identifies the link as the WordPress REST API root.

The official WordPress REST API Discovery documentation documents this link-based autodiscovery mechanism.

Which WordPress function outputs the REST API link?

The core function responsible is:

rest_output_link_wp_head()

The official rest_output_link_wp_head() reference states that the function outputs the REST API link tag into the page header.

Its current implementation first retrieves:

$api_root = get_rest_url();

and then outputs a link equivalent to:

<link
    rel="https://api.w.org/"
    href="REST_API_ROOT"
/>

WordPress can advertise more than the API root

The current rest_output_link_wp_head() implementation also checks whether the page being viewed corresponds to a REST API resource.

It does this through:

rest_get_queried_resource_route()

If WordPress finds an appropriate REST route, it can additionally output:

<link
    rel="alternate"
    title="JSON"
    type="application/json"
    href="https://example.com/wp-json/wp/v2/posts/123"
/>

This means WordPress can advertise two different things from the same frontend page:

REST API root
+
REST representation of the current resource

What is resource discovery?

Resource discovery links a normal frontend document with its machine-readable REST representation.

Suppose a visitor opens:

https://example.com/my-post/

WordPress may advertise:

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

as the corresponding JSON resource.

The relationship becomes:

HTML representation

https://example.com/my-post/

        ↓

JSON representation

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

This allows software to move from a human-readable URL to the corresponding API object automatically.

How WordPress determines the current REST resource

WordPress uses:

rest_get_queried_resource_route()

The official rest_get_queried_resource_route() documentation shows that WordPress currently handles several frontend query types.

These include:

  • singular posts and pages;
  • categories;
  • tags;
  • custom taxonomy terms;
  • author archives.

REST discovery for posts and pages

On singular content, WordPress can determine the route through:

rest_get_route_for_post()

The official rest_get_route_for_post() documentation shows that WordPress first determines the REST collection associated with the post type, then appends the object’s ID.

A normal post can therefore resolve conceptually to:

/wp/v2/posts/123

A page can resolve to:

/wp/v2/pages/123

Custom post types and REST discovery

Not every custom post type automatically receives a REST route.

The post type must normally be exposed to REST through:

show_in_rest

The official rest_get_route_for_post_type_items() documentation shows that WordPress returns no REST collection route when the post type does not have show_in_rest enabled.

This means resource discovery follows the post type’s actual REST configuration rather than inventing a route for every WordPress content type.

REST discovery for taxonomy terms

Categories, tags and REST-enabled custom taxonomies can also have machine-readable representations.

WordPress uses:

rest_get_route_for_term()

The official rest_get_route_for_term() documentation explains how WordPress obtains the REST route for a taxonomy term.

A category might therefore map to something similar to:

/wp-json/wp/v2/categories/12

REST discovery for author archives

The current rest_get_queried_resource_route() implementation can also map an author archive to:

/wp/v2/users/USER_ID

This is one reason REST user exposure deserves its own security review.

See WordPress REST API User Enumeration, Explained.

HTML discovery does not mean REST access is public

A discovery link tells software where a resource exists.

It does not guarantee that every operation on that endpoint is available anonymously.

For example:

GET /wp-json/wp/v2/posts/123

may return a public post.

But:

POST /wp-json/wp/v2/posts/123

to modify that post requires appropriate authentication and permissions.

The discovery URL and the authorization policy are separate layers.

REST API discovery through HTTP headers

WordPress does not rely exclusively on HTML.

It can also advertise the REST API through HTTP response headers.

A response can include:

Link: <https://example.com/wp-json/>;
      rel="https://api.w.org/"

The core function responsible is:

rest_output_link_header()

The official rest_output_link_header() documentation confirms that the function sends a Link header for the REST API.

Why WordPress uses an HTTP Link header

A software client may inspect HTTP response headers without parsing the HTML document.

That allows it to discover the REST API earlier and more directly.

The official REST API Discovery handbook describes HTTP Link header discovery as the preferred REST discovery method.

Conceptually:

HTTP response
│
├── HTML body
│   └── REST discovery
│
└── HTTP headers
    └── REST discovery

The HTTP header can also advertise the current JSON resource

The current implementation of:

rest_output_link_header()

does not stop at the API root.

If WordPress can determine a route for the currently queried resource, it can add another header equivalent to:

Link: <https://example.com/wp-json/wp/v2/posts/123>;
      rel="alternate";
      title="JSON";
      type="application/json"

This mirrors the resource-specific <link rel="alternate"> element WordPress can output in HTML.

Removing the HTML REST link does not remove the HTTP header

This is one of the most common mistakes in WordPress head cleanup.

Suppose you remove:

remove_action(
    'wp_head',
    'rest_output_link_wp_head',
    10
);

The HTML:

<link rel="https://api.w.org/" ...>

can disappear.

But WordPress may continue sending:

Link: <https://example.com/wp-json/>;
      rel="https://api.w.org/"

in the response headers.

Therefore:

REST head link removed
≠
all REST discovery removed

How this relates to hiding the REST API

If your objective is removing automatic discovery, you need to understand every discovery layer rather than deleting one HTML element and declaring the API hidden.

More importantly, even removing all discovery metadata would still not create actual access control.

See Hiding vs. Restricting the WordPress REST API.

REST API discovery through RSD

WordPress also advertises the REST API through a much older system called:

Really Simple Discovery

or:

RSD

A WordPress page can contain:

<link
    rel="EditURI"
    type="application/rsd+xml"
    title="RSD"
    href="https://example.com/xmlrpc.php?rsd"
/>

A compatible application can retrieve that RSD document and inspect the available APIs.

For the RSD mechanism itself, see What Is the RSD Tag in WordPress?.

How WordPress adds the REST API to RSD

WordPress uses:

rest_output_rsd()

to add the REST API URL to the RSD document.

The WordPress Developer Resources describe this function as adding the REST API URL to the WordPress RSD endpoint.

An RSD response can therefore include something similar to:

<api
    name="WP-API"
    blogID="1"
    preferred="false"
    apiLink="https://example.com/wp-json/"
/>

The official REST discovery documentation shows this WP-API entry in its RSD example.

Why is the REST API advertised through XML-RPC-era discovery?

Because WordPress prioritizes compatibility.

RSD was originally designed around remote publishing APIs such as XML-RPC.

When WordPress introduced the REST API, it could also expose the newer interface to clients that already understood RSD.

The flow becomes:

Frontend page
↓
RSD link
↓
xmlrpc.php?rsd
↓
RSD document
↓
WP-API entry
↓
REST API

This works, but it requires more steps than modern discovery methods.

RSD is not the preferred REST discovery method

The WordPress REST API handbook describes RSD as the least-preferred primary discovery method.

The client must:

  1. request the webpage;
  2. parse its HTML;
  3. find the RSD link;
  4. request the RSD XML document;
  5. parse that XML;
  6. find the WP-API entry.

By comparison, an HTTP Link header can expose the REST API root immediately.

For the broader relationship between these systems, see RSD and WordPress Discovery Endpoints, Explained.

The REST API root is itself discoverable

Once a client reaches:

/wp-json/

the REST API root acts as another discovery layer.

It can expose information about:

  • registered namespaces;
  • routes;
  • authentication capabilities;
  • site information;
  • available API functionality.

Typical namespaces can include:

wp/v2
oembed/1.0

Plugins can add their own namespaces, such as:

plugin-name/v1

REST namespaces can reveal installed functionality

This does not necessarily expose sensitive information, but namespaces can provide clues about the site’s architecture.

For example:

wp/v2
woocommerce/v3
plugin-name/v1
custom-app/v1

can indicate which application features are available.

This is why REST discovery is sometimes discussed in connection with fingerprinting.

See How Attackers Fingerprint WordPress Sites.

Route discovery is not a security boundary

A secure REST endpoint should remain secure even when its URL is completely known.

The correct model is:

Known endpoint
+
unauthorized requester
=
request denied

Trying to hide:

/wp-json/plugin-name/v1/private-data

is not a substitute for implementing an appropriate:

permission_callback

or another authorization mechanism.

The official Routes and Endpoints documentation explains how REST routes and permission callbacks should be registered.

Hypermedia discovery inside the REST API

WordPress’s discovery architecture continues after a client enters the REST API.

REST responses can contain:

_links

and:

_embedded

properties.

The official REST API Linking and Embedding documentation explains that WordPress uses hyperlinks throughout the API to improve discoverability and browsability.

What can REST _links contain?

Depending on the resource, REST responses can link to related resources such as:

  • the author;
  • categories;
  • tags;
  • collections;
  • attachments;
  • parent resources;
  • other related endpoints.

A simplified post response might conceptually include:

{
    "id": 123,
    "link": "https://example.com/my-post/",
    "_links": {
        "author": [
            {
                "href": "https://example.com/wp-json/wp/v2/users/4"
            }
        ],
        "wp:term": [
            {
                "href": "https://example.com/wp-json/wp/v2/categories"
            }
        ]
    }
}

This makes the API itself navigable.

External discovery vs. internal API discovery

WordPress effectively has two discovery stages.

Stage 1: find the API

HTML
HTTP headers
RSD
↓
REST API root

Stage 2: navigate the API

/wp-json/
↓
namespaces
↓
routes
↓
resources
↓
_links
↓
related resources

This is a much richer architecture than a single wp-json URL.

How WordPress generates the REST API root URL

WordPress uses:

get_rest_url()

rather than blindly concatenating:

home_url() . '/wp-json/'

The official get_rest_url() reference retrieves the REST URL according to the current installation and permalink configuration.

This matters because WordPress can use different REST URL formats.

Pretty permalink REST URLs

With normal pretty permalinks, the API root is usually:

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

A posts collection might be:

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

REST URLs without pretty permalinks

WordPress can also use the:

rest_route

query parameter.

Conceptually:

https://example.com/?rest_route=/

or:

https://example.com/?rest_route=/wp/v2/posts

This is another reason simply blocking:

/wp-json/

at one URL pattern is not always equivalent to properly restricting WordPress REST access.

REST discovery and the Block Editor

The REST API is not merely an optional interface for third-party developers.

Modern WordPress itself relies heavily on it.

The official REST API handbook identifies the API as foundational to the Block Editor.

REST requests are involved in workflows such as:

  • retrieving post data;
  • saving content;
  • working with taxonomies;
  • working with media;
  • loading editor settings;
  • plugin integrations;
  • site editing functionality.

Before restricting access, see What Depends on the WordPress REST API.

Removing discovery usually does not break the Block Editor

There is an important difference between:

remove frontend REST discovery metadata

and:

reject REST API requests

Internal WordPress applications do not necessarily need to discover the API through the frontend <link rel="https://api.w.org/"> element.

Removing that public discovery signal is therefore much narrower than globally blocking REST access.

Why WordPress advertises the same API more than once

The different methods serve different types of clients.

HTML link discovery

Useful for:

  • browser JavaScript;
  • HTML parsers;
  • clients without convenient access to response headers.

HTTP Link headers

Useful for:

  • HTTP-native clients;
  • applications that want discovery without parsing HTML;
  • software following standardized web linking behavior.

RSD

Useful primarily for:

  • legacy publishing applications;
  • software already implementing XML-RPC discovery.

REST API root

Useful once the client already knows where the API is.

Hypermedia links

Useful for discovering related resources while navigating the API.

WordPress REST discovery vs. RSS discovery

Both use machine-readable links, but their purposes are different.

REST discovery:

<link
    rel="https://api.w.org/"
    href="/wp-json/"
/>

RSS discovery:

<link
    rel="alternate"
    type="application/rss+xml"
    href="/feed/"
/>

REST points applications toward structured API resources.

RSS points feed readers toward syndicated content.

See How WordPress Advertises RSS Feeds by Default.

WordPress REST discovery vs. oEmbed discovery

WordPress can also output links such as:

<link
    rel="alternate"
    type="application/json+oembed"
    href="..."
/>

Those links advertise an embeddable representation of a page.

REST API discovery advertises general API resources.

oEmbed discovery advertises embedding functionality.

For that subsystem, see WordPress oEmbed Privacy and Security, Explained.

WordPress REST discovery vs. RSD

RSD is a discovery document that can advertise multiple publishing APIs.

REST discovery can point directly at the REST root.

Compare:

Modern REST discovery

HTML or HTTP response
↓
/wp-json/


RSD discovery

HTML
↓
/xmlrpc.php?rsd
↓
RSD XML
↓
WP-API
↓
/wp-json/

RSD therefore adds another discovery layer.

WordPress REST discovery vs. shortlinks

Both can appear as <link> elements in wp_head, but their purposes are unrelated.

A shortlink advertises another URL for the same content:

<link
    rel="shortlink"
    href="https://example.com/?p=123"
/>

REST discovery advertises a machine-readable interface.

See What Is the WordPress Shortlink, and Do You Need It?.

Does REST API discovery expose WordPress?

It provides a clear WordPress fingerprint.

Signals such as:

https://api.w.org/
/wp-json/
wp/v2

strongly suggest WordPress.

However, removing those signals does not make WordPress undetectable.

Other fingerprints can include:

  • /wp-content/;
  • /wp-includes/;
  • theme assets;
  • plugin assets;
  • RSD;
  • XML-RPC;
  • WordPress-generated markup;
  • login behavior;
  • feeds;
  • known HTTP responses.

Is REST API discovery a security vulnerability?

No.

Advertising an API endpoint is not inherently a vulnerability.

The security question is:

What does that endpoint allow an unauthorized user to access or modify?

A correctly protected endpoint remains protected even if its URL is public.

Public REST content is not automatically private data exposure

WordPress intentionally exposes some public content through REST.

If a post is already publicly available at:

https://example.com/my-post/

its public fields may also be available through:

/wp-json/wp/v2/posts/123

That does not automatically constitute a data leak.

Private fields and privileged operations should instead be protected through authentication, context handling and capability-based authorization.

Discovery is not authorization

This distinction deserves repeating because many WordPress security recommendations collapse the two concepts.

Discovery asks:

Where is the API?


Authentication asks:

Who are you?


Authorization asks:

May you perform this action?

Removing:

<link rel="https://api.w.org/">

only affects the first question.

Should you remove REST API discovery?

There is no universal requirement.

Removing it can make sense when:

  • automatic external API discovery is unnecessary;
  • the site wants cleaner frontend metadata;
  • you want to reduce passive WordPress fingerprinting signals;
  • known integrations already use explicitly configured REST URLs.

Keeping it can make sense when:

  • external applications discover WordPress dynamically;
  • frontend JavaScript relies on discovery;
  • the site deliberately exposes its REST interface;
  • you want standards-based API discoverability.

How to remove the REST API link from wp_head

If your objective is only to remove HTML REST discovery, WordPress allows the callback to be detached:

add_action(
    'after_setup_theme',
    function () {
        remove_action(
            'wp_head',
            'rest_output_link_wp_head',
            10
        );
    }
);

This removes the frontend callback responsible for generating the REST discovery links in the document head.

It does not disable:

/wp-json/

What exactly disappears?

The root discovery element can disappear:

<link
    rel="https://api.w.org/"
    href="https://example.com/wp-json/"
/>

and resource-specific JSON discovery generated by the same function can disappear as well:

<link
    rel="alternate"
    title="JSON"
    type="application/json"
    href="https://example.com/wp-json/wp/v2/posts/123"
/>

What does not disappear?

Removing rest_output_link_wp_head() alone does not necessarily remove:

  • the REST API itself;
  • the HTTP Link header;
  • RSD REST advertising;
  • REST namespaces;
  • REST routes;
  • plugin REST endpoints;
  • REST authentication;
  • Block Editor REST communication.

Removing the HTTP REST Link header

If the objective is broader discovery cleanup, the separate:

rest_output_link_header()

callback must also be considered.

This is separate because HTML output and HTTP headers are fundamentally different response layers.

Do not assume a page-source inspection reveals everything WordPress advertises.

Removing RSD discovery separately

If RSD remains enabled, the site can continue advertising its REST API through:

/xmlrpc.php?rsd

Removing the frontend RSD link itself can be done through:

remove_action( 'wp_head', 'rsd_link' );

But that still does not automatically disable the RSD endpoint or REST API functionality.

The complete relationship is covered in RSD and WordPress Discovery Endpoints, Explained.

Do not disable the REST API just to remove discovery links

If the goal is:

remove unnecessary metadata

then changing actual REST permissions is unnecessary.

Conversely, if the goal is:

protect sensitive REST data

then hiding discovery is insufficient.

Use the appropriate control for the actual objective.

Restricting REST API access is a separate operation

WordPress provides:

rest_authentication_errors

for REST authentication policies.

The official rest_authentication_errors documentation explains how authentication errors can be returned before REST requests continue.

A site could, for example, require authentication for selected requests.

That changes access.

Removing REST discovery links does not.

For the practical distinction, see Hiding vs. Restricting the WordPress REST API and How to Restrict the WordPress REST API.

REST discovery and user enumeration

The REST API can expose public author resources depending on WordPress configuration and permissions.

Because author archives can also receive resource-specific REST discovery, a frontend author page can have a relationship with:

/wp/v2/users/USER_ID

Removing the generic REST discovery link does not necessarily solve user enumeration.

That should be treated as a separate exposure problem.

See WordPress REST API User Enumeration, Explained.

REST discovery and custom plugins

Plugins can register their own REST namespaces and routes.

For example:

/wp-json/example/v1/orders
/wp-json/example/v1/settings
/wp-json/example/v1/search

Removing the frontend WordPress discovery link does not remove those routes.

Once the REST API root is known, registered namespaces can still make functionality discoverable.

Custom REST endpoints need their own permissions

A secure custom endpoint should include an explicit access policy.

For example:

register_rest_route(
    'example/v1',
    '/settings',
    array(
        'methods'  => 'GET',
        'callback' => 'example_get_settings',
        'permission_callback' => function () {
            return current_user_can( 'manage_options' );
        },
    )
);

The endpoint remains discoverable, but unauthorized users cannot retrieve the protected data.

That is a stronger security design than depending on an obscure URL.

REST discovery and Application Passwords

External software can authenticate to WordPress using Application Passwords.

The official Application Passwords documentation describes them as revocable credentials intended for programmatic access.

An integration using a known REST endpoint and Application Password does not need the public frontend REST discovery tag on every request.

Removing discovery and disabling external REST authentication are therefore independent choices.

Does removing REST discovery improve performance?

Not meaningfully.

The discovery output consists primarily of very small pieces of metadata.

Removing one or two:

<link>

elements does not materially improve:

  • Largest Contentful Paint;
  • Interaction to Next Paint;
  • server response time;
  • JavaScript execution;
  • database performance.

REST discovery cleanup should not be marketed as a serious performance optimization.

Can the REST API itself affect performance?

Yes, but that is a different issue.

Heavy REST traffic can consume resources when:

  • endpoints execute expensive queries;
  • large collections are requested repeatedly;
  • uncached REST responses are generated frequently;
  • plugins implement inefficient callbacks;
  • automated systems abuse endpoints.

That is an endpoint-performance or traffic-management problem, not a discovery-link problem.

Does removing REST discovery improve SEO?

Normally no meaningful SEO improvement should be expected.

The REST discovery link is not equivalent to:

  • a canonical URL;
  • a robots directive;
  • an XML sitemap;
  • structured data;
  • internal navigation.

Removing it is primarily technical cleanup.

For comparison, see WordPress Canonical URLs, Explained.

Do not remove canonical links together with REST cleanup

WordPress head output contains many unrelated elements.

For example:

<link rel="canonical" ...>

serves a search-engine URL consolidation purpose.

It should not be removed simply because REST, RSD or shortlink discovery is being cleaned up.

See WordPress Head Tags You Can Safely Remove.

REST discovery and WordPress head cleanup

A broader cleanup might include evaluating:

  • RSD;
  • Windows Live Writer metadata;
  • REST discovery;
  • RSS discovery;
  • shortlinks;
  • WordPress generator output;
  • oEmbed discovery.

But each should be handled separately.

For the complete process, see Cleaning Up WordPress’s Default Head Output.

How TheOneWP handles REST API discovery

TheOneWP separates REST API discovery from actual REST API access.

This distinction matters because the two controls solve different problems.

TheOneWP’s REST discovery cleanup targets signals such as:

<link rel="https://api.w.org/" ...>

HTTP Link discovery

without pretending that removing those signals makes:

/wp-json/

inaccessible.

The result can be summarized as:

Disable REST API Links
→ remove discovery metadata

Disable / Restrict REST API
→ change access policy

This is also consistent with the security model described in WordPress REST API Security Basics.

Why keep the controls separate?

Because a website may want any of these configurations:

REST API available and advertised

Discovery
→ enabled

REST API
→ enabled

REST API available but not advertised

Discovery
→ disabled

REST API
→ enabled

REST API advertised but protected

Discovery
→ enabled

Public access
→ restricted

Authenticated access
→ enabled

REST API heavily restricted

Discovery
→ optional

REST API
→ restricted according to site requirements

Combining every scenario into one switch would make precise WordPress configuration unnecessarily difficult.

When REST discovery is useful

Keeping discovery makes sense when the site intentionally wants applications to locate its API automatically.

Examples include:

  • public data services;
  • headless WordPress sites;
  • custom applications;
  • external publishing platforms;
  • browser-side applications;
  • integration platforms;
  • API-first projects.

When REST discovery may be unnecessary

A traditional brochure or company website may have:

  • no external REST consumers;
  • no headless frontend;
  • no automatic API discovery requirement;
  • no integration that parses frontend discovery metadata.

In that environment, removing REST discovery can be reasonable while retaining the REST API for WordPress itself.

How to audit WordPress REST API advertising

1. Inspect the page source

Search for:

https://api.w.org/

You may find:

<link
    rel="https://api.w.org/"
    href="https://example.com/wp-json/"
/>

2. Search for JSON resource links

Look for:

type="application/json"

and inspect whether the URL points to a specific REST resource.

3. Inspect HTTP response headers

Look for:

Link:

headers containing:

rel="https://api.w.org/"

or:

rel="alternate"

with:

type="application/json"

4. Inspect RSD

If the page advertises:

xmlrpc.php?rsd

retrieve the document and check for:

name="WP-API"

5. Request the API root

Visit:

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

or, where appropriate:

https://example.com/?rest_route=/

6. Inspect namespaces

Review which namespaces are registered by:

  • WordPress core;
  • plugins;
  • custom code.

7. Test multiple frontend page types

Resource-specific discovery can vary according to context.

Check:

  • a post;
  • a page;
  • a category;
  • a tag;
  • a custom taxonomy term;
  • an author archive;
  • a custom post type.

How to test after removing REST discovery

Clear caches

Clear:

  • page cache;
  • server cache;
  • CDN cache;
  • optimization-plugin cache.

Recheck HTML

Verify that:

rel="https://api.w.org/"

has disappeared if that was your intended change.

Check HTTP headers separately

Do not assume the absence of the HTML link means the header disappeared too.

Check RSD separately

If RSD remains active, determine whether it still contains the WP-API entry.

Request /wp-json/ directly

If you only removed discovery, the API should generally continue to function.

Test the Block Editor

Create, edit and save a post.

Test plugin interfaces

Check JavaScript-heavy administration screens and other functionality that can depend on REST.

Test external integrations

Verify:

  • mobile apps;
  • headless frontends;
  • automation;
  • custom clients;
  • Application Password integrations.

Common mistakes with WordPress REST API advertising

Assuming /wp-json/ is the only discovery mechanism

WordPress can advertise REST through HTML, headers and RSD as well.

Removing the api.w.org link and assuming REST is disabled

The REST API can remain completely functional.

Inspecting page source but ignoring response headers

HTTP Link headers are a separate discovery layer.

Ignoring resource-specific JSON links

WordPress can advertise both the API root and the JSON representation of the current resource.

Ignoring RSD

Legacy discovery can still advertise WP-API.

Assuming every post type has a REST resource

Custom post types need appropriate REST exposure, including show_in_rest.

Blocking /wp-json/ to remove an HTML link

That changes actual functionality to solve a discovery problem.

Removing REST because it identifies WordPress

Many other fingerprints remain.

Treating public API content as automatically sensitive

Public WordPress content can intentionally have public JSON representations.

Hiding an endpoint instead of protecting it

Known routes still need authentication and authorization when they expose sensitive functionality.

Applying global REST restrictions without testing Gutenberg

Modern WordPress uses the REST API extensively.

Assuming REST discovery has meaningful performance cost

The small discovery metadata itself is not a significant performance issue.

Removing every WordPress head link together

REST links, canonical URLs, feeds, oEmbed and other links have different purposes.

WordPress REST API advertising checklist

  • Know that the main REST root is usually /wp-json/.
  • Remember that WordPress can also use ?rest_route=/.
  • Understand what get_rest_url() does.
  • Recognize the rel="https://api.w.org/" discovery link.
  • Know that rest_output_link_wp_head() generates HTML REST discovery.
  • Understand that the same function can advertise the current JSON resource.
  • Know that WordPress uses rest_get_queried_resource_route() to identify frontend resources.
  • Understand REST discovery for singular posts and pages.
  • Understand REST discovery for categories and tags.
  • Understand REST discovery for custom taxonomy terms.
  • Understand REST discovery for author archives.
  • Check whether custom post types have show_in_rest enabled.
  • Recognize HTTP REST discovery through Link headers.
  • Know that rest_output_link_header() sends REST discovery headers.
  • Remember that the HTTP header can also advertise the current JSON resource.
  • Inspect both HTML and HTTP headers during an audit.
  • Understand that RSD can advertise WP-API.
  • Know that RSD is not the preferred modern REST discovery mechanism.
  • Inspect /xmlrpc.php?rsd when auditing discovery.
  • Inspect the REST API root itself.
  • Review registered namespaces.
  • Review routes added by plugins.
  • Understand _links and REST hypermedia discovery.
  • Do not confuse discovery with authentication.
  • Do not confuse authentication with authorization.
  • Do not treat hidden endpoints as protected endpoints.
  • Protect sensitive custom routes with proper permission callbacks.
  • Do not globally block REST merely to remove frontend metadata.
  • Check Block Editor dependencies before restricting REST.
  • Check Site Editor dependencies.
  • Check plugin administration interfaces.
  • Check headless frontend dependencies.
  • Check mobile applications.
  • Check external automation.
  • Check Application Password integrations.
  • Do not expect meaningful performance improvements from removing REST discovery links.
  • Do not expect REST discovery removal to make WordPress undetectable.
  • Do not remove canonical URLs as part of REST cleanup.
  • Evaluate RSD separately.
  • Evaluate RSS discovery separately.
  • Evaluate oEmbed separately.
  • Evaluate shortlinks separately.
  • Clear caches after changing REST discovery.
  • Test several frontend contexts after changes.
  • Request /wp-json/ directly after discovery cleanup.
  • Confirm whether you intended to hide discovery or restrict access before making changes.

Related guides

Final recommendation

WordPress advertises its REST API through several complementary discovery mechanisms rather than relying on a single /wp-json/ URL.

The main layers are:

HTML API-root discovery
+
HTML resource discovery
+
HTTP Link headers
+
RSD
+
REST root discovery
+
hypermedia links inside API responses

This gives browsers, external applications and API clients several ways to find the correct API URL and navigate from normal WordPress frontend resources to their JSON representations.

For modern applications, HTTP and HTML REST discovery provide relatively direct paths toward the API.

RSD remains available primarily as a compatibility mechanism for clients built around older XML-RPC discovery workflows.

Once a client reaches the API itself, REST namespaces, routes and hypermedia links continue the discovery process internally.

The most important operational distinction is that none of this should be confused with actual access control.

Removing:

<link rel="https://api.w.org/" ...>

does not disable:

/wp-json/

Removing the HTML discovery element does not automatically remove HTTP Link headers.

Removing both does not automatically remove RSD advertising.

And removing every discovery signal still does not provide authorization for sensitive REST routes.

If the goal is cleaner WordPress output or reduced passive discovery, remove only the discovery mechanisms the site does not need.

If the goal is protecting sensitive REST data, implement authentication and capability-based authorization instead.

If the goal is restricting public REST access entirely, first identify what depends on the API and test the Block Editor, plugins, frontend JavaScript and external integrations before deploying the restriction.

The right REST configuration is therefore not simply:

visible
or
hidden

It is a deliberate combination of:

discovery
+
access
+
authentication
+
authorization
+
actual site requirements

Once those layers are treated separately, WordPress’s REST API architecture becomes considerably easier to control without removing functionality the site still needs.

Simplify your WordPress stack

A modular WordPress toolkit. 104 focused tools.

Ultimately, you can build cleaner workflows, maintain fewer plugins and enable only the features each website actually needs.