{"id":249247,"date":"2025-09-05T05:59:24","date_gmt":"2025-09-05T05:59:24","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/easy-meta-capi\/"},"modified":"2026-08-24T08:02:10","modified_gmt":"2026-08-24T08:02:10","slug":"easy-meta-capi","status":"publish","type":"plugin","link":"https:\/\/fa-af.wordpress.org\/plugins\/easy-meta-capi\/","author":23356298,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"3.9.2","stable_tag":"3.9.2","tested":"7.1","requires":"6.0","requires_php":"7.4","requires_plugins":null,"header_name":"CAPI Suite: Meta Pixel, Pinterest & TikTok for WooCommerce","header_author":"Suhan Duman","header_description":"Injects GTM and sends server-side events to the Meta Conversion API with a unified Data Layer.","assets_banners_color":"1c3462","last_updated":"2026-08-24 08:02:10","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"","header_author_uri":"https:\/\/profiles.wordpress.org\/suhanduman\/","rating":5,"author_block_rating":0,"active_installs":60,"downloads":2146,"num_ratings":1,"support_threads":1,"support_threads_resolved":1,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"3.1.0":{"tag":"3.1.0","author":"suhanduman","date":"2025-09-29 10:48:49"},"3.1.1":{"tag":"3.1.1","author":"suhanduman","date":"2025-09-29 11:54:37"},"3.2.0":{"tag":"3.2.0","author":"suhanduman","date":"2026-04-16 13:47:32"},"3.2.1":{"tag":"3.2.1","author":"suhanduman","date":"2026-04-16 14:42:02"},"3.2.2":{"tag":"3.2.2","author":"suhanduman","date":"2026-04-18 14:18:43"},"3.2.3":{"tag":"3.2.3","author":"suhanduman","date":"2026-04-21 07:52:09"},"3.2.4":{"tag":"3.2.4","author":"suhanduman","date":"2026-04-21 08:01:43"},"3.2.5":{"tag":"3.2.5","author":"suhanduman","date":"2026-04-22 18:29:08"},"3.2.6":{"tag":"3.2.6","author":"suhanduman","date":"2026-04-22 18:37:43"},"3.3.0":{"tag":"3.3.0","author":"suhanduman","date":"2026-04-22 19:18:11"},"3.4.0":{"tag":"3.4.0","author":"suhanduman","date":"2026-05-04 15:41:27"},"3.4.1":{"tag":"3.4.1","author":"suhanduman","date":"2026-05-04 16:01:56"},"3.4.2":{"tag":"3.4.2","author":"suhanduman","date":"2026-05-04 16:29:53"},"3.5.0":{"tag":"3.5.0","author":"suhanduman","date":"2026-05-06 15:43:10"},"3.5.1":{"tag":"3.5.1","author":"suhanduman","date":"2026-05-06 17:53:08"},"3.5.2":{"tag":"3.5.2","author":"suhanduman","date":"2026-05-06 19:19:51"},"3.5.3":{"tag":"3.5.3","author":"suhanduman","date":"2026-05-07 10:41:35"},"3.6.0":{"tag":"3.6.0","author":"suhanduman","date":"2026-05-11 14:49:25"},"3.7.0":{"tag":"3.7.0","author":"suhanduman","date":"2026-05-28 13:21:21"},"3.7.1":{"tag":"3.7.1","author":"suhanduman","date":"2026-05-31 12:33:16"},"3.7.2":{"tag":"3.7.2","author":"suhanduman","date":"2026-06-16 14:13:35"},"3.8.0":{"tag":"3.8.0","author":"suhanduman","date":"2026-08-15 16:52:02"},"3.8.1":{"tag":"3.8.1","author":"suhanduman","date":"2026-08-15 21:46:10"},"3.9.2":{"tag":"3.9.2","author":"suhanduman","date":"2026-08-24 08:02:10"}},"upgrade_notice":{"3.9.2":"<p>Plainer wording on the settings screens. From 3.8.x you also get 3.9.0-3.9.1: hashed contact details kept up to 180 days, two first-party cookies, and a new privacy-policy section to review. An unanswered consent banner now counts as no consent, so match quality may read lower than before.<\/p>","3.9.1":"<p>Fixes identity records being orphaned by a security-salt rotation (WordPress secret keys changed), pruning them safely now. By-IP column labels, GTM manual, and DSAR export labels are clearer. A one-time review request appears after your first successful Purchase. No action needed.<\/p>","3.9.0":"<p>This release stores hashed contact details for up to 180 days to improve ad match quality, and sets two first-party cookies. Nothing is stored where marketing consent is refused \u2014 and minting a visitor identifier is now consent-gated too, so on a CMP-equipped store with consent unanswered, guests get NO external_id where 3.8.1 minted one unconditionally; you may see PageView match quality fall after updating. Review your privacy policy \u2014 the plugin now contributes its own section to the one WordPress generates.<\/p>","3.8.1":"<p>Fixes an order paid after checkout reporting your server&#039;s own IP address as the\ncustomer&#039;s, which cost match quality on every purchase through a redirect payment\ngateway, and a related issue where updating an order&#039;s status yourself in wp-admin\ncould attach your own browsing identity to that customer&#039;s purchase. Also sends more\nidentifying detail with each event, all of it respecting existing consent settings.\nNo action needed.<\/p>","3.8.0":"<p><strong>Critical: GTM template re-import required \u2014 TikTok double-counting otherwise.<\/strong> TikTok\nrenamed its event names in 2025 (<code>CompletePayment<\/code> \u2192 <code>Purchase<\/code>, <code>SubmitForm<\/code> \u2192 <code>Lead<\/code>); the\nserver-side CAPI call sends the new name, but the bundled GTM template&#039;s TikTok Purchase tag\nstill sent the retired <code>CompletePayment<\/code> name until this release. TikTok deduplicates browser\nand server events by event name plus <code>event_id<\/code> \u2014 with the two sides disagreeing, dedup never\nmatched and <strong>every TikTok purchase reported twice<\/strong>. Re-download <code>gtm-template.json<\/code> from\nMain Settings and re-import your GTM container in <strong>Merge<\/strong> mode (or edit the &quot;TikTok -\nPurchase&quot; tag&#039;s Event Name to <code>Purchase<\/code> manually \u2014 see <code>docs\/GTM-MANUAL-SETUP.txt<\/code>).\n<strong>Behaviour change: Purchase now waits for a paid order status.<\/strong> Previously a Purchase was\nsent as soon as the order-received page loaded, even when payment had failed \u2014 so an\nabandoned payment at a redirect gateway still counted as a sale in Meta. It is now sent when\nthe order reaches a paid status (by default whatever WooCommerce treats as paid, plus On\nhold), and if that happens later the event is sent then, even if the customer never returns.\nStores with a custom order status should check <strong>Event Management \u2192 Send Purchase when the\norder is<\/strong> after updating; a one-time notice points you there. Also fixes a bug where one\nstale queued event could silently discard a whole batch of valid ones. Also corrects\nidentity-field normalization, so hashed customer data actually matches, and keeps ad-click\nIDs attached to orders that are paid after checkout.<\/p>","3.7.2":"<p><strong>Hotfix for a 3.7.1 dispatch-halt regression.<\/strong> Sites where Action Scheduler marked <code>mcapi_process_event_queue<\/code> as &quot;failed after 300 seconds&quot; auto-recover on update. Plus three additional bot\/human detection signals: Cloudflare Bot Management score header (if you forward it to your origin), <code>navigator.webdriver<\/code> browser-automation flag, and <code>ip_state.human_score &amp;gt;= 100<\/code> strong-trust now qualifies as a Customer signal on its own.<\/p>","3.7.1":"<p>Browser-side AddToCart dataLayer push restored on themes that don&#039;t render a WC cart widget (was silently lost \u2014 server-side CAPI was always firing). Behavioral bot filter no longer leaks 3-5 event burst patterns into trusted state. Two small admin hygiene fixes.<\/p>","3.7.0":"<p>Event Log gains a By-IP grouped view and customer-protection badges that prevent excluding real buyers by mistake. AI crawlers (GPTBot, PerplexityBot, ClaudeBot, etc.) classified separately from bots with their own counter on the Dashboard. Block-list terminology clarified to Exclude (it filters CAPI dispatch, not site access). Google Ads Enhanced Conversions and Pinterest <code>_epik<\/code> capture continue from earlier work \u2014 re-import the GTM template if you haven&#039;t yet. One additive DB column on upgrade (instant DDL on InnoDB 5.7+ \/ MariaDB 10.3+).<\/p>","3.6.0":"<p>TikTok CAPI added. Plugin renamed to CAPI Suite. Behavioral bot detection (VPN shoppers no longer misclassified). Blocklist DB tables (IPv4+IPv6) with per-source toggle and one-click CIDR block on Event Log rows. CCPA toggle. Re-import the GTM template for TikTok tags.<\/p>","3.5.3":"<p>Reliability fixes. (1) Spurious AJAX add_to_cart events from sessionStorage fragment replay eliminated. (2) Per-platform queue retry: only the failing side is retried. (3) Event Log captures User Agent, supports date-range filtering, retention configurable. No GTM template change.<\/p>","3.5.2":"<p><strong>Critical: GTM template re-import required.<\/strong> Bundled template migrated to modern GTM API schema. Older templates rejected with &quot;File format invalid&quot;\/&quot;Unknown entity type&quot;. Re-download and re-import in Merge mode. Plugin runtime unchanged.<\/p>","3.5.1":"<p><strong>Critical hotfix.<\/strong> v3.5.0&#039;s CMP detection helper called class_exists() without disabling autoload, triggering CookieYes \/ Cookie Law Info fatal errors (white screen). Update immediately if you have either plugin installed.<\/p>","3.5.0":"<p><strong>GTM template re-import required.<\/strong> Fixes import-error bug (&quot;Unrecognized value [customEvent]&quot;). Adds Consent Mode v2, CMP auto-block exemptions (CookieYes\/Cookiebot\/Complianz), and WooCommerce Subscriptions integration. Server-side CAPI unchanged.<\/p>","3.4.2":"<p><strong>Action required for existing installs.<\/strong> Fixes a GA4-schema bug causing Meta Events Manager to reject browser-tag parameters. Re-import the GTM template (&quot;Merge&quot; mode) OR add two new Custom JavaScript variables manually.<\/p>"},"ratings":{"1":0,"2":0,"3":0,"4":0,"5":1},"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3528853,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3528853,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3528853,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3528853,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["3.1.0","3.1.1","3.2.0","3.2.1","3.2.2","3.2.3","3.2.4","3.2.5","3.2.6","3.3.0","3.4.0","3.4.1","3.4.2","3.5.0","3.5.1","3.5.2","3.5.3","3.6.0","3.7.0","3.7.1","3.7.2","3.8.0","3.8.1","3.9.2"],"block_files":[],"assets_screenshots":[],"screenshots":[]},"plugin_section":[262246],"plugin_tags":[195844,7855,207498,167802,179062],"plugin_category":[45],"plugin_contributors":[247430],"plugin_business_model":[],"class_list":["post-249247","plugin","type-plugin","status-publish","hentry","plugin_section-dashboard-widgets","plugin_tags-conversions-api","plugin_tags-facebook-pixel","plugin_tags-meta-pixel","plugin_tags-pinterest-tag","plugin_tags-tiktok-pixel","plugin_category-ecommerce","plugin_contributors-suhanduman","plugin_committers-suhanduman"],"banners":{"banner":"https:\/\/ps.w.org\/easy-meta-capi\/assets\/banner-772x250.png?rev=3528853","banner_2x":"https:\/\/ps.w.org\/easy-meta-capi\/assets\/banner-1544x500.png?rev=3528853","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/easy-meta-capi\/assets\/icon-128x128.png?rev=3528853","icon_2x":"https:\/\/ps.w.org\/easy-meta-capi\/assets\/icon-256x256.png?rev=3528853","generated":false},"screenshots":[],"raw_content":"<!--section=description-->\n<p><strong>Meta Pixel, Pinterest and TikTok, sent server-side, in one free plugin.<\/strong> A bundled Google Tag Manager template covers browser-side tracking. Sixteen events you switch on individually \u2014 PageView, ViewContent, ViewCategory, SelectItem, AddToCart, ViewCart, InitiateCheckout, AddShippingInfo, AddPaymentInfo, Purchase, Search, CompleteRegistration, AddToWishlist, Lead, Login and Comment \u2014 plus subscription renewals handled on their own terms. Classic and block-based checkout, HPOS compatible, each platform retried independently on failure. No cloud server to rent, no premium tier to unlock, no event limit.<\/p>\n\n<p><strong>Your match quality climbs on its own after you update.<\/strong> Twenty identity parameters are assembled per event and normalised exactly the way Meta requires before they are hashed. The hashed keys are then remembered for up to 180 days behind a consent gate, so a returning visitor arrives already identified instead of anonymous. Nothing raw is ever written to disk: only salted SHA-256 hashes, which survive even a WordPress security-key rotation.<\/p>\n\n<p><strong>Attribution survives the whole journey, not just the click.<\/strong> Eight click identifiers are captured and kept \u2014 <code>fbclid<\/code>, <code>gclid<\/code>, <code>wbraid<\/code>, <code>gbraid<\/code>, <code>ttclid<\/code>, <code>pina_id<\/code>, <code>_epik<\/code> and <code>_ttp<\/code> \u2014 written into first-party cookies client-side so a cached landing page never loses them, then persisted onto the order so a payment that completes days later is still credited to the campaign that earned it. Subscription renewals inherit the original order's identifiers instead of being credited to a fresh ad.<\/p>\n\n<p><strong>Bots don't get counted as customers \u2014 and real shoppers on a VPN still are.<\/strong> Datacenter ranges are weighed against actual browser behaviour: mouse movement, scrolling, and whether a cart ever appears. A doubtful visit is held rather than thrown away, and if that visitor goes on to act like a real person, the whole funnel is released and reported retroactively. Purchases are never held back while any of this is decided. Apple iCloud Private Relay and corporate VPN egress ranges are recognised as real people, not as datacenters.<\/p>\n\n<p><strong>Safari visitors stay attributable for 90 days, not 7.<\/strong> The cookie is written by the server, so Safari's seven-day cap on script-written cookies stops resetting the visitor every week.<\/p>\n\n<p><strong>Your orders are counted once, not twice.<\/strong> The same event ID goes out browser-side and server-side within Meta's 48-hour deduplication window, so each platform matches them up instead of double-counting. A browser event that falls outside the window is suppressed rather than sent as a second conversion.<\/p>\n\n<p><strong>You keep your analytics when a visitor declines cookies.<\/strong> The event still goes through for counting, with personal details stripped out first. Five consent platforms are recognised automatically \u2014 CookieYes, Cookiebot, Complianz, iubenda and Termly \u2014 and a filter covers anything else, including OneTrust, Usercentrics and hand-rolled banners.<\/p>\n\n<h4>Built like infrastructure, not like a tracking snippet<\/h4>\n\n<ul>\n<li><strong>Nothing is lost when a platform has a bad minute.<\/strong> Events queue and retry per platform: if Meta accepts an event and Pinterest times out, only Pinterest is retried. Dispatch runs on Action Scheduler rather than WP-Cron, so a stalled queue is visible and recoverable instead of silent.<\/li>\n<li><strong>Built for shared hosting.<\/strong> Counters are incremented atomically in SQL rather than read-modify-written, so overlapping requests cannot lose each other's work. The bot blocklist is stored as roughly 10,000 pre-computed numeric ranges queried through a database index, not as a text list parsed on every request.<\/li>\n<li><strong>The REST endpoint is not an open door.<\/strong> Events are signed with a rotating HMAC token, nonce-verified where a form is involved, and rate-limited per IP \u2014 with the limiter backed by a database table so it still works on hosts with no object cache.<\/li>\n<li><strong>A bundled GTM template gets your browser-side tags running in minutes.<\/strong> 29 tags, 11 triggers and 15 variables covering GA4, Meta Pixel, Pinterest Tag, TikTok Pixel and Google Ads, with Enhanced Conversions and Conversion Linker already attached \u2014 normally an afternoon of manual GTM work. A written manual is included for anyone who would rather build it by hand.<\/li>\n<li><strong>You can see exactly what was sent, and undo a bad exclude.<\/strong> The Event Log shows the identity parameters that went out with each event and the platform's own response. Its By-IP view groups repeat traffic together, flags real buyers so you don't accidentally exclude them, and excludes a confirmed bot in one click.<\/li>\n<li><strong>Page caching stays on.<\/strong> Works with LiteSpeed, WP Rocket, Varnish and Cloudflare full-page cache.<\/li>\n<li><strong>Queue health is visible from your WordPress dashboard.<\/strong> A widget shows backlog size, the oldest pending event, and when the last dispatch succeeded, so a stuck queue doesn't go unnoticed.<\/li>\n<li><strong>The bot blocklist maintains itself.<\/strong> Ranges for nine cloud providers ship with the plugin and refresh daily in the background. You can add your own, exclude any rule you disagree with, and download the active list as plain text.<\/li>\n<li><strong>Test before you trust it.<\/strong> Send a test event to Meta or TikTok from the settings page and watch it arrive in Events Manager, with test-event codes handled for you.<\/li>\n<li><strong>Privacy work is already done.<\/strong> The plugin registers with WordPress's personal-data export and erasure tools, contributes its own section to the privacy policy WordPress generates for you, and stores IP addresses only as salted hashes.<\/li>\n<\/ul>\n\n<h4>What this plugin stores<\/h4>\n\n<p>To match server-side conversion events to the right person, the plugin stores <strong>SHA-256 hashes<\/strong> of contact details a visitor provides \u2014 email, phone, name and address components \u2014 against an opaque visitor identifier. <strong>Raw contact details are never written to disk<\/strong>; values are hashed before storage and the hash cannot be reversed.<\/p>\n\n<ul>\n<li><strong>Two first-party cookies.<\/strong> An opaque visitor identifier (1 year) and a Meta-format browser identifier <code>_fbp<\/code> (90 days).<\/li>\n<li><strong>180-day retention.<\/strong> Records are deleted 180 days after they were last seen. Filterable via <code>mcapi_identity_retention_days<\/code>.<\/li>\n<li><strong>Consent-gated.<\/strong> Nothing is stored, and nothing already stored is read, where marketing consent has been refused. Withdrawing consent expires both cookies and deletes the stored record.<\/li>\n<li><strong>Privacy tools.<\/strong> WordPress's personal-data export and erasure both cover this data.<\/li>\n<li><strong>Shared devices.<\/strong> A stored record is replaced whenever a new person identifies themselves and is deleted at logout. A second person who only browses without identifying themselves is covered by the 180-day expiry rather than by an immediate reset \u2014 worth knowing if your customers use shared or public computers.<\/li>\n<\/ul>\n\n<h3>Our Philosophy<\/h3>\n\n<p>This plugin is free. Not \"free with limits\" \u2014 just free. Every feature works, there is no pro version waiting behind a paywall, and the code is GPL, so you can read every line that touches your customers' data.<\/p>\n\n<h3>External Services<\/h3>\n\n<p>This plugin connects your website to external services to send event data.<\/p>\n\n<ul>\n<li><strong>Service Used:<\/strong> Meta Conversion API (graph.facebook.com)\n\n<ul>\n<li><strong>Purpose:<\/strong> To send user interaction and e-commerce event data from your server to Meta's servers for ad performance measurement, optimization, and audience building.<\/li>\n<li><strong>Data Sent:<\/strong> Event details (product ID, price) and user parameters (IP address, user agent, hashed email\/name\/phone, Facebook cookies) are sent when a user performs a key action.<\/li>\n<\/ul><\/li>\n<li><strong>Service Used:<\/strong> TikTok Events API (business-api.tiktok.com)\n\n<ul>\n<li><strong>Purpose:<\/strong> Same as Meta CAPI, providing server-side conversion tracking for TikTok Ads optimization and attribution.<\/li>\n<li><strong>Data Sent:<\/strong> Event details (product ID, price, currency) and user parameters (IP address, user agent, hashed email\/phone\/external_id, ttp \/ ttclid cookies) are sent upon user action. Optional under the merchant's TikTok credentials \u2014 the plugin only sends to TikTok if the credentials are configured.<\/li>\n<\/ul><\/li>\n<li><strong>Service Used:<\/strong> Pinterest Conversions API (api.pinterest.com)\n\n<ul>\n<li><strong>Purpose:<\/strong> Same as the Meta CAPI, providing reliable tracking for ad performance and audience building on Pinterest.<\/li>\n<li><strong>Data Sent:<\/strong> Event details and hashed user parameters are sent upon user action.<\/li>\n<\/ul><\/li>\n<li><strong>Service Used:<\/strong> Google Tag Manager (googletagmanager.com)\n\n<ul>\n<li><strong>Purpose:<\/strong> To load a JavaScript container from Google's servers that allows you to manage and deploy marketing and analytics tags.<\/li>\n<li><strong>Data Sent:<\/strong> The plugin provides your GTM Container ID to Google to fetch the correct script. GTM itself may collect data based on how you configure your tags.<\/li>\n<\/ul><\/li>\n<li><strong>Service Used:<\/strong> Cloud-provider IP range list \u2014 <code>raw.githubusercontent.com\/rezmoss\/cloud-provider-ip-addresses<\/code>\n\n<ul>\n<li><strong>Purpose:<\/strong> Used by the optional <strong>Datacenter IP filter<\/strong> to keep the bot blocklist current. Daily background fetch downloads CIDR ranges for AWS, Google Cloud, Azure, Cloudflare, DigitalOcean, Linode, Vultr, Oracle Cloud, and Fastly so events from those ranges can be filtered out before reaching Meta \/ Pinterest \/ TikTok.<\/li>\n<li><strong>Data Sent:<\/strong> None. The plugin only downloads public IP-range manifests; no visitor data is sent to GitHub.<\/li>\n<li><strong>License:<\/strong> Source repository is CC0-licensed.<\/li>\n<\/ul><\/li>\n<li><strong>Service Used:<\/strong> Apple iCloud Private Relay egress IP list \u2014 same <code>raw.githubusercontent.com\/rezmoss\/cloud-provider-ip-addresses<\/code> source (folder <code>apple_private_relay\/<\/code>)\n\n<ul>\n<li><strong>Purpose:<\/strong> Used by the optional <strong>Datacenter IP filter<\/strong> to whitelist real Apple visitors who exit through Apple's relay infrastructure. Daily background fetch downloads the merged CIDR list so iOS Safari users on Private Relay aren't mistaken for datacenter bots.<\/li>\n<li><strong>Data Sent:<\/strong> None. The plugin only downloads the public manifest; no visitor data is sent.<\/li>\n<\/ul><\/li>\n<\/ul>\n\n<p><strong>Shared hosting note.<\/strong> Some restrictive shared hosts block outbound HTTPS by default. If event delivery silently fails after install, ask your host to whitelist the following domains for outgoing connections: <code>graph.facebook.com<\/code>, <code>business-api.tiktok.com<\/code>, <code>api.pinterest.com<\/code>, and <code>raw.githubusercontent.com<\/code> (only needed if you keep \"Auto-fetched\" enabled on the Blocked Traffic tab \u2014 covers both the datacenter blocklist and the Apple Private Relay whitelist).<\/p>\n\n<h3>Disclaimer<\/h3>\n\n<p>This plugin is an independent, community-driven implementation of server-side Conversions API protocols. It is not affiliated with, endorsed by, or sponsored by Meta Platforms, Inc., TikTok Ltd., Pinterest, Inc., Google LLC, Automattic Inc., or any other trademark holder referenced herein.<\/p>\n\n<p>\"Meta\", \"Facebook\", and the Meta Pixel are trademarks of Meta Platforms, Inc. \"TikTok\" is a trademark of TikTok Ltd. \"Pinterest\" is a trademark of Pinterest, Inc. \"Google Tag Manager\", \"Google Ads\", and \"GA4\" are trademarks of Google LLC. \"WooCommerce\" is a trademark of Automattic Inc. All trademark references are used solely for descriptive interoperability purposes \u2014 to indicate which platforms this plugin can transmit data to under the merchant's own configured credentials.<\/p>\n\n<p>No user data is transmitted to any external service until the merchant explicitly configures their own platform credentials in the plugin settings. The plugin does not \"phone home\" or contact any developer-controlled server. The only outbound HTTP calls are: (1) merchant-configured CAPI endpoints, (2) the public CIDR manifests at raw.githubusercontent.com used by the optional Datacenter IP filter \u2014 no visitor data is sent in those manifest fetches.<\/p>\n\n<!--section=installation-->\n<h3>Quick start (3 steps)<\/h3>\n\n<ol>\n<li>Install and activate the plugin. WooCommerce must already be active.<\/li>\n<li>Open <strong>CAPI Suite \u2192 Main Settings<\/strong> and paste your <strong>Meta Pixel ID + Access Token<\/strong>. Add <strong>TikTok<\/strong> and\/or <strong>Pinterest<\/strong> credentials if you use them. Empty fields for platforms you don't use are fine.<\/li>\n<li><em>(If you use GTM)<\/em> Download the bundled <code>gtm-template.json<\/code> from the <strong>GTM Container ID<\/strong> box, import it into your GTM container in <strong>Merge<\/strong> mode, set the pixel-code constants to your real IDs, and publish.<\/li>\n<\/ol>\n\n<p>Server-side events start flowing on the next page view. Send a test from <strong>Event Management \u2192 Test Modes<\/strong> to verify credentials before going live.<\/p>\n\n<h3>Recommended GTM dedup configuration<\/h3>\n\n<p>To prevent duplicate browser+server events:<\/p>\n\n<ol>\n<li>In <strong>Meta Events Manager \u2192 your Pixel \u2192 Settings \u2192 Event Setup<\/strong>, turn <strong>off<\/strong> \"Track Events Automatically Without Code\". This plugin handles all event sending.<\/li>\n<li>In your GTM container, pause or delete any auto-created tags starting with <code>FB_<\/code>.<\/li>\n<\/ol>\n\n<p>The bundled GTM template ships GA4 + Meta tags pre-wired to the GA4 ecommerce dataLayer, plus TikTok tags that read from a <code>CONST - TikTok Pixel Code<\/code> variable. Pinterest tags are added manually because the Community Template can fail to import inside container exports.<\/p>\n\n<p>If you cannot import the JSON template (locked container, workspace permissions) or want to set up GTM manually, the full step-by-step walkthrough ships with the plugin at <code>wp-content\/plugins\/easy-meta-capi\/docs\/GTM-MANUAL-SETUP.txt<\/code>.<\/p>\n\n<h3>Verify<\/h3>\n\n<p>Open <strong>CAPI Suite \u2192 Event Log<\/strong> after browsing your store. Successful dispatches show as \"Success (Meta)\" \/ \"Success (TikTok)\" \/ \"Success (Pinterest)\". The Dashboard widget shows queue health at a glance.<\/p>\n\n<p>If the log stays empty, a JS optimizer is probably deferring the plugin's inline scripts \u2014 see the cache-plugin FAQ. Detailed GTM setup, Google Ads Enhanced Conversions, and other platform tags live in <code>docs\/GTM-MANUAL-SETUP.txt<\/code>. Consent Mode v2, Strict server-side consent, CMP auto-block, and WC Subscriptions are documented under <strong>Advanced Configuration<\/strong> below.<\/p>\n\n<h4>Advanced Configuration<\/h4>\n\n<p>Setup details for Consent Mode v2, the strict server-side consent mode (GDPR PII gating), CMP auto-block compatibility, and the WooCommerce Subscriptions integration. None of these are required for a basic CAPI setup \u2014 turn them on as your store needs them.<\/p>\n\n<h3>Consent Mode v2 Setup (GDPR \/ EU Compliance)<\/h3>\n\n<p>If you serve EU visitors, GA4 and Meta browser tags don't fire when consent is denied \u2014 typically losing <strong>20\u201350% of measured event volume<\/strong>. Google Consent Mode v2 recovers this: when consent is denied, GA4 \/ Meta tags switch to <strong>cookieless pings<\/strong> (anonymous beacons carrying event name, value, currency, timestamp but no client identifier). Google's ML models the conversions from these pings and shows them mixed with observed ones in your reports. A single CMP integration repairs both GA4 and Meta attribution because the Meta Pixel template reads the same consent signals.<\/p>\n\n<p><strong>How to enable.<\/strong> Popular CMP plugins (Cookiebot, CookieYes, Complianz, Iubenda, Termly, OneTrust) all have a native Consent Mode v2 toggle in their settings \u2014 find and enable it. The CMP then calls <code>gtag('consent', 'default', {denied})<\/code> before GTM loads and <code>gtag('consent', 'update', {granted})<\/code> after the visitor accepts.<\/p>\n\n<p>The bundled GTM template includes a paused <strong>\"Consent Defaults (Pre-CMP)\"<\/strong> tag. Enable it only if your CMP doesn't set <code>gtag('consent', 'default', ...)<\/code> on its own (rare with modern CMPs).<\/p>\n\n<h3>Strict server-side consent mode (PII gating for CAPI)<\/h3>\n\n<p>Consent Mode v2 only controls <strong>browser<\/strong> tags. Server-side CAPI fires from PHP, never sees <code>gtag('consent', ...)<\/code> signals \u2014 so it transmits hashed PII regardless of cookie-banner choice. Fine outside the EU; a GDPR concern inside it.<\/p>\n\n<p>The <strong>Privacy &amp; Consent (Server-side)<\/strong> section has a Strict server-side consent toggle (default OFF). When enabled and the visitor has denied marketing consent in your CMP, identifying PII (<code>em<\/code>, <code>ph<\/code>, <code>fn<\/code>, <code>ln<\/code>, address, <code>fbp<\/code>, <code>fbc<\/code> \u2026) is stripped from the CAPI payload. The event still ships with <code>event_id<\/code>, <code>value<\/code>, <code>currency<\/code>, <code>contents<\/code> \u2014 Cookiebot, CookieYes, and Complianz cookies are read automatically; other CMPs supply state via the <code>mcapi_marketing_consent_granted<\/code> filter.<\/p>\n\n<p><strong>Why this matters alongside Consent Mode v2.<\/strong> Denied-consent browser pixels switch to cookieless pings \u2014 modeled, not observed. With Strict server-side consent ON, your server-side CAPI ships alongside that ping carrying the same <code>event_id<\/code>. Meta dedupes by <code>event_id<\/code> and now has an <strong>observed<\/strong> server signal feeding the same conversion record the cookieless ping created \u2014 cleaner Event Match Quality than browser-only or na\u00efve \"send everything\" CAPI, and GDPR-defensible because no identifying data leaves your server.<\/p>\n\n<p>Default OFF preserves match quality for existing non-EU setups. Recommended ON once Consent Mode v2 is configured in your CMP.<\/p>\n\n<h3>CMP Auto-Blocking and the Plugin's Inline Scripts<\/h3>\n\n<p>CMPs with \"auto-blocking\" (Cookiebot, CookieYes, others) scan every <code>&lt;script&gt;<\/code> tag on load and convert anything they suspect of tracking to <code>type=\"text\/plain\"<\/code> until consent. The plugin's inline scripts only POST first-party events to your own REST endpoint \u2014 but a generic auto-blocker can't tell. To avoid a silent break, every plugin-rendered inline script ships with opt-out attributes for Cookiebot (<code>data-cookieconsent=\"ignore\"<\/code>), CookieYes (<code>data-cookieyes=\"cookieyes-necessary\"<\/code>), and Complianz (<code>data-cmplz-no-cookielaw=\"1\"<\/code>). For other CMPs (OneTrust, Quantcast, in-house), append your own attribute via the <code>mcapi_inline_script_attrs<\/code> filter.<\/p>\n\n<h3>WooCommerce Subscriptions Integration<\/h3>\n\n<p>By default, every WooCommerce Subscriptions auto-renewal sends a fresh <code>Purchase<\/code> to Meta CAPI \u2014 credited to the original acquisition ad. Reported ROAS keeps climbing month after month from the same conversion, polluting optimization signals.<\/p>\n\n<p>The plugin auto-detects WooCommerce Subscriptions and exposes:<\/p>\n\n<p><strong>Subscription Renewal Behavior<\/strong> (radio):<\/p>\n\n<ul>\n<li><strong>Default<\/strong> \u2014 renewals send as regular <code>Purchase<\/code>. Existing setups unchanged.<\/li>\n<li><strong>Skip<\/strong> \u2014 renewals not sent. Cleanest ROAS hygiene; you forfeit Meta's LTV signal from renewals.<\/li>\n<li><strong>Tag<\/strong> \u2014 renewals still send <code>Purchase<\/code> but with <code>custom_data.customer_status = \"subscription_renewal\"<\/code> so you can filter them in Events Manager.<\/li>\n<li><strong>Subscribe \/ SubscriptionRenewal events<\/strong> \u2014 Meta's standard <code>Subscribe<\/code> for sign-ups + a <code>SubscriptionRenewal<\/code> custom event for renewals. <code>Purchase<\/code> stays clean, advertisers using LTV-bidding can opt into both.<\/li>\n<\/ul>\n\n<p><strong>Tag every Purchase with customer_status<\/strong> (checkbox): adds <code>custom_data.customer_status<\/code> (<code>new_customer<\/code> \/ <code>returning_customer<\/code> \/ <code>subscription_renewal<\/code>) to every <code>Purchase<\/code> so Meta Advantage+ can bid acquisition vs. retention differently. Guest checkouts fall back to billing-email lookup.<\/p>\n\n<h3>X-Forwarded-For Hop Count (advanced proxy setups)<\/h3>\n\n<p>Behind a trusted reverse proxy, the real-IP resolver walks <code>X-Forwarded-For<\/code> from the right, skipping entries that look like trusted infrastructure (a known proxy CIDR or a private\/reserved address), and uses the first one that doesn't. This defeats the common attack of forging a leftmost entry, but it has a residual gap: if your proxy is configured to pass <code>X-Forwarded-For<\/code> through <strong>unmodified<\/strong> instead of appending the hop it actually witnessed (nginx's <code>proxy_set_header X-Forwarded-For $http_x_forwarded_for<\/code> instead of <code>$proxy_add_x_forwarded_for<\/code> is the classic case), every entry in the header is client-controlled \u2014 a visitor can append a filler value that merely <em>resembles<\/em> infrastructure (e.g. a private-looking address) and have an earlier, forged entry accepted as their IP instead.<\/p>\n\n<p>The plugin cannot detect this misconfiguration or infer your real proxy hop count on its own. If you know it \u2014 one hop for a single reverse proxy, more for a CDN plus a local proxy \u2014 set it with the <code>mcapi_trusted_proxy_hops<\/code> filter:<\/p>\n\n<pre><code>add_filter( 'mcapi_trusted_proxy_hops', function() { return 1; } );\n<\/code><\/pre>\n\n<p>This bounds how many trailing hops the walk will ever treat as trusted-and-skippable; once that many are skipped it stops rather than continuing further left, so a crafted filler hop beyond the boundary can no longer push an attacker-chosen address through. Default is unbounded (today's behaviour) \u2014 leave it unset unless you are certain of your topology, since too low a value can make the walk stop before reaching a real client hop.<\/p>\n\n<!--section=faq-->\n<dl>\n<dt id=\"does%20this%20plugin%20replace%20the%20meta%20pixel%3F\"><h3>Does this plugin replace the Meta Pixel?<\/h3><\/dt>\n<dd><p>No, it works alongside it. The plugin sends server-side (CAPI) events, while GTM handles the browser-side Pixel. Both use the same <code>event_id<\/code>, so Meta merges them automatically without counting anything twice.<\/p><\/dd>\n<dt id=\"what%20is%20the%20difference%20between%20this%20and%20a%20gtm%20server%20container%3F\"><h3>What is the difference between this and a GTM Server Container?<\/h3><\/dt>\n<dd><p>A GTM Server Container runs on Google Cloud and costs money every month. This plugin does the same job directly from your WordPress server \u2014 no extra infrastructure, no extra bill.<\/p><\/dd>\n<dt id=\"does%20it%20work%20with%20page%20caching%20plugins%20%28wp%20rocket%2C%20litespeed%2C%20etc.%29%3F\"><h3>Does it work with page caching plugins (WP Rocket, LiteSpeed, etc.)?<\/h3><\/dt>\n<dd><p>Yes. PageView and ViewCategory events fire from JavaScript, so they work even on fully cached pages. Cart, checkout, and purchase pages are not cached by default.<\/p><\/dd>\n<dt id=\"what%20plugins%20are%20required%3F\"><h3>What plugins are required?<\/h3><\/dt>\n<dd><p>WooCommerce. That's it. If you use other GTM plugins (like Google Site Kit), disable their e-commerce features to avoid conflicts.<\/p><\/dd>\n<dt id=\"is%20there%20a%20pro%20version%3F\"><h3>Is there a pro version?<\/h3><\/dt>\n<dd><p>No. Everything is included.<\/p><\/dd>\n<dt id=\"my%20events%20aren%27t%20showing%20in%20meta%20events%20manager.\"><h3>My events aren't showing in Meta Events Manager.<\/h3><\/dt>\n<dd><p>Open the <strong>Event Log<\/strong> tab. If events appear there with \"Success (Meta)\", the plugin is sending \u2014 anything missing on Meta's end is a Pixel ID \/ Access Token mismatch. If the log is empty, your JS optimizer is likely deferring the inline scripts (see next answer) or your CMP auto-blocker converted them to <code>type=\"text\/plain\"<\/code> (see the CMP question below).<\/p><\/dd>\n<dt id=\"js%20optimizer%20%28litespeed%20%2F%20wp%20rocket%20%2F%20autoptimize%29%20%E2%80%94%20what%20do%20i%20configure%3F\"><h3>JS optimizer (LiteSpeed \/ WP Rocket \/ Autoptimize) \u2014 what do I configure?<\/h3><\/dt>\n<dd><p>Add these four IDs to your optimizer's \"exclude from defer \/ combine\" list: <code>mcapi-pageview-init<\/code>, <code>mcapi-viewcontent-events<\/code>, <code>mcapi-viewcategory-events<\/code>, <code>mcapi-frontend-events<\/code>. Cloudflare Rocket Loader is handled automatically via <code>data-cfasync=\"false\"<\/code>.<\/p><\/dd>\n<dt id=\"does%20it%20work%20with%20a%20block-based%20theme%20%28twenty%20twenty-five%20etc.%29%3F\"><h3>Does it work with a block-based theme (Twenty Twenty-Five etc.)?<\/h3><\/dt>\n<dd><p>Yes.<\/p><\/dd>\n<dt id=\"gtm%20preview%20shows%20my%20browser%20tags%20firing%2C%20but%20the%20plugin%27s%20event%20log%20is%20empty.\"><h3>GTM Preview shows my browser tags firing, but the plugin's Event Log is empty.<\/h3><\/dt>\n<dd><p>Your CMP's auto-blocker is converting the plugin's inline scripts to <code>type=\"text\/plain\"<\/code>. The plugin already carries opt-out attributes for Cookiebot, CookieYes, and Complianz; less common CMPs (OneTrust etc.) need the <code>mcapi_inline_script_attrs<\/code> filter \u2014 see <strong>CMP Auto-Blocking<\/strong> in Advanced Configuration.<\/p><\/dd>\n<dt id=\"i%20sell%20subscriptions%20%E2%80%94%20meta%20is%20over-attributing%20renewals%20to%20old%20ads.\"><h3>I sell subscriptions \u2014 Meta is over-attributing renewals to old ads.<\/h3><\/dt>\n<dd><p>The plugin auto-detects WooCommerce Subscriptions and offers four behavior modes (Default \/ Skip \/ Tag \/ Subscribe + SubscriptionRenewal). Pick Skip or the dedicated-events mode to keep <code>Purchase<\/code> clean. See <strong>WooCommerce Subscriptions<\/strong> in Advanced Configuration.<\/p><\/dd>\n<dt id=\"eu%20traffic%20%E2%80%94%20does%20the%20plugin%20respect%20cookie-banner%20consent%20for%20capi%3F\"><h3>EU traffic \u2014 does the plugin respect cookie-banner consent for CAPI?<\/h3><\/dt>\n<dd><p>Not by default \u2014 server-side CAPI fires from PHP, doesn't see your <code>gtag('consent', ...)<\/code> signals. The Privacy &amp; Consent section has a <strong>Strict server-side consent mode<\/strong> toggle: when consent is denied, hashed PII is stripped from the CAPI payload but the event still ships with its <code>event_id<\/code>, so Meta's browser\u2194CAPI dedup keeps working without identifying data. Recommended ON for EU stores. See <strong>Strict server-side consent mode<\/strong> in Advanced Configuration.<\/p><\/dd>\n<dt id=\"will%20the%20datacenter%20ip%20filter%20block%20my%20real%20vpn%20customers%3F\"><h3>Will the datacenter IP filter block my real VPN customers?<\/h3><\/dt>\n<dd><p>Rarely. Visitors with click IDs (fbclid \/ gclid \/ ttclid), Apple Private Relay IPs, logged-in customers, or prior-visit <code>_fbp<\/code> \/ <code>_ga<\/code> cookies all bypass the filter. Purchase events are never blocked. A brand-new VPN visitor with no cookies has their first PageView held; if they purchase, the full funnel is replayed so Meta sees the complete journey. Every blocked request is auditable in the <strong>Excluded Traffic<\/strong> tab.<\/p><\/dd>\n<dt id=\"why%20does%20the%20excluded%20traffic%20tab%20show%20ips%20as%20%60192.168.1.x%60%3F\"><h3>Why does the Excluded Traffic tab show IPs as `192.168.1.x`?<\/h3><\/dt>\n<dd><p>GDPR-friendly auditing \u2014 the last octet is masked at record-time, so wp-admin and DB exports never reveal raw visitor IPs.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>3.9.2<\/h4>\n\n<ul>\n<li>Settings, Excluded Traffic and Event Log copy simplified. Product Identifier explanation moved behind \"More detail\"; the live sample stays visible.<\/li>\n<\/ul>\n\n<h4>3.9.1<\/h4>\n\n<ul>\n<li>Fix: identity records survive a security-salt rotation \u2014 rotation is detected automatically, and orphaned rows are pruned safely in a resumable, cutoff-scoped sweep.<\/li>\n<li>Event Log By-IP columns are labeled clearly; the GTM manual is updated and linked; DSAR export field labels are human-readable.<\/li>\n<li>New: a one-time review request appears after the plugin's first successful Purchase.<\/li>\n<\/ul>\n\n<h4>3.9.0<\/h4>\n\n<ul>\n<li>New: identity is remembered between visits \u2014 contact details a shopper gives anywhere on the site are stored as hashes and attached to later events instead of being discarded at checkout. The change that moves Event Match Quality.<\/li>\n<li>New: a visitor identifier and a Meta-format <code>_fbp<\/code> are issued by the server, surviving full-page caching and Safari's 7-day cookie cap. Hashed identity is published to <code>window.dataLayer<\/code> for Advanced Matching, consent-gated. Event Log shows match keys per event; WordPress's exporter\/eraser handle this data.<\/li>\n<li>Fix: a merchant changing an order over admin-ajax or the REST API no longer has their own cookies attached to that customer's Purchase.<\/li>\n<li>Privacy: values are SHA-256 hashes, never raw contact details; records deleted 180 days after last seen.<\/li>\n<li>Behaviour change: minting a visitor identifier is now consent-gated \u2014 a guest on a CMP store with consent unanswered gets NO <code>external_id<\/code>. Expect PageView match quality to fall; that is the intended trade, not a bug.<\/li>\n<li>Behaviour change: a guest who volunteers no contact detail sees only one change \u2014 the added server-side <code>_fbp<\/code> cookie.<\/li>\n<\/ul>\n\n<h4>3.8.1<\/h4>\n\n<ul>\n<li>Fix: a purchase paid after checkout could report the server's own IP address instead of the customer's.<\/li>\n<li>Fix: an order updated from wp-admin, cron, or WP-CLI could attach whoever's own browser cookies to that customer's purchase.<\/li>\n<li>Phone numbers without a country code now use the billing or store country. Facebook Login user IDs are now sent for stores offering that sign-in.<\/li>\n<li>Subscription renewals carry the subscription's own ID; a second email-derived identifier helps platforms recognise returning shoppers sooner.<\/li>\n<li>New <code>mcapi_identity_extra_fields<\/code> filter for gender\/date of birth. Consent-denial stripping now covers these plus TikTok's click and pixel identifiers.<\/li>\n<\/ul>\n\n<h4>3.8.0<\/h4>\n\n<ul>\n<li>Critical: GTM template re-import required \u2014 TikTok renamed event names, causing double-counted purchases until you re-import.<\/li>\n<li>Purchase now waits for a paid order status, firing later if needed. Fix: a stale queued event no longer discards a whole batch.<\/li>\n<li>Fix: Cloudflare bot score header reads correctly; a broken filter can't bypass bot filtering. Block checkout reports correct amounts in odd-decimal currencies and sends <code>event_source_url<\/code>. Event Log Refresh button works again.<\/li>\n<li>Fix: identity fields normalized to Meta's spec before hashing. An order paid after checkout keeps click identifiers, including <code>ttclid<\/code>; renewals inherit them too. Revisiting order-received could double-count a sale \u2014 fixed.<\/li>\n<li>Fix: <code>X-Forwarded-For<\/code> trusts the rightmost hop, not a forged leftmost one (new <code>mcapi_trusted_proxy_hops<\/code> filter). Contact Form 7's Lead event uses the shared hashing pipeline, avoiding a collision with a bad digest. <code>event_id<\/code> fallback now uses a UUID, and multibyte User-Agent values aren't truncated mid-character.<\/li>\n<li>Fix: rate limiting, uninstall cleanup, blocklist pagination, and exclusion-source labeling corrected. New: scheduler watchdog auto-reschedules a missing task. Graph API v26.0; TikTok events renamed <code>Purchase<\/code>\/<code>Lead<\/code>.<\/li>\n<\/ul>\n\n<h4>3.7.2<\/h4>\n\n<ul>\n<li>Hotfix: a 3.7.1 regression could halt the event queue after a burst of events; auto-recovers on update.<\/li>\n<li>New: Cloudflare Bot Management score, <code>navigator.webdriver<\/code>, and human-score signals added to bot detection. Cloudflare does not send this score automatically \u2014 add it via a Transform Rule.<\/li>\n<\/ul>\n\n<h4>3.7.1<\/h4>\n\n<ul>\n<li>Fix: AddToCart tracking restored on themes without a cart widget. Bot filter no longer lets small event bursts slip into trusted state.<\/li>\n<\/ul>\n\n<h4>3.7.0<\/h4>\n\n<ul>\n<li>New: Event Log By-IP view, customer-protection badges, AI-crawler classification. \"Block\" renamed \"Exclude\". Google Ads Enhanced Conversions and Pinterest <code>_epik<\/code> capture \u2014 re-import GTM template.<\/li>\n<\/ul>\n\n<h4>3.6.0<\/h4>\n\n<ul>\n<li>New: TikTok CAPI; plugin renamed to CAPI Suite. Behavioral bot detection, redesigned IP blocklist, CCPA toggle, dashboard widget. Re-import the GTM template.<\/li>\n<\/ul>\n\n<p>For older versions (3.5.3 and below), see the SVN repository history at https:\/\/plugins.svn.wordpress.org\/easy-meta-capi\/tags\/.<\/p>","raw_excerpt":"Meta Pixel, Pinterest &amp; TikTok server-side CAPI. Recovers conversions that ad blockers and iOS hide. No monthly server, no pro tier, no limits.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/fa-af.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/249247","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fa-af.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/fa-af.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/fa-af.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=249247"}],"author":[{"embeddable":true,"href":"https:\/\/fa-af.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/suhanduman"}],"wp:attachment":[{"href":"https:\/\/fa-af.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=249247"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/fa-af.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=249247"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/fa-af.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=249247"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/fa-af.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=249247"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/fa-af.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=249247"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/fa-af.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=249247"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}