> For the complete documentation index, see [llms.txt](https://docs.feedotter.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.feedotter.com/newsletters/content-sources/wordpress-api.md).

# WordPress API

The WordPress API content source connects Feedotter directly to your WordPress site's REST API, pulling posts, custom post types, and taxonomy-filtered content into your email campaigns without an RSS

### Getting Started

Navigate to **Content Sources → Add Content Source** and select **WordPress API** from the source type list.

<figure><img src="https://2086102864-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIdHBGk8cqznUpEqm5g1U%2Fuploads%2FZxlWco3qThHPsQrnStRU%2Fimage.png?alt=media&amp;token=34d76b60-6cc2-4cfb-befa-5f500a0935df" alt=""><figcaption></figcaption></figure>

The editor opens to four tabs: **Details**, **Fields**, **Filters**, and **Preview**. Work through them in order the first time you set up a source.

***

### Tab 1 — Details

This tab is where you connect your site and configure what content to pull.

#### Connect Your Site

Enter your WordPress site's base URL (e.g. `https://www.example.com`) in the **Your WordPress Website URL** field, then click **Load Site Data**.

FeedOtter will reach your site's REST API, verify the connection, and pre-load your available post types, tags, and categories. A success toast confirms the connection. If the connection fails, an error message appears below the field explaining what went wrong.

<figure><img src="https://2086102864-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIdHBGk8cqznUpEqm5g1U%2Fuploads%2FbQN6tcrhVqPekWCjHcxJ%2Fimage.png?alt=media&amp;token=2ab0ab93-9f70-46e1-a7c4-bd70a3643b63" alt=""><figcaption></figcaption></figure>

> **Tip:** You only need to click Load Site Data once when setting up a new source. When editing an existing source, this data loads automatically.

***

#### Authentication *(optional)*

By default, Feedotter connects to your site without credentials and pulls only **published** posts — no authentication required for public content.

If you need to access **drafts, scheduled posts, private posts, or a password-protected site**, click **"Connecting to a private site, or need drafts, scheduled, or private posts? Add authentication"** to expand the Authentication section.

We recommend created a dedicated WordPress user for this integration. An example would be:

<figure><img src="https://2086102864-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIdHBGk8cqznUpEqm5g1U%2Fuploads%2FSGgzPesIHq04kX59Rd1m%2Fimage.png?alt=media&amp;token=c740f419-8c05-4d7f-a359-82f5cc46fc1b" alt=""><figcaption></figcaption></figure>

| Field                    | What to enter                                                                         |
| ------------------------ | ------------------------------------------------------------------------------------- |
| **Username**             | Your WordPress username (must have Editor or Administrator role)                      |
| **Application Password** | Generated in your WordPress dashboard under *Users → Profile → Application Passwords* |

Click **Test Connection** to verify your credentials before saving.&#x20;

> **Note:** Application Passwords are different from your login password.

***

#### Settings

Once connected, the Settings section appears with the following options:

**Max Number of Posts to Include** How many posts FeedOtter retrieves per sync. Default is 25, maximum is 100.

***

**Post Type** Defaults to **Posts** (the standard WordPress post type). If your site uses Custom Post Types (e.g. Case Studies, Events, Products), select the correct type from the dropdown. FeedOtter auto-discovers all REST-enabled post types from your site.

If a post type doesn't appear in the dropdown (it may not have `show_in_rest: true` set in WordPress), click **Enter manually** and type the post type's REST base slug directly (e.g. `case-study`, `event`).

***

**Status** Controls which post statuses FeedOtter retrieves. Defaults to **Publish** (live, publicly visible posts). You can select multiple statuses.

| Status             | Description                       | Requires Authentication |
| ------------------ | --------------------------------- | ----------------------- |
| Publish            | Live, publicly visible posts      | No                      |
| Future (Scheduled) | Posts scheduled for a future date | Yes                     |
| Draft              | Unpublished drafts                | Yes                     |
| Pending Review     | Posts awaiting editorial review   | Yes                     |
| Private            | Visible only to logged-in users   | Yes                     |

If you select any status other than Publish without having entered authentication credentials, an inline warning will prompt you to add them.

***

**Permalink Structure** *(appears only when "Future" is selected)*

WordPress does not return a real URL for scheduled posts through its API. To work around this, enter your site's permalink structure so FeedOtter can construct the final URL for each scheduled post.

Copy the value from your WordPress dashboard under *Settings → Permalinks → Custom Structure* (e.g. `/blog/%postname%/`).

> ![](https://2086102864-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIdHBGk8cqznUpEqm5g1U%2Fuploads%2FxCT7iSKQlkvBrmkuSfSc%2Fimage.png?alt=media\&token=fee6d2ef-0885-4569-840f-2362f381956c)

> **Note:** This field only appears when "Future (Scheduled)" is one of the selected statuses. Published and private posts already have correct URLs from WordPress. Draft and pending posts don't have a final URL yet, so they retain a `?p=ID` fallback link.

***

### Tab 2 — Fields

The Fields tab controls how WordPress post data is mapped to FeedOtter's standard content fields and any custom fields you want to make available in your templates.

<figure><img src="https://2086102864-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIdHBGk8cqznUpEqm5g1U%2Fuploads%2FelGD7v0SrqzPZ1zoreXH%2Fimage.png?alt=media&amp;token=bf85ba78-4447-413e-ada2-e6f38bc05dd1" alt=""><figcaption></figcaption></figure>

When you open this tab, FeedOtter samples up to 10 recent posts from your site and discovers all the available JSON paths — including standard fields like `title/rendered` and `excerpt/rendered`, as well as plugin data like Advanced Custom Fields groups (e.g. `acf/people_position`).

The number of discovered fields appears at the top: *"42 fields found by sampling recent 'posts' items."*

#### Standard Field Rows

| Row             | Default behavior if left blank                                                                                                                                                  |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Title**       | Uses `title/rendered`                                                                                                                                                           |
| **Description** | Uses `excerpt/rendered`                                                                                                                                                         |
| **Content**     | Uses `content/rendered` (full post body)                                                                                                                                        |
| **URL**         | Uses the post's `link` field                                                                                                                                                    |
| **Date**        | Uses `date` (publish date)                                                                                                                                                      |
| **Image URL**   | If your posts have a featured image specified you can use the *wp:featuredmedia/source\_url*. If left blank, Feedotter will attempt to detect the featured image automatically. |

Leaving a row blank means FeedOtter uses the automatic value listed above. You only need to set a mapping if you want to pull data from a different field — for example, mapping **Description** to an ACF custom excerpt field.

For best consistent results, we recommend mapping up all fields.

#### Custom Fields

Click **+ Add Row** at the bottom of the table to create additional fields. These are surfaced in curated email templates as `custom.<Name>.value`. Give each custom field a descriptive name, select its type (Text, Rich Text, URL, Date, Image URL), and pick the path from the dropdown.

#### Manual Path Entry

If a field doesn't appear in the dropdown (for example, an ACF field that happens to be empty on every post in the recent sample), check the **"Type paths manually"** box. All rows switch to free-text inputs so you can type the path directly (e.g. `acf/people_position`).

Click **Reload fields** at any time to re-sample the site and refresh the dropdown list.

***

### Tab 3 — Filters

The Filters tab gives you fine-grained control over which posts FeedOtter pulls. All filters are optional.

<figure><img src="https://2086102864-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIdHBGk8cqznUpEqm5g1U%2Fuploads%2Fkao3YGOjNBAnOZsTlTAA%2Fimage.png?alt=media&amp;token=8373fb0f-f024-4e51-a8a2-b79491a96a0a" alt=""><figcaption></figcaption></figure>

#### Tags and Categories

Each has a mode selector and a multi-select term picker:

* **Include tags / Include categories** — only return posts assigned to the selected terms
* **Exclude tags / Exclude categories** — return all posts *except* those assigned to the selected terms
* Leave the mode set to **None** to apply no filter

Start typing in the picker to search terms by name. If a term doesn't appear (sites with more than 100 terms cap the initial list), use the **"Can't find it? Add \[term] by ID"** link to look it up directly by its WordPress term ID.

***

#### Custom Taxonomies

If your site has Custom Taxonomies registered to the selected Post Type, they appear automatically below Categories after you load the site data. Each one works the same way as Tags and Categories — select Include or Exclude, then pick terms.

If no taxonomies appear, click **"Load tags, categories & taxonomies"** to trigger the lookup. A message will confirm if the post type has no additional custom taxonomies.

***

#### Date Filter

Restrict posts to a rolling time window using the **Published date** filter.

* Set the mode to **Published in the last** and enter a number of days (e.g. `30`)
* Leave the mode set to **None** to return posts from any date

<figure><img src="https://2086102864-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIdHBGk8cqznUpEqm5g1U%2Fuploads%2FIBpYFd0lnDhGwu1A6ONq%2Fimage.png?alt=media&amp;token=d745de34-a5fd-482e-a65b-f3738f5c21ae" alt=""><figcaption></figcaption></figure>

> **Note:** The date filter uses each post's WordPress publish date by default. If you've mapped the **Date** field on the Fields tab to `modified` or `modified_gmt`, the filter uses last-modified date instead.

***

### Tab 4 — Preview

The Preview tab lets you verify that FeedOtter is pulling the right content before you use this source in a campaign.

<figure><img src="https://2086102864-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIdHBGk8cqznUpEqm5g1U%2Fuploads%2FKvYFN290Gk0YneRHZTP4%2Fimage.png?alt=media&amp;token=052a6d5b-cfe7-47d7-a11c-33d43dcf56b9" alt=""><figcaption></figcaption></figure>

Click **Generate Preview**. FeedOtter saves your current settings and fetches a live sample of up to 10 posts from your site, applying all the filters and field mappings you've configured.

Each post card displays:

* Thumbnail image
* Title
* Description / excerpt
* URL
* Publish date

If no posts appear, check:

* The correct **Post Type** is selected on the Details tab
* Your **Status** selection matches posts that actually exist
* Your **Filters** are not excluding everything (try removing filters temporarily)
* **Authentication** credentials are set if you're targeting non-published content

***

### Saving the Source

Click **Add Source** (new) or **Save** (edit) at the bottom right of any tab to persist all settings. The source is now available to use in curated campaigns and automated RSS newsletters.
