Create a Custom Post in WordPress using Zapier

I know that WordPress probably needs no introduction, but Zapier just might.

Built to connect a dizzying variety of web services, Zapier lets non-developers and developers alike easily and quickly connect services to do things like taking Gmail messages from specific senders and posting them to Facebook or a Google spreadsheet or SalesForce. It’s a bit like IFTTT but geared more toward information and business. With more than 1,000 apps in the library, Zapier allows for some pretty powerful automation.

Now, back to WordPress. With custom post types firmly entrenched in the WordPress environment and a mature version 2 of the REST API, decoupling the back end of a WordPress site from the front end is easy. But getting data into that back end isn’t always a cinch.

And to be honest, Zapier’s WordPress integration has some limitations here as well, because while you can create posts for a custom post type with Zapier, passing along any custom fields or custom taxonomy terms is harder (Zapier currently only allows for the standard Categories and Tags). The reason is most likely because this has to happen in multiple steps.

But look at that scrollbar over there! You can clearly see that this is not the end of this tutorial. Which must mean that, yes!, you can still accomplish this in Zapier.

It just requires a couple of extra steps.

For our demo today, we’ll use Zapier to create posts of a custom post type with custom fields and custom taxonomies whenever a Google spreadsheet is updated.

This is mostly geared toward beginner and lower-end intermediate developers, but we’ll touch on a more advanced developer’s version toward the end.


You need a Zapier account and a WordPress site to use, obviously.

You’ll need the following WordPress plugins installed and activated:

You’ll also need your custom post type, custom fields, and custom taxonomy set up in WordPress. You can create these either by coding them into your theme, or by using plugins. If you’re not ready to code them yourself, try the Custom Post Type UI plugin (CPT UI also handles the creation of custom taxonomies).

The Beginning

Why are we using a Google spreadsheet as our triggering action in this situation? For a couple of reasons:

  • I have a client who uses something similar (Gmail) to send items to a WordPress installation
  • The Google Drive API is probably more daunting to jump into than some others, making it a natural to let Zapier do the heavy lifting of connecting and fetching data
  • Once you see the whole thing laid out, you’ll probably envision many other alternate triggers that could be used instead but which necessitate either some serious API work or, naturally, Zapier

So, in this situation, we have a custom post type called “Bands” with custom fields and custom taxonomies. And when people update a shared spreadsheet, it’s going to create a new Band post in WordPress.

Step One: Create your spreadsheet

We need a spreadsheet that’s going to cover all of our bases, so you’ll want the following columns:

  • Band Name
  • Lead Singer
  • Drummer
  • Style
  • Success Level

You’ll see that I’ve used the Data Validation feature in Drive to limit the input to specific categories which match what we’ll set up in WordPress. For more information on Data Validation in Google Sheets go here.

Step Two: Configure WordPress

First, let’s use CPT UI to create our custom post type and custom taxonomies.

Create a custom post type called “band”. You can leave most of the defaults in place, but make sure that you change the “Show in REST API” field to TRUE:

Now, let’s create our custom taxonomies and make them available to the custom post type.

Again, most defaults are fine, but make sure you set “Show in REST API” to TRUE:

Now populate your two custom taxonomies as follows:

  • Styles
    • Hard Rock
    • Metal
    • Blues
    • Pop
    • Kraut Rock
    • Prog Rock
    • Post Rock
  • Success Level
    • Cult
    • One-Hit Wonder
    • Moderate
    • Legendary

Finally, configure your custom fields, Lead Singer and Drummer. These simply need to be text fields.

Step Three: Start Zapping

Create a new Zap and start by setting your trigger app (the app that triggers the zap to run and do its thing). You’ll use Google Sheets and “New Spreadsheet Row” as the trigger. It’s going to prompt you to connect with Google to give Zapier access.

Once done, you can specify the spreadsheet and worksheet to be used:

Step Four: Connect WordPress

Choose WordPress as your Action app, and then follow the prompts to connect it to Zapier.

Once done, you’ll be able to fill out the template for your new posts/bands. You only really need post type and title (which is the band name in our case), but feel free to set the other fields as you choose (post status, etc.).

Now, you’re wondering about those custom fields and custom taxonomies, aren’t you? And you don’t see them here in Zapier, do you?

That’s because the real work is about to begin. In order to do this the way we want, we need to simply create and title the post in this step. Then in the subsequent steps, we’re going to go back and update the fields and taxonomy terms. Getting our content into WP through the REST API means a couple of different POST connections.

Step Five: Create Your Zapier App

Time to head to the Developer section in Zapier. From the footer pretty much anywhere on the Zapier site you can use the Developer Platform link.

Look for the link to Create a Web Builder App. Zapier will prompt you to consider using the CLI instead, but go ahead and continue with the web builder. Fill out the main app information here and continue.

Now, it’s time to set up Authorization. Click the Get Started button in the authorization section.

You’ll want to select the “OAuth v2” button and the “Yes, setup refresh” button.

Then copy the OAuth redirect URI that Zapier gives you there. You’ll need that in a minute.

Detour: Authorization

So far, we’ve taken advantage of WordPress’s API, but Zapier and its slick front-end have done all the real work. Now, it’s time to get a little deeper and work with the WordPress REST API more directly.

To do this, we need to create our own Zap App, which is possible using Zapier’s developer tools. There are two ways to do this: using the command line interface (CLI) or their builder tool. They’re trying to push people to use the CLI, and with good reason: it’s super flexible and powerful, but it’s also not really ideal for beginning coders. Thus, the builder is still available if you want to use it, so that’s what we’ll do here today. (Note: if you want to learn more about how it all works, and you should!, once you’ve built your app using the builder, you can convert it to a CLI version and look at the nuts and bolts of how it’s built.)

Whatever the case, the first thing your Zap App will need to do is to authenticate with your site. Zapier already has a built-in Webhooks app that can be used and it works to POST JSON data to the REST API. Problem is, it only allows for basic authentication. Which is fine for testing purposes but an absolute no-no on a production site. Your credentials are passed over every single time and they’re easy to grab and decode.

So we’re going to use OAuth right from the get-go here, and that’s the first reason we’re building our own Zapier app.

We’re going to use OAuth 2 so we’ll start by configuring the OAuth plugin you installed in your WordPress site earlier.

First, go to the settings for the plugin in WP and enable the OAuth server by checking the “OAuth Server Enabled” box. Then head to the Advanced Settings tab. Most of the defaults here are fine, except:

  • The only checkbox you really need checked for the Grant Types is “refresh tokens”.
  • You can extend the token lifetimes. Access tokens can expire basically whenever you want. But because you’re counting on Zapier automating this, you want it to mostly be set-it-and-forget-it. Which means you need a longer refresh token lifetime. Otherwise you’ll need to regularly reconnect the app in Zapier. So let’s set the access token lifetime to 14400 seconds (i.e. 24 hours) and the refresh token lifetime to 31536000 seconds (i.e. a year).

Once you’ve done that, you’ll need to create a client. Go to the OAuth Server > Clients area and add a new client. Check the boxes for Authorization Code and Refresh Token under the grant types. Then give your client a name. It should be something descriptive enough that if you have multiple clients and you need to revoke one, you can easily tell which is which. Now, in the Redirect URI field you can paste that redirect URI that Zapier gave you when you configured your Zapier app for OAuth 2 a few minutes ago. Choose which WordPress user to use (hint: DON’T use your main administrator account; set up a user just for this purpose). You can leave the client scope set to the default setting of “basic”. Save your new client and it’ll provide you with a Client ID and a Client Secret.

You’re finished here, let’s head back to our Zapier app.

Step Six: Configuring the App

When you choose OAuth v2 in Zapier, they very helpfully automatically create fields for Access Token and Refresh Token. So the Authorization configuration is now complete. But before we do anything else, the app needs a test trigger for authorization. This is so that, when testing the app or testing the connection to your site, Zapier can quickly determine whether its connection is still valid or not. So go ahead and add a new trigger, then configure it like so:

Click “Save & Next” and keep going: you don’t need any trigger fields.

In section 3 (Where Data Comes From), you’ll choose “Polling” for the first option. Your polling URL is going to be something like You can confirm this by going to Under Authentication, you’ll see the links for “authorize”, “token”, and “me”. You’ll use all three in this process, but in this case, the “me” link is what you need here. This simply lets Zapier confirm that you have access. Go ahead and hit “Save & Next” and leave the Sample Result as the default {}.

Now, you’ve got your authorization test trigger set.

Since the only thing our app is doing is creating and sending data, we’re done with both the Triggers and Searches sections.

Step Seven: Lights, Camera, Actions

Time to create our actions for actually sending our data over.

In the Actions section of your app, click the “Add New Action” button. We’ll start with our taxonomy terms.

Once you’ve completed that, you’ll need to add the fields to this action. We need three:

  • Style
  • Success
  • Endpoint URL

Configure them using mostly default settings, but make sure the box is checked for “Send to Action Endpoint URL in JSON body”.

Now, in the “Where To Send Data” step, you can use the endpoint_url field you just created.

This will let us specify the exact endpoint of the URL we’ll be using. This makes the app reusable. But you could also hardcode the endpoint here if you’re being more specific for this app.

Finally, creat the sample result for Zapier to use if it doesn’t or can’t pull any data.

It should look like this, using your terms and IDs:

"style": 11, 
"success": 16 

Now repeat the process with a separate action for your custom field data.

Why are we doing these separately instead of in one single action?

Good question! It’s because the endpoints for the taxonomy data and the ACF data are different. Plus, the JSON formatting is slightly different.

Here’s let’s take a look.

So you’ve created another action and populated the three fields for the custom fields: Lead Singer, Drummer, and endpoint URL.

There’s one crucial difference, that should be obvious in the sample result data you’ll use:

  "fields": { 
    "drummer": "Neil Peart", 
    "lead_singer": "Geddy Lee" 

The ACF fields here need to be children of “fields”, whereas the taxonomy terms were not.

Just so we can work through this, let’s use a feature that Zapier offers intended for line items.

When you edit your lead_singer and drummer fields, check out the Parent Key option:

Set that for both your fields and Zapier will automatically structure your JSON to place those fields under the “fields” parent.

We’re almost done, but because Zapier intends for this feature to be more for repeating line items, it’s going to format it just differently enough to prevent our data from properly submitting.

Zapier is actually going to try to submit it like this:

  "fields": [{ 
    "drummer": "Neil Peart", 
    "lead_singer": "Geddy Lee" 

Notice the difference? It’s those square brackets in there that’ll bork things for WordPress.

Step Eight: The Scripting API

Since this is a helpful tutorial and not necessarily a finished, streamlined piece of production code, here’s where we can use Zapier’s Scripting API. Which is basically a way to use some code to manipulate your app without going full-on with the CLI.

Head to your app’s home page and scroll down to find this section:

Use the Edit Code (Scripting API) button to get yourself to a mostly blank code editor view.

Here’s the code you’ll need, and we’ll walk through it in a minute:

'use strict'; 
var Zap = { 
  add_custom_data_pre_write: function(bundle) { 
    var theBundleData =; 
    var revisedBundle = theBundleData.replace(/([|])/ig, ''); 
    return { 
      url: bundle.request.url, 
      method: bundle.request.method, 
      auth: bundle.request.auth, 
      headers: bundle.request.headers, 
      params: bundle.request.params, 
      data: revisedBundle 

We’re using a pre_write method that lets us modify the Zap’s data before it sends it over. So ours is called add_custom_data_pre_write because it comes from our Add Custom Data action:

The method is just “your_action_pre_write”.

Then we simply get the, and remove the square brackets, then return this along with the rest of the bundle data.

You can save that and you’re all finished!

Step Nine: Finish Your Zap

Head back to the Zap you created earlier, with the Google Sheets trigger and the WordPress action.

Before we drop our new Zapier app into an action step, we need to do one more thing.

Remember, in our spreadsheet, we used the taxonomy term names, but when using the REST API, we need to turn that term name into a term ID.

For this, we’ll use two Code By Zapier apps as back to back steps.

You’ll get two options: Run Python or Run Javascript. Frankly, you could do this with either, but let’s use Javascript here.

For the Input Data, the theStyle as your key and the actual style data from step 1 of the zap.

Then use this code below:

const styleRes = await fetch(''); 
const stylejson = await styleRes.json(); 
for( var i = 0; i < stylejson.length; i++ ) { 
  if ( inputData.theStyle == stylejson[i].name ) { 
    var theStyleID = stylejson[i].id; 
    return { theStyle: await Promise.resolve( theStyleID )}; 

That goes to your site’s API, gets a list of all the style terms, checks each one against the term your trying to match here, and then returns the ID of the term.

Piece of cake.

Create a second step in your Zap using another Code By Zapier app and set it up the same way, but this time for our “success” taxonomy instead of “style”.

Now, you’re ready for the last two steps: Using your custom Zapier app. In the first of these steps, you’ll use your “Add Style and Success Data” action and configure with the appropriate endpoint. For example:

Now do the same thing again with your next step, but configure it for the custom field data.

In this case, for custom field data, your endpoint should look like:{{post_id}}

Where {{post_id}} is the post ID from step 2.

If you’ve configured everything correctly, your Zap should now run flawlessly!


That was a long, but rewarding tutorial. We covered authorization as well as passing custom data through the WordPress REST API in multiple steps. And using Zapier made it way, way easier than it otherwise would have been.

Now you can probably see a million other ways to use different triggers to move data into your WordPress site using this method.

Or, if you’re really bold, try out the Zapier CLI. The easiest way to get started is to install it and convert the Web Builder app we just built into a CLI app and then examine the code to see how it works.

Leave a Reply

Your email address will not be published. Required fields are marked *

Fill out this field
Fill out this field
Please enter a valid email address.
You need to agree with the terms to proceed