{"id":369761,"date":"2026-09-18T21:25:47","date_gmt":"2026-09-18T21:25:47","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/synth-antispam\/"},"modified":"2026-09-18T21:25:34","modified_gmt":"2026-09-18T21:25:34","slug":"synth-antispam","status":"publish","type":"plugin","link":"https:\/\/as.wordpress.org\/plugins\/synth-antispam\/","author":23543338,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"0.1.0","stable_tag":"0.1.0","tested":"7.1.1","requires":"6.0","requires_php":"8.0","requires_plugins":null,"header_name":"Synth Antispam","header_author":"Synth","header_description":"Synth is an AI antispam platform. Every comment is judged by what it sells, not by string matches. Get a site key in Settings.","assets_banners_color":"fbfbf9","last_updated":"2026-09-18 21:25:34","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/wordpress.synth.locker\/","header_author_uri":"https:\/\/synth.locker\/","rating":0,"author_block_rating":0,"active_installs":0,"downloads":41,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"0.1.0":{"tag":"0.1.0","author":"synthplatform","date":"2026-09-18 21:25:34","revision":3702773}},"upgrade_notice":[],"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3702774,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3702774,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256},"icon.svg":{"filename":"icon.svg","revision":3702774,"resolution":false,"location":"assets","locale":false}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3702774,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3702774,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["0.1.0"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3702774,"resolution":"1","location":"assets","locale":"","width":2292,"height":1542}},"screenshots":{"1":"The verdict for every comment, in the Comments list. Each row shows the category the classifier\nassigned and how sure it was, so a comment in the Spam folder is explainable rather than\nmysterious \u2014 and a mistake is easy to spot and reverse."}},"plugin_section":[],"plugin_tags":[109,107,1756,599],"plugin_category":[44,54],"plugin_contributors":[281531],"plugin_business_model":[],"class_list":["post-369761","plugin","type-plugin","status-publish","hentry","plugin_tags-antispam","plugin_tags-comments","plugin_tags-moderation","plugin_tags-spam","plugin_category-discussion-and-community","plugin_category-security-and-spam-protection","plugin_contributors-synthplatform","plugin_committers-synthplatform"],"banners":{"banner":"https:\/\/ps.w.org\/synth-antispam\/assets\/banner-772x250.png?rev=3702774","banner_2x":"https:\/\/ps.w.org\/synth-antispam\/assets\/banner-1544x500.png?rev=3702774","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":"https:\/\/ps.w.org\/synth-antispam\/assets\/icon.svg?rev=3702774","icon":"https:\/\/ps.w.org\/synth-antispam\/assets\/icon.svg?rev=3702774","icon_2x":false,"generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/synth-antispam\/assets\/screenshot-1.png?rev=3702774","caption":"The verdict for every comment, in the Comments list. Each row shows the category the classifier\nassigned and how sure it was, so a comment in the Spam folder is explainable rather than\nmysterious \u2014 and a mistake is easy to spot and reverse."}],"raw_content":"<!--section=description-->\n<p>Synth Antispam connects your site to Synth for WordPress, the hosted AI spam-checking service\nbuilt on Synth \u2014 the same platform that already reads more than three million messages a year.\nEvery comment is judged on what it is trying to sell, not matched against a keyword list you have\nto keep current, and not scored by code running on your site. To get started: install the plugin,\nopen Settings \u2192 Synth Antispam and press <strong>Get a site key<\/strong> \u2014 there is nothing to copy by hand.<\/p>\n\n<p>The visitor never waits: the verdict comes back a moment after the comment is submitted, not in the\nmiddle of the request. Spam lands in the Spam folder, or in the moderation queue in strict mode.<\/p>\n\n<p><strong>Nothing is ever deleted.<\/strong> The plugin never removes a comment and never puts one in Trash, so a\ncomment filed as spam by mistake stays recoverable for as long as you keep it. WordPress's\nscheduled cleanup empties Trash, not Spam.<\/p>\n\n<h4>Why a model instead of a rule list<\/h4>\n\n<ul>\n<li><strong>Rewording does not help the spammer.<\/strong> A rule list matches strings, so the spammer edits the\nstring. A model reads the message \u2014 and the message is the thing being sold.<\/li>\n<li><strong>Nothing to maintain.<\/strong> No keyword lists, no blocklists, no regular expressions to update when\nthe wording shifts.<\/li>\n<li><strong>Every surface, not just the form.<\/strong> The comment form, the REST API and XML-RPC are all checked,\nand so are pingbacks and trackbacks.<\/li>\n<li><strong>You can see why.<\/strong> The verdict appears as its own column in the comments list, so a comment in\nthe Spam folder is explainable instead of mysterious.<\/li>\n<li><strong>Your judgement wins.<\/strong> A decision you or another moderation plugin already made is left alone.\nMarking a comment as not-spam sends that correction back and teaches the filter.<\/li>\n<li><strong>Your site works when ours does not.<\/strong> If the service is unreachable you choose what happens:\npublish as usual (the default) or hold for review. Running out of your monthly allowance does not\nswitch the plugin off either.<\/li>\n<li><strong>Nothing runs on your visitors.<\/strong> No detection logic on your server, no scripts on your pages,\nno visitor tracking. Only what a verdict needs is sent, listed field by field under \"External\nservices\".<\/li>\n<\/ul>\n\n<p>You supply one thing: a site key. Until a key is entered the plugin sends no request at all, and\ncomments publish exactly as they would without it.<\/p>\n\n<h3>External services<\/h3>\n\n<p>This plugin is a thin client for the <strong>Synth Antispam classification service<\/strong>, an external,\ncloud-hosted processor. It sends each new comment (and pingback or trackback) to that service to\nobtain a spam verdict, and applies the verdict using WordPress's own moderation tools (Spam folder\nor moderation queue \u2014 see \"Description\" above). It also asks that same service for this site's key\nwhen you press <strong>Get a site key<\/strong>. No request serves any other purpose; the full list is below.<\/p>\n\n<p>The service is operated by LightApps O\u00dc (Estonia). Its terms and its privacy policy for this\nplugin \u2014 including the controller\/processor split described below, where the data is processed, and\nwho else it reaches \u2014 are published here:<\/p>\n\n<ul>\n<li>Terms of Use: https:\/\/synth.locker\/assets\/legal\/wordpress-terms-of-use.html<\/li>\n<li>Privacy Policy: https:\/\/synth.locker\/assets\/legal\/wordpress-privacy-policy.html<\/li>\n<li>Pricing: https:\/\/wordpress.synth.locker\/pricing<\/li>\n<\/ul>\n\n<p>Both legal documents cover the WordPress service specifically. Synth also operates a Telegram\nservice under separate general documents, which do not apply to this plugin.<\/p>\n\n<p><strong>This is a paid, cloud-hosted service.<\/strong> Every site that registers is given a starting allotment\nof checks at no charge, and higher volumes are available on paid subscription tiers above it.\nEvery paid tier applies to one site \u2014 a site's key covers checks made for that site, not a group of\nsites. Current check volumes and prices are on the pricing page linked above, not in this file:\nthis file ships frozen inside the build and is not corrected between releases, while they change.<\/p>\n\n<p><strong>Running out of checks does not turn off anything this plugin does.<\/strong> When a site has used its\nchecks for the current period, the classification service simply stops answering new requests for\nthat site until the period resets \u2014 the plugin does not lock, gate, or disable any of its own\nfunctionality in response, and it never has: no feature, mode, or setting in this plugin is gated\nbehind a tier or a payment state, at any usage level. Comments continue to be handled by\nWordPress's own native moderation tools, the same as whenever the service is briefly unreachable\nfor any other reason.<\/p>\n\n<p><strong>Every request this plugin can make, in full.<\/strong> Each one goes to the one service named above and to\nnothing else \u2014 see \"Payments\" below for the single case where your browser, rather than this plugin,\nis sent somewhere else:<\/p>\n\n<ol>\n<li><strong>Submitting a comment for a verdict.<\/strong> One request per comment, carrying the fields listed\nbelow, field by field.<\/li>\n<li><strong>Collecting the verdict.<\/strong> A verdict is not returned immediately, so the plugin asks for it a\nshort time later. This second request carries <strong>only the identifier the service issued for that\ncomment in step 1, and nothing else<\/strong> \u2014 no comment text, no commenter details, nothing about\nyour site.<\/li>\n<li><strong>Reporting a moderator correction \u2014 off by default, and it makes no request unless you turn it\non.<\/strong> If you switch it on, then when a moderator marks one of our decisions as wrong, the plugin\nsends the identifier from step 1 together with what the moderator decided (spam or not spam) \u2014\nand nothing else. This is controlled by the <code>synth_wp_send_feedback<\/code> filter, which ships\nreturning <code>false<\/code>; with no code added to your site, this request never happens.<\/li>\n<li><strong>Asking for a site key \u2014 only when you press the button.<\/strong> <strong>Get a site key<\/strong> sends one request\ncarrying the plugin version and nothing else: nothing about your site, nothing about a comment\nor a commenter. It never fires on its own, and only the key is kept from the answer. Your site's\naddress reaches the service with the first comment it checks \u2014 that is the request in step 1,\nwhich already carries it, and it is what ties the key to this site.<\/li>\n<li><strong>Checking the remaining allowance \u2014 only while an administrator has the settings screen\nopen.<\/strong> Sends your site key and site address, nothing else. Read-only; costs no check.<\/li>\n<li><strong>Starting a purchase \u2014 only when you press an upgrade button.<\/strong> Sends your site key, site\naddress and the option pressed, then takes you to the provider's own payment page.\n<strong>No card details reach your site, this plugin, or this service.<\/strong><\/li>\n<\/ol>\n\n<p><strong>Payments \u2014 the only time your browser leaves your site, and only if you press an upgrade button.<\/strong>\nPayment is taken by <strong>Stripe<\/strong> (Stripe Payments Europe, Ltd.), not by us. This plugin sends nothing\nto Stripe: it asks the Synth Antispam service for a payment page address, checks that the address\nreally is Stripe's checkout page, then opens it in your browser. What you type there, card details\nincluded, goes from your browser to Stripe and reaches neither your site, nor this plugin, nor the\nSynth Antispam service. Stripe's own documents govern that page:<\/p>\n\n<ul>\n<li>Stripe Terms: https:\/\/stripe.com\/legal<\/li>\n<li>Stripe Privacy Policy: https:\/\/stripe.com\/privacy<\/li>\n<\/ul>\n\n<p>Press no upgrade button and Stripe is never involved.<\/p>\n\n<p>Entering a site key is not a subscription step and does not put your site on a plan: no feature,\nmode, or setting in this plugin is gated behind a tier, a payment state, or a trial. Everything the\nplugin can do, it does for every configured site.<\/p>\n\n<p><strong>Nothing is sent until you opt in.<\/strong> The plugin attaches no comment-checking hooks until both a\nservice address and a site key are set; with either missing it behaves as with no key at all, and\nthe service is never contacted for any comment. Setting that pair \u2014 on the Settings \u2192 Synth\nAntispam screen, or at network level on multisite \u2014 is the act of opting in and is the consent\ngate; there is no separate checkbox.<\/p>\n\n<p><strong>Exactly what is sent, field by field.<\/strong> This list matches the plugin's request builder field for\nfield \u2014 nothing beyond it leaves your site:<\/p>\n\n<ul>\n<li><code>schema_version<\/code> \u2014 the version of the request format, so the service stays compatible with older and newer plugin versions at once.<\/li>\n<li><code>plugin_version<\/code> \u2014 the installed plugin version, for the same compatibility reason.<\/li>\n<li><code>surface<\/code> \u2014 a fixed label saying the request comes from the comment form (<code>wp_comment<\/code> in this version; a hook for future integrations such as forms outside comments).<\/li>\n<li><code>object_type<\/code> \u2014 <code>comment<\/code>, <code>pingback<\/code>, or <code>trackback<\/code>: the latter two are machine-submitted and the service weighs them differently.<\/li>\n<li><code>content.body<\/code> \u2014 the comment text as submitted, before any of WordPress's own HTML filtering runs, so a link the filtering would otherwise strip is still visible to the classifier.<\/li>\n<li><code>content.author_name<\/code> \u2014 the display name the commenter typed into the comment form.<\/li>\n<li><code>content.author_url<\/code> \u2014 the website URL the commenter typed into the comment form. On the traffic this plugin was built against, this field carries a very strong share of the spam signal \u2014 most of it is not visible in the comment text at all.<\/li>\n<li><code>content.author_email_domain<\/code> \u2014 only the domain part of the commenter's email address (for example <code>gmail.com<\/code>), used to recognise disposable or throwaway email patterns. <strong>The email address itself is never sent<\/strong> \u2014 see \"What is never sent\" below.<\/li>\n<li><code>content.author_id_hash<\/code> \u2014 a one-way SHA-256 hash of the commenter's email address combined with a secret value generated for your site alone (your site's own \"salt\"). It lets the service recognise that two comments on your site came from the same email address without ever receiving that address. Because the salt is unique to your site and known only to it, the same commenter cannot be linked across two sites using this plugin \u2014 impossible by construction, not merely disabled. It is a per-site pseudonym, not an anonymised identifier: uninstalling the plugin destroys the salt (see \"Retention\" below), after which even this site can no longer connect a previously sent hash back to an email address.<\/li>\n<li><code>context.author_status<\/code> \u2014 either <code>registered<\/code> (a logged-in registered user of your site) or <code>anonymous<\/code> (everyone else). Only these two values are ever sent: a commenter who already has an approved comment on your site is trusted and skipped <strong>before<\/strong> any request is built, so their comment is never sent at all and no status is transmitted for them.<\/li>\n<li><code>context.is_reply<\/code> \u2014 whether the comment is a reply to another comment.<\/li>\n<li><code>context.site_locale<\/code> \u2014 your site's configured language (for example <code>en_US<\/code>), used as a hint for language-specific handling.<\/li>\n<li><code>context.client_ip_status<\/code> \u2014 <code>absent<\/code> if the request carried no IP address, or <code>direct<\/code> if it did. This tells the service only whether one was present \u2014 <strong>the address itself is never sent, in either case<\/strong> \u2014 see \"What is never sent\" below. The plugin never reconstructs a \"real\" visitor IP from proxy or CDN forwarding headers: those are only as trustworthy as whoever sent the request, and a site behind a proxy cannot tell the difference.<\/li>\n<li><code>context.has_user_agent<\/code> \u2014 <code>true<\/code> or <code>false<\/code>, whether the browser sent a User-Agent string at all. <strong>The User-Agent string itself is never sent<\/strong> \u2014 see \"What is never sent\" below.<\/li>\n<\/ul>\n\n<p><strong>What is never sent, under any circumstances:<\/strong><\/p>\n\n<ul>\n<li>The commenter's <strong>full email address<\/strong> \u2014 only the domain (<code>content.author_email_domain<\/code>) and a salted one-way hash (<code>content.author_id_hash<\/code>) ever leave your site.<\/li>\n<li>The commenter's <strong>IP address<\/strong> \u2014 only the two-value status above (<code>context.client_ip_status<\/code>) leaves your site; the address itself never does.<\/li>\n<li>The commenter's raw <strong>User-Agent string<\/strong> \u2014 only whether one was present (<code>context.has_user_agent<\/code>) leaves your site.<\/li>\n<li>The post's title or body, the HTTP referrer, cookies, or any form field other than the comment fields listed above.<\/li>\n<\/ul>\n\n<p><strong>Retention.<\/strong> Two separate things are kept, for two different lengths of time.<\/p>\n\n<p><em>The verdict record.<\/em> The verdict for each comment is retained by the Synth Antispam service for 24\nhours and then expires automatically. That is the record your site collects its verdict from.<\/p>\n\n<p><em>The training record.<\/em> Separately, the service keeps its own copy of each request your site sends \u2014\nthe comment text and the commenter fields listed above, exactly as sent \u2014 together with the verdict\nits classifier produced and any later correction you make with the <strong>Not spam<\/strong> \/ <strong>Spam<\/strong> buttons in\nyour Comments list. It uses those copies to train and improve the Synth spam-classification models. <strong>These copies\nare kept indefinitely: they have no expiry date.<\/strong> They are stored as sent \u2014 not anonymised, not\naggregated, and not reduced to statistics. This applies to every site that uses the service; there is\nno setting, on this screen or anywhere else, that turns it off. If that is not acceptable for your\nsite, the choice available to you is not to install the plugin.<\/p>\n\n<p><em>Deletion on request.<\/em> To have your site's stored copies deleted, write to support@synth.locker with\nyour site's address. The service can delete them by site key, so a request covers every copy taken\nfrom your site rather than one comment at a time. An operator tool for this deletion is being built\nalongside this release; until it is in place the deletion is performed by hand on request, and the\naddress above is the route either way.<\/p>\n\n<p>Uninstalling this plugin permanently deletes your site's secret salt; after that, no\n    author_id_hash it previously sent can be linked back to an email address, by this site or by the\nservice. Uninstalling does <strong>not<\/strong> by itself delete copies already taken \u2014 use the address above for\nthat. Your site key is the one thing deliberately left behind, so that reinstalling the plugin\ndoes not cost you the checks attached to it. Tick\n<strong>Delete the site key when the plugin is deleted<\/strong> on the settings screen if you want it removed too.<\/p>\n\n<p><strong>Your own obligations under privacy law<\/strong> \u2014 see \"For site owners: your obligations under GDPR\nand similar privacy laws\" in the Frequently Asked Questions above.<\/p>\n\n<h4>Every address that appears in the source<\/h4>\n\n<p>A search of this plugin's files finds these addresses and no others:<\/p>\n\n<ul>\n<li><code>wp-api.synth.locker<\/code> \u2014 the Synth Antispam service above. The shipped default; changeable on the\nsettings screen or in <code>wp-config.php<\/code>. <strong>The only address this plugin sends a request to.<\/strong><\/li>\n<li><code>checkout.stripe.com<\/code> \u2014 Stripe's payment page. No request is sent there; the address is present\nonly so the plugin can check that the payment page it was handed really is Stripe's (see\n\"Payments\" above).<\/li>\n<li><code>synth.locker<\/code> and <code>wordpress.synth.locker<\/code> \u2014 the terms, privacy, pricing and plugin home pages\nlinked above. Links for you to follow; nothing is sent to them.<\/li>\n<li><code>www.gnu.org<\/code> \u2014 the GPL licence text.<\/li>\n<li><code>your-synth-endpoint.example<\/code> and <code>https:\/\/x<\/code> \u2014 not addresses: a greyed-out example in the empty\nsettings field, and an example inside a code comment.<\/li>\n<\/ul>\n\n<!--section=installation-->\n<ol>\n<li>Install the plugin and activate it. Nothing happens on activation: the plugin attaches no\ncomment hooks and contacts nothing at all until it has been configured.<\/li>\n<li>Open Settings \u2192 Synth Antispam and press <strong>Get a site key<\/strong>. The button is shown while this\nsite has no key: pressing it asks the Synth Antispam service for a key and stores the key it\nissues, so there is nothing to copy by hand and no account to create. Nothing about your site\nis sent when you press it; the key attaches itself to this site the first time it checks a\ncomment. The <strong>Service address<\/strong> is already filled in with the Synth Antispam service and\nneeds no change. If somebody has already given you a key for this site, paste it into the\n<strong>Site key<\/strong> field instead and save; the button is not shown once a key is set, because asking\nfor a second key would revoke the one that works. An install that is never given a key simply\nstays unconfigured, and that state is safe: see step 5.<\/li>\n<li>The address can be overridden if you need a different deployment: change it on the settings\nscreen, or set <code>define('SYNTH_WP_API_BASE', 'https:\/\/\u2026');<\/code> in <code>wp-config.php<\/code>. A value set there\nwins over the stored one, and the field on the settings screen is then shown disabled, naming\nwhere its value came from.<\/li>\n<li>Press <strong>Test connection<\/strong>. It reports one of seven distinguishable states \u2014 success, no key set,\naddress not configured, invalid or revoked key, key issued to a different domain, monthly quota\nused up, or service temporarily unreachable \u2014 so a misconfiguration can be told apart from an\noutage before a single comment is sent.<\/li>\n<li>Until both fields are set, the plugin does nothing to your comments: no request leaves your\nsite, and every comment is published, held or marked exactly as WordPress and your own comment\nrules decide, as though the plugin were not installed. \"Test connection\" in that state reports\nthat the service address has not been configured for this install yet.<\/li>\n<li>While you are on that screen, choose the two fallbacks: what happens <strong>when the service is\nunreachable<\/strong> (publish the comment \u2014 the default \u2014 or hold it for review), and what happens\n<strong>when the monthly check quota is used up<\/strong> (let your site decide \u2014 the default \u2014 or hold the\ncomment until the quota resets). Both concern comments the service did not answer for; neither\nturns off anything this plugin does.<\/li>\n<\/ol>\n\n<p><strong>Multisite.<\/strong> Activating the plugin network-wide requires a network-level site key to be set\nalready: without one, activation is refused with a notice rather than silently doing nothing.\nActivating it on individual sites is unaffected. Where the network sets an address or a key, that\nvalue wins over a single site's own; where the network leaves the address unset, a site can still\nset its own.<\/p>\n\n<!--section=faq-->\n<dl>\n<dt id=\"does%20the%20plugin%20do%20anything%20before%20i%20give%20it%20a%20service%20address%20and%20a%20site%20key%3F\"><h3>Does the plugin do anything before I give it a service address and a site key?<\/h3><\/dt>\n<dd><p>No. With either one missing it attaches no comment hooks, so there is no code path that could\ncontact the service about a comment, and comments are handled by WordPress and your own comment\nrules exactly as they would be with the plugin absent. The two exceptions are buttons you press\nyourself on the settings screen \u2014 <strong>Get a site key<\/strong> and <strong>Test connection<\/strong> \u2014 and each sends a\nsingle request because that is what pressing it means. Neither carries anything about a comment or\na commenter, and neither is ever triggered on its own.<\/p><\/dd>\n<dt id=\"will%20it%20delete%20my%20comments%3F\"><h3>Will it delete my comments?<\/h3><\/dt>\n<dd><p>Never. It does not delete a comment and does not move one to Trash. A comment it marks as spam goes\nto the Spam folder and stays there until you empty that folder yourself; WordPress's own scheduled\ncleanup does not empty the Spam folder, so there is no deadline after which a mistake becomes\nunrecoverable.<\/p><\/dd>\n<dt id=\"can%20spam%20be%20held%20for%20review%20instead%20of%20going%20to%20the%20spam%20folder%3F\"><h3>Can spam be held for review instead of going to the Spam folder?<\/h3><\/dt>\n<dd><p>Yes \u2014 set <strong>Moderation mode<\/strong> to Strict on the settings screen, and the same comments go to the\nmoderation queue instead of the Spam folder.<\/p><\/dd>\n<dt id=\"what%20happens%20if%20the%20service%20is%20unreachable%3F\"><h3>What happens if the service is unreachable?<\/h3><\/dt>\n<dd><p>Whatever you chose under \"When the service is unreachable\": publish the comment (the default, so a\nvisitor never waits on an outage) or hold it for review. The verdict simply never arrives, and no\nother behaviour changes.<\/p><\/dd>\n<dt id=\"what%20happens%20when%20my%20monthly%20check%20quota%20is%20used%20up%3F\"><h3>What happens when my monthly check quota is used up?<\/h3><\/dt>\n<dd><p>The service stops answering new checks for your site until the period resets. Nothing in the plugin\nis switched off in response \u2014 no feature, mode or setting here is gated behind a tier or a payment\nstate, at any usage level. Comments meanwhile follow \"When the monthly check quota is used up\":\nreturned untouched to your site's own decision (the default), or held until the quota resets.<\/p><\/dd>\n<dt id=\"what%20happens%20to%20my%20site%20key%20if%20i%20delete%20the%20plugin%3F\"><h3>What happens to my site key if I delete the plugin?<\/h3><\/dt>\n<dd><p>It stays. Deleting the plugin removes everything else it stored here \u2014 its settings, the verdicts\nrecorded against your comments, its scheduled task, its local secret value \u2014 but the site key is\nleft in place, so installing the plugin again carries straight on with the same key and the same\nmonthly allowance of checks. That is deliberate: the key is stored only on your site, the service\nkeeps a one-way hash of it and cannot hand it back, so discarding it would cost you the checks\nattached to it and there would be no way to recover them.<\/p>\n\n<p>If you would rather leave nothing behind, tick <strong>Delete the site key when the plugin is deleted<\/strong> on\nthe settings screen before you delete the plugin. There is no way back from that: you can ask for a\nnew key afterwards, but it starts from nothing.<\/p>\n\n<p>On multisite the network-level key is a separate stored value, and the settings screen does not\nwrite it. A network administrator who wants it gone runs this before deleting the plugin:<\/p>\n\n<pre><code>wp site option patch insert synth_wp_settings purge_on_uninstall 1\n<\/code><\/pre>\n\n<p>(<code>insert<\/code> and not <code>update<\/code>: the network value has no such setting in it to begin with, and WP-CLI's\n    patch update refuses a key that is not already there.)<\/p><\/dd>\n<dt id=\"does%20it%20override%20akismet%2C%20or%20a%20decision%20i%20made%20by%20hand%3F\"><h3>Does it override Akismet, or a decision I made by hand?<\/h3><\/dt>\n<dd><p>No. A status already set by a moderator or by another moderation plugin is left alone rather than\noverridden. A comment your site has already refused \u2014 because another plugin marked it as spam, or\nbecause it hit your disallowed keyword list \u2014 is not sent to the service at all. A comment your site\nmerely held for review, through your moderation keyword list, is checked, but is never published\nover that hold.<\/p><\/dd>\n<dt id=\"which%20comments%20does%20it%20check%3F\"><h3>Which comments does it check?<\/h3><\/dt>\n<dd><p>Comments, pingbacks and trackbacks, whether submitted through the comment form, the REST API or\nXML-RPC. Authors who can moderate comments, and authors who already have an approved comment on\nyour site, are recognised as trusted before any request is built \u2014 their comments are never sent.<\/p><\/dd>\n<dt id=\"what%20is%20sent%20to%20the%20service%3F\"><h3>What is sent to the service?<\/h3><\/dt>\n<dd><p>The comment text and a small set of context fields, listed one by one under \"External services\"\nbelow. The commenter's full email address, IP address and raw User-Agent string are never sent.<\/p><\/dd>\n<dt id=\"does%20it%20work%20on%20multisite%3F\"><h3>Does it work on multisite?<\/h3><\/dt>\n<dd><p>Yes. Per-site activation works as usual; network-wide activation requires a network-level site key\nto be set first, and is refused with a notice if there is none.<\/p><\/dd>\n<dt id=\"for%20site%20owners%3A%20your%20obligations%20under%20gdpr%20and%20similar%20privacy%20laws\"><h3>For site owners: your obligations under GDPR and similar privacy laws<\/h3><\/dt>\n<dd><p>If any of your commenters are in the EU\/EEA\/UK, or another jurisdiction with comparable rules, using\nthis plugin makes the Synth Antispam service a data processor acting on your instructions, while\nyour site remains the data controller for its own comments. That adds to your existing obligations\nrather than replacing them. In practice:<\/p>\n\n<ol>\n<li><strong>Tell your visitors.<\/strong> Your privacy policy should name the Synth Antispam service, state that\ncomment data is sent to it to obtain a spam verdict, and list what is sent \u2014 the field list\nunder \"External services\" below.<\/li>\n<li><strong>Have a lawful basis for sending it.<\/strong> Spam prevention is commonly treated as a legitimate\ninterest, but that determination is yours to make for your own site and jurisdiction; this is not\nlegal advice.<\/li>\n<li><strong>Reflect retention accurately \u2014 both parts of it.<\/strong> State that verdicts are retained for 24\nhours and then expire automatically, <strong>and<\/strong> that the service keeps its own copy of the comment\ndata and the verdict indefinitely, with no expiry, to train and improve the Synth spam-classification models.\nThe second part is not optional to mention and applies to every site; see \"Retention\" under\n\"External services\" below. If your policy today says only the first part, it understates what\nhappens to your commenters' data.<\/li>\n<li><strong>Update your policy before this site has a key, not after<\/strong> \u2014 sending begins as soon as a valid\nkey is in place, however it got there.<\/li>\n<\/ol>\n\n<p>WordPress gives you a built-in place to do this: this plugin registers with the Privacy Policy Guide\n(Tools \u2192 Privacy \u2192 Policy Guide \u2192 \"Synth Antispam\"), which inserts ready-to-review text covering the\nsame fields and the same retention terms listed under \"External services\" below, for you to include\nin your published policy. If you\nwrite your policy by hand instead, here is that same list as a paste-ready paragraph, minus the four\nfields that describe the request's shape rather than the commenter or the submission \u2014\n    schema_version, <code>plugin_version<\/code>, <code>surface<\/code> and <code>object_type<\/code>. It is generated from the same\nmanifest as that field list, so it cannot fall behind it or over-claim beyond it:<\/p>\n\n<blockquote>\n  <p>Synth Antispam sends each comment (and each pingback or trackback) to the Synth Antispam\n  classification service \u2014 an external processor \u2014 to obtain a spam verdict. What is sent: the\n  comment body; the commenter\u2019s display name; the commenter\u2019s website URL; the domain part (not\n  the full address) of the commenter\u2019s email address; a one-way salted hash derived from that\n  email address; whether the commenter is anonymous or a registered user of this site; whether the\n  comment is a reply; the site\u2019s language; whether an IP address was present at all, never the\n  address itself; whether a User-Agent string was present at all, never the string itself.\n  Comments from people who already have an approved comment on this site are not sent to the\n  service at all. The commenter\u2019s full email address, IP address and raw User-Agent string are\n  never sent, in any case. Verdicts are retained by the service for 24 hours and then expire\n  automatically. Separately from that, the service keeps its own copy of everything listed above,\n  together with the verdict it produced and any correction a moderator of this site later makes to\n  that verdict, and uses those copies to train and improve the Synth spam-classification models. Those copies are\n  kept indefinitely and have no expiry date; the comment text and the commenter details above are\n  kept as sent, not anonymised or aggregated. This applies to every site that uses the service:\n  there is no setting that turns it off. To have this site\u2019s stored copies deleted, write to\n  support@synth.locker. Uninstalling this plugin deletes this site\u2019s local secret value, after\n  which any previously sent hash can no longer be linked back to an email address, by this site or\n  by the service.<\/p>\n<\/blockquote>\n\n<p>Note on the two values above: <code>context.author_status<\/code> carries <code>anonymous<\/code> or <code>registered<\/code> and\nnothing else, matching the field list under \"External services\" below. \"Returning\" and \"trusted\" are states\nin the plugin's own local bookkeeping only \u2014 a commenter in either state is recognised before any\nrequest is built, so their comment is never sent to the service at all and no status is transmitted\nfor them. A contract test compares this paragraph's enumeration against the value the plugin code\nactually assigns, so the two cannot drift apart.<\/p>\n\n<p>This plugin also implements WordPress's core personal-data <strong>export<\/strong> and <strong>erase<\/strong> tools (Tools \u2192\nExport Personal Data \/ Erase Personal Data), covering the classification records it stores locally\non your site.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>0.1.0<\/h4>\n\n<ul>\n<li>Plugin scaffold, surface-adapter interface, settings screen, connection test (T-493).<\/li>\n<\/ul>","raw_excerpt":"Synth is an AI antispam platform: every comment is read for what it sells, not string matches, and nothing is deleted. Get a site key in Settings.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/as.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/369761","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/as.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/as.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/as.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=369761"}],"author":[{"embeddable":true,"href":"https:\/\/as.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/synthplatform"}],"wp:attachment":[{"href":"https:\/\/as.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=369761"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/as.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=369761"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/as.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=369761"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/as.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=369761"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/as.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=369761"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/as.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=369761"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}