There is no dedicated Yoast SEO API — searching for /wp-json/yoast/v1/ returns a 404. All Yoast SEO data (meta title, meta description, og_image, canonical URL) appears in the `yoast_head_json` field inside standard WordPress REST API responses. In Bubble, a single API Connector GET call to /wp-json/wp/v2/posts returns both post content and Yoast SEO metadata. No authentication is required for public posts.
| Fact | Value |
|---|---|
| Tool | Yoast SEO (for WordPress) |
| Category | Marketing |
| Method | Bubble API Connector |
| Difficulty | Beginner |
| Time required | 1–2 hours |
| Last updated | July 2026 |
Yoast SEO + Bubble: Headless WordPress and SEO Audit Dashboards
The single most important thing to understand before building this integration is that Yoast SEO does not have its own API endpoint. Beginners frequently test `/wp-json/yoast/v1/` and get a 404, then conclude the API is unavailable or requires a premium plugin. The truth is simpler: Yoast SEO injects its data into the standard WordPress REST API response. When you call `GET /wp-json/wp/v2/posts`, each post object includes a `yoast_head_json` field containing the meta title, meta description, og_image array, canonical URL, Twitter card data, and JSON-LD schema markup — all in a single response.
This makes the Bubble integration particularly clean. One API Connector call returns both the post content you want to display and the SEO metadata you want to surface. For a headless WordPress + Bubble app, this means your Bubble pages can show SEO-optimized page titles and descriptions derived from Yoast's carefully crafted metadata, not raw WordPress post titles.
For a Bubble SEO audit dashboard, the same data source enables a powerful review workflow: display all posts with their Yoast meta description length, flag any that are missing or under 120 characters, and highlight posts with missing og_image. Since the WordPress REST API imposes no enforced rate limit (only server capacity), you can pull an entire site's worth of posts in a few paginated calls and cache them in Bubble's database for team review.
Write operations — updating Yoast meta titles and descriptions via the Bubble API — require WordPress Application Passwords and a small PHP addition to WordPress's functions.php. This is covered as an optional advanced step.
Integration method
Call the WordPress REST API via Bubble's API Connector to retrieve posts including their yoast_head_json SEO metadata fields in a single request.
Prerequisites
- A WordPress site with Yoast SEO plugin installed and activated (either free or premium — the free version exposes yoast_head_json in the REST API)
- The WordPress site's REST API must be accessible — verify by opening https://yoursite.com/wp-json/wp/v2/posts?per_page=1 in a browser and confirming you see JSON post data
- The API Connector plugin installed in your Bubble app (Plugins tab → Add plugins → search 'API Connector' by Bubble)
- For write operations only: WordPress admin access to generate Application Passwords (Users → Profile → Application Passwords), available in WordPress 5.6+
Step-by-step guide
Verify the WordPress REST API and confirm yoast_head_json is present
Before opening Bubble, verify the integration source in your browser. Open a new browser tab and navigate to: `https://yoursite.com/wp-json/wp/v2/posts?per_page=1` Replace `yoursite.com` with your actual WordPress domain. You should see a JSON array containing one post object. Scroll through the object and look for the `yoast_head_json` key — it will be a nested object containing at minimum `title`, `description`, and possibly `og_image`, `canonical`, and `schema` sub-fields. If you see `yoast_head_json` in the response, the integration will work. If it's not present, Yoast SEO may not be active on the site, or the plugin version may be outdated (update Yoast SEO to the latest version from the WordPress plugins screen). If the URL returns a 401 or 403 error instead of JSON, a security plugin (Wordfence, iThemes Security, or similar) is blocking unauthenticated REST API access. The fix is to whitelist the REST API in that plugin's settings, or use WordPress Application Passwords for authenticated reads (covered in step 5). Also check: `yoast_head_json.title` includes the site name suffix by design (e.g., 'How to Bake Bread | Your Site Name'). For clean post titles without the site name, use `yoast_head_json.og_title` instead — this omits the suffix and gives you the pure post title as Yoast sees it.
1// Browser verification URLs23// Basic check — returns latest post with all fields:4https://yoursite.com/wp-json/wp/v2/posts?per_page=156// Yoast field verification — returns minimal payload with SEO fields:7https://yoursite.com/wp-json/wp/v2/posts?per_page=1&_fields=id,title,slug,yoast_head_json89// Expected yoast_head_json structure in response:10{11 "yoast_head_json": {12 "title": "Post Title | Site Name",13 "description": "The meta description Yoast has set for this post.",14 "og_title": "Post Title",15 "og_description": "The Open Graph description.",16 "og_image": [17 { "url": "https://yoursite.com/wp-content/uploads/image.jpg", "width": 1200, "height": 630 }18 ],19 "canonical": "https://yoursite.com/post-slug/",20 "schema": { ... }21 }22}Pro tip: If the yoast_head_json field is present but empty (`{}`), the post has no Yoast SEO settings configured yet. Open the post in WordPress editor, scroll down to the Yoast SEO panel, and fill in the meta title and description. Save and re-check the REST API response.
Expected result: Browser shows JSON with a yoast_head_json object containing title, description, and possibly og_image and canonical fields. The REST API is publicly accessible without authentication for published posts.
Configure API Connector for the WordPress REST API
In Bubble, click the Plugins tab → 'API Connector' (install it if not already present via 'Add plugins' → search 'API Connector'). Click 'Add another API'. Name it 'WordPress Site' (or your client site name). Set the base URL to `https://yoursite.com/wp-json/wp/v2` — replace `yoursite.com` with your actual domain. For public WordPress sites with Yoast, no authentication is needed — leave the Authentication field set to 'None' and add no shared headers. This is one of the rare integrations where the API Connector requires no Private key at all for basic read-only use. Click 'Add a call'. Name it 'Get Posts with SEO'. Set method to GET, path to `/posts`. Add these URL parameters: - `per_page` — value: `100` (max is 100 per WordPress REST API) - `status` — value: `publish` (return only published posts) - `_fields` — value: `id,title,slug,excerpt,date,yoast_head_json` — the `_fields` parameter limits the response to only the listed fields, reducing payload size by roughly 80%. This is important for Bubble's API response size limits and for WU efficiency. Optionally add: - `page` — leave as a dynamic parameter for pagination - `categories` — dynamic parameter if you want to filter by category ID Click 'Initialize call'. Bubble will fetch one real response from your WordPress site and detect the field structure. Confirm that `yoast_head_json` appears in the detected fields — expand it to see `title`, `description`, `og_title`, `og_image`, and `canonical` as sub-fields.
1// API Connector: WordPress Site2{3 "api_name": "WordPress Site",4 "base_url": "https://yoursite.com/wp-json/wp/v2",5 "authentication": "none",6 "calls": [7 {8 "name": "Get Posts with SEO",9 "method": "GET",10 "path": "/posts",11 "params": [12 { "name": "per_page", "value": "100" },13 { "name": "status", "value": "publish" },14 {15 "name": "_fields",16 "value": "id,title,slug,excerpt,date,yoast_head_json"17 },18 { "name": "page", "value": "<dynamic: default 1>" }19 ]20 }21 ]22}Pro tip: The `_fields` URL parameter is the single most important optimization for this integration. Without it, each WordPress post response can exceed 10KB including all meta fields, embedded content, and Gutenberg blocks. With `_fields=id,title,slug,excerpt,date,yoast_head_json`, responses are typically under 2KB per post.
Expected result: Initialize call returns HTTP 200. Bubble shows auto-detected fields including id, title (as object with rendered sub-field), slug, excerpt, date, and yoast_head_json with its nested sub-objects. 'Use as: Data' option is available.
Map yoast_head_json fields and create a Bubble data type
Create a Bubble data type to cache WordPress posts with their Yoast SEO metadata. Go to Data tab → Data types → 'Create a new type' → name it 'WPPost'. Add these fields: - `wp_id` (number) — WordPress post ID - `title` (text) — the rendered post title (from response's title.rendered) - `slug` (text) — URL slug - `excerpt_html` (text) — rendered excerpt - `published_at` (date) - `seo_title` (text) — from yoast_head_json.og_title (clean title without site suffix) - `seo_description` (text) — from yoast_head_json.description - `seo_og_image_url` (text) — from yoast_head_json.og_image[0].url - `seo_canonical` (text) — from yoast_head_json.canonical - `synced_at` (date) — when this record was last fetched from WordPress Create a page or workflow that calls the API Connector 'Get Posts with SEO' and stores results in the WPPost data type. For each item returned: - title = API result's title's rendered - seo_title = API result's yoast_head_json's og_title - seo_description = API result's yoast_head_json's description - seo_og_image_url = API result's yoast_head_json's og_image's first item's url - seo_canonical = API result's yoast_head_json's canonical - synced_at = Current date/time Bubble's dot-notation field access handles nested objects like `yoast_head_json.description` natively in the API Connector result expressions. The `og_image` field is an array — use `:first item` to access the first image's URL. Important note about `yoast_head_json.title` vs. `yoast_head_json.og_title`: the `title` field includes ' | Site Name' appended. The `og_title` field is the clean post title without the suffix. Use `og_title` for display in your Bubble UI; reserve `title` only if you need the full SEO title tag string.
1// Bubble data type: WPPost2// wp_id (number)3// title (text) -- raw post title4// slug (text)5// excerpt_html (text)6// published_at (date)7// seo_title (text) -- from yoast_head_json.og_title8// seo_description (text) -- from yoast_head_json.description9// seo_og_image_url (text) -- from yoast_head_json.og_image[0].url10// seo_canonical (text) -- from yoast_head_json.canonical11// synced_at (date)1213// Field mapping in Bubble workflow action 'Create a new WPPost':14// title = API result's title's rendered15// seo_title = API result's yoast_head_json's og_title16// seo_description = API result's yoast_head_json's description17// seo_og_image_url = API result's yoast_head_json's og_image's :first item's url18// seo_canonical = API result's yoast_head_json's canonical19// published_at = API result's date (auto-parsed by Bubble)20// synced_at = Current date/timePro tip: Add a `wp_id` field and use it as a deduplication check when syncing. Before creating a new WPPost, search for existing records with the same wp_id — if found, update the existing record instead of creating a duplicate. This makes repeated syncs safe and idempotent.
Expected result: WPPost data type exists with all SEO fields defined. After running the sync workflow, Data tab → App Data → All WPPosts shows records with seo_title, seo_description, and seo_og_image_url populated from Yoast's metadata.
Build a headless WordPress blog page or SEO audit dashboard
You can use the WPPost data type for two different Bubble pages — a headless blog display or an SEO audit dashboard. For a headless blog page: Add a Repeating Group to a new page. Set its type to WPPost. Set the data source to 'Do a search for WPPosts' with Sort by = published_at descending. In each cell, add: - An image element: URL = Current cell's WPPost's seo_og_image_url - A text element for the post title: Current cell's WPPost's seo_title - A text element for the excerpt: Current cell's WPPost's excerpt_html (use Bubble's 'Formatted as HTML' display option) - A link element: URL = https://yoursite.com/ + Current cell's WPPost's slug For an SEO audit dashboard: Add a Repeating Group bound to WPPost. Add a calculated text column showing description character count: Current cell's WPPost's seo_description:count of characters. Add conditional row coloring: if seo_description's character count < 120 or seo_description is empty, set row background to light red. Add another condition: if seo_og_image_url is empty, add a 'No OG Image' text badge in an overlay group. Add a 'Sync Posts' button on the admin dashboard with a workflow that calls the API Connector, loops through results, and creates or updates WPPost records. Store the last sync timestamp in an AppConfig record. RapidDev's team builds headless WordPress + Bubble content apps and SEO audit tools regularly — if you need help mapping complex Yoast field structures or building multi-site dashboards, book a free scoping call at rapidevelopers.com/contact.
1// SEO Audit Dashboard — Repeating Group conditional formatting23// Data source: Search for WPPosts, sort by published_at desc45// Column: SEO Description Length6// Text value: Current cell's WPPost's seo_description:count of characters7// + " chars"89// Row background condition (flag short/missing descriptions):10// Condition A: Current cell's WPPost's seo_description is empty11// → Background: #FFECEC (light red)12// Condition B: Current cell's WPPost's seo_description:count of characters < 12013// → Background: #FFF3CD (light yellow)14// Condition C: Current cell's WPPost's seo_og_image_url is empty15// → Show 'No OG Image' badge group1617// Sync workflow ('Sync Posts' button):18// Step 1: Call WordPress Site - Get Posts with SEO (page=1)19// Step 2: For each result:20// - Search for WPPosts where wp_id = result's id21// - If count = 0: Create new WPPost with mapped fields22// - If count > 0: Make changes to existing WPPostPro tip: For an SEO audit dashboard, sort the Repeating Group by seo_description character count ascending — this puts posts with the most critical SEO gaps (empty or very short descriptions) at the top for immediate attention.
Expected result: Bubble blog page shows WordPress posts with Yoast-optimized titles, descriptions, and og_images. SEO audit dashboard highlights posts with missing or under-length meta descriptions using conditional row colors.
Optional: Configure write operations with WordPress Application Passwords
If you need to update Yoast SEO metadata from Bubble (for example, bulk-updating meta descriptions based on AI suggestions), you need WordPress Application Passwords for authenticated write access. This is an advanced optional step. In your WordPress admin: go to Users → Profile (for the admin user you want to authenticate as). Scroll down to the 'Application Passwords' section. Enter a label like 'Bubble Integration' → click 'Add New Application Password'. WordPress generates a password like `AbCd EfGh IjKl MnOp QrSt UvWx` — copy it immediately (it's only shown once). Remove the spaces when using it. In Bubble's API Connector, in your 'WordPress Site' API configuration, change the Authentication type from 'None' to 'Username & Password'. Enter your WordPress username (not email) in the Username field and the Application Password (without spaces) in the Password field. Enable 'Private' on both fields. Now for write operations: add a new API Connector call named 'Update Post SEO'. Set method to POST (WordPress REST API uses POST for updates, not PUT), path to `/posts/{{post_id}}`. In the Body, add: `meta` object with the Yoast keys you want to update. HOWEVER: Yoast meta fields (`_yoast_wpseo_title`, `_yoast_wpseo_metadesc`) are NOT exposed via the WordPress REST API for writing by default. They're registered as protected meta by Yoast. To enable REST API write access for these keys, a WordPress developer needs to add a small snippet to the theme's functions.php file that calls `register_rest_field()` for these meta keys. Without this PHP code on the WordPress side, the REST API accepts the request with a 200 OK but silently ignores the Yoast meta values — a common 'works but doesn't work' frustration.
1// WordPress functions.php snippet to expose Yoast meta for REST API writes2// (Requires WordPress developer access to add this code)3add_action('rest_api_init', function() {4 register_rest_field('post', '_yoast_wpseo_title', [5 'get_callback' => function($post) {6 return get_post_meta($post['id'], '_yoast_wpseo_title', true);7 },8 'update_callback' => function($value, $post) {9 update_post_meta($post->ID, '_yoast_wpseo_title', sanitize_text_field($value));10 },11 'schema' => ['type' => 'string']12 ]);13 register_rest_field('post', '_yoast_wpseo_metadesc', [14 'get_callback' => function($post) {15 return get_post_meta($post['id'], '_yoast_wpseo_metadesc', true);16 },17 'update_callback' => function($value, $post) {18 update_post_meta($post->ID, '_yoast_wpseo_metadesc', sanitize_text_field($value));19 },20 'schema' => ['type' => 'string']21 ]);22});2324// Bubble API Connector — Update Post SEO (POST /posts/{post_id})25// Body:26{27 "_yoast_wpseo_title": "<dynamic: new SEO title>",28 "_yoast_wpseo_metadesc": "<dynamic: new meta description>"29}Pro tip: If you don't have direct WordPress file access, ask your WordPress developer or hosting provider to add the register_rest_field snippet via a site-specific plugin rather than editing functions.php directly — this way it persists through theme updates.
Expected result: After adding the PHP snippet to WordPress, a POST call from Bubble to /posts/{post_id} with Yoast meta keys updates the meta description in WordPress. Verify by re-fetching the post via GET and checking yoast_head_json.description reflects the new value.
Common use cases
Headless WordPress Blog in Bubble
Pull WordPress posts including Yoast SEO metadata into Bubble to power a headless blog or content hub. Display each post's Yoast-optimized title (from yoast_head_json.og_title) and meta description in post listing cards, and use the og_image as the featured image. This approach keeps your content in WordPress while delivering it through a custom Bubble-designed UI.
Build a Bubble blog page that fetches WordPress posts from my site's REST API and displays each post's title, excerpt, featured image (from yoast_head_json.og_image), and publication date in a card grid. Add a search bar that filters posts by title.
Copy this prompt to try it in Bubble
SEO Metadata Audit Dashboard
Create a Bubble dashboard that pulls all published posts from a WordPress site and evaluates their Yoast SEO metadata quality. For each post, show the meta title length, meta description length (flag if under 120 characters), whether an og_image is set, and whether a canonical URL is defined. Color-code rows to highlight SEO gaps at a glance.
Create a Bubble admin dashboard that shows all WordPress posts from my site with columns for: post title, Yoast meta description (and its character count), og_image status (present/missing), and a row color that turns red if meta description is empty or under 100 characters.
Copy this prompt to try it in Bubble
Multi-Site Content Management Panel
For agencies managing multiple WordPress client sites, build a Bubble panel that connects to each client's WordPress REST API and displays a unified view of their posts' SEO status. Each client is a separate AppConfig record with their WordPress site URL. A dropdown selects the active client and the Repeating Group shows their posts' Yoast metadata quality.
Build a Bubble multi-client panel where admins select a WordPress client site from a dropdown and see a Repeating Group of that site's posts with Yoast meta title, meta description length, and og_image presence. Include a 'Sync Posts' button for each client.
Copy this prompt to try it in Bubble
Troubleshooting
GET /wp-json/yoast/v1/ returns 404 Not Found
Cause: There is no dedicated Yoast SEO API endpoint at /wp-json/yoast/v1/. This endpoint does not exist. Yoast SEO data is embedded in standard WordPress REST API responses, not served from a separate namespace.
Solution: Use the standard WordPress REST API endpoint instead: /wp-json/wp/v2/posts. Each post in the response includes a yoast_head_json field with all Yoast SEO metadata (title, description, og_image, canonical, schema). This is the correct and only way to access Yoast data programmatically.
API Connector Initialize call returns 401 Unauthorized even for published posts
Cause: A WordPress security plugin (Wordfence, iThemes Security, All In One WP Security, or similar) has disabled REST API access for unauthenticated users. This is a common hardening setting that blocks all external REST API calls by default.
Solution: First verify the issue by opening https://yoursite.com/wp-json/wp/v2/posts in a browser — if this returns 401, the security plugin is blocking it. Options: (1) whitelist the REST API in your security plugin settings (usually labeled 'Disable REST API' or 'REST API access'), (2) switch to authenticated reads using WordPress Application Passwords in the API Connector (set Authentication to 'Username & Password' with admin credentials, both fields marked Private).
yoast_head_json field is missing from API responses or returns an empty object
Cause: Either Yoast SEO plugin is not installed/activated on the WordPress site, the plugin version is outdated (yoast_head_json was added in Yoast SEO 14.0), or Yoast's REST API integration is disabled in Yoast's settings.
Solution: In WordPress admin → Plugins, verify Yoast SEO appears and is activated. Update it to the latest version if it shows an update available. Then check Yoast SEO → General → Features and ensure 'REST API: Head endpoint' is enabled (this toggle controls whether yoast_head_json appears in WordPress REST responses).
Writing Yoast meta fields via POST returns 200 OK but the meta description in WordPress doesn't change
Cause: WordPress's REST API silently accepts but ignores unknown or protected meta keys by default. Yoast SEO registers its meta keys as protected, so they cannot be written via REST API without explicitly registering them using register_rest_field() in WordPress PHP code.
Solution: Add the register_rest_field() PHP snippet (shown in step 5) to WordPress's functions.php or a site-specific plugin. Without this code, WordPress accepts your POST request gracefully but discards the Yoast meta key values. After adding the snippet, re-test the Bubble write call and verify with a GET call that yoast_head_json.description reflects the new value.
Best practices
- Always use the _fields URL parameter when calling /wp-json/wp/v2/posts from Bubble. Requesting only id,title,slug,excerpt,date,yoast_head_json reduces response payload by roughly 80% compared to full post responses, which is critical for Bubble's API response size handling and Workload Unit efficiency.
- Use yoast_head_json.og_title for displaying post titles in Bubble UI — not yoast_head_json.title. The og_title omits the ' | Site Name' suffix that Yoast appends to the full title tag, giving you a clean post title suitable for display in cards and lists.
- Cache WordPress posts in a Bubble WPPost data type with a synced_at timestamp rather than calling the WordPress REST API on every page load. A one-per-day or on-demand sync keeps your Bubble database current without unnecessary API calls.
- Implement deduplication in your sync workflow using the WordPress post's id field. Before creating a new WPPost record, search for existing records with the same wp_id. If found, update the existing record — this prevents duplicate entries when syncing multiple times.
- For public WordPress sites, no authentication is needed for reading published posts. Avoid adding unnecessary credentials to a public-data API call. Only add WordPress Application Passwords (as Private headers) if the WordPress site restricts REST API access or if you need write operations.
- Handle the og_image as an array with :first item to access the URL. The yoast_head_json.og_image field is always an array even if only one image is set — attempting to access .url directly without :first item will fail in Bubble's expression builder.
- For multi-site agency dashboards, create a separate AppConfig record per client site with the WordPress base URL as a field. Reference this URL dynamically in the API Connector call rather than hardcoding one site's URL — this lets one API Connector call serve multiple WordPress sites by switching the base URL based on the selected client.
Alternatives
SEMrush provides external SEO intelligence — keyword rankings, backlink counts, domain traffic estimates, and competitor analysis — via a paid API. Yoast SEO integration reads your own WordPress site's on-page metadata for free. Use Yoast for managing and auditing your own content SEO; use SEMrush for competitive market research and keyword discovery.
Ahrefs specializes in backlink data and domain authority metrics accessed via a paid API. Yoast SEO gives you on-page metadata from your own WordPress posts at no API cost. The two tools serve complementary purposes: Yoast for what's on your pages, Ahrefs for who links to them. Both can be integrated into the same Bubble SEO dashboard.
Google Analytics tracks user behavior (pageviews, bounce rate, session duration) after pages are loaded. Yoast SEO data tells you what metadata is configured on pages before users arrive. Combine both in a Bubble dashboard to correlate Yoast SEO quality scores with actual GA traffic and engagement metrics.
Frequently asked questions
Is there a /wp-json/yoast/v1/ endpoint I can call directly?
No — this endpoint does not exist in current Yoast SEO versions. All Yoast SEO metadata is embedded in standard WordPress REST API responses as the yoast_head_json field. Call /wp-json/wp/v2/posts (or /pages) and read the yoast_head_json object from each post in the response.
Do I need Yoast SEO Premium to access yoast_head_json via the API?
No. The yoast_head_json field is available in the free Yoast SEO plugin from version 14.0 onward. The free plugin includes meta title, meta description, og_image, canonical URL, and JSON-LD schema in every REST API response. Yoast SEO Premium adds features like internal linking suggestions and multiple focus keywords, but these are not relevant to the REST API integration.
What's the difference between yoast_head_json.title and yoast_head_json.og_title?
yoast_head_json.title is the full title tag string including the site name suffix (e.g., 'How to Bake Bread | Your Site'). yoast_head_json.og_title is the clean Open Graph title without the suffix (e.g., 'How to Bake Bread'). For displaying post titles in Bubble UI cards and lists, always use og_title. Use the full title only if you're generating HTML meta tags for SEO purposes.
Can I use this integration to update Yoast meta titles and descriptions from Bubble?
Yes, but it requires two prerequisites: (1) WordPress Application Passwords set up for authenticated API access, and (2) a PHP register_rest_field() snippet added to WordPress's functions.php to expose Yoast's meta keys for REST API writes. Without the PHP snippet, WordPress accepts write requests silently but ignores the Yoast meta values. The read-only integration (pulling post data) works without either of these.
How do I paginate through a WordPress site with more than 100 posts?
WordPress REST API returns a maximum of 100 posts per request (per_page=100). For sites with more posts, use the page parameter to iterate: page=1, page=2, etc. The response headers include X-WP-Total (total post count) and X-WP-TotalPages (total pages). In Bubble, implement pagination by building a Backend Workflow that fetches page 1, stores results, then schedules itself with page+1 until all posts are synced.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation