Roam Research Docs · Developer documentation
pull-many endpoint: /api/graph/{graph-name}/pull-many (POST)
batch-actions write requests
num-actions-successfully-transacted-before-failure in the response.data so you can figure out which action in your request failed
num-actions-successfully-transacted-before-failure would be 2
create-block and move-block write actions, you can pass a different parameter page-title. If you use this instead of parent-uid, it will create the page if it does not exist already
location
page-title
{"daily-note-page": "MM-DD-YYYY"}.
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
curl -X POST "https://api.roamresearch.com/api/graph/MY-GRAPH/q" --location-trusted \
-H "accept: application/json" \
-H "X-Authorization: Bearer roam-graph-token-for-MY-GRAPH-1JN132hnXUYIfso22" \
-H "Content-Type: application/json" \
-d "{\"query\" : \"[:find ?block-uid ?block-str :in \$ ?search-string :where [?b :block/uid ?block-uid] [?b :block/string ?block-str] [(clojure.string/includes? ?block-str ?search-string)]]\", \"args\": [\"apple\"]}"
query and args
--location-trusted is required because your request is redirected to the actual machine doing the work.
https://api.roamresearch.com/ abstracts away this from the developer point of view, by redirecting messages to the actual machine doing the work
Bearer and are passed in the Authorization header
/api/graph/{graph-name}/q (POST)
{
"query" : "[:find ?block-uid ?block-str :in $ ?search-string :where [?b :block/uid ?block-uid] [?b :block/string ?block-str] [(clojure.string/includes? ?block-str ?search-string)]]",
"args": ["apple"]
}
curl -X POST "https://api.roamresearch.com/api/graph/MY-GRAPH/q" --location-trusted \
-H "accept: application/json" \
-H "X-Authorization: Bearer roam-graph-token-for-MY-GRAPH-1JN132hnXUYIfso22" \
-H "Content-Type: application/json" \
-d "{\"query\" : \"[:find ?block-uid ?block-str :in \$ ?search-string :where [?b :block/uid ?block-uid] [?b :block/string ?block-str] [(clojure.string/includes? ?block-str ?search-string)]]\", \"args\": [\"apple\"]}"
query and args
/api/graph/{graph-name}/pull (POST)
eid
selector
{
"eid": "[:block/uid \"08-30-2022\"]",
"selector": "[:block/uid :node/title :block/string {:block/children [:block/uid :block/string]} {:block/refs [:node/title :block/string :block/uid]}]"
}
curl -X POST "https://api.roamresearch.com/api/graph/MY-GRAPH/pull" --location-trusted \
-H "accept: application/json" \
-H "Authorization: Bearer roam-graph-token-for-MY-GRAPH-1JN132hnXUYIfso22" \
-H "Content-Type: application/json" \
-d "{\"eid\": \"[:block/uid \\\"08-30-2022\\\"]\", \"selector\": \"[:block/uid :node/title :block/string {:block/children [:block/uid :block/string]}{:block/refs [:node/title :block/string :block/uid]}]\"}"
/api/graph/{graph-name}/pull-many (POST)
eids
selector
{
"eids": "[[:block/uid \"08-30-2022\"] [:block/uid \"08-31-2022\"]]",
"selector": "[:block/uid :node/title :block/string {:block/children [:block/uid :block/string]} {:block/refs [:node/title :block/string :block/uid]}]"
}
curl -X POST "https://api.roamresearch.com/api/graph/MY-GRAPH/pull-many" --location-trusted \
-H "accept: application/json" \
-H "Authorization: Bearer roam-graph-token-for-MY-GRAPH-1JN132hnXUYIfso22" \
-H "Content-Type: application/json" \
-d "{\"eids\": \"[[:block/uid \\\"08-30-2022\\\"]]\", \"selector\": \"[:block/uid :node/title :block/string {:block/children [:block/uid :block/string]}{:block/refs [:node/title :block/string :block/uid]}]\"}"
/api/graph/{graph-name}/write (POST)
action key (alongside all the other required parameters)
create-block write action:
location
parent-uid required
order required
block
string required
uid optional
open optional
heading optional
text-align optional
children-view-type optional
block-view-type optional
{
"action" : "create-block",
"location": {
"parent-uid": "09-28-2022",
"order": "last"
},
"block": {
"string": "new block created via the backend",
"open": false,
"heading": 2,
"text-align": "right",
"children-view-type": "document"
}
}
/api/graph/MY-GRAPH/write (POST)
{
"action" : "create-block",
"location": {
"parent-uid": "09-28-2022",
"order": "last"
},
"block": {
"string": "new block created via the backend",
"open": false,
"heading": 2,
"text-align": "right",
"children-view-type": "document"
}
}
curl -X POST "https://api.roamresearch.com/api/graph/MY-GRAPH/write" --location-trusted \
-H "accept: application/json" \
-H "Authorization: Bearer roam-graph-token-for-MY-GRAPH-1JN132hnXUYIfso22" \
-H "Content-Type: application/json" \
-d "{\"action\":\"create-block\",\"location\":{\"parent-uid\":\"09-28-2022\",\"order\":\"last\"},\"block\":{\"string\":\"new block created via the backend\",\"open\":false,\"heading\":2,\"text-align\":\"right\",\"children-view-type\":\"document\"}}"
batch-actions create-block
location
parent-uid
page-title
page-title
{"daily-note-page": "MM-DD-YYYY"}.
order required
block
string required
uid optional
open optional
heading optional
text-align optional
children-view-type optional
block-view-type optional
message value
"order": 2 in the update-block example request
batch-actions especially, You have to carefully handle this (to know how many requests suceeded)
n actions in a batch action request, the first x could succeed/transact and if then error occurs, the remaining n-x ones would not happen
num-actions-successfully-transacted-before-failure to figure out where exactly in the actions list the error happened
message value
/api/graph/MY-GRAPH/write (POST)
{
"action" : "create-block",
"location": {
"parent-uid": "09-28-2022",
"order": "last"
},
"block": {
"string": "new block created via the backend",
"open": false,
"heading": 2,
"text-align": "right",
"children-view-type": "document"
}
}
curl -X POST "https://api.roamresearch.com/api/graph/MY-GRAPH/write" --location-trusted \
-H "accept: application/json" \
-H "Authorization: Bearer roam-graph-token-for-MY-GRAPH-1JN132hnXUYIfso22" \
-H "Content-Type: application/json" \
-d "{\"action\":\"create-block\",\"location\":{\"parent-uid\":\"09-28-2022\",\"order\":\"last\"},\"block\":{\"string\":\"new block created via the backend\",\"open\":false,\"heading\":2,\"text-align\":\"right\",\"children-view-type\":\"document\"}}"
move-block
page-title in location)
block
uid required
location
parent-uid
page-title
page-title
{"daily-note-page": "MM-DD-YYYY"}.
order required
message value
"order": 2 in the update-block example request
batch-actions especially, You have to carefully handle this (to know how many requests suceeded)
n actions in a batch action request, the first x could succeed/transact and if then error occurs, the remaining n-x ones would not happen
num-actions-successfully-transacted-before-failure to figure out where exactly in the actions list the error happened
message value
/api/graph/MY-GRAPH/write (POST)
{
"action" : "move-block",
"block": {
"uid": "7yYBPW-WO"
},
"location": {
"parent-uid": "09-27-2022",
"order": 3
}
}
curl -X POST "https://api.roamresearch.com/api/graph/MY-GRAPH/write" --location-trusted \
-H "accept: application/json" \
-H "Authorization: Bearer roam-graph-token-for-MY-GRAPH-1JN132hnXUYIfso22" \
-H "Content-Type: application/json" \
-d "{\"action\":\"move-block\",\"block\":{\"uid\":\"7yYBPW-WO\"},\"location\":{\"parent-uid\":\"09-27-2022\",\"order\":3}}"
update-block
block
uid required
string optional
open optional
heading optional
text-align optional
children-view-type optional
block-view-type optional
message value
"order": 2 in the update-block example request
batch-actions especially, You have to carefully handle this (to know how many requests suceeded)
n actions in a batch action request, the first x could succeed/transact and if then error occurs, the remaining n-x ones would not happen
num-actions-successfully-transacted-before-failure to figure out where exactly in the actions list the error happened
message value
/api/graph/MY-GRAPH/write (POST)
{
"action" : "update-block",
"block": {
"uid": "51v-orCLm",
"string": "new string from the backend",
"open": false,
"heading": 2,
"text-align": "center",
"children-view-type": "numbered"
}
}
curl -X POST "https://api.roamresearch.com/api/graph/MY-GRAPH/write" --location-trusted \
-H "accept: application/json" \
-H "Authorization: Bearer roam-graph-token-for-MY-GRAPH-1JN132hnXUYIfso22" \
-H "Content-Type: application/json" \
-d "{\"action\":\"update-block\",\"block\":{\"uid\":\"51v-orCLm\",\"string\":\"new string from the backend\",\"open\":false,\"heading\":2,\"text-align\":\"center\",\"children-view-type\":\"numbered\"}}"
delete-block
block
uid required
message value
"order": 2 in the update-block example request
batch-actions especially, You have to carefully handle this (to know how many requests suceeded)
n actions in a batch action request, the first x could succeed/transact and if then error occurs, the remaining n-x ones would not happen
num-actions-successfully-transacted-before-failure to figure out where exactly in the actions list the error happened
message value
/api/graph/MY-GRAPH/write (POST)
{
"action" : "delete-block",
"block": {
"uid": "7yYBPW-WO"
}
}
curl -X POST "https://api.roamresearch.com/api/graph/MY-GRAPH/write" --location-trusted \
-H "accept: application/json" \
-H "Authorization: Bearer roam-graph-token-for-MY-GRAPH-1JN132hnXUYIfso22" \
-H "Content-Type: application/json" \
-d "{\"action\":\"update-block\",\"block\":{\"uid\":\"51v-orCLm\",\"string\":\"new string from the backend\",\"open\":false,\"heading\":2,\"text-align\":\"center\",\"children-view-type\":\"numbered\"}}"
create-page
January 21st, 2021 will create a new daily note if it does not yet exist
page
title required
uid optional
children-view-type optional
message value
"order": 2 in the update-block example request
batch-actions especially, You have to carefully handle this (to know how many requests suceeded)
n actions in a batch action request, the first x could succeed/transact and if then error occurs, the remaining n-x ones would not happen
num-actions-successfully-transacted-before-failure to figure out where exactly in the actions list the error happened
message value
/api/graph/MY-GRAPH/write (POST)
{
"action" : "create-page",
"page": {
"title": "List of participants",
"children-view-type": "numbered"
}
}
curl -X POST "https://api.roamresearch.com/api/graph/MY-GRAPH/write" --location-trusted \
-H "accept: application/json" \
-H "Authorization: Bearer roam-graph-token-for-MY-GRAPH-1JN132hnXUYIfso22" \
-H "Content-Type: application/json" \
-d "{\"action\":\"create-page\",\"page\":{\"title\":\"List of participants\",\"children-view-type\":\"numbered\"}}"
update-page
page
uid required
title optional
children-view-type optional
message value
"order": 2 in the update-block example request
batch-actions especially, You have to carefully handle this (to know how many requests suceeded)
n actions in a batch action request, the first x could succeed/transact and if then error occurs, the remaining n-x ones would not happen
num-actions-successfully-transacted-before-failure to figure out where exactly in the actions list the error happened
message value
/api/graph/MY-GRAPH/write (POST)
{
"action" : "update-page",
"page": {
"uid": "xK98D8L7U",
"title": "List of participants (updated)"
}
}
curl -X POST "https://api.roamresearch.com/api/graph/MY-GRAPH/write" --location-trusted \
-H "accept: application/json" \
-H "Authorization: Bearer roam-graph-token-for-MY-GRAPH-1JN132hnXUYIfso22" \
-H "Content-Type: application/json" \
-d "{\"action\":\"update-page\",\"page\":{\"uid\":\"xK98D8L7U\",\"title\":\"List of participants (updated)\"}}"
delete-page
page
uid required
message value
"order": 2 in the update-block example request
batch-actions especially, You have to carefully handle this (to know how many requests suceeded)
n actions in a batch action request, the first x could succeed/transact and if then error occurs, the remaining n-x ones would not happen
num-actions-successfully-transacted-before-failure to figure out where exactly in the actions list the error happened
message value
/api/graph/MY-GRAPH/write (POST)
{
"action" : "delete-page",
"page": {
"uid": "xK98D8L7U"
}
}
curl -X POST "https://api.roamresearch.com/api/graph/MY-GRAPH/write" --location-trusted \
-H "accept: application/json" \
-H "Authorization: Bearer roam-graph-token-for-MY-GRAPH-1JN132hnXUYIfso22" \
-H "Content-Type: application/json" \
-d "{\"action\":\"delete-page\",\"page\":{\"uid\":\"xK98D8L7U\"}}"
batch-actions
batch-actions and pass the actions as a list under the key actions
{
"action": "batch-actions",
"actions": [
{
"action": "create-block"
"location": {...},
"block": {...}
},
{
"action": "write-action-2"
//... params required by write-action-2
},
{
"action": "write-action-3"
//... params required by write-action-3
},
]
}
{
"tempids-to-uids": {
-1: "EBiw8LzPb",
-2: "X4DelKvsP"
}
}
/api/graph/MY-GRAPH/write (POST)
{
"action" : "batch-actions",
"actions": [
{
"action": "create-page",
"page": {
"title": "Batch action test page",
"uid": -1
}
},
{
"action": "create-block",
"location": {
"parent-uid": -1,
"order": "last"
},
"block": {
"string": "First"
}
},
{
"action": "create-block",
"location": {
"parent-uid": -1,
"order": "last"
},
"block": {
"string": "Third"
}
},
{
"action": "create-block",
"location": {
"parent-uid": -1,
"order": "last"
},
"block": {
"string": "Second",
"uid": -2
}
},
{
"action": "move-block",
"block": {
"uid": -2
},
"location": {
"parent-uid": -1,
"order": 1
}
}
]
}
curl -X POST "https://api.roamresearch.com/api/graph/MY-GRAPH/write" --location-trusted \
-H "accept: application/json" \
-H "Authorization: Bearer roam-graph-token-for-MY-GRAPH-1JN132hnXUYIfso22" \
-H "Content-Type: application/json" \
-d "{\"action\":\"batch-actions\",\"actions\":[{\"action\":\"create-page\",\"page\":{\"title\":\"Batch action test page\",\"uid\":-1}},{\"action\":\"create-block\",\"location\":{\"parent-uid\":-1,\"order\":\"last\"},\"block\":{\"string\":\"First\"}},{\"action\":\"create-block\",\"location\":{\"parent-uid\":-1,\"order\":\"last\"},\"block\":{\"string\":\"Third\"}},{\"action\":\"create-block\",\"location\":{\"parent-uid\":-1,\"order\":\"last\"},\"block\":{\"string\":\"Second\",\"uid\":-2}},{\"action\":\"move-block\",\"block\":{\"uid\":-2},\"location\":{\"parent-uid\":-1,\"order\":1}}]}"
{
"tempids-to-uids": {
-1: "EBiw8LzPb",
-2: "X4DelKvsP"
}
}
n actions in a batch action request, the first x could succeed/transact and if then error occurs, the remaining n-x ones would not happen
num-actions-successfully-transacted-before-failure to figure out where exactly in the actions list the error happened
response.body contains
message
message could have a value like "Error in create-block: Block already exists"
batch-error-message
num-actions-successfully-transacted-before-failure
num-actions-successfully-transacted-before-failure would be 2
batch-error-message
message because message returns the technical thing that went wrong, while batch-error-message is more on a meta level
num-actions-successfully-transacted-before-failure actions were successful/transacted. The action immediately after that is the one that failed."
/api/graph/MY-GRAPH/write (POST)
message value
"order": 2 in the update-block example request
batch-actions especially, You have to carefully handle this (to know how many requests suceeded)
n actions in a batch action request, the first x could succeed/transact and if then error occurs, the remaining n-x ones would not happen
num-actions-successfully-transacted-before-failure to figure out where exactly in the actions list the error happened
message value
X-Authorization header instead of the Authorization header
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)
"message": "You are not authenticated" response from the server, which is super confusing unless you go to the console and really look at the requests
fetch or equivalent in my roam/js (i.e. in the browser)
markdown version · view in Roam Research · exported 2026-07-03