/wp-json/ URLs in Search Console: REST API endpoints Google found in your page head
/wp-json/ is the WordPress REST API. WordPress links to it from the head of every page and in an HTTP header, so Googlebot requests it. The API answers with an X-Robots-Tag: noindex header, which is why these URLs appear as excluded. They are endpoints, not pages, and the exclusion is correct.
You can leave them alone. If the number is large or the entries bother you, you can remove the links that advertise the API without switching the API off.
Where Google finds the URLs
View the source of any post and its response headers:
curl -s https://example.com/a-post/ | grep -ioE '<link[^>]*(api\.w\.org|oembed)[^>]*>'
curl -sI https://example.com/a-post/ | grep -i "^link:"
A default site prints:
<link rel="https://api.w.org/" href="https://example.com/wp-json/">, the API root.<link rel="alternate" ... href="https://example.com/wp-json/wp/v2/posts/123">, the JSON version of the current post.- Two oEmbed discovery links of the form
/wp-json/oembed/1.0/embed?url=…, one JSON and one XML. - A
Link:response header repeating the API root.
Plugins add their own routes, and front-end scripts that call the API expose further URLs in the page source. Each distinct address becomes an entry in Search Console.
Why they land in different report rows
Check one directly:
curl -sI https://example.com/wp-json/wp/v2/posts/123 | grep -iE "^HTTP|x-robots-tag|content-type"
- Excluded by 'noindex' tag. The usual case. WordPress sends
X-Robots-Tag: noindexwith REST responses. In URL Inspection the detail reads that noindex was detected in the X-Robots-Tag HTTP header. - Blocked due to unauthorized request (401). Endpoints that need a logged-in user, such as
/wp-json/wp/v2/users/me, answer 401 with the coderest_not_logged_in. - Blocked due to access forbidden (403) or Not found (404). Routes restricted by a security plugin, or belonging to a plugin that has since been removed.
- Crawled - currently not indexed. Occasionally, for responses that lack the header, for instance when a caching layer serves the JSON without passing headers through.
None of these indicate a fault in your pages.
The one case to investigate
If a /wp-json/ URL is reported as indexed, something is stripping the noindex header. Compare the headers above with and without your CDN or cache in the path. Fix the cache rule so response headers are preserved, or exclude /wp-json/ from page caching altogether, which is usually the right configuration anyway because API responses are dynamic.
Also look at what public endpoints reveal. /wp-json/wp/v2/users lists the usernames and slugs of authors with published posts. That is a privacy and security consideration more than an SEO one, and restricting it is a job for a security plugin or a small filter, not for robots.txt.
Do not block /wp-json/ in robots.txt
It looks like the obvious fix and it backfires in two ways.
- Google can no longer fetch the endpoint, so it cannot see the
noindexheader. URLs that are linked from your pages can then be reported as indexed, though blocked by robots.txt, which is worse than the status you started with. - Scripts on your pages may call the REST API to load content: forms, product data, block-based features. When Google renders the page, those requests are refused and the content is missing. See robots.txt blocking CSS and JS for how to detect blocked resources.
Reduce discovery instead
If you want fewer of these URLs found, stop announcing them.
In Hydrogen SEO, open Hydrogen SEO → General, expand Crawl cleanup and switch on:
- Remove REST API links: removes the API link from the head and from the
Linkheader. The REST API itself keeps working, so the block editor and plugins are unaffected. - Remove oEmbed discovery links: removes the two oEmbed links. Keep this off if you want your posts to embed as preview cards when pasted into other WordPress sites.
Both are off by default and reversible; they are described under crawl cleanup, with a tag-by-tag explanation in our post on cleaning up the WordPress head.
In code, the equivalents are:
remove_action( 'wp_head', 'rest_output_link_wp_head', 10 );
remove_action( 'template_redirect', 'rest_output_link_header', 11 );
remove_action( 'wp_head', 'wp_oembed_add_discovery_links', 4 );
remove_action( 'wp_head', 'wp_oembed_add_discovery_links' );
Do not disable the REST API itself for visitors unless you know nothing on the front end depends on it. The block editor, many plugins and some themes do.
What changes afterwards
View source and repeat the first curl check: the api.w.org and oEmbed links should be gone, and the Link header should no longer list the API. Existing /wp-json/ entries in Search Console fade as Google stops rediscovering them, over weeks to months. URLs embedded in scripts will continue to be found, and that is fine. There is nothing to validate, and no ranking change to expect: this is tidying.
Common questions
Is it bad that Google crawls my REST API?
No. The requests are few compared with page crawling, and the responses tell Google not to index them.
Can /wp-json/ URLs rank in Google?
Not while they send the noindex header, which WordPress does by default.
Will removing the REST API links break the block editor?
No. The switch removes the link that announces the API, not the API. The editor calls the API by its address.
Should I disable the REST API for security?
Restricting specific sensitive endpoints is reasonable. Disabling the whole API for logged-out visitors breaks features that depend on it, so test carefully.