Publish blog posts from AI agents to WordPress via Notion. One API call handles page creation, markdown conversion, image uploads, featured image generation, and SEO metadata.
Installs into .claude/skills of the current project.
Are you the author of Notipo?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/lord1egypt-notipo)
---
name: notipo
description: Publish blog posts from AI agents to WordPress via Notion. One API call handles page creation, markdown conversion, image uploads, featured image generation, and SEO metadata.
homepage: https://notipo.com/docs/api/introduction
metadata: {"clawdbot":{"emoji":"π","requires":{"bins":[],"env":["NOTIPO_URL","NOTIPO_API_KEY"]}}}
---
## Install Notipo CLI if it doesn't exist
```bash
npm install -g notipo
```
- npm release: https://www.npmjs.com/package/notipo
- notipo docs: https://notipo.com/docs/api/introduction
- notipo cli docs: https://notipo.com/docs/api/cli
## Setup
Sign up at [notipo.com](https://notipo.com/auth/register), connect your Notion database and WordPress site through the dashboard, then grab your API key from **Settings β Account**.
Set the environment variables:
```bash
export NOTIPO_URL="https://notipo.com"
export NOTIPO_API_KEY="ntp_your-api-key"
```
## Core Workflow
1. **Generate** β AI agent creates title, body (markdown), category, tags, SEO keyword
2. **Fetch context** β get categories and tags from Notipo to pick valid values
3. **Publish** β `notipo posts create` with all fields
4. **Monitor** β `notipo jobs` to check completion status
## Essential Commands
### Check connection status
```bash
notipo status
```
### Fetch categories and tags
```bash
# Get available categories (for picking a valid category)
curl -s $NOTIPO_URL/api/categories \
-H "X-API-Key: $NOTIPO_API_KEY" | jq '.data[].name'
# Get available tags
curl -s $NOTIPO_URL/api/tags \
-H "X-API-Key: $NOTIPO_API_KEY" | jq '.data[].name'
```
### Create a post (draft)
```bash
notipo posts create \
--title "Your Post Title" \
--body "## Introduction\n\nYour markdown content here.\n\n## Main Section\n\nMore content." \
--category "Tutorials" \
--tags "automation,ai" \
--seo-keyword "your focus keyword" \
--image-title "Featured Image Title" \
--slug "custom-url-slug"
```
### Create and publish immediately
```bash
notipo posts create \
--title "Your Post Title" \
--body "Markdown content here." \
--category "Guides" \
--seo-keyword "focus keyword" \
--publish
```
### Create, publish, and wait for completion
```bash
notipo posts create \
--title "Your Post Title" \
--body "Markdown content here." \
--category "Guides" \
--publish --wait
```
The `--wait` flag polls until the job completes and returns the result with the WordPress URL.
### Create with inline Unsplash images (Pro plan, curl only)
```bash
curl -X POST $NOTIPO_URL/api/posts/create \
-H "X-API-Key: $NOTIPO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Your Post Title",
"body": "## Introduction\n\nContent here.\n\n## Getting Started\n\nMore content.",
"category": "Tutorials",
"seoKeyword": "focus keyword",
"images": [
{ "query": "developer workspace laptop", "afterHeading": "## Introduction" },
{ "query": "getting started tutorial", "afterHeading": "## Getting Started" }
],
"publish": true
}'
```
### Update a post (fix content, change metadata, re-sync to WordPress)
```bash
notipo posts update POST_ID \
--body "## Introduction\n\nUpdated content without the H1." \
--seo-keyword "updated focus keyword" \
--wait
```
Updates the Notion page content and/or properties, then triggers a re-sync to WordPress. Only the provided fields are updated β omitted fields stay unchanged. This is the correct way to fix post content after creation.
### Check job status
```bash
notipo jobs
```
### List posts
```bash
notipo posts
```
### Trigger a sync (pick up Notion changes)
```bash
notipo sync
```
### Delete a post
```bash
notipo posts delete POST_ID
```
## Common Patterns
### AI-generated blog post with full metadata
```bash
# 1. Fetch categories to pick a valid one
curl -s $NOTIPO_URL/api/categories -H "X-API-Key: $NOTIPO_API_KEY" | jq '.data[].name'
# 2. Create the post with all fields and wait for completion
notipo posts create \
--title "10 Docker Best Practices for Production" \
--body "## Introduction\n\nDocker containers are the standard...\n\n## Use Multi-Stage Builds\n\nReduce image size by separating build and runtime...\n\n## Pin Base Image Versions\n\nAvoid surprises by pinning specific tags..." \
--category "DevOps" \
--tags "docker,containers,production" \
--seo-keyword "docker best practices production" \
--image-title "Docker Best Practices" \
--slug "docker-best-practices-production" \
--publish --wait
```
### Batch content pipeline
```bash
# Generate and publish multiple posts in sequence
for topic in "React hooks" "TypeScript generics" "Node.js streams"; do
notipo posts create \
--title "A Guide to $topic" \
--body "## Overview\n\nGenerated content about $topic." \
--category "Tutorials" \
--seo-keyword "$(echo $topic | tr '[:upper:]' '[:lower:]')" \
--wait
done
```
### Full pipeline with inline images (curl)
```bash
curl -X POST $NOTIPO_URL/api/posts/create \
-H "X-API-Key: $NOTIPO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "10 Docker Best Practices for Production",
"body": "## Introduction\n\nDocker containers are the standard...\n\n## Use Multi-Stage Builds\n\nReduce image size...",
"category": "DevOps",
"tags": ["docker", "containers", "production"],
"seoKeyword": "docker best practices production",
"imageTitle": "Docker Best Practices",
"slug": "docker-best-practices-production",
"images": [
{ "query": "docker containers server", "afterHeading": "## Introduction" }
],
"publish": true
}'
```
## CLI Reference
| Command | Description |
|---------|-------------|
| `notipo status` | Show Notion and WordPress connection status |
| `notipo sync` | Trigger an immediate Notion poll |
| `notipo posts` | List all posts |
| `notipo posts create` | Create a post in Notion and sync to WordPress |
| `notipo posts update <id>` | Update post content/properties and re-sync to WordPress |
| `notipo posts delete <id>` | Delete a post (cleans up WordPress + Notion) |
| `notipo jobs` | List recent sync and publish jobs |
| `notipo help` | Show usage and examples |
### posts create flags
| Flag | Description |
|------|-------------|
| `--title <title>` | Post title (required) |
| `--body <markdown>` | Markdown content |
| `--category <name>` | Category name (must exist in WordPress) |
| `--tags <a,b,c>` | Comma-separated tag names |
| `--seo-keyword <kw>` | Focus keyword for Rank Math / SEOPress |
| `--image-title <text>` | Text overlay on featured image (Pro) |
| `--slug <slug>` | Custom URL slug |
| `--publish` | Publish immediately (default: draft) |
| `--wait` | Wait for job completion and return result |
### posts update flags
| Flag | Description |
|------|-------------|
| `--title <title>` | New post title |
| `--body <markdown>` | New markdown content (replaces all existing content) |
| `--category <name>` | New category name |
| `--tags <a,b,c>` | New comma-separated tag names |
| `--seo-keyword <kw>` | New focus keyword for Rank Math / SEOPress |
| `--slug <slug>` | New URL slug |
| `--publish` | Publish after syncing (default: keep current status) |
| `--wait` | Wait for job completion and return result |
## API Request Body Reference
### PATCH /api/posts/:id (update)
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| **title** | string | No | New post title |
| **body** | string | No | New markdown content (replaces all existing content on the Notion page) |
| **category** | string | No | New category name |
| **tags** | string[] | No | New tag names |
| **seoKeyword** | string | No | New focus keyword |
| **slug** | string | No | New URL slug |
| **publish** | boolean | No | Publish after syncing |
Returns `{ jobId, postId, message }`. The update writes to Notion first, then triggers a sync job to push changes to WordPress.
### POST /api/posts/create
For curl/HTTP usage, `POST /api/posts/create` accepts:
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| **title** | string | Yes | Post title |
| **body** | string | No | Markdown content with headings and paragraphs |
| **category** | string | No | Category name (must exist in WordPress) |
| **tags** | string[] | No | Array of tag names |
| **seoKeyword** | string | No | Focus keyword for Rank Math / SEOPress |
| **imageTitle** | string | No | Text overlay on featured image (Pro) |
| **slug** | string | No | Custom URL slug |
| **publish** | boolean | No | Publish immediately (default: false) |
| **images** | object[] | No | Inline Unsplash images (Pro). Each: `{query, afterHeading}` |
## What Notipo Handles
- Notion page creation from markdown (no Notion credentials needed)
- Markdown β Notion blocks β WordPress Gutenberg block conversion
- Image download from Notion and upload to WordPress media library
- Featured image generation (1200Γ628 with category background + title overlay)
- Inline Unsplash image insertion by search query (Pro plan)
- SEO metadata β Rank Math, Yoast, SEOPress, AIOSEO
- Post status management in Notion
- Failure notifications via Slack/Discord webhook
## Common Gotchas
1. **Use `posts update` to fix content** β don't delete and recreate. `notipo posts update <id> --body "..."` updates the Notion page and re-syncs to WordPress in one call.
2. **Include all fields for best results** β only `title` is technically required, but AI agents should always generate body, category, tags, seoKeyword, imageTitle, and slug for a complete post.
2. **Category must exist** β the category name must match an existing WordPress category. Fetch valid options first.
3. **`--publish` runs two jobs** β first SYNC_POST (creates draft), then PUBLISH_POST (makes it live). Use `--wait` to block until both complete.
4. **Images require Pro plan** β the `images` array and featured image generation are Pro features. On Free plan, these fields are silently ignored.
5. **Fire and forget** β the API returns a `jobId` immediately. Processing happens in the background. Use `notipo jobs` to check status.
6. **Markdown body format** β use `## Heading` for h2, `### Heading` for h3. Paragraphs are separated by `\n\n`. Images can be included as ``.
8. **Rate limits** β `notipo sync` has a 15-second cooldown. `notipo posts create` has no rate limit.
9. **API key format** β keys start with `ntp_`. Get yours from Settings β Account in the dashboard.
10. **Slug defaults** β if not set, the slug is derived from the SEO keyword. If no SEO keyword, WordPress generates it from the title.