Description
AI crawlers (GPTBot, ClaudeBot, PerplexityBot, Google-Extended and others) do
not run JavaScript. They read the raw HTML your server returns and move on. So
schema added by client-side JavaScript is invisible to them.
This plugin fetches the schema.org JSON-LD that Baseline Labs has already
generated for each of your pages and injects it server-side into the page
, inside a <script type="application/ld+json"> block – exactly where a
non-JavaScript crawler will find it.
It is a thin reflector: it does not generate schema and has no schema logic of
its own. Baseline Labs generates and stores the schema; the plugin simply
reflects it into your HTML.
It never cloaks. The same schema is served to every visitor, human or bot.
Serving crawlers different content than people is against search-engine
guidelines and is not something this plugin will ever do.
What it does
- Hooks
wp_headand injects the JSON-LD for the current URL. - Caches each page’s schema (12–24h) so the API is only called on a cache miss,
and clears that cache within minutes when Baseline regenerates your schema. - Corrects or supplies your page titles and descriptions, when you switch that
on in your Baseline account. - Fails open: if the API is unreachable or has no schema for a page, the plugin
emits nothing and never breaks the page. - Reports injection failures back to your Baseline account so you can see them.
Requirements
- A free Baseline Labs account and an API key. Schema generation and injection
are included on the free plan for one site; paid plans raise the page limit
and refresh your schema more often.
External services
This plugin talks to Baseline Labs (https://baselinelabs.ai) – its whole
purpose is to connect your site to that account. Nothing is sent until you
connect the site with your API key, and the traffic reporting in items 2, 3
and 6 stays off until you switch it on under Settings Baseline
Connector. Every call it makes:
- Fetching your schema. On a cache miss, one request per page asking for
the JSON-LD Baseline generated for that URL. Sends the domain and path. -
Reporting AI-bot requests. A batch, at most every few minutes via
WP-Cron, of the AI crawler requests your site received: user agent, path,
status, timestamp. No full IP addresses and nothing identifying your
human visitors. Only requests whose user agent looks like a known AI bot
are ever included, plus requests for paths that only automated scanners ask
for (files like.env,.gitandwp-login.php, whatever the user agent
claims to be – nothing is recorded at all while you are signed in), plus
visits that arrived from a known AI answer engine (ChatGPT, Perplexity and
the like), for which the same fields plus the referring site are sent and
nothing else.A bot request may also carry one true/false flag saying whether it came
from an IP range that crawler publicly announces, and the network block
the request came from. Neither sends us a visitor’s address. The
published ranges are downloaded to your server (item 10) and the address is
compared against them inside PHP; what leaves your site is one true or
false plus the surrounding block – the first three numbers of an IPv4
address with the last replaced by a zero (203.0.113.0/24, a block of 256
addresses), or the equivalent/48for IPv6. The address itself is never
written to your database, never put in a batch, never logged, and never
hashed either – a hashed address is still an identifier. A block identifies
a network rather than a machine, and it is what lets your dashboard tell
one crawler’s run of visits from another’s and check that a request
claiming to be Googlebot really came from Google.Off by default; switch it on or off under Settings Baseline Connector.
- Confirming delivery. Once a day, the plugin asks Baseline how many bot
hits it has actually received for this site in the last 24 hours, and warns
you if the answer is none while the plugin believes it has been sending
them. Sends your domain and API key; returns counts only. - Setting up. When you click Connect & verify this site (and only
then), the plugin registers the domain with your account, collects its
tokens and asks Baseline to verify ownership. Verifying means Baseline
fetches your homepage and looks for the tag this plugin prints there. Two
things happen alongside it, both only on that click: the plugin clears your
site’s page cache first (WP Rocket, LiteSpeed, W3 Total Cache, WP Super
Cache, WP-Optimize, WP Fastest Cache, Cloudflare – whichever you run), so
Baseline is not handed a copy of your homepage saved before the plugin was
installed; and the plugin answers a small read-only address of its own,
/wp-json/baseline/v1/verify, which Baseline can read when your cache is
still serving the old page. That address returns only what the tag in your
page already says – the same ownership token, the plugin version, and which
features are switched on. No key, no settings, no visitor data, and nothing
there can change anything. - Reporting its own errors. If injection or delivery fails, a short
diagnostic goes to your account so the failure is visible on the Baseline
side too. No page content and no visitor data. - Measuring visits from AI answer engines. This is the one call your
visitors’ browsers make rather than your server. While reporting is on,
the plugin adds a small script tag to your pages; it records the page
visited and the referring site, so you can see when ChatGPT, Perplexity or
Google’s AI surfaces send someone to you. No IP address is stored, no
cookie is set, and no cross-site profile is built – the visitor id is a
random string kept in the browser’s local storage for your domain alone.
Controlled by the same opt-in toggle as bot reporting. Where your visitors
must consent to analytics, you are responsible for collecting it. - Checking for a cache in front of your site. At most twice a day, the
plugin requests your own homepage from your own server to see whether a
page cache answers before WordPress does. It goes to your site, not to us;
only the resulting one-word verdict is sent with the next bot batch, so we
can tell you honestly whether your crawler counts are complete. -
Syncing your site profile and published pages. Once a day, the plugin
sends a description of the site so your dashboard can compare what you
have published against what AI crawlers actually read: WordPress and PHP
version, language, permalink style, whether search engines are
discouraged, the active theme and any active SEO plugin, plus the list of
published, public pages (path, title, type, published and modified
dates). Never drafts, never private content, never post bodies – only
facts already visible to anyone with a browser. Same toggle as bot
reporting;wp baseline sync-siteor the settings button runs it on
demand.Publishing or editing a post also sends that one page’s entry down the
same route, so Baseline can refresh its schema straight away instead of
re-reading your whole site on a timer. Same fields, one row, at most once
every thirty seconds, and it happens after the page you were saving has
already been handed back to you. If it does not get through, the daily
sync above carries it. - Fetching a page’s title and description. Only while metadata
correction or generation is switched on in your Baseline account. On a
cache miss, one request per page asking what the title and description for
that URL should be, and it sends the same domain and path as item 1 and
nothing else. Turn either switch off in your account and the plugin stops
asking. The answer is cached the same way your schema is, and a page
Baseline has nothing to say about is remembered as such so it is not asked
about again on every load. - Downloading the AI-agent list. About once a day the plugin fetches the
list of user agents that identify AI crawlers, so it knows what to look
for without asking us about each request. The same file carries the IP
ranges those crawlers publish and the answer-engine sites worth
recognising as referrers. It is a list of names and numbers, not code –
nothing downloaded here is ever executed. It is anonymous – no site
URL, no API key, no query string. The download only ever comes to you;
nothing about your visitors goes out on it.
Privacy policy: https://baselinelabs.ai/privacy
Terms: https://baselinelabs.ai/terms
Screenshots


Installation
- Upload the plugin and activate it.
- Go to Settings Baseline Connector.
- Paste your Baseline API key and save.
- Click Connect & verify this site.
- That’s it – schema appears in your pages as Baseline generates it.
WP-CLI:
wp baseline set-key bl_xxx && wp baseline enable && wp baseline connect
FAQ
-
Does this slow down my site?
-
On a cache miss the plugin makes one short (max 2s) request to fetch a page’s
schema, then caches it for 12–24 hours. Warm page loads do no network work. -
Where is my API key stored?
-
Encrypted at rest in the WordPress options table, using a key derived from your
site’s own secret salts. (If the libsodium PHP extension is unavailable it falls
back to base64 obfuscation – install libsodium for real encryption.) Anyone with
both your database and yourwp-config.phpcan still read it; that is inherent
to WordPress.
Reviews
There are no reviews for this plugin.
Contributors & Developers
“Baseline Labs Connector” is open source software. The following people have contributed to this plugin.
ContributorsTranslate “Baseline Labs Connector” into your language.
Interested in development?
Browse the code, check out the SVN repository, or subscribe to the development log by RSS.
Changelog
2.12.3
- Traffic reporting is now opt-in: off on a new install until you switch it on
in Settings. Sites that already had it on keep it. - The visitor tracker no longer falls back to a cookie.
- The tracker script is enqueued through WordPress instead of printed by hand.
- Class names carry the full Baseline_Connector_ prefix.
2.12.2
- Performance: a scanner sweeping your site for hundreds of addresses at once
can no longer tie up your server while the plugin records it. Each request
used to wait up to two seconds to record itself after the page was sent;
scanner requests now never wait, and are recorded once per address per
minute, up to 30 addresses a minute. AI crawler visits wait at most a fifth
of a second. On a small hosting plan that is the difference between a scan
your visitors never notice and one that uses up every worker the site has. - During such a burst some scanner requests, and occasionally a crawler visit,
go unrecorded rather than slow your site down.
2.12.1
- Security: a corrected page title is now escaped before WordPress prints it
into your page’s title tag, and any markup is removed from corrected titles
and descriptions. WordPress prints a title supplied this way exactly as it
receives it, so the plugin now does the escaping itself. - Security: the schema written into your pages is encoded so that no text
inside it can end the script tag it sits in, whatever the text says. - Missing pages no longer ask Baseline for schema or metadata. A page that
returns “not found” has none, and scanners probing hundreds of missing
addresses were costing a lookup and a stored entry for each one.
2.12.0
- Each crawler request now tells you which network it came from, so your
dashboard can say whether a run of visits was one crawler or several, and
whether something calling itself Googlebot really came from Google. Your
visitors’ addresses still never leave your site: the address is shortened on
your own server to the surrounding block of 256 addresses, which names a
network rather than a machine, and only that block is sent. - Scanners are reported now, so their 404s stop making your site look broken.
Every site on the internet is swept for files like.env,.gitand
wp-login.php by software that never reads a page, and it usually claims to
be an ordinary browser – so it was invisible here while its missing-page
errors counted against you. Requests for those paths are reported whatever
they claim to be, and your dashboard files them as suspicious traffic rather
than as readers. Your own visits to your login page are not included: while
you are signed in, none of this is recorded.
2.11.0
- If Baseline is unreachable, your pages stop waiting for it. Each page load
already gave up after two seconds, but every page whose stored copy had
expired paid those two seconds again. After three failed attempts the plugin
now stops calling for two minutes and serves the schema it last held, so an
outage at our end costs your visitors nothing after the first few seconds.
It reconnects on its own.
2.10.0
- Publishing or editing a post now tells Baseline immediately, so your schema
is refreshed for that page within minutes instead of on the next full crawl
of your site. It is one small message about the one page, sent after your
save has already finished, at most once every thirty seconds. - Because Baseline now knows which pages changed, it stops re-reading the ones
that did not. A large site was being fetched thousands of times a day to
find a handful of edits; it is a handful of requests a day now, plus one
full pass a week to catch theme and menu changes. - Fixed: when Baseline regenerated your schema or corrected a title, the
plugin cleared its own copy but not your page cache, so pages already stored
by WP Rocket, LiteSpeed and the like kept serving the old version until they
expired on their own. Your page cache is now cleared too, at most once every
ten minutes.
2.9.1
- On a site running no SEO plugin, a page whose description Baseline supplies
now carries exactly one description tag – ours. Before this, a theme that
printed its own left the page with two.
2.9.0
- Your page titles and descriptions can now be corrected or filled in by
Baseline. Switch it on in your Baseline account under Rolling metadata; the
plugin asks for each page’s title and description and prints what comes back,
through Yoast, Rank Math or All in One SEO where one of those is running, and
on its own where none is. Settings Baseline Connector shows whether it is
on. There is no switch here, because your account is where you chose it. - A site that no AI crawler has visited yet now checks in with Baseline once an
hour. Everything the server tells this plugin – that your schema was
regenerated, that your metadata changed, which of the above is switched on –
rides back on the batch of crawler requests it sends, so a site with no
crawler traffic to send never heard any of it. - The daily site sync now includes each page’s own description, so Baseline
compares its suggestions against what your pages really say rather than
against a copy read through your page cache.
2.8.0
- Verification no longer fails on a cached site. Baseline verifies your site by
reading a tag this plugin prints in your pages, and a page cache was handing
it the copy of your homepage saved before the plugin was installed – so a
correctly installed plugin reported “tag not found”, repeatedly. The plugin
now clears your page cache before verifying, offers Baseline a second address
no cache stores, and says plainly that a cache or Cloudflare can take up to
half an hour rather than showing a red failure. - Regenerated schema appears within minutes instead of up to a day. Each page’s
schema was cached for 12 to 24 hours with nothing to tell it that Baseline
had produced a new version, so a regeneration was invisible for half a day.
The plugin is now told, and clears the cache when it happens – and after the
plugin itself is updated. - The visitor-measurement script is now excluded from JavaScript optimisation
in WP Rocket, LiteSpeed Cache and Autoptimize, and carries its reporting
address on the tag. A minifier that copied the script onto your own domain,
combined with delayed JavaScript, could leave every visit unrecorded with
nothing to show for it.
2.7.0
- Updates now come from the WordPress.org plugin directory like every other
plugin you have installed. The self-updater this replaces fetched new
versions from our own server, which the directory does not permit and which
you should not have to trust us about. If you installed an earlier copy from
a zip rather than from the directory, install it once from the directory to
keep receiving updates. - Request data read from the server (user agents, referrers, query strings) is
now unslashed and sanitised at the point it is read rather than where it is
used.
2.6.0
- Crawler hits are now checked against the IP ranges each AI company publishes,
so “GPTBot read you 400 times” is a claim someone verified rather than a user
agent string taken at its word. No IP address leaves your site or is stored
anywhere – the check happens on your server against a list downloaded to it,
and only a true/false result is reported. - People who arrive from ChatGPT, Perplexity and other AI answer engines are
now recorded by your server as well as by the tracker script, so visitors
with JavaScript blocked stop going uncounted. - When a page cache is in front of WordPress, the plugin now names the layer
and tells you exactly why it hides traffic – whether the page is answered by
your webserver, by a drop-in before plugins load, or at a CDN edge – instead
of one generic sentence. If your cache is set to let crawlers straight
through, it says that too, because then your bot counts are nearly complete
even though the cache is there.
2.5.0
- Site Intelligence. Once a day the plugin now sends your site profile
(WordPress/PHP version, language, permalink style, the “discourage search
engines” flag, active theme and SEO plugins) and the list of published
pages with their titles and modified dates. Your Baseline dashboard uses
it to show which published pages AI crawlers have never read, which ones
you have edited since they last crawled, and to warn you when a WordPress
setting is quietly hiding you from search and AI engines. Public facts
only – no drafts, no private content, no post bodies.
2.4.0
- One install now covers both halves of the picture. As well as recording the
AI crawlers that read your site, the plugin measures the people AI answer
engines send you – no second snippet to paste. It is the same toggle, and
the same no-IP, no-cookie promise. - Cache detection now runs by itself, twice a day. It only ever ran when
somebody opened the settings screen, so most sites reported “we could not
determine whether a cache sits in front of you” forever – and your crawler
counts were caveated more heavily than they needed to be.
2.3.2
- A fresh install shows its first schema in minutes, not an hour. The
“no schema yet” result is now cached for 5 minutes instead of 60, and
a successful verification clears the schema cache, so pages viewed
before connecting no longer pin the empty state.
2.3.1
- The settings screen no longer rejects every valid API key. Key validation
now uses an endpoint that accepts API keys; it previously hit a
session-only endpoint, so saving a correct key reported
“validation failed: Not authenticated”.
2.3.0
- Works on a free Baseline account. Schema generation and injection no longer
need a paid plan. - The
baseline-channelmarker is now stored during channel registration, so
it appears even if domain setup fails afterwards. - Detects silent delivery loss. Baseline accepts bot-hit batches without
saying whether the token was recognised, so a wrong token used to discard
every hit while this screen showed “sent”. The plugin now asks once a day
what Baseline actually received, and warns when the two disagree. - Warns when bot reporting is on but the site has no token yet.
2.2.0
- The plugin can now update itself. Before this, an installed copy stayed on
whatever version it was first given – a fix could be shipped and never
reach anyone. - Emits a single unified
baseline-channelmarker carrying ownership,
channel, version and capabilities. A site running only the free bot
reporting previously announced no channel at all, because the old marker
was written alongside the schema and skipped when injection was off.
2.0.0
- Renamed from “MarkupSchema Schema Injector” to “Baseline Connector”.
- WP-CLI namespace is now
wp baseline.wp markupschemastill works as a
deprecated alias and will be removed in the next release. - Default API host is now
https://baselinelabs.ai. Override it with the
BASELINE_CONNECTOR_API_BASE constant inwp-config.php.
1.0.0
- Initial release.
