API
Cflow 提供公开的 HTTP RESTful API,可以用脚本对笔记做增删改查、上传附件,适合备份、批量处理或与第三方工具集成。
准备
- 在 设置 → 我的账号 → 访问 Token 创建一个 API Token,按需选择有效期、读写权限与允许访问的空间。
- 每个请求带上
Authorization: Bearer <你的Token>请求头。
接口一览
| 方法 | 路径 | 用途 |
|---|---|---|
| POST | /api/v1/memo | 创建笔记 |
| GET | /api/v1/memo | 笔记列表(分页) |
| GET | /api/v1/memo/{memoId} | 笔记详情 |
| PATCH | /api/v1/memo/{memoId} | 修改笔记 |
所有接口返回 JSON。时间字段均为 Unix 秒级时间戳。
参数说明
创建笔记 — POST /api/v1/memo
Body 为 JSON 对象:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
content | string | 必填 | 正文,Markdown 语法 |
spaceId | string | 选填 | 目标空间 ID,不传或传空串为默认空间 |
title | string | 选填 | 标题 |
secretLv | int | 选填 | 私密等级:0 公开(默认)、1 私密 |
createdTs | int | 选填 | 创建时间(Unix 秒),不传为当前时间。用于导入历史数据 |
返回创建后的笔记对象,笔记 ID 在 MemoId 字段(注意大小写)。
笔记列表 — GET /api/v1/memo
参数通过 URL query 传递,全部选填:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
limit | int | 选填 | 每页数量。不传则返回全部,分页时建议始终传 |
offset | int | 选填 | 偏移量,配合 limit 翻页,从 0 开始 |
spaceId | string | 选填 | 单空间过滤(旧参数,与 spaceIds 同传时以 spaceIds 为准) |
返回笔记对象数组。
笔记详情 — GET /api/v1/memo/{memoId}
| 参数 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
memoId | path | int | 必填 | 笔记 ID |
修改笔记 — PATCH /api/v1/memo/{memoId}
memoId(path,int,必填)之外,Body 为 JSON,所有字段选填,只更新传了的字段:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
content | string | 选填 | 新正文 |
title | string | 选填 | 标题 |
secretLv | int | 选填 | 0 公开、1 私密 |
pinned | bool | 选填 | 是否置顶 |
createdTs | int | 选填 | 修改创建时间(Unix 秒) |
Python 示例
以下示例使用 requests 库(pip install requests)。
import requests
BASE = "https://cflow.cc"
TOKEN = "你的API Token"
headers = {"Authorization": f"Bearer {TOKEN}"}
json_headers = {**headers, "Content-type": "application/json"}
新增笔记
resp = requests.post(f"{BASE}/api/v1/memo", headers=json_headers, json={
"content": "通过 API 创建的笔记 #api",
"spaceId": "", # 选填,默认空间
"skipWebhook": "1", # 选填,批量导入时跳过自动化
})
memo_id = resp.json()["MemoId"]
查询笔记
# 单篇
memo = requests.get(f"{BASE}/api/v1/memo/{memo_id}", headers=headers).json()
# 列表(分页)
memos = requests.get(f"{BASE}/api/v1/memo", headers=headers, params={
"rowStatus": "NORMAL",
"offset": 0,
"limit": 20,
}).json()
修改笔记
resp = requests.patch(f"{BASE}/api/v1/memo/{memo_id}", headers=json_headers, json={
"content": "修改后的内容",
})
删除笔记
resp = requests.delete(f"{BASE}/api/v1/memo/{memo_id}", params={"removeFromKanban": "1"}, headers=headers)
上传附件
multipart/form-data 表单,先上传得到附件 ID,再挂到笔记上:
| 参数 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
file | form-data | file | 必填 | 文件本体 |
content_type | form-data | string | 选填 | 文件 MIME 类型,写法见下 |
返回附件对象,附件 ID 在 id 字段(小写,与笔记的 MemoId 不同)。
文件类型怎么写(重要)
附件的 MIME 类型决定它在 Cflow 里能否被正确识别和预览,请按文件的真实格式指定。
常见格式对照:
| 文件 | 类型写法 |
|---|---|
| .png | image/png |
| .jpg / .jpeg | image/jpeg |
| .gif | image/gif |
| .webp | image/webp |
| .svg | image/svg+xml |
application/pdf | |
| .txt / .md | text/plain |
| .html | text/html |
| .mp4 | video/mp4 |
| .mp3 | audio/mpeg |
| .docx | application/vnd.openxmlformats-officedocument.wordprocessingml.document |
| .xlsx | application/vnd.openxmlformats-officedocument.spreadsheetml.sheet |
| .pptx | application/vnd.openxmlformats-officedocument.presentationml.presentation |
| .zip | application/zip |
# 1. 上传文件:三元组第三个参数就是文件类型,按真实格式写
files = {"file": ("照片.png", open("照片.png", "rb"), "image/png")}
resource_id = requests.post(f"{BASE}/api/v1/resource/blob", headers=headers, files=files).json()["id"]
# 2. 挂到笔记(创建时挂:resourceIdList 一样可用)
resp = requests.patch(f"{BASE}/api/v1/memo/{memo_id}", headers=json_headers, json={
"resourceIdList": [resource_id],
})
下载附件
# 加 download=1 以「保存文件」方式返回(带原始文件名);不加则按预览(inline)返回
resp = requests.get(f"{BASE}/o/r/{resource_id}", params={"download": "1"}, headers=headers)
resp.raise_for_status()
with open("照片.png", "wb") as f:
f.write(resp.content)
注意事项
- Token 的读写权限与空间范围会实际生效:只读 Token 无法创建/修改,空间范围外的操作会被拒绝。
- 批量操作请控制频率,过快的请求会被限流。
- 更完整的 Token 管理与 AI 智能体接入说明见 API 与 Token。