Title: Palette Data Analyzer
Author: PaletteAgency
Published: <strong>August 29, 2026</strong>
Last modified: August 29, 2026

---

Search plugins

![](https://ps.w.org/palette-data-analyzer/assets/banner-772x250.png?rev=3671377)

![](https://ps.w.org/palette-data-analyzer/assets/icon-256x256.png?rev=3671377)

# Palette Data Analyzer

 By [PaletteAgency](https://profiles.wordpress.org/paletteagencyy/)

[Download](https://downloads.wordpress.org/plugin/palette-data-analyzer.4.20.4.zip)

 * [Details](https://wordpress.org/plugins/palette-data-analyzer/#description)
 * [Reviews](https://wordpress.org/plugins/palette-data-analyzer/#reviews)
 *  [Installation](https://wordpress.org/plugins/palette-data-analyzer/#installation)
 * [Development](https://wordpress.org/plugins/palette-data-analyzer/#developers)

 [Support](https://wordpress.org/support/plugin/palette-data-analyzer/)

## Description

Palette Data Analyzer reads your Google Search Console data and turns it into a 
report you can act on: which queries are growing, which pages sit just off page 
one, where your click-through rate is below what your own site normally achieves
at that position, and which changes are large enough to be real rather than noise.

Every number is produced by a fixed formula, not by a language model. Run the same
file twice and you get the same answer twice.

#### Two ways to get data in

**Upload a file.** Export from Search Console as .xlsx, .csv, or the .zip it hands
you, and upload it. Any date range works. For the full analysis, enable the “Compare”
tab in Search Console so each row carries the previous period too.

**Connect the API with the separate Pro add-on.** The free plugin does not require
an API connection. If you install the separately distributed Palette Data Analyzer
Pro add-on, you can connect your Google account and pull reports automatically.

#### What it measures

Growing and lost queries, page-two opportunities (positions 11-20), top-three opportunities(
positions 4-10), abnormally low CTR, position drops that happen despite rising impressions,
ranking volatility across several archived reports, big movers, position and CTR
distribution by rank bucket, and an overall KPI panel – all feeding one prioritised
action plan.

Two things set the analysis apart. Changes are tested against a Poisson noise band,
so a query going from 10 clicks to 14 is reported as noise rather than 40% growth.
And when your average position moves, the report separates real ranking movement
from a shift in which queries earn impressions – the two look identical in a single
average but call for completely different responses.

#### Related plugin

A direct Search Console API connection, single-page analysis and an optional AI 
summary layer are provided by Palette Data Analyzer Pro, a separately distributed
add-on. This plugin is complete on its own and needs none of them.

### External services

**Google connectivity check** (www.googleapis.com) – contacted only when an administrator
presses the connection-test button on the settings screen. It sends nothing beyond
the request itself, and reports whether this server can reach Google at all.
 [Google Privacy Policy](https://policies.google.com/privacy)

**Google Search Status Dashboard** (status.search.google.com) – an optional public
JSON feed used to label reports with ranking updates. It is disabled by default 
and is contacted only after an administrator enables it on the upload screen. Your
server contacts the service at most once every 12 hours; the plugin does not send
report data, Google credentials, or your site URL. As with any web request, the 
service receives normal connection metadata such as your server IP address.
 [Google Privacy Policy](https://policies.google.com/privacy)

**Chart.js** 4.4.0 – charting library, MIT license.
 File: `assets/js/chart.umd.
min.js` License: `licenses/chartjs-MIT.txt` Source: https://github.com/chartjs/Chart.
js

**Vazirmatn font** 33.0.3 (variable, weights 100-900) – SIL Open Font License 1.1.

File: `assets/fonts/Vazirmatn-Variable.woff2` – full license: `assets/fonts/LICENSE.
txt` Source: https://github.com/rastikerdar/vazirmatn

## Screenshots

[⌊The dashboard: every capability at a glance, the latest report's four KPIs, and
the top five suggested actions.⌉⌊The dashboard: every capability at a glance, the
latest report's four KPIs, and the top five suggested actions.⌉[

The dashboard: every capability at a glance, the latest report’s four KPIs, and 
the top five suggested actions.

[⌊Report header: clicks, impressions, CTR and average position against the previous
period, the last five reports side by side, and the daily trend.⌉⌊Report header:
clicks, impressions, CTR and average position against the previous period, the last
five reports side by side, and the daily trend.⌉[

Report header: clicks, impressions, CTR and average position against the previous
period, the last five reports side by side, and the daily trend.

[⌊Distribution: how queries and pages spread across position buckets, and the click-
through rate your own site actually earns at each bucket. That curve is the benchmark
the low-CTR module judges against, instead of a generic industry table.⌉⌊Distribution:
how queries and pages spread across position buckets, and the click-through rate
your own site actually earns at each bucket. That curve is the benchmark the low-
CTR module judges against, instead of a generic industry table.⌉[

Distribution: how queries and pages spread across position buckets, and the click-
through rate your own site actually earns at each bucket. That curve is the benchmark
the low-CTR module judges against, instead of a generic industry table.

[⌊Analysis modules: growing queries, page-one opportunities at positions 11-20, 
and pages whose CTR is far below what their position should deliver. A query that
did not exist last period is marked "new" rather than shown as a rank drop.⌉⌊Analysis
modules: growing queries, page-one opportunities at positions 11-20, and pages whose
CTR is far below what their position should deliver. A query that did not exist 
last period is marked "new" rather than shown as a rank drop.⌉[

Analysis modules: growing queries, page-one opportunities at positions 11-20, and
pages whose CTR is far below what their position should deliver. A query that did
not exist last period is marked “new” rather than shown as a rank drop.

[⌊The Action Plan: one prioritised list assembled from every module by fixed rules.
No language model is involved in producing or ordering it.⌉⌊The Action Plan: one
prioritised list assembled from every module by fixed rules. No language model is
involved in producing or ordering it.⌉[

The Action Plan: one prioritised list assembled from every module by fixed rules.
No language model is involved in producing or ordering it.

[⌊Report archive: every report is kept per property, each with a printable view 
you can save as PDF.⌉⌊Report archive: every report is kept per property, each with
a printable view you can save as PDF.⌉[

Report archive: every report is kept per property, each with a printable view you
can save as PDF.

[⌊Generating a report: upload the .xlsx, .csv or .zip that Search Console hands 
you. Any date range works.⌉⌊Generating a report: upload the .xlsx, .csv or .zip 
that Search Console hands you. Any date range works.⌉[

Generating a report: upload the .xlsx, .csv or .zip that Search Console hands you.
Any date range works.

## Installation

 1. Upload the `palette-data-analyzer` folder to `wp-content/plugins/`, or install 
    the .zip from Plugins – Add New – Upload Plugin.
 2. Activate the plugin.
 3. Open the Palette Data Analyzer menu and upload a Search Console export.

Your server needs the standard PHP `zip` and `xml` extensions, which are enabled
on almost all WordPress hosts. No Composer packages are required – .xlsx files are
parsed directly.

## FAQ

### Do I need a Google API connection?

No. The free plugin analyses uploaded files. Direct API connection is an optional
capability of the separately distributed Palette Data Analyzer Pro add-on.

### Which date range should I export?

Any range works, and the plugin scales its thresholds to match. A 28-day window 
is the best default because it is exactly four weeks, so each period contains the
same number of Saturdays, Sundays and so on, and day-of-week seasonality cancels
out of the comparison. A calendar-month comparison does not have that property.

### Is my data sent anywhere?

Not unless you ask for it. File uploads are processed on your own server. The Google
Search Status feed is contacted only after you explicitly enable it on the upload
screen. The separately distributed Pro add-on contacts Google only after you start
its connection flow, and contacts an AI service only after you configure a key and
request a summary. See the External services section below.

### Does the AI layer change the numbers?

No. In the separately distributed Pro add-on, it receives already-calculated figures
and writes prose about them. Turning it off changes nothing about the analysis.

### Why is a section of the report empty?

Some modules need history. Ranking volatility, for example, is measured as the standard
deviation of a page’s position across at least three archived reports, because volatility
cannot be defined from two data points. The section explains what it still needs.

## Reviews

There are no reviews for this plugin.

## Contributors & Developers

“Palette Data Analyzer” is open source software. The following people have contributed
to this plugin.

Contributors

 *   [ PaletteAgency ](https://profiles.wordpress.org/paletteagencyy/)

[Translate “Palette Data Analyzer” into your language.](https://translate.wordpress.org/projects/wp-plugins/palette-data-analyzer)

### Interested in development?

[Browse the code](https://plugins.trac.wordpress.org/browser/palette-data-analyzer/),
check out the [SVN repository](https://plugins.svn.wordpress.org/palette-data-analyzer/),
or subscribe to the [development log](https://plugins.trac.wordpress.org/log/palette-data-analyzer/)
by [RSS](https://plugins.trac.wordpress.org/log/palette-data-analyzer/?limit=100&mode=stop_on_copy&format=rss).

## Changelog

Older releases are listed in `changelog.txt` inside the plugin folder.

#### 4.20.4

 * Added the dedicated plugin page as the Plugin URI.

#### 4.20.3

 * Removed the redundant Plugin URI header so the plugin and author URIs are not
   identical.

#### 4.20.2

 * Clarified which capabilities belong to the free plugin and which require the 
   separately distributed Pro add-on.
 * Connection and relay tests now run only after an administrator explicitly clicks
   a nonce-protected test link; opening Settings never makes a network request.
 * Removed Pro upgrade cards from the free plugin dashboard; the single contextual
   add-on notice remains on the Settings page.

#### 4.20.1

 * Google Search Status updates are now strictly opt-in. The upload screen explains
   the network request and the feed does not include the site URL in its User-Agent.
 * Removed code that suppressed other plugins’ admin notices.
 * Added the bundled Chart.js MIT license and moved the WordPress minimum version
   into the main plugin header.

#### 4.20.0

 * The Action Plan is now ordered by estimated impact inside each priority level,
   instead of by the order the modules happen to run in. Previously every item of
   one module came out in a block, so a report with ten page-two queries opened 
   with ten near-identical lines while a single low-CTR page worth several times
   the traffic sat further down. Each action is now scored in one common unit – 
   the clicks it would gain or recover, using your own site’s CTR curve for the 
   target position – and ties are broken by title so the same file still produces
   the same report twice.

#### 4.19.0

 * A query or page that did not exist in the previous period no longer shows a position
   drop. With no earlier rank, its “position change” was computed as zero minus 
   the current rank, so a brand-new query at position 15.3 was reported as having
   fallen 15.30 places. Those rows are now labelled “new”.
 * The dashboard said “19 analysis modules” in both editions. It now states the 
   real count for the edition you are running.

#### 4.18.0

 * Search Console reports the same page once per anchor link, so `/page/`, `/page/#
   h-1` and `/page/#h-2` arrived as three separate rows. On a real site 376 of 585
   page rows were anchors and a single page was split across eleven of them, which
   meant no row carried that page’s real weight and one page could fill most of 
   the action plan. Anchors are now merged: clicks and impressions are summed, position
   becomes an impression-weighted average, and CTR is recalculated from the totals
   rather than averaged.

#### 4.17.0

 * Saving a report now returns its archive ID, so anything referring back to that
   exact report — such as a shareable link — can name the right row.
 * Setup guide updated for Google’s new console: “Publishing status” and “Test users”
   both moved to the Audience page, and the wizard links there directly.

#### 4.16.0

 * Fixed a slowdown on servers that cannot reach Google. The Google Search Status
   feed is fetched while building a report, but a failed fetch was never cached —
   so every single report waited out the full 15-second timeout, again and again.
   Failures are now remembered for an hour, the timeout is 5 seconds, and the previous
   data is kept rather than discarded.
 * That feed can now go through the relay. It was missing from the allowlist, so
   a configured relay did not help it. Added to both the PHP list and the sample
   Cloudflare Worker.

#### 4.15.0

 * The setup guide now covers the “Access blocked / Error 403: access_denied” screen
   people hit when connecting their Google account, and adds a step for publishing
   the OAuth app. That step matters more than it looks: while the app stays in Testing,
   Google expires the connection after seven days, so the plugin silently loses 
   access about once a week and scheduled reports stop. Publishing removes that 
   limit and needs no Google review.

#### 4.14.1

 * Bot setup instructions no longer print bare @handles, which some marketplace 
   scanners flag as personal contact details. The instructions name the official
   BotFather bot instead.

#### 4.14.0

 * The settings page no longer probes Google on load. It only checks connectivity
   once you have entered a Client ID or a property address — before that there is
   nothing to connect to, and probing meant an outbound request just for opening
   a page.
 * Sections that need a direct API connection now say so instead of showing a “Pro”
   upsell. Those sections have no data when the report comes from a file upload,
   and telling a customer who already owns Pro to buy Pro was confusing.
 * Added a `PALDA_DISTRIBUTION` constant so a vendor-neutral build can be produced
   from the same source, without maintaining a second copy of the plugin.

#### 4.13.0

 * A fresh install no longer makes any outbound request until you generate your 
   first report. The Google Search Status feed was fetched on a daily cron that 
   scheduled itself five minutes after the first admin page view — before the user
   had done anything, and while its output had nothing to label yet. It is now scheduled
   only once a report exists. Existing installs keep their schedule.

#### 4.12.0

 * **Fixed “jump to section”, which had been broken in Persian.** Section IDs were
   built from the section number — a _translated_ string. In English it stayed “
   1” and worked; in Persian it became “۱”, every non-ASCII character was stripped,
   and all twenty sections ended up with the identical id `pda-sec-`. So `getElementById`
   always returned the first section (every jump went to the top of the report) 
   and the active-section highlight had nothing to map to. IDs are now derived from
   section order and are language-independent.
 * Pro teaser sections had the same bug and were also missing from the jump bar 
   entirely, so free users could not jump to them. Both section builders now share
   one ID source.
 * The jump offset was hardcoded at 120px while the real sticky-bar height is around
   230px, so the target landed hidden underneath the bar. It is now measured, which
   also covers RTL, mobile and a hidden admin bar.
 * Jumping now survives environments that ignore smooth scrolling (reduced-motion
   settings), re-checks its position once the scroll settles — charts change height
   as they load — and cancels a pending correction when you click another section.
 * **Bidirectional text is now derived from content, not assumed.** Every link was
   forced to `direction: ltr`, which is right for a URL but wrong for links whose
   text is Persian, whose trailing punctuation jumped to the wrong side. Links and
   inline code now use `unicode-bidi: plaintext`, so each element takes its direction
   from its own first strong character. Standalone URLs stay explicitly LTR so a
   Persian slug cannot flip them.
 * Multi-line URLs in tables were right-aligned line by line, breaking their left-
   to-right reading order. They are block-level now, so the box follows the page
   direction while the text inside stays left-aligned.
 * Free dashboard: the “Get started” link pointed at the settings page, which without
   a licence is only a Pro pitch — a free user clicking it landed on a sales page
   instead of somewhere they could work. It now points at the file upload, and the
   main button carries a “Start here” badge until the first report exists.

#### 4.11.0

 * Plugin Check compliance: zero errors and zero warnings against the official WordPress
   plugin-check tool.
 * readme.txt is now in English, as the plugin directory requires. The full Persian
   history moved to `changelog.txt`.
 * File operations in the uninstaller and the ZIP-signature check now use WP_Filesystem,
   so they work on hosts where WordPress writes over FTP or SSH.
 * Dropped `wp_set_option_autoload()`, which needs WordPress 6.4 while this plugin
   supports 5.8. The same result is achieved with functions available in every supported
   version.
 * Removed the manual `load_plugin_textdomain()` call; WordPress has loaded translations
   automatically since 4.6. Verified that Persian still loads without it.

#### 4.10.0

 * The `palda_settings_sections` seam is now live, so the Pro add-on can render 
   its own settings block without any of its code living in the free plugin.
 * `PALDA_Connectivity::rewrite_google()` renamed to `rewrite_if_allowed()`; the
   relay allowlist is no longer Google-only. The old name is kept as an alias.
 * Sample Cloudflare Worker: `api.telegram.org` added to the allowlist.

#### 4.9.0

 * Report thresholds now scale with the length of the exported window. Minimum-impression
   gates were tuned for 28 days, so on a 3-month export they were roughly three 
   times too loose and on a 7-day export three times too strict.

#### 4.8.0

 * Comparison exports now work with any date range, not just 28 days. Previously
   the column detection matched the literal text “Last 28 days”; every other range
   silently produced a report where all numbers were zero, alongside a misleading“
   your file is single-period” message.
 * Added a guard against that silent failure: if a sheet has rows but no numbers
   could be read, the plugin says so and names the sheet.
 * Re-running the same report no longer clutters the archive. Each run used to insert
   a new row, which put duplicate points into the time series and dragged volatility
   toward zero.

#### 4.7.0

 * Rewrote the ranking-volatility module. It previously measured the absolute difference
   between two periods, which is not volatility and duplicated the “biggest movers”
   module. It now uses the standard deviation of position across at least three 
   archived reports.
 * Each report now stores a snapshot of the top 50 pages so per-page time series
   can be built.

#### 4.6.1

 * Property selection in the report archive is now correctly limited to the Pro 
   add-on.
 * Fixed archive rows saved under an inconsistent property format, with a one-time
   migration.

## Meta

 *  Version **4.20.4**
 *  Last updated **2 days ago**
 *  Active installations **Fewer than 10**
 *  WordPress version ** 5.8 or higher **
 *  Tested up to **7.1**
 *  PHP version ** 7.4 or higher **
 * Tags
 * [analytics](https://wordpress.org/plugins/tags/analytics/)[google](https://wordpress.org/plugins/tags/google/)
   [reporting](https://wordpress.org/plugins/tags/reporting/)[Search Console](https://wordpress.org/plugins/tags/search-console/)
   [seo](https://wordpress.org/plugins/tags/seo/)
 *  [Advanced View](https://wordpress.org/plugins/palette-data-analyzer/advanced/)

## Ratings

No reviews have been submitted yet.

[Your review](https://wordpress.org/support/plugin/palette-data-analyzer/reviews/#new-post)

[See all reviews](https://wordpress.org/support/plugin/palette-data-analyzer/reviews/)

## Contributors

 *   [ PaletteAgency ](https://profiles.wordpress.org/paletteagencyy/)

## Support

Got something to say? Need help?

 [View support forum](https://wordpress.org/support/plugin/palette-data-analyzer/)