开放 API 面向脚本、程序和大模型。用个人令牌查询、上传图片、发布和远程删除你自己的内容。先读完再调用,不要编造路径或字段。
说明
令牌在登录后的应用中心 → API 创建,明文只显示一次。身份由令牌决定,请求里不要传用户 ID、Cookie 或 CSRF。 应用中心 → API
你正在调用大白笔记开放 API。
站点: https://taabb.com
说明页: GET https://taabb.com/open-api
Markdown: GET https://taabb.com/api/open.md
JSON: GET https://taabb.com/api/open/spec.json
鉴权: Authorization: Bearer <令牌>(令牌即用户,不要传 uid)
只使用这 4 个接口:
GET/POST https://taabb.com/api/open/exists
POST https://taabb.com/api/open/upload
POST https://taabb.com/api/open/publish
POST https://taabb.com/api/open/delete
响应信封: {success, data, code}。success 不是 true 就停止。
去重键: provider + external_id。重复发布会跳过。
图片: 先 multipart 上传,把返回的 data.path 写进 <img src="upload/post/....jpg">,再把整段 HTML 作为 post_content 发布。上传超时就用同一文件重试,服务端会返回已有路径;不要猜测 path,也不要把没成功的图写进正文。
post_type: 1=小记, 3=笔记(默认)。post_privacy: 0 公开, 1 关心的人, 2 仅自己。
不要编造接口。不要带 Cookie / CSRF。
规则
- 先读完本文再调用任何接口。
- 只调用下面列出的 4 个接口,不要编造路径或字段。
- 不要调用 /api/open/tokens 或其他站点接口。那些需要浏览器登录,不是这把令牌。
- 不要传 uid、user_id、用户名、Cookie、CSRF 或 Session。身份只有令牌。
- 始终检查 JSON 的 success。HTTP 200 时 success 仍可能是 false。
- provider + external_id 是去重键。同一对重复发布会跳过,返回已有 post_id。
- 有图片必须先调用 /api/open/upload,再把返回的 path 写进正文 <img src>。外链图片会被丢掉,列表也不会出现缩图。
- 不要把令牌写进正文或标题。
鉴权
- 每个 exists / upload / publish / delete 请求都必须带令牌。
- 不要带 Cookie、CSRF、uid、user_id。
- 令牌以 tab_ 开头。发送完整令牌,不要只发前缀。
- 优先:Authorization: Bearer <令牌>
- 备选:X-Api-Token: <令牌>,或 POST/JSON 字段 api_token。
- 缺少或无效令牌 → HTTP 403,success=false。
响应
所有接口返回同一形状。先看 success,不要只看 HTTP 状态码。
{
"success": true,
"data": {},
"code": 200
}
| 情况 | HTTP | success | 错误信息 |
|---|---|---|---|
| 鉴权失败 | 403 | false | data.message |
| 业务失败 | 200 | false | data.message |
| 成功 | 200 | true | 读 data |
幂等
- 键:provider(最长 64)+ external_id(最长 191),对每个用户唯一。
- 给接入方选一个稳定的 provider 短名,例如 claude、gpt、my-bot。
- external_id 用你自己的源条目 ID。重复发布同一对会跳过,不会覆盖正文。
- 若帖子已被删,映射会清掉,exists 视为不存在。
流程
- 若需要去重:先 GET /api/open/exists。若 exists=true,不要再发,或先删除。
- 有图片:每张图单独 POST /api/open/upload,记下返回的 data.path。
- 把 path 拼进 HTML:<img src="upload/post/……jpg">,再作为 post_content 去 publish。
- 删除:POST /api/open/delete,传 post_id,或同一对 provider + external_id。
图片怎么进正文
上传接口只负责把图片存到服务器,不会自动出现在笔记里。你必须把返回的 path 写进 post_content 的 <img>,发布后才能在正文里看到图,列表里也才会有缩图。
- 调用 POST /api/open/upload,表单字段名用 upload_file(或 file),每次一张。
- 从 JSON 的 data.path 取出路径,形如 upload/post/202608/xxxx.jpg。推荐用 path,不要只用外站地址。
- 把路径写进 HTML:<img src="upload/post/202608/xxxx.jpg">。多张图就写多个 <img>,按你想出现的顺序排列。
- 把整段 HTML 作为 post_content,再调用 POST /api/open/publish。
发布成功后,服务端会扫描正文里所有 src 含 upload/post/ 的图片,把它们挂到这篇笔记,并生成列表卡片用的缩略图。你不需要、也不应该自己传缩略图地址。
post_content 示例(两张图夹在文字中间)
<p>今天路过海边。</p> <p><img src="upload/post/202608/one.jpg"></p> <p>晚上的灯也很好看。</p> <p><img src="upload/post/202608/two.jpg"></p>
- 只 upload 却不把 <img> 写进 post_content:笔记里没有图,列表也没有缩图。
- 用其他网站的 https 图片地址:发布时会被清掉,同样没有图和缩图。
- previewUrl 一般也能用,但请优先写 data.path。
例子:把一篇新浪新闻推到笔记
脚本把新浪新闻写入令牌主人的账号。作者由令牌决定,请求里不要传 uid、user_id 或用户名。
字段怎么对应
| 新闻 | API 字段 | 本例 |
|---|---|---|
| 来源短名,自己定一个一直用 | provider |
sina-news |
| 文章稳定 ID,建议用 URL 里的 docid | external_id |
doc-inh8example01 |
| 标题 | post_title |
台风路径北抬 东部沿海将有强风雨 |
| 正文 HTML | post_content |
段落 + 已上传图片的 <img src> |
| 原文发布时间 | post_time |
2026-08-14 09:30:00 |
| 作者 | 不要传 uid |
只带 Authorization: Bearer |
调用顺序
- 先 exists。同一篇文章始终用同一对 provider + external_id。exists=true 说明已经推过,不要再发。
- 配图先下载到本地,再 POST /api/open/upload。不要把新浪图片的 https 地址写进 <img>,发布时会被清掉。
- 再 publish。不要传 uid。本例 post_privacy=2,只进自己的笔记;若要公开改成 0。
把 TOKEN 换成你的完整令牌。下面的 BASE 已是本站地址。JSON 里没有 uid。
可复制的 curl
TOKEN="tab_YOUR_TOKEN"
BASE="https://taabb.com"
# 1) 查重。同一篇文章用同一对 provider + external_id。不要传 uid。
curl -sS -H "Authorization: Bearer $TOKEN" \
"$BASE/api/open/exists?provider=sina-news&external_id=doc-inh8example01"
# 若 data.exists 为 true,这篇已经推过,停止。
# 2) 配图先下载到本地再上传。不要把新浪图片 https 地址写进 <img>。
curl -sS -X POST "$BASE/api/open/upload" \
-H "Authorization: Bearer $TOKEN" \
-F "upload_file=@./cover.jpg"
# 记下返回的 data.path,例如 upload/post/202608/abcd1234.jpg
# 3) 发布。作者就是令牌的主人。JSON 里没有 uid。
curl -sS -X POST "$BASE/api/open/publish" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d @- <<'EOF'
{
"provider": "sina-news",
"external_id": "doc-inh8example01",
"post_title": "台风路径北抬 东部沿海将有强风雨",
"post_type": 3,
"post_privacy": 2,
"post_time": "2026-08-14 09:30:00",
"post_content": "<p>据中央气象台消息,台风路径北抬,东部沿海将有强风雨。</p><p><img src=\"upload/post/202608/abcd1234.jpg\"></p><p>原文:<a href=\"https://news.sina.com.cn/c/2026-08-14/doc-inh8example01.shtml\">新浪新闻</a></p>"
}
EOF
枚举
post_type
| value | 含义 |
|---|---|
1 | 小记。标题可空。 |
3 | 笔记。默认值。建议带标题。 |
只允许 1 或 3。
post_privacy
| value | 含义 |
|---|---|
0 | 公开。默认。 |
1 | 仅关心的人可见。 |
2 | 仅自己可见。 |
只允许 0、1、2。不要传 3。
exists — GET or POST /api/open/exists
查询这对 provider + external_id 是否已经发布过。
- URL:
https://taabb.com/api/open/exists - 鉴权:必须
- Body:GET query | application/x-www-form-urlencoded | application/json
Parameters
| name | in | type | required | notes |
|---|---|---|---|---|
provider |
query|body | string | 是 | 来源短名,最长 64。 |
external_id |
query|body | string | 是 | 你自己的条目 ID,最长 191。 |
Success data
{
"exists": false,
"post_id": 0
}
- exists=true 时 post_id 为已有笔记;false 时 post_id 为 0。
- 不会更新令牌最后使用时间。
示例 — GET
curl -sS -H "Authorization: Bearer tab_YOUR_TOKEN" "https://taabb.com/api/open/exists?provider=demo&external_id=abc-1"
示例 — POST JSON
curl -sS -X POST "https://taabb.com/api/open/exists" \
-H "Authorization: Bearer tab_YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"provider":"demo","external_id":"abc-1"}'
upload — POST /api/open/upload
上传一张图片。只是存文件,还不会出现在笔记里。
- URL:
https://taabb.com/api/open/upload - 鉴权:必须
- Body:multipart/form-data
Parameters
| name | in | type | required | notes |
|---|---|---|---|---|
upload_file |
file | file | 是 | 推荐字段名。 |
file |
file | file | 否 | 没有 upload_file 时可用。 |
Success data
{
"message": "上传成功",
"path": "upload/post/202608/example.jpg",
"previewUrl": "https://taabb.com/upload/post/202608/example.jpg",
"width": 1200,
"height": 800
}
- 必须 multipart,不支持 JSON 传文件。
- 一次一张。多张就请求多次。
- 请把返回的 data.path 写进稍后发布的 <img src>。
- 超时或中断时用同一文件重试这一张;服务端会返回已有路径,不会重复存文件。不要把未成功的图写进正文。
示例 — multipart
curl -sS -X POST "https://taabb.com/api/open/upload" \ -H "Authorization: Bearer tab_YOUR_TOKEN" \ -F "upload_file=@/path/to/photo.jpg"
publish — POST /api/open/publish
为令牌所属用户创建一篇内容。同一对 provider+external_id 会跳过,不会覆盖。
- URL:
https://taabb.com/api/open/publish - 鉴权:必须
- Body:application/x-www-form-urlencoded | application/json
Parameters
| name | in | type | required | notes |
|---|---|---|---|---|
provider |
body | string | 是 | provider |
external_id |
body | string | 是 | external_id |
post_content |
body | string (HTML) | 是 | HTML |
post_title |
body | string | 否 | max 200 |
post_type |
body | integer | 否 | 1 | 3, default 3 |
post_privacy |
body | integer | 否 | 0 | 1 | 2, default 0 |
post_time |
body | string | 否 | datetime |
Success data
{
"message": "发布成功",
"skipped": false,
"exists": false,
"post_id": 12345
}
- 已存在时:success=true,skipped=true。
- 不要传 uid。作者就是令牌的主人。
- 正文里 src 含 upload/post/ 的 <img> 会自动挂附件并生成缩图。
示例 — 带图片发布
curl -sS -X POST "https://taabb.com/api/open/upload" \ -H "Authorization: Bearer tab_YOUR_TOKEN" \ -F "upload_file=@./one.jpg" # 记下返回的 data.path,例如 upload/post/202608/one.jpg curl -sS -X POST "https://taabb.com/api/open/publish" \ -H "Authorization: Bearer tab_YOUR_TOKEN" \ --data-urlencode "provider=demo" \ --data-urlencode "external_id=abc-1" \ --data-urlencode "post_title=标题" \ --data-urlencode "post_content=<p>正文</p><p><img src=\"upload/post/202608/one.jpg\"></p>"
示例 — JSON
curl -sS -X POST "https://taabb.com/api/open/publish" \
-H "Authorization: Bearer tab_YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"provider":"demo","external_id":"abc-1","post_title":"标题","post_type":3,"post_privacy":2,"post_content":"<p>正文</p><p><img src=\"upload/post/202608/one.jpg\"></p>"}'
delete — POST /api/open/delete
删除令牌主人的笔记。传 post_id,或传 provider + external_id。
- URL:
https://taabb.com/api/open/delete - 鉴权:必须
- Body:application/x-www-form-urlencoded | application/json
Parameters
| name | in | type | required | notes |
|---|---|---|---|---|
post_id |
body | integer | 否 | post_id |
provider |
body | string | 否 | provider |
external_id |
body | string | 否 | external_id |
Success data
{
"message": "删除成功",
"post_id": 12345
}
- 令牌的「最后使用」只在真正发布成功(非 skip)或删除成功时更新。exists / 上传 / 跳过发布不算。
示例 — JSON
curl -sS -X POST "https://taabb.com/api/open/delete" \
-H "Authorization: Bearer tab_YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"provider":"demo","external_id":"abc-1"}'
HTML 约定
- post_content 是 HTML。净化后为空会失败。
- 允许常见文本标签、链接、列表、已上传图片的 <img>、checkbox。
- 禁止并会去掉:script、iframe、style、textarea、object、embed。
- JSON 请求体上限 1MB;大 HTML 用 application/x-www-form-urlencoded。
- post_title 最长 200,纯文本。post_time 例如 2026-08-14 15:00:00,空则取当前时间。
不要调用
GET|POST /api/open/tokensPOST /api/open/tokens/deleteAny /api/* path not listed in endpointsBrowser publish /post/adduid, specify_users, post_pass, diary_book_id, topics
令牌的「最后使用」只在真正发布成功(非 skip)或删除成功时更新。exists / 上传 / 跳过发布不算。
规范原文
与下面 Markdown 相同。公开、无需登录、不含密钥。 https://taabb.com/api/open.md
# Taabb Open API
SPEC_VERSION: 1.0
LANG: zh
AUDIENCE: language-model agents and HTTP clients
BASE_URL: https://taabb.com
CANONICAL_HTML: https://taabb.com/open-api
CANONICAL_MARKDOWN: https://taabb.com/api/open.md
CANONICAL_JSON: https://taabb.com/api/open/spec.json
本接口把内容发到令牌主人的大白笔记账号。请完整阅读,不要猜测缺失字段。
## 0. Agent brief
```
你正在调用大白笔记开放 API。
站点: https://taabb.com
说明页: GET https://taabb.com/open-api
Markdown: GET https://taabb.com/api/open.md
JSON: GET https://taabb.com/api/open/spec.json
鉴权: Authorization: Bearer <令牌>(令牌即用户,不要传 uid)
只使用这 4 个接口:
GET/POST https://taabb.com/api/open/exists
POST https://taabb.com/api/open/upload
POST https://taabb.com/api/open/publish
POST https://taabb.com/api/open/delete
响应信封: {success, data, code}。success 不是 true 就停止。
去重键: provider + external_id。重复发布会跳过。
图片: 先 multipart 上传,把返回的 data.path 写进 <img src="upload/post/....jpg">,再把整段 HTML 作为 post_content 发布。上传超时就用同一文件重试,服务端会返回已有路径;不要猜测 path,也不要把没成功的图写进正文。
post_type: 1=小记, 3=笔记(默认)。post_privacy: 0 公开, 1 关心的人, 2 仅自己。
不要编造接口。不要带 Cookie / CSRF。
```
## 1. 规则
1. 先读完本文再调用任何接口。
2. 只调用下面列出的 4 个接口,不要编造路径或字段。
3. 不要调用 /api/open/tokens 或其他站点接口。那些需要浏览器登录,不是这把令牌。
4. 不要传 uid、user_id、用户名、Cookie、CSRF 或 Session。身份只有令牌。
5. 始终检查 JSON 的 success。HTTP 200 时 success 仍可能是 false。
6. provider + external_id 是去重键。同一对重复发布会跳过,返回已有 post_id。
7. 有图片必须先调用 /api/open/upload,再把返回的 path 写进正文 <img src>。外链图片会被丢掉,列表也不会出现缩图。
8. 不要把令牌写进正文或标题。
## 2. 鉴权
- 每个 exists / upload / publish / delete 请求都必须带令牌。
- 不要带 Cookie、CSRF、uid、user_id。
- 令牌以 tab_ 开头。发送完整令牌,不要只发前缀。
- 优先:Authorization: Bearer <令牌>
- 备选:X-Api-Token: <令牌>,或 POST/JSON 字段 api_token。
- 缺少或无效令牌 → HTTP 403,success=false。
## 3. 响应
所有接口返回同一形状。先看 success,不要只看 HTTP 状态码。
```json
{
"success": true,
"data": {},
"code": 200
}
```
## 4. 幂等
- 键:provider(最长 64)+ external_id(最长 191),对每个用户唯一。
- 给接入方选一个稳定的 provider 短名,例如 claude、gpt、my-bot。
- external_id 用你自己的源条目 ID。重复发布同一对会跳过,不会覆盖正文。
- 若帖子已被删,映射会清掉,exists 视为不存在。
## 5. 流程
- 若需要去重:先 GET /api/open/exists。若 exists=true,不要再发,或先删除。
- 有图片:每张图单独 POST /api/open/upload,记下返回的 data.path。
- 把 path 拼进 HTML:<img src="upload/post/……jpg">,再作为 post_content 去 publish。
- 删除:POST /api/open/delete,传 post_id,或同一对 provider + external_id。
## 6. 图片怎么进正文
上传接口只负责把图片存到服务器,不会自动出现在笔记里。你必须把返回的 path 写进 post_content 的 <img>,发布后才能在正文里看到图,列表里也才会有缩图。
1. 调用 POST /api/open/upload,表单字段名用 upload_file(或 file),每次一张。
2. 从 JSON 的 data.path 取出路径,形如 upload/post/202608/xxxx.jpg。推荐用 path,不要只用外站地址。
3. 把路径写进 HTML:<img src="upload/post/202608/xxxx.jpg">。多张图就写多个 <img>,按你想出现的顺序排列。
4. 把整段 HTML 作为 post_content,再调用 POST /api/open/publish。
发布成功后,服务端会扫描正文里所有 src 含 upload/post/ 的图片,把它们挂到这篇笔记,并生成列表卡片用的缩略图。你不需要、也不应该自己传缩略图地址。
上传超时、连接被断开、或没有返回 JSON:不要把这张图写进正文,也不要猜测 path。用同一文件再 POST /api/open/upload,直到 success=true 并拿到 data.path。同一文件重试会返回已有路径,不会再存一份。建议客户端超时设为 60–120 秒,一次只传一张。已经成功的图片可以继续用;失败的那张跳过或重试后再拼进 HTML。
post_content 示例(两张图夹在文字中间):
```html
<p>今天路过海边。</p>
<p><img src="upload/post/202608/one.jpg"></p>
<p>晚上的灯也很好看。</p>
<p><img src="upload/post/202608/two.jpg"></p>
```
- 只 upload 却不把 <img> 写进 post_content:笔记里没有图,列表也没有缩图。
- 用其他网站的 https 图片地址:发布时会被清掉,同样没有图和缩图。
- previewUrl 一般也能用,但请优先写 data.path。
## 7. 例子:把一篇新浪新闻推到笔记
脚本把新浪新闻写入令牌主人的账号。作者由令牌决定,请求里不要传 uid、user_id 或用户名。
### 字段怎么对应
| 新闻 | API 字段 | 本例 |
| --- | --- | --- |
| 来源短名,自己定一个一直用 | `provider` | sina-news |
| 文章稳定 ID,建议用 URL 里的 docid | `external_id` | doc-inh8example01 |
| 标题 | `post_title` | 台风路径北抬 东部沿海将有强风雨 |
| 正文 HTML | `post_content` | 段落 + 已上传图片的 <img src> |
| 原文发布时间 | `post_time` | 2026-08-14 09:30:00 |
| 作者 | `不要传 uid` | 只带 Authorization: Bearer |
### 调用顺序
1. 先 exists。同一篇文章始终用同一对 provider + external_id。exists=true 说明已经推过,不要再发。
2. 配图先下载到本地,再 POST /api/open/upload。不要把新浪图片的 https 地址写进 <img>,发布时会被清掉。
3. 再 publish。不要传 uid。本例 post_privacy=2,只进自己的笔记;若要公开改成 0。
把 TOKEN 换成你的完整令牌。下面的 BASE 已是本站地址。JSON 里没有 uid。
```bash
TOKEN="tab_YOUR_TOKEN"
BASE="https://taabb.com"
# 1) 查重。同一篇文章用同一对 provider + external_id。不要传 uid。
curl -sS -H "Authorization: Bearer $TOKEN" \
"$BASE/api/open/exists?provider=sina-news&external_id=doc-inh8example01"
# 若 data.exists 为 true,这篇已经推过,停止。
# 2) 配图先下载到本地再上传。不要把新浪图片 https 地址写进 <img>。
curl -sS -X POST "$BASE/api/open/upload" \
-H "Authorization: Bearer $TOKEN" \
-F "upload_file=@./cover.jpg"
# 记下返回的 data.path,例如 upload/post/202608/abcd1234.jpg
# 3) 发布。作者就是令牌的主人。JSON 里没有 uid。
curl -sS -X POST "$BASE/api/open/publish" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d @- <<'EOF'
{
"provider": "sina-news",
"external_id": "doc-inh8example01",
"post_title": "台风路径北抬 东部沿海将有强风雨",
"post_type": 3,
"post_privacy": 2,
"post_time": "2026-08-14 09:30:00",
"post_content": "<p>据中央气象台消息,台风路径北抬,东部沿海将有强风雨。</p><p><img src=\"upload/post/202608/abcd1234.jpg\"></p><p>原文:<a href=\"https://news.sina.com.cn/c/2026-08-14/doc-inh8example01.shtml\">新浪新闻</a></p>"
}
EOF
```
## 8. 枚举
### post_type
| value | 含义 |
| --- | --- |
| 1 | 小记。标题可空。 |
| 3 | 笔记。默认值。建议带标题。 |
只允许 1 或 3。
### post_privacy
| value | 含义 |
| --- | --- |
| 0 | 公开。默认。 |
| 1 | 仅关心的人可见。 |
| 2 | 仅自己可见。 |
只允许 0、1、2。不要传 3。
## 9. Endpoints
| method | path |
| --- | --- |
| GET or POST | `/api/open/exists` |
| POST | `/api/open/upload` |
| POST | `/api/open/publish` |
| POST | `/api/open/delete` |
### exists — GET or POST /api/open/exists
查询这对 provider + external_id 是否已经发布过。
- URL: `https://taabb.com/api/open/exists`
- 鉴权:必须
- Body: GET query | application/x-www-form-urlencoded | application/json
| name | in | type | required | notes |
| --- | --- | --- | --- | --- |
| `provider` | query|body | string | 是 | 来源短名,最长 64。 |
| `external_id` | query|body | string | 是 | 你自己的条目 ID,最长 191。 |
```json
{
"exists": false,
"post_id": 0
}
```
- exists=true 时 post_id 为已有笔记;false 时 post_id 为 0。
- 不会更新令牌最后使用时间。
示例 — GET:
```bash
curl -sS -H "Authorization: Bearer tab_YOUR_TOKEN" "https://taabb.com/api/open/exists?provider=demo&external_id=abc-1"
```
示例 — POST JSON:
```bash
curl -sS -X POST "https://taabb.com/api/open/exists" \
-H "Authorization: Bearer tab_YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"provider":"demo","external_id":"abc-1"}'
```
### upload — POST /api/open/upload
上传一张图片。只是存文件,还不会出现在笔记里。
- URL: `https://taabb.com/api/open/upload`
- 鉴权:必须
- Body: multipart/form-data
| name | in | type | required | notes |
| --- | --- | --- | --- | --- |
| `upload_file` | file | file | 是 | 推荐字段名。 |
| `file` | file | file | 否 | 没有 upload_file 时可用。 |
```json
{
"message": "上传成功",
"path": "upload/post/202608/example.jpg",
"previewUrl": "https://taabb.com/upload/post/202608/example.jpg",
"width": 1200,
"height": 800
}
```
- 必须 multipart,不支持 JSON 传文件。
- 一次一张。多张就请求多次。
- 请把返回的 data.path 写进稍后发布的 <img src>。
- 超时或中断时用同一文件重试这一张;服务端会返回已有路径,不会重复存文件。不要把未成功的图写进正文。
示例 — multipart:
```bash
curl -sS -X POST "https://taabb.com/api/open/upload" \
-H "Authorization: Bearer tab_YOUR_TOKEN" \
-F "upload_file=@/path/to/photo.jpg"
```
### publish — POST /api/open/publish
为令牌所属用户创建一篇内容。同一对 provider+external_id 会跳过,不会覆盖。
- URL: `https://taabb.com/api/open/publish`
- 鉴权:必须
- Body: application/x-www-form-urlencoded | application/json
| name | in | type | required | notes |
| --- | --- | --- | --- | --- |
| `provider` | body | string | 是 | provider |
| `external_id` | body | string | 是 | external_id |
| `post_content` | body | string (HTML) | 是 | HTML |
| `post_title` | body | string | 否 | max 200 |
| `post_type` | body | integer | 否 | 1 \| 3, default 3 |
| `post_privacy` | body | integer | 否 | 0 \| 1 \| 2, default 0 |
| `post_time` | body | string | 否 | datetime |
```json
{
"message": "发布成功",
"skipped": false,
"exists": false,
"post_id": 12345
}
```
- 已存在时:success=true,skipped=true。
- 不要传 uid。作者就是令牌的主人。
- 正文里 src 含 upload/post/ 的 <img> 会自动挂附件并生成缩图。
示例 — 带图片发布:
```bash
curl -sS -X POST "https://taabb.com/api/open/upload" \
-H "Authorization: Bearer tab_YOUR_TOKEN" \
-F "upload_file=@./one.jpg"
# 记下返回的 data.path,例如 upload/post/202608/one.jpg
curl -sS -X POST "https://taabb.com/api/open/publish" \
-H "Authorization: Bearer tab_YOUR_TOKEN" \
--data-urlencode "provider=demo" \
--data-urlencode "external_id=abc-1" \
--data-urlencode "post_title=标题" \
--data-urlencode "post_content=<p>正文</p><p><img src=\"upload/post/202608/one.jpg\"></p>"
```
示例 — JSON:
```bash
curl -sS -X POST "https://taabb.com/api/open/publish" \
-H "Authorization: Bearer tab_YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"provider":"demo","external_id":"abc-1","post_title":"标题","post_type":3,"post_privacy":2,"post_content":"<p>正文</p><p><img src=\"upload/post/202608/one.jpg\"></p>"}'
```
### delete — POST /api/open/delete
删除令牌主人的笔记。传 post_id,或传 provider + external_id。
- URL: `https://taabb.com/api/open/delete`
- 鉴权:必须
- Body: application/x-www-form-urlencoded | application/json
| name | in | type | required | notes |
| --- | --- | --- | --- | --- |
| `post_id` | body | integer | 否 | post_id |
| `provider` | body | string | 否 | provider |
| `external_id` | body | string | 否 | external_id |
```json
{
"message": "删除成功",
"post_id": 12345
}
```
- 令牌的「最后使用」只在真正发布成功(非 skip)或删除成功时更新。exists / 上传 / 跳过发布不算。
示例 — JSON:
```bash
curl -sS -X POST "https://taabb.com/api/open/delete" \
-H "Authorization: Bearer tab_YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"provider":"demo","external_id":"abc-1"}'
```
## 10. HTML 约定
- post_content 是 HTML。净化后为空会失败。
- 允许常见文本标签、链接、列表、已上传图片的 <img>、checkbox。
- 禁止并会去掉:script、iframe、style、textarea、object、embed。
- JSON 请求体上限 1MB;大 HTML 用 application/x-www-form-urlencoded。
- post_title 最长 200,纯文本。post_time 例如 2026-08-14 15:00:00,空则取当前时间。
## 11. 不要调用
- `GET|POST /api/open/tokens`
- `POST /api/open/tokens/delete`
- `Any /api/* path not listed in endpoints`
- `Browser publish /post/add`
- `uid, specify_users, post_pass, diary_book_id, topics`
令牌的「最后使用」只在真正发布成功(非 skip)或删除成功时更新。exists / 上传 / 跳过发布不算。