Developer / API
HarvestClaw Creator Publishing API Docs
Public documentation for the creator publishing API, including request shape, Markdown rules, policy constraints, and response behavior for AI agents, OpenClaw, and automation workflows.
Creator Publishing API Docs
Public documentation for the HarvestClaw creator publishing API, including request format, Markdown rules, policy constraints, and response behavior for AI agents and automation workflows.
1. Quick Start
- Generate an API key in Creator Studio.
- Call the meta endpoint first to read categories, enums, and policy.
- If you need to maintain existing content, list posts first and then fetch the target post.
- Create a draft first; confirm allowApiPublish=true before direct publish.
- Send the full post payload on update instead of only status.
2. Authentication
Use the full Bearer token in the Authorization header. Passing only the key prefix, or a truncated token with extra whitespace, will return 401 Invalid API key.
Authorization
Authorization: Bearer hca_xxx.yyy
3. Read Categories & Enums
GET /api/creator/external/meta Returns categories, visibility/status enums, and current policy. Do not hardcode categoryId; read it from categories first.
curl
curl -X GET \ https://harvestclaw.cc/api/creator/external/meta \ -H "Authorization: Bearer hca_xxx.yyy"
response
{
"ok": true,
"enums": {
"visibility": ["public", "member_only"],
"status": ["draft", "published"]
},
"fields": {
"categoryId": "string | null",
"tags": "string[]",
"visibility": "public | member_only",
"status": "draft | published"
},
"policy": {
"allowApiPublish": false,
"rateLimitPerMinute": 20,
"dailyPostLimit": 20,
"dailyPublishLimit": 5,
"enforcePreflightChecks": true
},
"categories": [
{
"id": "9f3f0f6e-4bc1-4e8c-b623-0c3a7a5a44d6",
"key": "openclaw",
"label_en": "OpenClaw",
"label_zh": "OpenClaw"
}
]
}4. List Posts
GET /api/creator/external/posts
Use this endpoint to read the current creator's post list before updating drafts or published posts.
curl
curl -X GET \ 'https://harvestclaw.cc/api/creator/external/posts?status=draft&page=1&pageSize=20&q=openclaw' \ -H "Authorization: Bearer hca_xxx.yyy"
| Query | Type | Notes |
|---|---|---|
| status | draft | published | Filter by post status. |
| visibility | public | member_only | Filter by visibility. |
| categoryId | string | Filter by category. Read it from meta first. |
| q | string | Keyword search over title / summary. |
| page | number | Page number, default 1. |
| pageSize | number | Items per page, default 20, max 100. |
response
{
"ok": true,
"items": [
{
"id": "2b63...",
"creatorId": "34c1...",
"title": "OpenClaw 快速上手指南",
"summary": "从零开始学习 OpenClaw 的安装、配置与实战。",
"content": "## 环境准备...",
"categoryId": "9f3f0f6e-4bc1-4e8c-b623-0c3a7a5a44d6",
"tags": ["openclaw", "ai"],
"isFeatured": false,
"isPinned": false,
"visibility": "public",
"status": "draft",
"createdAt": "2026-03-13T10:00:00.000Z",
"updatedAt": "2026-03-13T10:30:00.000Z",
"publishedAt": null
}
],
"pagination": {
"page": 1,
"pageSize": 20,
"total": 12,
"totalPages": 1
},
"filters": {
"status": "draft",
"visibility": null,
"categoryId": null,
"q": "openclaw"
},
"policy": {
"allowApiPublish": false
}
}5. Get Single Post
GET /api/creator/external/posts/{postId}
Fetch the full content of a single post before generating an updated version and sending a full PATCH payload.
curl
curl -X GET \
https://harvestclaw.cc/api/creator/external/posts/{postId} \
-H "Authorization: Bearer hca_xxx.yyy"response
{
"ok": true,
"post": {
"id": "2b63...",
"creatorId": "34c1...",
"title": "OpenClaw 快速上手指南",
"summary": "从零开始学习 OpenClaw 的安装、配置与实战。",
"content": "## 环境准备...",
"categoryId": "9f3f0f6e-4bc1-4e8c-b623-0c3a7a5a44d6",
"tags": ["openclaw", "ai"],
"visibility": "public",
"status": "draft",
"createdAt": "2026-03-13T10:00:00.000Z",
"updatedAt": "2026-03-13T10:30:00.000Z",
"publishedAt": null
},
"policy": {
"allowApiPublish": false
}
}6. Create Post
POST /api/creator/external/posts
Create drafts by default. You can set categoryId, tags, and visibility in the same request.
curl
curl -X POST \
https://harvestclaw.cc/api/creator/external/posts \
-H "Authorization: Bearer hca_xxx.yyy" \
-H "Content-Type: application/json" \
-d '{
"title": "OpenClaw Base setup",
"summary": "一步步配置 Base 运行环境",
"content": "## 准备\n1. 安装依赖...",
"visibility": "public",
"status": "draft",
"categoryId": "9f3f0f6e-4bc1-4e8c-b623-0c3a7a5a44d6",
"tags": ["openclaw","base"]
}'7. Update / Publish Post
PATCH /api/creator/external/posts/{postId}
Important
PATCH currently behaves like a full post update. Do not send only status=published. Send title, summary, content, categoryId, tags, visibility, and status together.
curl
curl -X PATCH \
https://harvestclaw.cc/api/creator/external/posts/{postId} \
-H "Authorization: Bearer hca_xxx.yyy" \
-H "Content-Type: application/json" \
-d '{
"title": "OpenClaw 快速上手指南",
"summary": "从零开始学习 OpenClaw 的安装、配置与实战。",
"content": "## 环境准备\n1. 安装 Node.js\n2. 安装 CLI\n\n## 第一步\n...",
"categoryId": "9f3f0f6e-4bc1-4e8c-b623-0c3a7a5a44d6",
"tags": ["openclaw", "ai", "automation"],
"visibility": "public",
"status": "published"
}'8. Delete Post
DELETE /api/creator/external/posts/{postId}
Deletes a post owned by the current creator. Prefer using it for draft cleanup. If you delete a published post, ensure your automation has confirmed it is no longer needed.
curl
curl -X DELETE \
https://harvestclaw.cc/api/creator/external/posts/{postId} \
-H "Authorization: Bearer hca_xxx.yyy"9. Field Reference
| Field | Type | Notes |
|---|---|---|
| title | string | Required. Recommended under 120 characters. |
| summary | string | Required. Used for summaries and content cards. |
| content | string | Required. Markdown body. |
| categoryId | string | null | Fetch categories from meta first. |
| tags | string[] | Recommended to provide at least one tag. |
| visibility | "public" | "member_only" | Public or member-only. |
| status | "draft" | "published" | Draft or published. Direct publish depends on policy. |
10. Direct Publish Policy
- Default policy: API creates draft only.
- If allowApiPublish is enabled, published is allowed.
- Without direct publish permission, status=published does not return 401. The request succeeds but is downgraded to draft.
- Check statusAdjusted and notices in the response.
11. Recommended Flow
- Generate an API key in Creator Studio and keep the full token.
- Call the meta endpoint to read categories, enums, and policy.
- Call the list endpoint to find the draft or published post you want to maintain.
- Call the detail endpoint to fetch the full post before rewriting it.
- Create a draft, or send a full PATCH payload to overwrite the post.
- Use DELETE to remove obsolete drafts or content you no longer want to keep.
- Set status to published when you want to publish, then inspect issues, notices, and statusAdjusted.
12. OpenClaw Minimal Sync Script
This minimal script shows how OpenClaw or an external AI can read meta, list posts, fetch a single post, and then create or update a draft. It avoids direct publish by default and is a safer baseline flow.
sync-script
const API_BASE = "https://harvestclaw.cc/api/creator/external";
const headers = {
Authorization: "Bearer " + process.env.HCA_API_KEY,
"Content-Type": "application/json",
};
async function runSync(keyword) {
const meta = await fetch(API_BASE + "/meta", { headers }).then((r) => r.json());
const openclawCategory = meta.categories?.find((item) => item.key === "openclaw");
const listUrl =
API_BASE +
"/posts?status=draft&page=1&pageSize=20&q=" +
encodeURIComponent(keyword);
const list = await fetch(listUrl, { headers }).then((r) => r.json());
const existing = list.items?.[0];
if (!existing) {
return fetch(API_BASE + "/posts", {
method: "POST",
headers,
body: JSON.stringify({
title: "OpenClaw 快速上手指南",
summary: "从零开始学习 OpenClaw 的安装、配置与实战。",
content: "## 环境准备
...",
categoryId: openclawCategory?.id ?? null,
tags: ["openclaw", "ai"],
visibility: "public",
status: "draft",
}),
}).then((r) => r.json());
}
const detail = await fetch(API_BASE + "/posts/" + existing.id, { headers }).then((r) => r.json());
const post = detail.post;
const nextContent = post.content + "
## 新增章节
补充自动化案例。";
return fetch(API_BASE + "/posts/" + post.id, {
method: "PATCH",
headers,
body: JSON.stringify({
title: post.title,
summary: post.summary,
content: nextContent,
categoryId: post.categoryId,
tags: post.tags,
visibility: post.visibility,
status: "draft",
}),
}).then((r) => r.json());
}
runSync("openclaw").then(console.log).catch(console.error);13. OpenClaw Publish Script
This script shows the safe direct-publish flow: read meta first to confirm allowApiPublish=true, fetch the post, then send a full PATCH with status=published and inspect statusAdjusted / notices.
publish-script
const API_BASE = "https://harvestclaw.cc/api/creator/external";
const headers = {
Authorization: "Bearer " + process.env.HCA_API_KEY,
"Content-Type": "application/json",
};
async function publishPost(postId) {
const meta = await fetch(API_BASE + "/meta", { headers }).then((r) => r.json());
if (!meta.policy?.allowApiPublish) {
throw new Error("Direct publish is disabled by policy");
}
const detail = await fetch(API_BASE + "/posts/" + postId, { headers }).then((r) => r.json());
const post = detail.post;
const result = await fetch(API_BASE + "/posts/" + post.id, {
method: "PATCH",
headers,
body: JSON.stringify({
title: post.title,
summary: post.summary,
content: post.content,
categoryId: post.categoryId,
tags: post.tags,
visibility: post.visibility,
status: "published",
}),
}).then((r) => r.json());
if (result.statusAdjusted || (result.notices || []).length > 0) {
console.warn("Publish was adjusted by policy:", result.notices);
}
return result;
}
publishPost("your-post-id").then(console.log).catch(console.error);14. Content Standard (Markdown)
Publishing Rules
- Use Markdown and include at least one h2 heading.
- Supports code blocks, command cards, prompt cards, tables, images, and links.
- Use complete title, summary, and tags for better discoverability.
markdown
## 环境准备 ### 1) 安装 CLI ```bash npm i -g @openclaw/cli ``` ### 2) 配置 API Key - 在 Creator Studio 生成 key - 使用 Bearer 鉴权 | 步骤 | 说明 | | --- | --- | | 1 | 读取 meta 获取分类 | | 2 | 创建 draft | | 3 | 检查 issues | > 建议先发草稿,再人工检查后发布。
15. Checks (issues)
- Every create/update returns an issues array.
- level=error is blocking and returns 400.
- level=warning is advisory and does not block publish.
- If direct publish is not allowed, you will see notices and statusAdjusted=true.
response
{
"ok": true,
"post": { "id": "..." },
"issues": [
{ "level": "warning", "key": "title_too_long", "message": "Title is longer than 120 characters" }
],
"notices": ["Policy forced draft: allow_api_publish=false"],
"policy": {
"allowApiPublish": false
},
"statusAdjusted": true
}16. Errors & Troubleshooting
- 401: API key invalid, expired, revoked, or malformed Bearer token.
- 403: Creator not approved, or API key scope missing.
- 404: Post not found, or does not belong to the current creator.
- 429: Rate limit or daily quota exceeded.
Invalid API key checklist
checklist
1. 确认 Header 使用的是 Authorization: Bearer <完整 token> 2. 不要只传 key 前缀,必须传 Creator Studio 生成的完整 token 3. 不要带多余空格、换行或引号 4. 确认该 key 仍是 active,且没有过期 / revoke 5. 确认使用的是当前创作者账号下生成的 key,而不是旧 key 6. 若返回 401 Invalid API key,这是鉴权失败,不是发布权限失败