Roam Research Docs · Developer documentation
response.body used to contain only the error message, now it is a map of the format {message: error-message-str}
response.body will have a "message" key clarifying what the error)
retry-after which mentions how many seconds to wait for before next request
req = count(JSON.stringify(req.body.append-data))
req = count(JSON.stringify(req.body.append-data))
retry-after which mentions how many seconds to wait for before next request
curl -X POST "https://append-api.roamresearch.com/api/graph/MY-GRAPH/append-blocks" \
-H "Authorization: Bearer YOUR_ROAM_GRAPH_TOKEN" \
-H "Content-Type: application/json" \
-d '{"location": {"page": {"title": "Append API Captures"}, "nest-under": {"string": "Captures from [[CURL]]"}}, "append-data": [{"string": "a new capture", "children": [{"string": "child block of capture"}]}]}'
page and nest-under capture group if they did not exist already
nest-under below
curl -X POST "https://append-api.roamresearch.com/api/graph/MY-GRAPH/append-blocks" \
-H "Authorization: Bearer YOUR_ROAM_GRAPH_TOKEN" \
-H "Content-Type: application/json" \
-d '{"location": {"page": {"title": "Append API Captures"}, "nest-under": {"string": "Captures from [[CURL]]"}}, "append-data": [{"string": "second capture"}]}'
"Raycast extension capture"
"Captures from [[Zapier]]"
"{{[[TODO]]}} TODOs from Slack bot (be sure to go handle these)"
+ New API Token button
curl -X POST "https://append-api.roamresearch.com/api/graph/MY-GRAPH/append-blocks" \
-H "Authorization: Bearer YOUR_ROAM_GRAPH_TOKEN" \
-H "Content-Type: application/json" \
-d '{"location": {"page": {"title": "Append API Captures"}, "nest-under": {"string": "Captures from [[CURL]]"}}, "append-data": [{"string": "a new capture", "children": [{"string": "child block of capture"}]}]}' *
MY-GRAPH with your graph name and YOUR_ROAM_GRAPH_TOKEN with the API token you copied to the clipboard
roam-graph-token-
X-Authorization header
Authorization header too (would be more secure) but you have to make sure that your code/library handles redirect properly and passes the authorization header when redirect has been followed (and the latter is generally not default behavior for most network libraries)
Bearer
Bearer roam-graph-token-t_OjqgIAH1JZphzP4HxjJNad55lLFKpsqIM7x3bW
/api/graph/{graph-name}/append-blocks (POST) IMPORTANT
location required
page required
title required
{"daily-note-page": "MM-DD-YYYY"}. *
{"daily-note-page": "MM-DD-YYYY"}
{"daily-note-page": "MM-DD-YYYY"}
block (alternative to page)
location.block.uid below
Append API Captures attempted under non-existent blocks:
America/Chicago. This means that the captures may appear in yesterday/tomorrow's daily note page (from the POV of the user)
location.block.uid. If you do so, please be advised that this is fragile
uid optional
uid
nest-under optional
"Raycast extension capture"
"Captures from [[Zapier]]"
"{{[[TODO]]}} TODOs from Slack bot (be sure to go handle these)"
string
append-data required
string required
string
children optional
heading optional
0 (no heading styling)
1
2
3
text-align optional
text-align
left
center
right
justify
open optional
open
true by default (if not passed)
children-view-type optional
children-view-type
bullet
numbered
document
uid optional
{captureSuccessful: true}
response.body will have a "message" key clarifying what the error)
retry-after which mentions how many seconds to wait for before next request
req = count(JSON.stringify(req.body.append-data))
req = count(JSON.stringify(req.body.append-data))
retry-after which mentions how many seconds to wait for before next request
curl -X POST "https://append-api.roamresearch.com/api/graph/MY-GRAPH/append-blocks" \
-H "Authorization: Bearer YOUR_ROAM_GRAPH_TOKEN" \
-H "Content-Type: application/json" \
-d '{"location": {"page": {"title": "Append API Captures"}, "nest-under": {"string": "Captures from [[CURL]]"}}, "append-data": [{"string": "a new capture", "children": [{"string": "child block of capture"}]}]}'
page and nest-under capture group if they did not exist already
nest-under below
curl -X POST "https://append-api.roamresearch.com/api/graph/MY-GRAPH/append-blocks" \
-H "Authorization: Bearer YOUR_ROAM_GRAPH_TOKEN" \
-H "Content-Type: application/json" \
-d '{"location": {"page": {"title": "Append API Captures"}, "nest-under": {"string": "Captures from [[CURL]]"}}, "append-data": [{"string": "second capture"}]}'
"Raycast extension capture"
"Captures from [[Zapier]]"
"{{[[TODO]]}} TODOs from Slack bot (be sure to go handle these)"
{
"location": {
"page": {
"title": "May 18th, 2024"
},
"nest-under": {
"string": "Captures from [[Zapier]]"
}
},
"append-data": [
{
"string": "Hey I am a block with children",
"open": false,
"children-view-type": "document",
"children": [
{
"string": "hey I am a child block",
"open": false,
"children": [
{
"string": "nested two layers deep"
}
]
}
]
},
{
"string": "I am a second block getting added"
}
]
}
{"daily-note-page": "MM-DD-YYYY"}. * as location.page.title
{"daily-note-page": "05-18-2024"} in location.page.title instead of passing in "May 18th, 2024")
{
"location": {
"page": {
"title": {"daily-note-page": "05-18-2024"}
},
"nest-under": {
"string": "Captures from [[Zapier]]"
}
},
"append-data": [
{
"string": "Hey I am a block with children",
"open": false,
"children-view-type": "document",
"children": [
{
"string": "hey I am a child block",
"open": false,
"children": [
{
"string": "nested two layers deep"
}
]
}
]
},
{
"string": "I am a second block getting added"
}
]
}
location.block.uid below
Append API Captures attempted under non-existent blocks:
America/Chicago. This means that the captures may appear in yesterday/tomorrow's daily note page (from the POV of the user)
location.block.uid. If you do so, please be advised that this is fragile
uid optional
{
"location": {
"block": {
"uid": "f-gVYZHz4"
},
"nest-under": {
"string": "Captures from [[Append API]]"
}
},
"append-data": [
{
"string": "Hey I am a block with children"
}
]
}
string argument for any block in append-data now also accepts a nested markdown string!
open value is not passed, it is now true by default
{captureSuccessful: true}** (previously was null)
location.block.uid below
Append API Captures attempted under non-existent blocks:
America/Chicago. This means that the captures may appear in yesterday/tomorrow's daily note page (from the POV of the user)
location.block.uid. If you do so, please be advised that this is fragile
uid optional
response.body used to contain only the error message, now it is a map of the format {message: error-message-str}
response.body will have a "message" key clarifying what the error)
retry-after which mentions how many seconds to wait for before next request
req = count(JSON.stringify(req.body.append-data))
req = count(JSON.stringify(req.body.append-data))
retry-after which mentions how many seconds to wait for before next request
append-api.roamresearch.com (as opposed to the api.roamresearch.com for the Backend API)
req = count(JSON.stringify(req.body.append-data))
req = count(JSON.stringify(req.body.append-data))
retry-after which mentions how many seconds to wait for before next request
markdown version · view in Roam Research · exported 2026-07-03