{"id":284510,"date":"2026-02-26T19:34:17","date_gmt":"2026-02-26T19:34:17","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/markdown-for-agents\/"},"modified":"2026-02-26T21:19:31","modified_gmt":"2026-02-26T21:19:31","slug":"botkibble","status":"publish","type":"plugin","link":"https:\/\/pcd.wordpress.org\/plugins\/botkibble\/","author":15004835,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_crdt_document":"","version":"1.3.0","stable_tag":"1.3.0","tested":"6.9.4","requires":"6.0","requires_php":"8.2","requires_plugins":null,"header_name":"Botkibble","header_author":"Greg Randall","header_description":"Serve published posts and pages as clean Markdown for AI agents and crawlers.","assets_banners_color":"","last_updated":"2026-02-26 21:19:31","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/github.com\/greg-randall\/botkibble","header_author_uri":"https:\/\/gregr.org","rating":0,"author_block_rating":0,"active_installs":0,"downloads":204,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.2.1":{"tag":"1.2.1","author":"gregrandall","date":"2026-02-26 19:36:11"},"1.3.0":{"tag":"1.3.0","author":"gregrandall","date":"2026-02-26 21:19:31"}},"upgrade_notice":[],"ratings":[],"assets_icons":{"icon.svg":{"filename":"icon.svg","revision":3470658,"resolution":false,"location":"assets","locale":false}},"assets_banners":[],"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.2.1","1.3.0"],"block_files":[],"assets_screenshots":[],"screenshots":[],"jetpack_post_was_ever_published":false},"plugin_section":[],"plugin_tags":[15643,2353,1556,12928,4608],"plugin_category":[],"plugin_contributors":[256690],"plugin_business_model":[],"class_list":["post-284510","plugin","type-plugin","status-publish","hentry","plugin_tags-agents","plugin_tags-ai","plugin_tags-api","plugin_tags-crawlers","plugin_tags-markdown","plugin_contributors-gregrandall","plugin_committers-gregrandall"],"banners":[],"icons":{"svg":"https:\/\/ps.w.org\/botkibble\/assets\/icon.svg?rev=3470658","icon":"https:\/\/ps.w.org\/botkibble\/assets\/icon.svg?rev=3470658","icon_2x":false,"generated":false},"screenshots":[],"raw_content":"<!--section=description-->\n<p>AI agents, LLMs, and crawlers have to wade through navigation bars, sidebars, ads, and comment forms to reach the content they want, and every element costs tokens. <a href=\"https:\/\/blog.cloudflare.com\/markdown-for-agents\/\">Cloudflare measured<\/a> an 80% reduction in token usage when converting a blog post from HTML to Markdown (16,180 tokens down to 3,150).<\/p>\n\n<p>Botkibble adds a Markdown endpoint to every published post and page.<\/p>\n\n<p>Cloudflare offers <a href=\"https:\/\/developers.cloudflare.com\/fundamentals\/reference\/markdown-for-agents\/\">Markdown for Agents<\/a> at the CDN edge on Pro, Business, and Enterprise plans. Botkibble does the same thing (for free) at the origin, so it works on any host.<\/p>\n\n<p><a href=\"https:\/\/github.com\/greg-randall\/botkibble\">GitHub Repository<\/a><\/p>\n\n<p><strong>Three ways to request Markdown:<\/strong><\/p>\n\n<ul>\n<li><strong><code>.md<\/code> suffix<\/strong>: append <code>.md<\/code> to any post or page URL (e.g. <code>example.com\/my-post.md<\/code>)<\/li>\n<li><strong>Query parameter<\/strong>: add <code>?format=markdown<\/code> to any post or page URL<\/li>\n<li><strong>Content negotiation<\/strong>: send <code>Accept: text\/markdown<\/code> in the request header<\/li>\n<\/ul>\n\n<p><strong>What's in every response:<\/strong><\/p>\n\n<ul>\n<li>Structured metadata header with title, date, categories, tags, word count, character count, and estimated token count (in YAML frontmatter format, readable by any AI agent)<\/li>\n<li>Clean Markdown converted from fully-rendered post HTML (shortcodes run, filters applied)<\/li>\n<li><code>Content-Type: text\/markdown<\/code> and <code>Vary: Accept<\/code> response headers<\/li>\n<li><code>Content-Signal<\/code> header for AI signal declaration \u2014 defaults to <code>ai-train=no, search=yes, ai-input=yes<\/code> \u2014 see <a href=\"https:\/\/contentsignals.org\/\">contentsignals.org<\/a><\/li>\n<li><code>X-Markdown-Tokens<\/code> header with estimated token count<\/li>\n<li>Discovery via <code>&lt;link rel=\"alternate\"&gt;<\/code> in the HTML head and <code>Link<\/code> HTTP header<\/li>\n<li>Automatic cache invalidation when a post is updated or deleted<\/li>\n<\/ul>\n\n<p><strong>Performance:<\/strong><\/p>\n\n<p>Botkibble writes Markdown to disk on the first request, then serves it as a static file. A built-in Fast-Path serves cached files during WordPress's <code>init<\/code> hook, before the main database query runs. No extra configuration needed.<\/p>\n\n<p>Add a web server rewrite rule and Botkibble bypasses PHP entirely, serving <code>.md<\/code> files the same way a server would serve an image or CSS file:<\/p>\n\n\n\n\n  Method\n  Avg. response time\n\n\n\n\n  Standard HTML\n  0.97s\n\n\n  Markdown (cold, first request)\n  0.95s\n\n\n  Markdown (cached, PHP Fast-Path)\n  0.87s\n\n\n  Markdown (Nginx\/Apache direct)\n  0.11s\n\n\n\n\n<p>Serving directly from disk is <strong>88% faster<\/strong> than a full WordPress page load. See the Performance section below for Nginx and Apache configuration.<\/p>\n\n<p><strong>Security:<\/strong><\/p>\n\n<ul>\n<li>Drafts, private posts, and password-protected content return <code>403 Forbidden<\/code><\/li>\n<li>Rate limits cache-miss regenerations (20\/min by default) to mitigate DoS abuse<\/li>\n<li><code>X-Robots-Tag: noindex<\/code> keeps Markdown versions out of search results<\/li>\n<li><code>Link: rel=\"canonical\"<\/code> points search engines back to the HTML version<\/li>\n<\/ul>\n\n<p><strong>Cache variants (optional):<\/strong><\/p>\n\n<p>You can persist alternate cached representations by adding <code>?botkibble_variant=slim<\/code> (or any other variant name).\nVariant caches are stored under:<\/p>\n\n<pre><code>\/wp-content\/uploads\/botkibble\/_v\/&lt;variant&gt;\/&lt;slug&gt;.md\n<\/code><\/pre>\n\n<p><strong>What it does NOT do:<\/strong><\/p>\n\n<ul>\n<li>Expose drafts, private posts, or password-protected content<\/li>\n<li>Serve non-post\/page content types by default<\/li>\n<li>Require any configuration. Activate and it works.<\/li>\n<\/ul>\n\n<h3>Why Markdown?<\/h3>\n\n<p>HTML is expensive for AI systems to process. <a href=\"https:\/\/blog.cloudflare.com\/markdown-for-agents\/\">Cloudflare measured<\/a> an 80% reduction in token usage when converting a blog post from HTML to Markdown (16,180 tokens down to 3,150).<\/p>\n\n<p>Cloudflare now offers <a href=\"https:\/\/developers.cloudflare.com\/fundamentals\/reference\/markdown-for-agents\/\">Markdown for Agents<\/a> at the CDN edge via the <code>Accept: text\/markdown<\/code> header, available on Pro, Business, and Enterprise plans.<\/p>\n\n<p>This plugin does the same thing at the origin, so it works on any host. It also adds <code>.md<\/code> suffix URLs, <code>?format=markdown<\/code> query parameters, YAML frontmatter, static file caching, and server-level offloading.<\/p>\n\n<p>If you use Cloudflare, both share the same <code>Accept: text\/markdown<\/code> header, <code>Content-Signal<\/code> headers, and <code>X-Markdown-Tokens<\/code> response headers.<\/p>\n\n<p>Cloudflare currently defaults to <code>Content-Signal: ai-train=yes, search=yes, ai-input=yes<\/code> with no way to change it. Botkibble defaults to <code>ai-train=no<\/code> and lets you override the full signal per site via the <code>botkibble_content_signal<\/code> filter.<\/p>\n\n<h3>Performance &amp; Static Offloading<\/h3>\n\n<p>This plugin supports static file offloading by writing Markdown content to <code>\/wp-content\/uploads\/botkibble\/<\/code>.<\/p>\n\n<h3>Nginx Configuration<\/h3>\n\n<p>To bypass PHP entirely and have Nginx serve the files (including variants) directly:<\/p>\n\n<pre><code># Variants\nlocation ~* ^\/(_v\/[^\/]+\/.+)\\.md$ {\n    default_type text\/markdown;\n    try_files \/wp-content\/uploads\/botkibble\/$1.md \/index.php?$args;\n}\n\n# Default\nlocation ~* ^\/(.+)\\.md$ {\n    default_type text\/markdown;\n    try_files \/wp-content\/uploads\/botkibble\/$1.md \/index.php?$args;\n}\n<\/code><\/pre>\n\n<h3>Apache (.htaccess)<\/h3>\n\n<p>Add this to your <code>.htaccess<\/code> before the WordPress rules:<\/p>\n\n<pre><code>RewriteEngine On\n# Variants\nRewriteCond %{DOCUMENT_ROOT}\/wp-content\/uploads\/botkibble\/_v\/$1\/$2.md -f\nRewriteRule ^_v\/([^\/]+)\/(.+)\\.md$ \/wp-content\/uploads\/botkibble\/_v\/$1\/$2.md [L,T=text\/markdown]\n\n# Default\nRewriteCond %{DOCUMENT_ROOT}\/wp-content\/uploads\/botkibble\/$1.md -f\nRewriteRule ^(.*)\\.md$ \/wp-content\/uploads\/botkibble\/$1.md [L,T=text\/markdown]\n<\/code><\/pre>\n\n<p>Even without these rules, the plugin uses a \"Fast-Path\" that serves cached files from PHP before the main database query is executed.<\/p>\n\n<h3>Credits<\/h3>\n\n<p>We thank Cristi Constantin (https:\/\/github.com\/cristi-constantin) for contributing cache variants, URL and SEO improvements, and fixing important bugs.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Upload the <code>botkibble<\/code> directory to <code>wp-content\/plugins\/<\/code>.<\/li>\n<li>Run <code>composer install<\/code> inside the plugin directory to install dependencies.<\/li>\n<li>Activate the plugin through the <strong>Plugins<\/strong> menu in WordPress.<\/li>\n<li>That's it. No settings page needed.<\/li>\n<\/ol>\n\n<p><strong>Test it:<\/strong><\/p>\n\n<pre><code>curl https:\/\/gregr.org\/great-hvac-meltdown\/?format=markdown\ncurl https:\/\/gregr.org\/great-hvac-meltdown.md\ncurl -H \"Accept: text\/markdown\" https:\/\/gregr.org\/great-hvac-meltdown\/\n<\/code><\/pre>\n\n<!--section=faq-->\n<dl>\n<dt id=\"how%20do%20i%20add%20support%20for%20custom%20post%20types%3F\"><h3>How do I add support for custom post types?<\/h3><\/dt>\n<dd><p>The plugin only serves posts and pages by default. To add a custom post type, use the <code>botkibble_served_post_types<\/code> filter in your theme or a custom plugin:<\/p>\n\n<pre><code>add_filter( 'botkibble_served_post_types', function ( $types ) {\n    $types[] = 'docs';\n    return $types;\n} );\n<\/code><\/pre>\n\n<p>Be careful. Only add post types that contain public content. Do not expose post types that may contain private or sensitive data (e.g. WooCommerce orders).<\/p><\/dd>\n<dt id=\"what%20does%20the%20yaml%20frontmatter%20include%3F\"><h3>What does the YAML frontmatter include?<\/h3><\/dt>\n<dd><p>Every response starts with a YAML block containing:<\/p>\n\n<ul>\n<li><code>title<\/code> \u2014 the post title<\/li>\n<li><code>date<\/code> \u2014 publish date in ISO 8601 format<\/li>\n<li><code>type<\/code> \u2014 post type (e.g. <code>post<\/code>, <code>page<\/code>)<\/li>\n<li><code>word_count<\/code> \u2014 word count of the Markdown body<\/li>\n<li><code>char_count<\/code> \u2014 character count of the Markdown body<\/li>\n<li><code>tokens<\/code> \u2014 estimated token count (word_count \u00d7 1.3)<\/li>\n<li><code>categories<\/code> \u2014 array of category names (posts only)<\/li>\n<li><code>tags<\/code> \u2014 array of tag names (posts only, omitted if none)<\/li>\n<\/ul>\n\n<p>Example:<\/p>\n\n<pre><code>---\ntitle: My Post Title\ndate: '2025-06-01T12:00:00+00:00'\ntype: post\nword_count: 842\nchar_count: 4981\ntokens: 1095\ncategories:\n  - Technology\ntags:\n  - wordpress\n  - markdown\n---\n<\/code><\/pre><\/dd>\n<dt id=\"how%20do%20i%20add%20custom%20fields%20to%20the%20frontmatter%3F\"><h3>How do I add custom fields to the frontmatter?<\/h3><\/dt>\n<dd><p>Use the <code>botkibble_frontmatter<\/code> filter:<\/p>\n\n<pre><code>add_filter( 'botkibble_frontmatter', function ( $data, $post ) {\n    $data['excerpt'] = get_the_excerpt( $post );\n    return $data;\n}, 10, 2 );\n<\/code><\/pre><\/dd>\n<dt id=\"how%20do%20i%20change%20the%20content-signal%20header%3F\"><h3>How do I change the Content-Signal header?<\/h3><\/dt>\n<dd><p>Use the <code>botkibble_content_signal<\/code> filter:<\/p>\n\n<pre><code>add_filter( 'botkibble_content_signal', function ( $signal, $post ) {\n    return 'ai-train=no, search=yes, ai-input=yes';\n}, 10, 2 );\n<\/code><\/pre>\n\n<p>Return an empty string to omit the header entirely.<\/p><\/dd>\n<dt id=\"can%20i%20change%20the%20token%20count%20estimation%3F\"><h3>Can I change the token count estimation?<\/h3><\/dt>\n<dd><p>Yes, use the <code>botkibble_token_multiplier<\/code> filter. The default multiplier of <code>1.3<\/code> (word count \u00d7 1.3) comes from <a href=\"https:\/\/developers.cloudflare.com\/fundamentals\/reference\/markdown-for-agents\/\">Cloudflare's implementation<\/a>:<\/p>\n\n<pre><code>add_filter( 'botkibble_token_multiplier', function () {\n    return 1.5; \/\/ Adjusted for a different model's tokenizer\n} );\n<\/code><\/pre><\/dd>\n<dt id=\"how%20do%20i%20adjust%20the%20rate%20limit%3F\"><h3>How do I adjust the rate limit?<\/h3><\/dt>\n<dd><p>Cache misses (when a post needs to be converted) are limited to 20 per minute globally. You can change this with the <code>botkibble_regen_rate_limit<\/code> filter:<\/p>\n\n<pre><code>add_filter( 'botkibble_regen_rate_limit', function () {\n    return 50; \n} );\n<\/code><\/pre><\/dd>\n<dt id=\"can%20i%20add%20custom%20html%20cleanup%20rules%3F\"><h3>Can I add custom HTML cleanup rules?<\/h3><\/dt>\n<dd><p>Yes, use the <code>botkibble_clean_html<\/code> filter. This runs after the default cleanup and before conversion:<\/p>\n\n<pre><code>add_filter( 'botkibble_clean_html', function ( $html ) {\n    \/\/ Remove a plugin's wrapper divs\n    $html = preg_replace( '\/&lt;div class=\"my-plugin-wrapper\"&gt;(.*?)&lt;\\\/div&gt;\/s', '$1', $html );\n    return $html;\n} );\n<\/code><\/pre><\/dd>\n<dt id=\"can%20i%20strip%20script%20nodes%20during%20conversion%3F\"><h3>Can I strip script nodes during conversion?<\/h3><\/dt>\n<dd><p>Yes. Botkibble keeps converter node removal disabled by default (for backward compatibility), but you can opt in with <code>botkibble_converter_remove_nodes<\/code>:<\/p>\n\n<pre><code>add_filter( 'botkibble_converter_remove_nodes', function ( $nodes ) {\n    $nodes = is_array( $nodes ) ? $nodes : [];\n    $nodes[] = 'script';\n    return $nodes;\n} );\n<\/code><\/pre>\n\n<p>If you also need <code>application\/ld+json<\/code>, extract it in <code>botkibble_clean_html<\/code> first, then let converter-level script removal clean up any remaining script tags.<\/p><\/dd>\n<dt id=\"how%20do%20i%20modify%20the%20body%20before%20metrics%20are%20calculated%3F\"><h3>How do I modify the body before metrics are calculated?<\/h3><\/dt>\n<dd><p>Use the <code>botkibble_body<\/code> filter. This is the best place to add content like ld+json that you want included in the word count and token estimation:<\/p>\n\n<pre><code>add_filter( 'botkibble_body', function ( $body, $post ) {\n    $json_ld = '&lt;script type=\"application\/ld+json\"&gt;...&lt;\/script&gt;';\n    return $body . \"\\n\\n\" . $json_ld;\n}, 10, 2 );\n<\/code><\/pre><\/dd>\n<dt id=\"how%20do%20i%20modify%20the%20final%20markdown%20output%3F\"><h3>How do I modify the final Markdown output?<\/h3><\/dt>\n<dd><p>Use the <code>botkibble_output<\/code> filter to append or modify the text after conversion:<\/p>\n\n<pre><code>add_filter( 'botkibble_output', function ( $markdown, $post ) {\n    return $markdown . \"\\n\\n---\\nServed by Botkibble\";\n}, 10, 2 );\n<\/code><\/pre><\/dd>\n<dt id=\"can%20i%20cache%20multiple%20markdown%20variants%20%28e.g.%20a%20slim%20version%29%3F\"><h3>Can I cache multiple Markdown variants (e.g. a slim version)?<\/h3><\/dt>\n<dd><p>Yes. Add <code>?botkibble_variant=slim<\/code> when requesting Markdown to generate and serve a separate cached file. To ensure your variants are invalidated on post updates, return them from the <code>botkibble_cache_variants<\/code> filter:<\/p>\n\n<pre><code>add_filter( 'botkibble_cache_variants', function ( $variants, $post ) {\n    $variants[] = 'slim';\n    return $variants;\n}, 10, 2 );\n<\/code><\/pre><\/dd>\n<dt id=\"can%20i%20disable%20the%20accept%20header%20detection%3F\"><h3>Can I disable the Accept header detection?<\/h3><\/dt>\n<dd><p>Yes, if you only want to serve Markdown via explicit URLs (.md or ?format=markdown), use the <code>botkibble_enable_accept_header<\/code> filter:<\/p>\n\n<pre><code>add_filter( 'botkibble_enable_accept_header', '__return_false' );\n<\/code><\/pre><\/dd>\n<dt id=\"does%20the%20.md%20suffix%20work%20with%20all%20permalink%20structures%3F\"><h3>Does the .md suffix work with all permalink structures?<\/h3><\/dt>\n<dd><p>It works with the most common structures (post name, page hierarchy). Complex date-based permalink structures may require the query parameter or Accept header method instead.<\/p><\/dd>\n<dt id=\"what%20about%20password-protected%20posts%3F\"><h3>What about password-protected posts?<\/h3><\/dt>\n<dd><p>They return a <code>403 Forbidden<\/code> response. There's no point serving a password form to a bot.<\/p><\/dd>\n<dt id=\"what%20are%20the%20response%20headers%3F\"><h3>What are the response headers?<\/h3><\/dt>\n<dd><ul>\n<li><code>Content-Type: text\/markdown; charset=utf-8<\/code><\/li>\n<li><code>Vary: Accept<\/code> \u2014 tells caches that responses vary by Accept header<\/li>\n<li><code>X-Markdown-Tokens: &lt;count&gt;<\/code> \u2014 estimated token count (word_count \u00d7 1.3)<\/li>\n<li><code>X-Robots-Tag: noindex<\/code> \u2014 prevents search engines from indexing the Markdown version<\/li>\n<li><code>Link: &lt;url&gt;; rel=\"canonical\"<\/code> \u2014 points search engines to the original HTML post<\/li>\n<li><code>Link: &lt;url&gt;; rel=\"alternate\"<\/code> \u2014 advertises the Markdown version for discovery<\/li>\n<li><code>Content-Signal: ai-train=no, search=yes, ai-input=yes<\/code> \u2014 see <a href=\"https:\/\/contentsignals.org\/\">contentsignals.org<\/a><\/li>\n<\/ul><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.3.0<\/h4>\n\n<ul>\n<li>Changed default Content-Signal from ai-train=yes to ai-train=no (opt-out of AI training by default).<\/li>\n<li>Added botkibble_converter_remove_nodes filter for opt-in HTML node stripping during conversion.<\/li>\n<\/ul>\n\n<h4>1.2.1<\/h4>\n\n<ul>\n<li>Changed cache directory from \/uploads\/botkibble-cache\/ to \/uploads\/botkibble\/ per plugin guidelines.<\/li>\n<\/ul>\n\n<h4>1.2.0<\/h4>\n\n<ul>\n<li>Rebranded to Botkibble to avoid naming ambiguity.<\/li>\n<li>Prefixed all functions, filters, and constants with botkibble_ for better compatibility.<\/li>\n<li>Updated symfony\/yaml to 7.4.1 (Requires PHP 8.2).<\/li>\n<li>Corrected all internal references and documentation.<\/li>\n<\/ul>\n\n<h4>1.1.2<\/h4>\n\n<ul>\n<li>Fixed routing issues for posts by implementing a custom botkibble_path resolver.<\/li>\n<li>Disabled canonical redirects for .md URLs to prevent 301 trailing slash loops.<\/li>\n<li>Added automatic version-based rewrite rule flushing.<\/li>\n<\/ul>\n\n<h4>1.1.0<\/h4>\n\n<ul>\n<li>Replaced manual YAML encoder with symfony\/yaml for security.<\/li>\n<li>Replaced regex-based shortcode removal with native strip_shortcodes().<\/li>\n<li>Added token estimation based on 1.3 word count heuristic.<\/li>\n<li>Replaced transients with static file offloading in \/uploads\/.<\/li>\n<li>Added SEO protection with noindex and canonical headers.<\/li>\n<li>Added \"Fast-Path\" serving to bypass main DB queries for cached content.<\/li>\n<li>Added support for direct server offloading (Nginx\/Apache).<\/li>\n<\/ul>\n\n<h4>1.0.0<\/h4>\n\n<ul>\n<li>Initial release.<\/li>\n<li>HTML-to-Markdown conversion via league\/html-to-markdown.<\/li>\n<li>.md suffix, query parameter, and Accept header support.<\/li>\n<li>YAML frontmatter with title, date, categories, tags.<\/li>\n<li>Static file caching with automatic invalidation.<\/li>\n<li>Content-Signal and X-Markdown-Tokens response headers.<\/li>\n<li>Discovery via alternate link tag.<\/li>\n<\/ul>","raw_excerpt":"Serves every published post and page as Markdown for AI agents and crawlers. No configuration, no API keys. Activate and it works.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/284510","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=284510"}],"author":[{"embeddable":true,"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/gregrandall"}],"wp:attachment":[{"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=284510"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=284510"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=284510"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=284510"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=284510"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=284510"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}