Title: Scayla Connect
Author: liorzabari
Published: <strong>September 15, 2026</strong>
Last modified: September 16, 2026

---

Search plugins

![](https://ps.w.org/scayla-connect/assets/banner-772x250.png?rev=3696465)

![](https://ps.w.org/scayla-connect/assets/icon-256x256.png?rev=3696465)

# Scayla Connect

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

[Download](https://downloads.wordpress.org/plugin/scayla-connect.1.0.1.zip)

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

 [Support](https://wordpress.org/support/plugin/scayla-connect/)

## Description

Scayla Connect is not an SEO plugin. It is the site-side connector for [Scayla](https://scayla.co.il/),
a cloud service that measures whether AI assistants actually name your store when
a shopper asks what to buy, and then acts on what it measured.

The queries it measures are not generic keywords typed into a box. They are derived
from a scan of your own catalogue — real product titles, product types and categories—
which is why they reach the level of a specific product or category. When a gap 
is found, the service turns it into a change on your site through this plugin, then
measures the same fixed query set again the following week.

Every SEO value written is read back from the source your site will actually serve
before the write is reported as successful. That is why a separate connector exists.
Since Yoast SEO 14, Yoast does not serve SEO meta from post meta; it serves it from
its own `wp_yoast_indexable` table. A tool that calls `update_post_meta( $id, '_yoast_wpseo_title',...)`
gets a successful database write, a 200 response, and a front end that keeps serving
the old title indefinitely. This plugin writes, reconciles the indexable, re-reads
from the serving source, compares, and on any mismatch returns a hard `scayla_write_not_verified`
error carrying the expected value, the actual value and which storage layer answered.

Yoast SEO and Rank Math — the two SEO plugins this connector writes through — both
ship AI-visibility tracking of their own, and track it well, at brand level. Scayla
is the other shape of the same problem: catalogue-derived queries, a write path 
back into the exact product or category that caused the gap, and verification on
every write. Scayla is not the only vendor that both measures and writes back, and
this plugin does not claim to be.

**Hebrew and RTL.** Redirect paths never pass through `sanitize_text_field()`, which
strips every percent-encoded octet and would silently turn an encoded Hebrew slug
into a live 301 to the wrong page; the plugin uses its own percent-safe sanitiser.
FAQ content renders as a native `<details>` / `<summary>` accordion with no JavaScript
and no stylesheet, so it inherits your theme’s RTL direction. Hebrew content analysis
is not claimed as a differentiator — Yoast and Rank Math both support Hebrew already.

**What the plugin does on your site**

 * Pairs with your Scayla account through WordPress’s own Application Password approval
   screen (or a manually created Application Password), used once, then operates
   through a dedicated `scayla-connector` service user with a narrow, revocable 
   token.
 * Bridges SEO title and meta description writes to Yoast SEO or Rank Math, with
   mandatory read-back verification on every write. With no SEO plugin active it
   stores and renders those values itself.
 * Renders FAQ structured data as a single FAQPage node merged into Yoast’s schema
   graph, or into Rank Math’s JSON-LD, or as its own script tag when neither is 
   present. The three paths are mutually exclusive, so an FAQPage is never rendered
   twice.
 * Writes category and tag descriptions through a dedicated endpoint, because WordPress
   core registers `wp_filter_kses` on `pre_term_description` unconditionally and
   silently strips `div`, `h2`, `p`, `details` and `summary` while returning a 200.
   The plugin does not detach core’s filter; it runs its own allowlist and outranks
   core, so nothing else on the site loses kses protection.
 * Manages a redirects table for dead URLs, with guards against self-redirects, 
   two-step loops, cross-host targets, and the protected prefixes `/wp-admin`, `/
   wp-json`, `/wp-login.php`, `/wp-content` and the site root.
 * Adds one admin page: a Connect button, connection status, detected SEO plugin,
   redirect and FAQ counts, and a Disconnect button.

**How it is built.** Plain, readable PHP: six classes plus the main file and `uninstall.
php`. No build step, no minified or obfuscated code, no bundled JavaScript, and 
no script, stylesheet, font or image loaded from a remote server. Nothing is compiled,
so what you read in the plugin folder is exactly what runs.

**Nothing in the plugin is gated.** No premium tier inside this code, no license
check, no feature flag, no nag, no upsell that unlocks a function. Every capability
above works in full without paying anything. Paid limits exist only in the Scayla
cloud service, and they limit how much work the service does, not what the plugin
may do.

### External services

This plugin is a connector for Scayla, a third-party cloud service operated by Scayla(
https://scayla.co.il/). **A Scayla account is required.** Without one the plugin
has nothing to talk to: it will pair with nothing, receive no writes, and do nothing
useful.

**The plugin makes no outbound requests.** It contains no `wp_remote_*`, `curl_*`,`
file_get_contents` or `fsockopen` call anywhere in its code. It never contacts Scayla,
on any schedule or on any event, including deactivation. The **Connect to Scayla**
button is an ordinary link: your browser travels to the Scayla portal; the plugin
sends nothing. All traffic is inbound: Scayla’s servers call your site’s REST API
and authenticate with the paired token, and data leaves your site only inside the
response to one of those authenticated requests.

**What leaves your site, and when:**

 * **When you pair.** Clicking **Connect to Scayla** takes your browser to the Scayla
   portal (`https://wp-api.scayla.co.il/connect/start`) with your site address and
   admin language in the link. The portal reads your site’s public REST index (`
   GET /wp-json/`) to confirm this plugin is active and to find your approval screen,
   then sends your browser to that screen on your own site (`/wp-admin/authorize-
   application.php`). If you approve, WordPress creates an Application Password 
   named Scayla and sends your browser back to the portal with it. Scayla uses it
   for one authenticated `POST /wp-json/scayla/v1/pair`, then deletes it: `GET /
   wp-json/wp/v2/users/me/application-passwords/introspect` identifies that one 
   password and `DELETE /wp-json/wp/v2/users/me/application-passwords/{uuid}` removes
   it, leaving any other Application Passwords untouched. (Connecting manually instead,
   you paste an Application Password into the portal and revoke it yourself afterwards.)
   The pairing response carries your site address and REST API address, your WordPress
   and WooCommerce version numbers, your permalink structure, which SEO plugin was
   detected, the login name of the service user just created, and — once only, in
   this one response — the API token your site mints for Scayla to authenticate 
   with from then on. Your site keeps only a SHA-256 hash of that token.
 * **While the service operates** (each time Scayla’s servers call your site with
   the paired token): the content being worked on — product, post, page and category
   titles and descriptions, SEO titles and meta descriptions, image alt text, FAQ
   questions and answers, and redirect paths. Scayla reads these to know the current
   state, and writes new values back the same way.
 * **When Scayla checks the connection** (`GET /wp-json/scayla/v1/health`, authenticated):
   plugin version, WordPress and WooCommerce versions, detected SEO plugin, permalink
   structure, site and home URL, locale, time zone, and the first 8 characters of
   the stored token hash as a connection fingerprint. The token itself is never 
   returned.

**What never leaves your site:** no visitor data, no IP addresses, no analytics,
no tracking beacons, no order or customer data, no user accounts or email addresses,
and no data of any kind sent to any host other than the Scayla service that authenticated
the request.

By pairing your site you agree to Scayla’s terms and privacy policy:

 * Terms of service: https://scayla.co.il/terms
 * Privacy policy: https://scayla.co.il/privacy

## Installation

 1. Upload the plugin files to `/wp-content/plugins/scayla-connect`, or install it 
    through the WordPress Plugins screen.
 2. Activate the plugin. Activation creates the redirects table and nothing else — 
    no user account is created and no token exists yet.
 3. Open the **Scayla** admin menu and read the external-service disclosure shown there
    before you continue.
 4. Click **Connect to Scayla** and approve the request on the WordPress screen that
    follows. Scayla uses the Application Password WordPress creates once, to pair, 
    and then deletes it.
 5. Prefer to do it by hand? Under **Connect manually instead**: create an Application
    Password for your administrator account (Users  Profile  Application Passwords),
    paste it into the Scayla portal, and revoke it once pairing succeeds.

## FAQ

### What exactly can the service do on my site?

Pairing creates one user, `scayla-connector`, holding a custom role with exactly
13 capabilities: `read`, `edit_posts`, `edit_others_posts`, `publish_posts`, `edit_published_posts`,`
delete_posts`, `delete_others_posts`, `delete_published_posts`, `edit_pages`, `edit_others_pages`,`
edit_published_pages`, `upload_files`, `manage_categories`. With WooCommerce active,
9 product capabilities are added, including `read_private_products` (WooCommerce
maps a product collection read to it) and `manage_product_terms`.

It does not get `manage_options`, `install_plugins`, `install_themes`, `switch_themes`,`
edit_theme_options`, `edit_users`, `unfiltered_html`, `publish_pages` or `delete_pages`.
Pages are editable but not publishable or deletable, because the service only writes
SEO onto pages that already exist. The role is re-asserted on every load and any
capability not on the list is stripped, so another plugin cannot quietly widen it.

### Is any code downloaded or executed from the remote service?

No. The plugin never fetches, stores or evaluates remote code — no `eval`, no dynamic
include, no remote file download. What arrives from Scayla is text: titles, descriptions,
FAQ questions and answers, and paths. Each passes an explicit filter before storage:
FAQ questions have all tags stripped and answers pass `wp_kses_post`; category and
tag descriptions pass a post-context `wp_kses` allowlist extended only with `details`,`
summary` and a small set of `class`/`id`/`data-` attributes, so `script`, `iframe`
and `on*` handlers cannot be stored even if the token were stolen. Redirect paths
pointing at another host are rejected outright.

### What happens if a write does not land?

It fails loudly. After every SEO write the plugin reconciles the provider’s storage,
re-reads the value from the source your front end will actually serve, and compares.
If they differ it returns HTTP 500 with `scayla_write_not_verified` and a body containing
the expected value, the actual value, which storage layer answered (`indexable`,`
postmeta`, `option` or `scayla`) and a hint distinguishing “Yoast’s indexable did
not reconcile” from “another plugin may be overriding SEO meta”. For Yoast terms
the read-back deliberately reads the indexable rather than the option just written,
because a verification that reads back its own write proves nothing.

### Does it work without WooCommerce, or without an SEO plugin?

Both are optional. Without WooCommerce it works on posts, pages, categories and 
tags; with it, products and product categories are covered too. Without Yoast or
Rank Math it stores values in its own `_scayla_seo_title` and `_scayla_seo_description`
meta and renders them through `pre_get_document_title` and a `wp_head` meta description.
Those standalone renderers refuse to run unless the detected provider is exactly“
none”, so there is never a duplicate title alongside Yoast or Rank Math.

### Does it slow down my site?

The redirect matcher runs at `template_redirect` and costs zero database queries
when a request does not match: the map lives in one autoloaded option WordPress 
has already fetched, an empty map returns before the request URI is parsed, and 
only a hit touches the database. If the map would exceed 100 KB it is dropped in
favour of a single prepared query, so a large table never bloats every admin and
cron request. Paths are stored in `utf8mb4_bin` columns so matching is byte-exact,
which stops a case-normalising rule such as `/Page` to `/page` from matching its
own destination and looping forever. The plugin registers no cron jobs.

### Can the service user log in?

No. It is created with a 64-character random password that is never transmitted,
displayed, stored in plaintext or logged — but the guarantee does not rest on that.
An `authenticate` filter rejects any interactive login resolving to the service 
user, and an `allow_password_reset` filter refuses password resets for it, closing
the otherwise real path of requesting a reset to `connector@yourdomain` on a catch-
all mail domain. The token maps to the service user only on REST requests, anchored
to the first path segment via `rest_get_url_prefix()`, so a front-end permalink 
merely containing `wp-json` cannot borrow the identity.

### Are any of the REST routes public?

No. Every route has a real permission callback, including `GET /health`; there is
no `__return_true` anywhere in the code. Write routes additionally check the specific
object: `current_user_can( 'edit_post', $id )` for that post, or term existence 
plus a taxonomy allowlist plus `manage_categories` for that term. The bulk read 
endpoint enforces authorisation per ID rather than once per batch, and anything 
the service user may not touch is returned in a `skipped` list instead of being 
read. Failed token attempts are rate-limited per IP, bucketed on `REMOTE_ADDR` rather
than on spoofable proxy headers.

### How do I disconnect, and what is removed if I delete the plugin?

Click **Disconnect** on the Scayla admin page. The token hash is deleted immediately
and every subsequent request from Scayla is rejected; your content, SEO values, 
FAQ data and redirects stay exactly as they are. Deactivating changes nothing else,
so you can deactivate to troubleshoot and reactivate without re-pairing.

Deleting the plugin removes the role from the service user, deletes the role, drops
the redirects table, deletes `_scayla_faq`, `_scayla_seo_title` and `_scayla_seo_description`
from every post and term, and sweeps every `scayla_*` option and transient — on 
every site of a multisite network. Two things are kept on purpose: the `scayla-connector`
account, so content it authored keeps its author attribution (it has no role, zero
capabilities and cannot be logged into; delete it manually if you prefer), and SEO
values already written into Yoast or Rank Math, because at that point they are your
site’s meta, not the plugin’s.

### Does it support multisite?

Yes. Network activation provisions every existing site, sites created afterwards
are provisioned automatically, and uninstall walks every site so no orphan table
or role is left behind.

## Reviews

There are no reviews for this plugin.

## Contributors & Developers

“Scayla Connect” is open source software. The following people have contributed 
to this plugin.

Contributors

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

[Translate “Scayla Connect” into your language.](https://translate.wordpress.org/projects/wp-plugins/scayla-connect)

### Interested in development?

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

## Changelog

#### 1.0.1

 * One-click connect: a **Connect to Scayla** button takes you through WordPress’s
   own Application Password approval screen, so nothing has to be copied or pasted.
   Scayla uses that password once to pair and then deletes it.
 * The manual flow (create an Application Password, paste it into the portal) is
   still available under **Connect manually instead**.

#### 1.0.0

 * First public release.
 * Pairing through a one-time admin Application Password; day-to-day access through
   a scoped, revocable token stored only as a SHA-256 hash.
 * Dedicated service user and role with a fixed capability list that cannot be logged
   into or password-reset.
 * SEO title and meta description bridge for Yoast SEO and Rank Math, plus a standalone
   mode, with read-back verification on every write.
 * FAQPage JSON-LD merged into Yoast’s schema graph or Rank Math’s JSON-LD, with
   a self-contained fallback.
 * Category and tag description endpoint that preserves structural HTML through 
   an allowlist without detaching core’s kses filter, and verifies the stored result.
 * Redirects table with byte-exact matching, loop, self-redirect, cross-host and
   protected-path guards, and a zero-query front-end match on a miss.
 * Multisite provisioning and multisite-aware uninstall.

## Meta

 *  Version **1.0.1**
 *  Last updated **12 hours ago**
 *  Active installations **Fewer than 10**
 *  WordPress version ** 6.4 or higher **
 *  Tested up to **7.1**
 *  PHP version ** 7.4 or higher **
 * Tags
 * [AI](https://wordpress.org/plugins/tags/ai/)[redirects](https://wordpress.org/plugins/tags/redirects/)
   [seo](https://wordpress.org/plugins/tags/seo/)[structured data](https://wordpress.org/plugins/tags/structured-data/)
   [woocommerce](https://wordpress.org/plugins/tags/woocommerce/)
 *  [Advanced View](https://wordpress.org/plugins/scayla-connect/advanced/)

## Ratings

No reviews have been submitted yet.

[Your review](https://wordpress.org/support/plugin/scayla-connect/reviews/#new-post)

[See all reviews](https://wordpress.org/support/plugin/scayla-connect/reviews/)

## Contributors

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

## Support

Got something to say? Need help?

 [View support forum](https://wordpress.org/support/plugin/scayla-connect/)