Polyblog for developers

Everything you need to drive Polyblog from your own code: a REST API with scoped keys, endpoints for articles, blogs and topics, and signed webhooks for every change.

AI integrations

Connect Polyblog to Claude and ChatGPT

Polyblog has one hosted Model Context Protocol server for Claude, ChatGPT and other compatible clients. OAuth signs you in and limits every call to the Polyblog organization your own account can access.

https://mcp.polyblog.io/mcp
  1. Open the connectors or plugins settings in your MCP host and add the remote URL above.
  2. Sign in to Polyblog in the OAuth window and approve the requested read and write scopes.
  3. Ask for a blog overview, a localization audit, draft and translation coverage, topic research, or a specific editorial change.

What the connector can do

Read and search blogs and articles, compare configured locales with available translations, inspect validated sitemap links, research topic ideas from bounded Reddit and RSS sources, create or edit drafts, publish only when requested, and generate a text-only SEO draft. Two inline views show a compact blog overview and a bounded article preview.

Every create, update, generation and deletion is marked as a destructive write so your host can request confirmation. Topic refresh and article generation may spend paid model or source-fetching usage. Lists and previews are bounded, and the connector does not expose credentials, sender configuration, contacts or organization identifiers.

Media-generation boundary

The public MCP deliberately does not expose AI cover-image generation or the image-generating autopilot. The generate_article tool always disables inline and cover images. Those media features remain available in the Polyblog dashboard, REST API and CLI, but are outside the connector submitted to software directories.

Remove Polyblog from your host’s connector settings to revoke that host’s access. Your normal Polyblog permissions continue to decide which blogs and articles are visible.

API keys

Get an API key

The Polyblog REST API is what you use to publish from a CMS, a static site generator, a CI pipeline or any backend of your own. Every request is authenticated with an API key you create yourself.

  1. Open your Polyblog dashboard and go to settings.
  2. Create an API key, choose the scopes it needs, and optionally pin it to a single blog.
  3. Copy the secret. It is shown once, at creation, and never returned again.

Send the secret as HTTP Basic credentials. All endpoints are relative to https://api.polyblog.io.

Authorization: Basic base64(<your key secret>)

A key pinned to a blog can only ever touch that blog, and a key can only ever touch the organization it was created in — the tenant is read from the key, never from the request.

Quick start

List and publish articles

List the articles of a blog. Anonymous callers only ever see published articles; with a key of the owning organization you also get drafts.

curl "https://api.polyblog.io/api/articles?blogId=YOUR_BLOG_ID&locale=en" \
  -H "Authorization: Basic $(printf %s YOUR_API_KEY_SECRET | base64)"

Publish an article

Posting an article publishes it on your blog and fires the article.created webhook.

curl -X POST "https://api.polyblog.io/api/articles" \
  -H "Authorization: Basic $(printf %s YOUR_API_KEY_SECRET | base64)" \
  -H "Content-Type: application/json" \
  -d '{
    "blogId": "YOUR_BLOG_ID",
    "locale": "en",
    "title": "Hello from the API",
    "description": "A short summary used in listings and meta tags.",
    "content": "<p>Written straight from my own backend.</p>",
    "published": true
  }'

Browse the full API reference — every endpoint with its parameters, request body, responses and required scope.

CLI

Command-line interface

The same blogs, articles, topic research and article generation are available from your terminal through the polyblog CLI. Install it globally with npm, or run it ad hoc with npx.

Authentication is one command: polyblog login opens your browser to sign in to your Polyblog account and stores a session for later commands — no API key to paste.

# Install once, globally
npm install -g polyblog
# or run it ad hoc without installing
npx polyblog --help

# Log in — opens your browser to sign in and stores a session
polyblog login

# The blogs of your account, with their ids
polyblog blogs list

# The 10 most recent articles of a blog
polyblog articles list --blogId YOUR_BLOG_ID

# Research article ideas from your configured Reddit and RSS sources
polyblog topics refresh
polyblog topics list

# Generate a full SEO article as a draft
polyblog articles generate --topic "How to localize a SaaS blog"

The CLI is open source at github.com/polyblog-io/cli and published as polyblog on npm. Run any command with --help to see its options.

Agent Skills

Teach your coding agent Polyblog

Polyblog ships Agent Skills — guides following the agentskills.io standard that teach coding agents how to run editorial and localization workflows with the polyblog CLI and the MCP connector, instead of guessing at commands and tools.

# Install the Polyblog skills into your coding agent
npx skills add polyblog-io/skills

One command installs the skills into Claude Code, Cursor, Codex, Gemini CLI and any other agent that follows the Skills standard. The CLI also bundles the same guides, version-matched to the commands it ships: polyblog skills get <name> prints one on demand.

The skills are open source at github.com/polyblog-io/skills. Claude users can also install the Polyblog Claude plugin, which bundles the connector together with the editorial skill: github.com/polyblog-io/claude-plugin.

Scopes

Least privilege by default

Each key carries a set of per-resource scopes, so an integration that only needs to read articles cannot delete them. New keys start read-only; widen them explicitly.

  • articles:readRead articles, including drafts of your own blogs.
  • articles:writeCreate, generate, update and delete articles.
  • blogs:readRead the blogs of your account.
  • blogs:writeCreate a blog and update its settings.
  • topics:readRead the topics of a blog.
  • topics:writeCreate and update topics.
  • contacts:readRead the contacts collected by your blog.
  • contacts:writeCreate and update contacts.
  • images:writeUpload images used as article covers or in content.

A request made with a key that lacks the required scope is refused with 403. Keys are also rate limited, and a request over the limit is refused with 429.

Webhooks

Get told when something changes

Subscribe an endpoint of yours and Polyblog POSTs each matching event to it as it happens. A subscription can cover the whole organization or a single blog, and can filter the events it wants.

  • article.createdA new article was created, by you or by the API.
  • article.updatedAn existing article changed, including translations.
  • article.deletedAn article was deleted.
  • blog.createdA new blog was created.
  • contact.createdA visitor subscribed through one of your blogs.
POST https://your-server.com/polyblog-webhook
X-Polyblog-Event: article.created
X-Polyblog-Signature: t=1719000000,v1=<hmac-sha256 hex>
Content-Type: application/json

{
  "event": "article.created",
  "timestamp": 1719000000,
  "data": { "...": "..." }
}

Verify the signature

Every delivery carries an X-Polyblog-Signature header of the form t=timestamp,v1=signature. The signature is an HMAC-SHA256 of timestamp.body keyed by your subscription secret; recompute it over the raw body and compare before trusting the payload.

import crypto from 'node:crypto'

// body must be the RAW request body, byte for byte
function isSignatureValid({ header, body, secret }) {
  const [t, v1] = header.split(',')
  const timestamp = t.slice(2)
  const signature = v1.slice(3)

  const expected = crypto
    .createHmac('sha256', secret)
    .update(`${timestamp}.${body}`)
    .digest('hex')

  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected),
  )
}

Delivery is one best-effort attempt with a 5 second timeout and no retries. Failures are counted, and a subscription that fails 20 times in a row is deactivated until you re-enable it.

Subscriptions are managed from your dashboard or through the webhook subscriptions endpoints in the API reference.

Start building