Craft Document Management
Operate on a Craft space via the Craft Connect REST API. Full CRUD on documents,
blocks, folders, tasks, collections, and comments.
Requirements
- - curl — used for all API requests
- CRAFTAPIURL — your Craft Connect API base URL (contains embedded link token for authentication)
Setup
- 1. Create a Craft Connect link in your Craft space (Settings → Connect → Create Link)
- Copy the API base URL and store it in TOOLS.md under a Craft section:
CODEBLOCK0
- 3. Read TOOLS.md before making any calls to retrieve the URL.
All calls use curl with -H "Content-Type: application/json" for writes and
-H "Accept: application/json" for reads.
Important: URL-encode non-ASCII characters (e.g. Chinese) in query params.
API Reference
Connection Info
CODEBLOCK1
Returns space ID, timezone, current time, and deep-link URL templates.
Discovery
CODEBLOCK2
Search
CODEBLOCK3
Documents
CODEBLOCK4
Reading Content
CODEBLOCK5
Writing Content
Two methods: markdown (recommended) and blocks JSON.
Method 1: Markdown (Recommended)
Best for most content. Craft parses markdown and auto-generates correct block
types, indentation levels, and list styles.
CODEBLOCK6
Method 2: Blocks JSON
Use when you need explicit control over color, font, textStyle, or other
properties not expressible in plain markdown.
CODEBLOCK7
Position Options
| Position | Syntax |
|---|
| Append to document | INLINECODE6 |
| Prepend to document |
{"position": "start", "pageId": "<DOC_ID>"} |
| After a specific block |
{"position": "after", "siblingId": "<BLOCK_ID>"} |
| Before a specific block |
{"position": "before", "siblingId": "<BLOCK_ID>"} |
| Append to daily note |
{"position": "end", "date": "today"} |
Updating & Deleting Blocks
CODEBLOCK8
Tasks
CODEBLOCK9
Folders
CODEBLOCK10
Collections (Structured Databases)
Collections are like Notion databases — structured tables with typed columns.
CODEBLOCK11
Comments
CODEBLOCK12
File Upload
CODEBLOCK13
Position params: position (start|end|before|after) + pageId/date/siblingId.
Block Types & Formatting
Headings
CODEBLOCK14
Inline Styles
CODEBLOCK15
Highlights (9 solid + 5 gradient)
CODEBLOCK16
Solid: yellow, blue, red, green, purple, pink, mint, cyan, gray
Gradient: gradient-blue, gradient-purple, gradient-red, gradient-yellow, INLINECODE28
Lists
CODEBLOCK17
Toggle (Collapsible) Lists — CRITICAL
Children MUST be indented 2 spaces to nest inside a toggle:
CODEBLOCK18
Use markdown mode only. indentationLevel in blocks JSON is silently
ignored on insert.
Blockquote
CODEBLOCK19
Produces block with decorations: ["quote"].
Dividers / Lines
Blocks JSON with lineStyle:
CODEBLOCK20
Markdown mode: --- produces extraLight by default.
Code Blocks
Markdown mode:
INLINECODE34
Blocks JSON (requires rawCode!):
CODEBLOCK23 python\ndef hello():\n print('Hello')\n``"}
CODEBLOCK24 json
{"type": "code", "language": "math_formula", "rawCode": "x = \\frac{-b \\pm \\sqrt{b^2 - 4ac}}{2a}", "markdown": "`math_formula\nx = \\frac{-b \\pm \\sqrt{b^2 - 4ac}}{2a}\n`"}
CODEBLOCK25 markdown
| Col A | Col B |
| --- | --- |
| val 1 | val 2 |
CODEBLOCK26 json
{"type": "image", "url": "https://example.com/photo.jpg", "markdown": ""}
CODEBLOCK27 json
{"type": "richUrl", "url": "https://www.youtube.com/watch?v=..."}
CODEBLOCK28 json
{"type": "page", "textStyle": "page", "markdown": "Sub-page Title"}
{"type": "page", "textStyle": "card", "markdown": "Card Title"}
CODEBLOCK29 json
{"type": "text", "color": "#00A3CB", "markdown": "<callout>💡 Info</callout>"}
CODEBLOCK30 json
{"type": "text", "textStyle": "caption", "markdown": "<caption>Small annotation</caption>"}
CODEBLOCK31 json
{"type": "text", "listStyle": "task", "taskInfo": {"state": "todo"}, "markdown": "- [ ] Task"}
CODEBLOCK32 json
{
"type": "text",
"font": "rounded",
"textStyle": "h3",
"color": "#9862E8",
"markdown": "<callout>### ✨ Purple rounded heading callout</callout>"
}
`
---
## Choosing Insert Method
| Need | Use | Why |
|------|-----|-----|
| Text, lists, headings | Markdown | Clean, auto-detects types |
| Toggle lists with children | Markdown | Only way to get indentation right |
| Code blocks, tables | Either | Markdown is simpler; JSON needs rawCode |
| Colored callouts | Blocks JSON | Need color property |
| Custom fonts | Blocks JSON | Need font property |
| Captions | Blocks JSON | Need textStyle: "caption" |
| Images, richUrl, pages | Blocks JSON | Need type field |
| Line styles | Blocks JSON | Need lineStyle |
| Math formulas | Blocks JSON | Need language: "mathformula" + rawCode |
| Mixed content | Split calls | Combine markdown + blocks JSON |
---
## Gotchas & Lessons Learned
1. **Toggle indentation**: markdown mode with 2-space indent is the only way.
indentationLevel in blocks JSON is silently ignored on insert.
2. **Task state values**: todo | done | canceled. NOT completed.
3. **Position after/before**: use siblingId (not blockId).
4. **Position end/start**: use pageId or date.
5. **Code blocks in JSON mode**: require rawCode field. Without it you get
a validation error.
6. **Collection item keys**: the API docs say title but the real field name
is the auto-generated contentProp key from the schema (e.g. 4).
Always GET /collections//schema?format=json-schema-items first
to discover the correct keys.
7. **URL-encode search terms**: Chinese and special characters in query params
must be URL-encoded or curl returns 400.
8. **Accept header**: use application/json for reads. text/markdown may 502.
9. **Document delete is soft**: goes to trash, restorable via move.
Block delete is permanent.
10. **Large inserts**: one POST can insert many blocks. Prefer fewer larger
writes to avoid rate limits.
11. **Image re-hosting**: Craft downloads external images and re-hosts them
at https://r.craft.do/`. Your original URL is replaced.
- 12. Collections are experimental: the API may change. Always read the
schema before writing items.
Craft 文档管理
通过 Craft Connect REST API 操作 Craft 空间。支持对文档、区块、文件夹、任务、集合和评论的完整增删改查。
要求
- - curl — 用于所有 API 请求
- CRAFTAPIURL — 您的 Craft Connect API 基础 URL(包含用于身份验证的嵌入式链接令牌)
设置
- 1. 在您的 Craft 空间中创建一个 Craft Connect 链接(设置 → 连接 → 创建链接)
- 复制 API 基础 URL 并将其存储在 TOOLS.md 的 Craft 部分下:
CRAFTAPIURL=https://connect.craft.do/links//api/v1
- 3. 在发起任何调用以获取 URL 之前,请先阅读 TOOLS.md。
所有调用均使用 curl,写入时使用 -H Content-Type: application/json,读取时使用 -H Accept: application/json。
重要提示: 对查询参数中的非 ASCII 字符(例如中文)进行 URL 编码。
API 参考
连接信息
bash
curl -s $CRAFTAPIURL/connection
返回空间 ID、时区、当前时间和深度链接 URL 模板。
发现
bash
列出所有文件夹和位置
curl -s $CRAFT
APIURL/folders
列出某个位置的文档(unsorted | trash | templates | daily_notes)
curl -s $CRAFT
APIURL/documents?location=unsorted
列出文件夹中的文档
curl -s $CRAFT
APIURL/documents?folderId=
带元数据(创建/修改日期、深度链接)
curl -s $CRAFTAPIURL/documents?location=unsorted&fetchMetadata=true
日期筛选(ISO YYYY-MM-DD 或:today, yesterday, tomorrow)
curl -s $CRAFTAPIURL/documents?createdDateGte=2025-01-01&lastModifiedDateLte=today
搜索
bash
搜索所有文档(对非 ASCII 字符进行 URL 编码!)
curl -s $CRAFTAPIURL/documents/search?include=&fetchMetadata=true
在特定文档内搜索(带上下文区块)
curl -s $CRAFTAPIURL/blocks/search?blockId=&pattern=&beforeBlockCount=2&afterBlockCount=2
按文件夹或位置筛选搜索
curl -s $CRAFTAPIURL/documents/search?include=&folderIds=
curl -s $CRAFTAPIURL/documents/search?include=&location=daily_notes
文档
bash
创建文档(默认为 unsorted)
curl -s -X POST $CRAFTAPIURL/documents \
-H Content-Type: application/json \
-d {documents: [{title: 我的文档}]}
在特定文件夹中创建
curl -s -X POST $CRAFTAPIURL/documents \
-H Content-Type: application/json \
-d {documents: [{title: 文档}], destination: {folderId: }}
创建为模板
curl -s -X POST $CRAFTAPIURL/documents \
-H Content-Type: application/json \
-d {documents: [{title: 模板}], destination: {destination: templates}}
删除(软删除到回收站,可恢复)
curl -s -X DELETE $CRAFTAPIURL/documents \
-H Content-Type: application/json \
-d {documentIds: []}
在位置之间移动
curl -s -X PUT $CRAFTAPIURL/documents/move \
-H Content-Type: application/json \
-d {documentIds: [], destination: {folderId: }}
从回收站恢复
curl -s -X PUT $CRAFTAPIURL/documents/move \
-H Content-Type: application/json \
-d {documentIds: [], destination: {destination: unsorted}}
读取内容
bash
获取文档内容(JSON)
curl -s $CRAFTAPIURL/blocks?id= -H Accept: application/json
获取每日笔记
curl -s $CRAFTAPIURL/blocks?date=today -H Accept: application/json
控制深度(0=仅区块,1=直接子级,-1=全部)
curl -s $CRAFTAPIURL/blocks?id=&maxDepth=1
带元数据(评论、作者、时间戳)
curl -s $CRAFTAPIURL/blocks?id=&fetchMetadata=true
写入内容
两种方法:markdown(推荐)和 blocks JSON。
方法 1:Markdown(推荐)
适用于大多数内容。Craft 解析 markdown 并自动生成正确的区块类型、缩进级别和列表样式。
bash
curl -s -X POST $CRAFTAPIURL/blocks \
-H Content-Type: application/json \
-d {
markdown: ## 标题\n\n段落\n\n- 项目 1\n- 项目 2,
position: {position: end, pageId: }
}
方法 2:Blocks JSON
当您需要对 color、font、textStyle 或其他无法在纯 markdown 中表达的属性进行显式控制时使用。
bash
curl -s -X POST $CRAFTAPIURL/blocks \
-H Content-Type: application/json \
-d {
blocks: [
{type: text, textStyle: h2, markdown: ## 标题},
{type: text, color: #00A3CB, markdown: 💡 信息}
],
position: {position: end, pageId: }
}
位置选项
| 位置 | 语法 |
|---|
| 追加到文档末尾 | {position: end, pageId: <DOCID>} |
| 插入到文档开头 |
{position: start, pageId: ID>} |
| 在特定区块之后 | {position: after, siblingId: } |
| 在特定区块之前 | {position: before, siblingId: } |
| 追加到每日笔记 | {position: end, date: today} |
更新和删除区块
bash
更新(仅更改提供的字段;其他字段保持不变)
curl -s -X PUT $CRAFTAPIURL/blocks \
-H Content-Type: application/json \
-d {blocks: [{id: , markdown: 已更新, font: serif}]}
删除区块(永久删除!)
curl -s -X DELETE $CRAFTAPIURL/blocks \
-H Content-Type: application/json \
-d {blockIds: [, ]}
在文档之间移动区块
curl -s -X PUT $CRAFTAPIURL/blocks/move \
-H Content-Type: application/json \
-d {blockIds: [], position: {position: end, pageId: }}
任务
bash
列出任务(范围:inbox, active, upcoming, logbook, document)
curl -s $CRAFTAPIURL/tasks?scope=active
curl -s $CRAFTAPIURL/tasks?scope=document&documentId=
在收件箱中创建任务
curl -s -X POST $CRAFTAPIURL/tasks \
-H Content-Type: application/json \
-d {tasks: [{markdown: 任务文本, taskInfo: {scheduleDate: tomorrow}, location: {type: inbox}}]}
在每日笔记中创建任务
curl -s -X POST $CRAFTAPIURL/tasks \
-H Content-Type: application/json \
-d {tasks: [{markdown: 任务, taskInfo: {scheduleDate: 2025-01-20, deadlineDate: 2025-01-22}, location: {type: dailyNote, date: today}}]}
在文档中创建任务
curl -s -