Zernio
Zernio
Overview

Social Posting

XInstagramFacebookLinkedInTikTokYouTubePinterestRedditBlueskyThreadsGoogle Business ProfileSnapchat

Messaging

WhatsAppTelegramDiscordSlack

Telephony

Phone NumbersVoice & CallsSMS

Advertising

Meta AdsGoogle AdsLinkedIn AdsTikTok AdsPinterest AdsX AdsOpenAI Ads

Blogs & Commerce

ShopifyWordPress
Dashboard
llms.txtOpenAPI
OverviewPlatformsAPI ReferenceResources

WordPress

Connect WordPress.com or a self-hosted WordPress site, then create, schedule, update and delete its articles through the Blogs API.


Connect a WordPress.com or self-hosted WordPress site and manage its articles with the Blogs API. A connected account uses platform: "wordpress" and represents one site with one account-scoped blog. WordPress is a blog integration: the account never appears as a target in POST /v1/posts and has no Zernio analytics or inbox.

Quick reference

PropertyValue
Platform valuewordpress
What it managesOne site's standard posts through one account-scoped blog
WordPress.com authOAuth 2.0
Self-hosted authUsername and WordPress Application Password
Social postingNo
AnalyticsNo
SchedulingYes, native (publishDate; no Zernio queue)
DraftsYes (isPublished: false)
Article bodyHTML (bodyHtml)
TagsNames; missing tags are created on the site
AuthorNumeric WordPress user ID encoded as a string
Featured imagePublic JPEG, PNG, WebP or GIF URL; up to 10 MB
SEO plugin fieldsNot supported
PaginationCursor (limit 1 to 50, default 20, plus nextCursor)

Before you start

Choose one connection path for each site:

  • WordPress.com: the site owner approves OAuth and selects a site on WordPress.com.
  • Self-hosted WordPress: the site owner supplies an HTTPS site URL, their WordPress login username and an Application Password created in WordPress admin.

The authenticated WordPress user must be able to publish posts and upload files. Zernio verifies both capabilities before it saves the connection. A role that can only write drafts is insufficient.

The account represents the selected site, not the person who authorized it. Connect another site as another account. Site and article data stays on WordPress; Zernio maps it into the common Blogs API response shape.

Connect WordPress.com

Call GET /v1/connect/wordpress with profileId and redirect_url, then send the site owner's browser to the returned authUrl:

curl "https://zernio.com/api/v1/connect/wordpress?profileId=66a1f0c2a4b9d3e8f1a2b3c4&redirect_url=https%3A%2F%2Fmyapp.com%2Fconnected" \
  -H "Authorization: Bearer $ZERNIO_API_KEY"

Response (200):

{
  "authUrl": "https://public-api.wordpress.com/oauth2/authorize?...",
  "state": "..."
}

Redirect the browser to authUrl. WordPress.com handles consent and site selection. Its callback connects the selected site and sends the browser to your redirect_url. The returned WordPress.com numeric site ID becomes that account's blogId; read it through List blogs instead of constructing it.

redirect_url must be a safe absolute destination. Keep the returned state opaque; Zernio validates it at the callback. Connecting the same profile to the same site again refreshes the connection in place rather than creating another account slot.

WordPress.com OAuth scopes

Zernio uses WordPress.com's default single-site authorization by omitting the scope parameter. The consent grants access to the selected site; Zernio uses that connection for articles, featured images and tags. It does not request the explicit global scope that grants access across all your sites. Granular scopes such as posts and media do not support the /wp/v2 API used by this integration. See the official WordPress.com OAuth documentation for the upstream scope model.

Connect self-hosted WordPress

In WordPress admin, the site owner opens their user profile and creates an Application Password for Zernio. Send the generated password with the login username to POST /v1/connect/wordpress/token:

curl -X POST "https://zernio.com/api/v1/connect/wordpress/token" \
  -H "Authorization: Bearer $ZERNIO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "profileId": "66a1f0c2a4b9d3e8f1a2b3c4",
    "siteUrl": "https://example.com",
    "username": "editor@example.com",
    "applicationPassword": "xxxx xxxx xxxx xxxx xxxx xxxx"
  }'

Response (200):

{
  "account": {
    "_id": "66b2e19d8c3f5a7e9d0b1c2d",
    "platform": "wordpress",
    "username": "example.com",
    "displayName": "Example Press",
    "profileId": "66a1f0c2a4b9d3e8f1a2b3c4"
  }
}

siteUrl must use HTTPS and identify the public site root. Do not include /wp-json, a REST endpoint, a username, a password or other credentials in the URL. Zernio safely discovers the site's REST API, rejects private or local network targets, verifies the credentials and checks publish/upload capabilities before persisting the account.

An Application Password is separate from the user's interactive WordPress password. Treat it as a secret and revoke it from WordPress admin when it is no longer needed. Revoking it immediately stops API access; reconnect the account with a new Application Password to restore it.

Publish articles

WordPress uses the same article endpoints as Shopify. The differences are the single-blog model, WordPress author IDs and tag/media handling described below.

List the site blog

Always start with List blogs:

curl "https://zernio.com/api/v1/accounts/66b2e19d8c3f5a7e9d0b1c2d/blogs" \
  -H "Authorization: Bearer $ZERNIO_API_KEY"

A self-hosted account returns exactly one blog with id: "1":

{
  "platform": "wordpress",
  "blogs": [
    {
      "id": "1",
      "platform": "wordpress",
      "title": "Example Press",
      "handle": "example.com"
    }
  ],
  "nextCursor": null
}

The value "1" is scoped to the connected account. It does not claim that the WordPress database's internal blog ID is 1. A WordPress.com account uses its numeric WordPress.com site ID instead. Code that supports both connection types should use blogs[0].id from this response.

Fetch the same site metadata with Get a blog:

curl "https://zernio.com/api/v1/accounts/66b2e19d8c3f5a7e9d0b1c2d/blogs/1" \
  -H "Authorization: Bearer $ZERNIO_API_KEY"

Create a draft

Call Create a blog article with a title. New WordPress articles default to draft, so this minimal request does not publish:

curl -X POST "https://zernio.com/api/v1/accounts/66b2e19d8c3f5a7e9d0b1c2d/blogs/1/articles" \
  -H "Authorization: Bearer $ZERNIO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Autumn collection preview",
    "bodyHtml": "<p>The first pieces land next month.</p>",
    "handle": "autumn-collection-preview",
    "excerpt": "An early look at what is arriving this September.",
    "tags": ["autumn", "new arrivals"],
    "author": "42",
    "image": {
      "url": "https://cdn.example.com/autumn.jpg",
      "altText": "Wool coats on a rail"
    },
    "isPublished": false
  }'

WordPress resolves existing tags by name case-insensitively and creates a missing tag on the site. You can send up to 100 non-empty tag names. Creating a missing term depends on the connected user's WordPress permissions. author is the numeric ID of a WordPress user who can author the post, encoded as a JSON string. It is not a login, email or display name; assigning another user as author can require a higher WordPress role.

For image.url, WordPress downloads the file into that site's media library and sets the resulting attachment as the featured image. The URL must be publicly reachable and return a JPEG, PNG, WebP or GIF no larger than 10 MB. altText becomes the attachment's alternative text. Omitting image during a later PATCH preserves the existing featured image; this API has no featured-image removal sentinel.

Response (201):

{
  "platform": "wordpress",
  "article": {
    "id": "1842",
    "blogId": "1",
    "platform": "wordpress",
    "title": "Autumn collection preview",
    "bodyHtml": "<p>The first pieces land next month.</p>",
    "handle": "autumn-collection-preview",
    "tags": ["autumn", "new arrivals"],
    "author": "42",
    "excerpt": "An early look at what is arriving this September.",
    "image": {
      "url": "https://example.com/wp-content/uploads/2026/09/autumn.jpg",
      "altText": "Wool coats on a rail"
    },
    "status": "draft",
    "isPublished": false,
    "publishDate": null,
    "publishedAt": null,
    "createdAt": null,
    "updatedAt": "2026-09-16T09:30:00Z"
  }
}

bodyHtml is raw article HTML. Zernio does not provide a visual editor or transform Markdown into HTML.

Publish now

Set isPublished: true without a future publishDate:

{
  "title": "Autumn collection preview",
  "bodyHtml": "<p>The first pieces are now available.</p>",
  "isPublished": true
}

The response reports status: "publish", isPublished: true and the WordPress publication time in publishedAt.

Schedule on WordPress

Send a future ISO 8601 publishDate to schedule publication natively:

{
  "title": "Autumn collection preview",
  "bodyHtml": "<p>The first pieces land next month.</p>",
  "publishDate": "2027-01-01T12:00:00+01:00"
}

The response reports status: "future", isPublished: false and the scheduled instant in publishDate. WordPress, not Zernio's queue, publishes the article. The site must run WordPress scheduled jobs correctly; Zernio does not add a second scheduler or force publication after the requested time.

isPublished: false explicitly requests a draft and wins when it is sent alongside a future publishDate. Omit isPublished when scheduling. You cannot write WordPress's raw status field through this API.

List and get articles

List blog articles includes every publish, future, draft, pending and private article visible to the connected user. It is cursor-paginated: pass limit from 1 to 50 and then reuse the opaque nextCursor exactly as returned.

curl "https://zernio.com/api/v1/accounts/66b2e19d8c3f5a7e9d0b1c2d/blogs/1/articles?limit=20" \
  -H "Authorization: Bearer $ZERNIO_API_KEY"
{
  "platform": "wordpress",
  "articles": [
    {
      "id": "1842",
      "blogId": "1",
      "platform": "wordpress",
      "title": "Autumn collection preview",
      "status": "draft",
      "isPublished": false,
      "publishDate": null
    }
  ],
  "nextCursor": "wp:2"
}

Get one article with Get a blog article:

curl "https://zernio.com/api/v1/accounts/66b2e19d8c3f5a7e9d0b1c2d/blogs/1/articles/1842" \
  -H "Authorization: Bearer $ZERNIO_API_KEY"

Article IDs are WordPress post IDs represented as strings. Read them from list/create responses rather than constructing them.

Update an article

Update a blog article is a partial update. Omitted fields keep their current value:

curl -X PATCH "https://zernio.com/api/v1/accounts/66b2e19d8c3f5a7e9d0b1c2d/blogs/1/articles/1842" \
  -H "Authorization: Bearer $ZERNIO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Autumn collection is here",
    "tags": ["autumn", "available now"],
    "isPublished": true
  }'

tags replaces the full tag list; an empty array clears it. Empty bodyHtml and excerpt strings clear those fields. Sending isPublished: false moves a published or scheduled article back to draft. Omitting both isPublished and publishDate preserves its current WordPress status and publication date.

Delete an article

Delete a blog article permanently deletes the article on WordPress:

curl -X DELETE "https://zernio.com/api/v1/accounts/66b2e19d8c3f5a7e9d0b1c2d/blogs/1/articles/1842" \
  -H "Authorization: Bearer $ZERNIO_API_KEY"

A successful delete returns 204 with no response body. Zernio stores no copy to restore. WordPress retains the article's media attachments and tags so other content can keep using them.

Supported operations

OperationEndpoint
List blogsGET /v1/accounts/{accountId}/blogs
Get a blogGET /v1/accounts/{accountId}/blogs/{blogId}
List articlesGET /v1/accounts/{accountId}/blogs/{blogId}/articles
Create an articlePOST /v1/accounts/{accountId}/blogs/{blogId}/articles
Get an articleGET /v1/accounts/{accountId}/blogs/{blogId}/articles/{articleId}
Update an articlePATCH /v1/accounts/{accountId}/blogs/{blogId}/articles/{articleId}
Delete an articleDELETE /v1/accounts/{accountId}/blogs/{blogId}/articles/{articleId}

Article fields

There is no platformSpecificData for WordPress because a WordPress site is not a POST /v1/posts target.

FieldTypeBehavior
titlestringRequired on create.
bodyHtmlstringRaw article HTML.
handlestringWordPress post slug. Generated from the title when omitted.
excerptstringShort summary stored in the WordPress excerpt field.
tagsstring[]Tag names. The complete list replaces existing tags; missing names are created.
authorstringNumeric WordPress user ID encoded as a string.
image{url, altText?}Public image downloaded into the site's media library and set as the featured image.
isPublishedbooleanfalse creates or restores a draft; true publishes now unless a future date schedules it.
publishDatedatetimeISO 8601 with offset or Z; a future value schedules publication on WordPress.

Responses also include WordPress's normalized status: publish, future, draft, pending or private. This field is read-only. isPublished is true only for publish; publishDate reports a scheduled future time when applicable.

The shared Blogs API also exposes seo for Shopify. WordPress rejects seo explicitly because core WordPress has no portable SEO-write contract and plugin fields differ. Zernio does not silently discard it. Use a plugin's own API outside Zernio if you need Yoast, Rank Math or another plugin's metadata.

What you cannot do

The WordPress connection does not expose:

  • Social posts through POST /v1/posts
  • Analytics, comments, DMs or the Inbox API
  • Ads or social account insights
  • Creating a site or another blog
  • Renaming or deleting the connected site/blog through the Blogs API
  • SEO plugin fields
  • Custom post types, pages, categories or taxonomies other than article tags
  • A visual editor or Markdown conversion
  • Removing an existing featured image through a PATCH sentinel

POST /v1/accounts/{accountId}/blogs, PATCH /v1/accounts/{accountId}/blogs/{blogId} and DELETE /v1/accounts/{accountId}/blogs/{blogId} return 405 for WordPress. Those operations remain available to platforms that support blog management.

Common errors

ErrorCauseFix
400 on self-hosted connectsiteUrl is not HTTPS, includes credentials, resolves to a private/local address or does not expose a usable WordPress REST APIPass the public HTTPS site root without credentials or /wp-json.
400 on an article requestA field is invalid, author is not a numeric user ID, or seo was sentCorrect the named field. Remove seo; SEO plugin writes are unsupported.
401 or 403 on self-hosted connectThe username/Application Password is invalid, revoked or lacks publish/upload capabilitiesCreate a new Application Password for a user that can publish posts and upload files.
403 on an article requestThe connected WordPress user cannot perform that action, such as assigning another author or creating a tagRestore the user's WordPress role/capabilities or reconnect with another user.
404 blog_not_foundblogId does not identify this account's single site blogCall List blogs and use its only returned ID. Self-hosted sites use 1.
404 blog_article_not_foundThe post was deleted or belongs to another connected siteList articles on this account and blog to find a current ID.
405 on a blog mutationWordPress site/blog creation, rename and deletion are unsupportedManage the site itself in WordPress; use article CRUD through Zernio.
429Zernio or WordPress rate limited the requestRetry later. See rate limits.
502 or 503WordPress failed or was unavailableCheck the site and retry only after the earlier request's result is known; a timed-out mutation may have reached WordPress.

When a WordPress.com grant or self-hosted Application Password stops working, reconnect the same site on the same profile. The existing account is refreshed in place when the site identity matches.

Related

  • Connecting accounts: both authentication paths.
  • Blogs API: the generated reference for every blog and article endpoint.
  • Get WordPress.com authorization URL: OAuth query and response fields.
  • Connect self-hosted WordPress: Application Password request and response fields.
  • Error handling: canonical error envelopes and retry guidance.
  • Platforms overview: social-posting platforms and connect-only integrations.
  • WordPress REST API authentication: upstream authentication and Application Password behavior.
  • WordPress posts, media and tags: upstream resources behind the article mapping.
Was this page helpful?

Shopify

Connect a Shopify store to manage its blog articles through the Blogs API and read and edit its product catalog through the Products API; a store publishes no social posts.

On this page

Quick referenceBefore you startConnect WordPress.comWordPress.com OAuth scopesConnect self-hosted WordPressPublish articlesList the site blogCreate a draftPublish nowSchedule on WordPressList and get articlesUpdate an articleDelete an articleSupported operationsArticle fieldsWhat you cannot doCommon errorsRelated