Skip to main content
RapidDev - Software Development Agency
retool-integrationsREST API Resource

How to Integrate Retool with WordPress

Connect Retool to WordPress using a REST API Resource pointed at your site's /wp-json/wp/v2/ base URL, authenticated with a WordPress Application Password. Once configured, build queries to list, create, update, and delete posts, pages, media, and users via WordPress's built-in REST API. Retool becomes a faster, more powerful content management panel than WordPress's own admin UI — especially valuable for teams managing hundreds of posts or performing bulk content operations.

What you'll learn

  • How to generate a WordPress Application Password and configure Basic Auth in Retool
  • How to query WordPress posts and pages with filters for status, author, category, and date
  • How to build a bulk content editing panel with inline status updates and batch publishing
  • How to manage WordPress users from a Retool admin interface
  • How to use JavaScript transformers to flatten WordPress REST API's nested response objects
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Intermediate15 min read20 minutesCMSLast updated April 2026RapidDev Engineering Team
TL;DR

Connect Retool to WordPress using a REST API Resource pointed at your site's /wp-json/wp/v2/ base URL, authenticated with a WordPress Application Password. Once configured, build queries to list, create, update, and delete posts, pages, media, and users via WordPress's built-in REST API. Retool becomes a faster, more powerful content management panel than WordPress's own admin UI — especially valuable for teams managing hundreds of posts or performing bulk content operations.

Quick facts about this guide
FactValue
ToolWordPress
CategoryCMS
MethodREST API Resource
DifficultyIntermediate
Time required20 minutes
Last updatedApril 2026

Why connect Retool to WordPress?

WordPress's admin panel (wp-admin) is designed for individual authors working on one post at a time. It is slow for bulk operations, offers limited filtering options on the All Posts screen, and requires navigating through multiple screens to make even simple changes across multiple posts. Teams managing content at scale — editorial teams with hundreds of posts, SEO agencies auditing metadata across a site, or operations teams maintaining product pages — hit these limitations quickly.

Retool transforms WordPress content management by giving you a faster, filterable, bulk-editable interface backed by the WordPress REST API. You can build a single Retool panel that shows all posts with their status, author, categories, and SEO metadata in one table; allows inline editing of titles, slugs, and excerpts; supports bulk status changes (draft → published) across multiple selected rows; and links directly to the WordPress editor for posts that need deeper editing. The same approach works for pages, custom post types, and WooCommerce products if WooCommerce is installed.

The WordPress REST API has been production-ready since WordPress 5.6 (December 2020) when Application Passwords were introduced, providing secure per-application authentication without exposing the admin password. Virtually all WordPress.org installations on 5.6+ have the REST API available at /wp-json/wp/v2/ by default. WordPress.com (hosted) also supports the REST API with OAuth authentication.

Integration method

REST API Resource

WordPress exposes a comprehensive REST API at /wp-json/wp/v2/ that covers posts, pages, media, users, categories, tags, and custom post types. Retool connects via a REST API Resource with Basic Auth using a WordPress Application Password — a credential type introduced in WordPress 5.6 that generates per-application tokens without exposing the main admin password. All API requests route through Retool's server-side proxy, so your WordPress credentials never reach the browser and your WordPress server does not need CORS headers configured.

Prerequisites

  • A self-hosted WordPress site running version 5.6 or higher with the REST API accessible (not blocked by a security plugin)
  • Admin or Editor access to the WordPress site (required to generate Application Passwords)
  • The base URL of your WordPress site (e.g., https://example.com)
  • A Retool account with Resource creation permissions
  • Confirmation that the WordPress REST API is accessible: visit https://yoursite.com/wp-json/wp/v2/posts in a browser and confirm you see a JSON response

Step-by-step guide

1

Generate a WordPress Application Password

Application Passwords (introduced in WordPress 5.6) let you generate per-application credentials that authenticate with the WordPress REST API without using your main admin password. In your WordPress admin panel, go to Users → Profile (or Users → All Users → click your username → Edit). Scroll down to the Application Passwords section near the bottom of the profile page. If you do not see this section, your WordPress installation may have it disabled by a security plugin (some plugins like Wordfence block Application Passwords by default) — check your security plugin settings. In the Add New Application Password section, enter a descriptive name in the Name field, such as Retool Integration. Click Add New Application Password. WordPress generates and displays a password in the format XXXX XXXX XXXX XXXX XXXX XXXX (24 characters with spaces). Copy this password immediately — it is only shown once. Save it in a secure location. This Application Password is used for HTTP Basic Auth: the username is your WordPress admin username (not the email address), and the password is the Application Password you just generated, including the spaces. Note that the Application Password grants the same permissions as the user account you generated it from — use an admin account for full REST API access, or a more restricted role if you only need read access.

Pro tip: If the Application Passwords section is missing from your profile, check if a security plugin is blocking it. In Wordfence, go to Wordfence → All Options → Login Security Options and enable or check Application Passwords settings. Alternatively, add define('WP_APPLICATION_PASSWORDS_ENABLED', true) to wp-config.php.

Expected result: You have a WordPress Application Password (24 characters with spaces) and your WordPress username ready to use for Basic Auth in Retool.

2

Create the WordPress REST API Resource in Retool

In Retool, go to the Resources tab and click Add Resource. Select REST API from the resource type list. Give the resource a name like WordPress Production or your site name + CMS (e.g., Acme Blog CMS). In the Base URL field, enter your WordPress site's REST API base URL: https://yoursite.com/wp-json/wp/v2. Include the /wp-json/wp/v2 path prefix — this means all query paths in Retool will be relative to this base, so a query for posts would use path /posts rather than the full URL. In the Authentication section, select Basic Auth. Enter your WordPress admin username in the Username field — this is the username you log in with, not the email address. In the Password field, enter the Application Password you generated, including the spaces (e.g., Ab12 Cd34 Ef56 Gh78 Ij90 Kl12). WordPress accepts Application Passwords with or without spaces. Click Save. To verify the connection, create a test query targeting /posts with method GET and run it — you should receive a JSON array of posts. If you receive a 401 error, double-check the username and Application Password. If you receive a 403 error, the user account may not have the required role for the operation.

Pro tip: WordPress.com (hosted) uses OAuth 2.0 rather than Application Passwords. For WordPress.com sites, set up an Application in the WordPress.com developer console to get a client ID and secret, then use OAuth 2.0 in the Retool resource's authentication settings.

Expected result: The WordPress REST API Resource is configured with Basic Auth. A test GET /posts query returns a JSON array of post objects confirming the connection and authentication are working.

3

Query and display WordPress posts

Create a new query, select your WordPress resource, set Method to GET, and set Path to /posts. WordPress's posts endpoint supports extensive query parameters for filtering: per_page (up to 100), page (for pagination), status (publish, draft, pending, private — or any for all), author (user ID), categories (comma-separated category IDs), search (keyword search), orderby (date, title, modified, relevance), and order (asc or desc). Add these as URL Parameters in the query editor, referencing Retool component values using {{ }} syntax. For example, add a status parameter with value {{ statusFilter.value || 'any' }} to filter by status from a Select component. Set per_page to {{ perPageSelect.value || 100 }}. WordPress also supports the _fields parameter to restrict which fields are returned — add _fields with value id,title,status,date,modified,author,categories,excerpt,link,slug to avoid fetching full post content for list views, significantly reducing response size. Run the query. WordPress returns an array of post objects with nested objects for title (rendered), excerpt (rendered), and content (rendered) — each has a .rendered sub-field containing the actual HTML or text. Apply a transformer to flatten these nested objects before binding to Table.

posts_transformer.js
1// WordPress posts transformer — flatten nested title/excerpt objects
2// Paste into Advanced → Transform results
3const posts = data || [];
4return posts.map(post => ({
5 id: post.id,
6 title: post.title?.rendered || '(no title)',
7 slug: post.slug || '',
8 status: post.status || '',
9 date: post.date ? new Date(post.date).toLocaleDateString() : '',
10 modified: post.modified ? new Date(post.modified).toLocaleDateString() : '',
11 author_id: post.author || '',
12 excerpt: post.excerpt?.rendered
13 // Strip HTML tags from excerpt
14 ? post.excerpt.rendered.replace(/<[^>]*>/g, '').trim()
15 : '',
16 // Direct link to WordPress editor for this post
17 edit_link: `${post.link.replace(/\/[^\/]*$/, '')}/wp-admin/post.php?post=${post.id}&action=edit`,
18 view_link: post.link || ''
19}));

Pro tip: Use the _fields query parameter to request only the fields you need in the transformer. This reduces response payload significantly for sites with thousands of posts and speeds up the query.

Expected result: The posts query returns a flat array of post objects with readable title, excerpt, status, and dates. The data binds cleanly to a Table component with no raw HTML in the cells.

4

Implement post status updates and bulk editing

Create an update query to change post fields. Select your WordPress resource, set Method to POST (WordPress uses POST for updates to existing resources, not PATCH), Path to /posts/{{ table1.selectedRow.id }}, and Body type to JSON. In the Body field, enter a JSON object with the fields to update. For a status change: { status: {{ statusUpdateSelect.value }} }. For a title and excerpt update: { title: {{ titleInput.value }}, excerpt: {{ excerptInput.value }} }. WordPress validates the status value against allowed values (draft, pending, publish, future, private) and returns the updated post object on success. Wire this query to a Save Changes button. For bulk status updates across multiple selected rows, use a JavaScript query that iterates over table1.selectedRows (an array of all checked rows when multi-select is enabled) and calls the update query for each. Enable multi-select on the Table by toggling the Selection Type to Multiple in the Table settings. Add a Publish Selected button that triggers the JavaScript bulk update with status: 'publish'. On success, refresh the posts query and show a notification with the count of updated posts. For updating custom fields stored as post meta, include the meta object in the request body: { meta: { _yoast_wpseo_metadesc: {{ metaDescInput.value }} } }. Note that custom meta fields must be registered with register_meta() and exposed via the REST API to be writable.

bulk_update_posts.js
1// JavaScript query for bulk status update of selected posts
2// Triggered by a 'Publish Selected' button onClick
3const selectedPosts = table1.selectedRows;
4if (!selectedPosts || selectedPosts.length === 0) {
5 utils.showNotification({ title: 'No posts selected', notificationType: 'warning' });
6 return;
7}
8
9const targetStatus = bulkStatusSelect.value || 'publish';
10
11const updatePromises = selectedPosts.map(post =>
12 updatePostStatus.trigger({
13 additionalScope: {
14 postId: post.id,
15 newStatus: targetStatus
16 }
17 })
18);
19
20try {
21 await Promise.all(updatePromises);
22 await getPosts.trigger();
23 utils.showNotification({
24 title: `Updated ${selectedPosts.length} posts to ${targetStatus}`,
25 notificationType: 'success'
26 });
27} catch (err) {
28 utils.showNotification({
29 title: 'Some updates failed: ' + err.message,
30 notificationType: 'error'
31 });
32}

Pro tip: WordPress rate limits REST API requests by IP if too many requests arrive quickly. Use Promise.all() for small batches but consider sequential execution with a small delay for bulk operations on hundreds of posts to avoid 429 errors.

Expected result: Individual post status updates work via a single-row update query. Selecting multiple rows and clicking Publish Selected changes all selected posts to published status in WordPress and refreshes the panel.

5

Add user management and media queries

Extend the WordPress panel with user management and media library capabilities. For users, create a query with Path /users and Method GET. Add query parameters: per_page 100, context edit (required to see email addresses and capabilities, requires authentication), and roles to filter by role (administrator, editor, author, subscriber). Apply a transformer to extract the relevant user fields. Create an update query targeting /users/{{ table1_users.selectedRow.id }} to change user roles: { roles: [{{ roleSelect.value }}] }. For the media library, create a query with Path /media and GET method. Add mime_type as a query parameter to filter by file type (image/jpeg, image/png, application/pdf). The response includes source_url for the full-size file, media_details.sizes for different size variants, title.rendered for the filename, and alt_text. Display media items in a Retool Image Mosaic or Table component with clickable links to the source URLs. For creating new media (uploading files), this requires multipart form data upload which is best handled directly in WordPress — Retool's REST API resource can send binary data, but file upload UI is typically simpler in WordPress's native media uploader. For RapidDev's team building complex WordPress editorial workflows combining multiple endpoints, custom fields, and multi-site configurations, RapidDev can architect the full Retool solution.

users_transformer.js
1// WordPress users transformer
2const users = data || [];
3return users.map(user => ({
4 id: user.id,
5 username: user.slug || '',
6 name: user.name || '',
7 email: user.email || '(hidden)',
8 roles: Array.isArray(user.roles) ? user.roles.join(', ') : '',
9 registered: user.registered_date
10 ? new Date(user.registered_date).toLocaleDateString()
11 : '',
12 post_count: user.meta?.post_count || 0,
13 profile_url: user.link || ''
14}));

Pro tip: The context=edit parameter is required to see user email addresses and full role information. Without it, the API returns a reduced public view of user data even with authentication.

Expected result: The WordPress panel has tabs or sections for Posts, Users, and optionally Media. All three data types load from the WordPress REST API and display in tables with appropriate actions.

Common use cases

Bulk content status and metadata editor

Build a Retool panel that shows all posts with their current publish status, author, category, and meta description in an editable Table. Editorial teams can filter by status (draft, pending, published), bulk-select rows, and change status for multiple posts in one operation. A direct link column opens the post in the WordPress block editor for deeper editing when needed.

Retool Prompt

Build a Retool WordPress content panel that lists all posts with status, author, date, and category in a Table. Include filter dropdowns for status and author. Add a Publish Selected button that changes the status of selected rows to 'publish' using the WordPress Posts API, and a direct link column that opens the post in wp-admin/post.php?post={id}&action=edit.

Copy this prompt to try it in Retool

SEO content audit dashboard

Create a Retool SEO audit tool that fetches all published posts along with their excerpt, yoast_meta_description, and slug. The Table highlights posts missing meta descriptions (conditional formatting on empty fields), allows inline editing of the excerpt and slug, and saves changes directly via the WordPress Posts API. This replaces the need to open each post individually in the WordPress editor for SEO updates.

Retool Prompt

Build a Retool SEO audit dashboard that queries all published WordPress posts and shows title, slug, excerpt, and meta description in an editable Table. Highlight rows where the excerpt is empty with red conditional formatting. Include a Save button that patches changed post fields via the WordPress REST API.

Copy this prompt to try it in Retool

WordPress user management panel

Build a user management panel that lists all WordPress users with their roles, email, and registration date. Admins can change user roles, reset passwords by triggering the WordPress password reset email, and deactivate accounts by downgrading the role. This is more efficient than wp-admin's Users screen for sites with hundreds of users.

Retool Prompt

Build a Retool WordPress user management tool that lists all users from the /wp/v2/users endpoint with columns for name, email, role, and registered date. Add a role change dropdown on each row and a Save button that updates the user's role via the WordPress Users API.

Copy this prompt to try it in Retool

Troubleshooting

API returns 401 Unauthorized despite correct credentials

Cause: Application Passwords may be disabled by a security plugin (Wordfence, iThemes Security, All-In-One Security), or the Application Password feature is explicitly disabled in wp-config.php, or SSL is not enabled and WordPress blocks Application Password auth over HTTP.

Solution: Check your security plugin settings for Application Passwords — Wordfence has a specific setting to allow or block them. Ensure your site uses HTTPS (Application Passwords require SSL in many configurations). Add define('WP_APPLICATION_PASSWORDS_ENABLED', true) to wp-config.php if the feature has been explicitly disabled. Also verify you are using the WordPress username (not email) as the Basic Auth username.

Posts query returns 403 Forbidden when filtering by status=draft or status=any

Cause: The WordPress REST API requires authentication to view non-published content. Without authentication, or with insufficient permissions, the API only returns published posts and rejects requests for draft or private content.

Solution: Verify that the WordPress Resource in Retool has Basic Auth configured with an admin or editor account credentials. Check that the Application Password is still active in WordPress (Users → Profile → Application Passwords). The user account needs at least the edit_others_posts capability to view other authors' drafts.

Post update query returns 'rest_cannot_edit' error

Cause: The authenticated WordPress user does not have permission to edit the target post — typically because it was authored by a different user and the authenticated account has Author role (not Editor or Admin).

Solution: Use an Editor or Administrator account for the Application Password. Authors can only edit their own posts via the REST API. Alternatively, if you only need to manage specific post types, ensure the user has the appropriate capabilities for those post types.

Title and excerpt cells show raw HTML tags like <p> and <strong>

Cause: WordPress REST API returns title, excerpt, and content as objects with a .rendered field containing HTML. The transformer is not stripping HTML tags before binding to the Table.

Solution: In your posts transformer, strip HTML from text fields using a regex replace: post.excerpt.rendered.replace(/<[^>]*>/g, '').trim(). For titles, WordPress's title.rendered usually contains minimal formatting — apply the same replacement to be safe.

typescript
1// Strip HTML from WordPress rendered fields
2const stripHtml = (html) => (html || '').replace(/<[^>]*>/g, '').trim();
3
4return posts.map(post => ({
5 title: stripHtml(post.title?.rendered),
6 excerpt: stripHtml(post.excerpt?.rendered)
7}));

Best practices

  • Use WordPress Application Passwords for REST API authentication rather than your main admin password — Application Passwords can be revoked independently without changing your login credentials.
  • Request only the fields you need using the _fields query parameter in GET requests — WordPress posts have large response payloads by default, and limiting fields significantly speeds up queries for list views.
  • Add confirmation modals for any query that changes post status to published — accidentally publishing draft posts is difficult to reverse quickly, especially for sites with RSS subscribers.
  • Use per_page=100 (the WordPress maximum) and implement pagination using the X-WP-TotalPages response header to handle sites with many posts efficiently.
  • Store the Application Password in a Retool configuration variable marked as secret rather than directly in the resource — this keeps it out of resource configuration exports and enables rotation without editing the resource.
  • Test all write operations on a WordPress staging site before running them on production — status changes, bulk updates, and user role changes are immediately live on production WordPress.
  • For custom post types or WooCommerce products, verify the REST API namespace and endpoint path — custom post types use /wp/v2/{post_type_slug} but only if registered with show_in_rest: true.
  • Handle WordPress pagination using the page query parameter and the X-WP-Total and X-WP-TotalPages response headers to accurately show users how many records exist and implement proper pagination controls.

Alternatives

Frequently asked questions

Does Retool support WordPress.com (hosted) in addition to self-hosted WordPress.org?

Yes, but with different authentication. WordPress.com uses OAuth 2.0 rather than Application Passwords. You need to create an application in the WordPress.com developer console (developer.wordpress.com/apps) to get a client ID and secret, then configure OAuth 2.0 in Retool's REST API Resource. The API endpoints are slightly different (https://public-api.wordpress.com/wp/v2/sites/{site}/posts) compared to self-hosted installations.

Can I access custom post types and Advanced Custom Fields (ACF) from Retool?

Yes. Custom post types are accessible at /wp-json/wp/v2/{post_type_slug} if the post type is registered with show_in_rest: true. ACF fields appear in the REST response if ACF is configured to expose them (the Show in REST API setting in ACF group settings). The fields appear under an acf key in the post object. You can read and write ACF fields through the REST API the same way you handle standard meta fields.

How do I handle WordPress sites with thousands of posts in Retool?

Use per_page=100 (the maximum WordPress allows per request) and implement pagination using the page query parameter. Reference a Retool Pagination component or Number input for the current page. The WordPress REST API returns X-WP-Total and X-WP-TotalPages headers in the response — access these in a JavaScript query via the rawData property to set pagination limits accurately. For very large datasets, use WordPress search, category filters, and date filters to limit queries to manageable subsets.

Can I use Retool to create new WordPress posts?

Yes. Create a query with Method POST and Path /posts. Set the Body to a JSON object with the required fields: title (as a string), content (HTML or plain text), status (draft or publish), and optional fields like categories, tags, author, and slug. WordPress creates the post and returns the created post object including the generated ID. Wire this query to a form's Submit button and refresh the posts list on success.

Will Retool's WordPress queries bypass my WordPress security plugins?

Not entirely. Retool's requests arrive at your WordPress server's REST API endpoint like any other HTTPS request. Security plugins like Wordfence still apply rate limiting, IP blocking, and request inspection to Retool's requests. If a security plugin blocks Retool, you may need to whitelist Retool's IP ranges in the plugin settings. Application Password authentication itself is a WordPress core feature that operates independently of most security plugins.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Integrations are where projects stall

We wire Retool integrations like this one every week — auth, webhooks, edge cases included. Fixed-price builds from $13K, delivered in 6–10 weeks.

Talk to an integration engineer

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.