productivity
Notion Lua API for KosmoKrator Agents
Agent-facing Lua documentation and function reference for the Notion KosmoKrator integration.Lua Namespace
Agents call this integration through app.integrations.notion.*.
Use lua_read_doc("integrations.notion") inside KosmoKrator to discover the same reference at runtime.
Call Lua from the Headless CLI
Use kosmo integrations:lua when a shell script, CI job, cron job, or another coding CLI should run a deterministic
Notion workflow without starting an interactive agent session.
kosmo integrations:lua --eval 'dump(app.integrations.notion.search({query = "example_query", filter_type = "example_filter_type", sort_direction = "example_sort_direction", page_size = 1, start_cursor = "example_start_cursor"}))' --json kosmo integrations:lua --eval 'print(docs.read("notion"))' --json
kosmo integrations:lua --eval 'print(docs.read("notion.search"))' --json Workflow file
Put repeatable logic in a Lua file, then execute it with JSON output for the calling process.
local notion = app.integrations.notion
local result = notion.search({query = "example_query", filter_type = "example_filter_type", sort_direction = "example_sort_direction", page_size = 1, start_cursor = "example_start_cursor"})
dump(result) kosmo integrations:lua workflow.lua --json
kosmo integrations:lua workflow.lua --force --json integrations:lua exposes app.integrations.notion, app.mcp.*, docs.*, json.*, and regex.*. Use app.integrations.notion.default.* or app.integrations.notion.work.* when you configured named credential accounts.
MCP-only Lua
If the script only needs configured MCP servers and does not need Notion, use the narrower mcp:lua command.
# Use mcp:lua for MCP-only scripts; use integrations:lua for this integration namespace.
kosmo mcp:lua --eval 'dump(mcp.servers())' --json Agent-Facing Lua Docs
This is the rendered version of the full Lua documentation exposed to agents when they inspect the integration namespace.
Notion — Lua API Reference
Notion is a workspace for wikis, docs, and databases. This integration lets you search, create, update, and archive pages; manage databases and query rows; manipulate content blocks; read users; and work with comments — all from Lua scripts.
Authentication
Uses a Notion Internal Integration Secret (starts with secret_…). Configure it in your integration settings. The integration must be explicitly shared with any pages or databases you want to access — in Notion, open a page → ⋯ → Connections → add your integration. Unshared resources return object_not_found errors.
Overview
All tools are called via app.integrations.notion.<tool_name>({ ... }). Every function takes a single Lua table of named parameters and returns a result table.
local result = app.integrations.notion.search({ query = "meeting notes" })
Errors surface as result.error (string). Check for it before using the response.
Search
app.integrations.notion.search(...)
Search pages and databases in the Notion workspace. Returns matching results with IDs, types, titles, and URLs.
| Name | Type | Required | Description |
|---|---|---|---|
query | string | no | Search query text |
filter_type | string | no | Filter by object type: "page" or "database" |
sort_direction | string | no | "ascending" or "descending" (default: descending by last edited time) |
page_size | integer | no | Results per page, max 100, default 10 |
start_cursor | string | no | Pagination cursor from a previous response |
-- Search for pages matching "meeting notes"
local result = app.integrations.notion.search({
query = "meeting notes",
filter_type = "page",
page_size = 5
})
for _, item in ipairs(result.results) do
print(item.title, item.url)
end
-- Search for databases only, sorted oldest first
local result = app.integrations.notion.search({
filter_type = "database",
sort_direction = "ascending"
})
Pages
app.integrations.notion.create_page(...)
Create a new page in Notion — either as a row in a database or as a sub-page under another page.
| Name | Type | Required | Description |
|---|---|---|---|
parent_type | string | yes | "database" or "page" |
parent_id | string | yes | ID of the parent database or page |
properties | string | no | Page properties as a JSON object. For database parents, keys must match database property names |
children | string | no | Page content as a JSON array of block objects |
-- Create a database row (page in a database)
local result = app.integrations.notion.create_page({
parent_type = "database",
parent_id = "abc123def456",
properties = '{"Name": {"title": [{"text": {"content": "New Task"}}]}, "Status": {"select": {"name": "Todo"}}}'
})
print(result.id, result.url)
-- Create a sub-page under an existing page with content
local result = app.integrations.notion.create_page({
parent_type = "page",
parent_id = "page123abc",
children = '[{"object":"block","type":"heading_2","heading_2":{"rich_text":[{"type":"text","text":{"content":"Section Title"}}]}},{"object":"block","type":"paragraph","paragraph":{"rich_text":[{"type":"text","text":{"content":"Some body text here."}}]}}]'
})
print(result.id, result.url)
app.integrations.notion.get_page(...)
Retrieve a page by its ID. Returns the full page object including properties, title, icon, cover, parent info, and timestamps.
| Name | Type | Required | Description |
|---|---|---|---|
page_id | string | yes | The ID of the page to retrieve |
local result = app.integrations.notion.get_page({
page_id = "abc123def456"
})
print(result.url, result.created_time)
-- result.properties contains all page properties
app.integrations.notion.update_page(...)
Update properties on a page and/or change its archived status.
| Name | Type | Required | Description |
|---|---|---|---|
page_id | string | yes | The ID of the page to update |
properties | string | no | Properties to update as a JSON object matching the page/database schema |
archived | boolean | no | Set to true to archive or false to unarchive |
-- Update a page's Status property
local result = app.integrations.notion.update_page({
page_id = "abc123def456",
properties = '{"Status": {"select": {"name": "Done"}}}'
})
print(result.id, result.last_edited_time)
-- Unarchive a previously archived page
local result = app.integrations.notion.update_page({
page_id = "abc123def456",
archived = false
})
app.integrations.notion.archive_page(...)
Archive a page by setting its archived flag to true. To restore, use notion_update_page with archived = false.
| Name | Type | Required | Description |
|---|---|---|---|
page_id | string | yes | The ID of the page to archive |
local result = app.integrations.notion.archive_page({
page_id = "abc123def456"
})
print(result.id, result.archived)
Databases
app.integrations.notion.create_database(...)
Create a new database as a child of a page. You define the property schema (columns) at creation time.
| Name | Type | Required | Description |
|---|---|---|---|
parent_id | string | yes | ID of the parent page where the database will be created |
title | string | yes | Title of the new database |
properties | string | yes | Database property schema as a JSON object. Each key is a property name with its type configuration |
local result = app.integrations.notion.create_database({
parent_id = "page123abc",
title = "Project Tracker",
properties = '{"Name": {"title": {}}, "Status": {"select": {"options": [{"name": "Todo"}, {"name": "In Progress"}, {"name": "Done"}]}}, "Priority": {"select": {"options": [{"name": "Low"}, {"name": "Medium"}, {"name": "High"}]}}, "Due Date": {"date": {}}}'
})
print(result.id, result.url)
app.integrations.notion.get_database(...)
Retrieve a database’s full schema by its ID, including all property definitions (columns), title, and parent info.
| Name | Type | Required | Description |
|---|---|---|---|
database_id | string | yes | The ID of the database to retrieve |
local result = app.integrations.notion.get_database({
database_id = "db123abc456"
})
-- result.properties contains all column definitions
-- result.title contains the database title
app.integrations.notion.update_database(...)
Update a database’s title and/or property schema. Only included fields are changed.
| Name | Type | Required | Description |
|---|---|---|---|
database_id | string | yes | The ID of the database to update |
title | string | no | New title for the database |
properties | string | no | Updated property schema as a JSON object. Only included properties will be changed |
-- Rename the database and add a new column
local result = app.integrations.notion.update_database({
database_id = "db123abc456",
title = "Project Tracker 2025",
properties = '{"Tags": {"multi_select": {"options": [{"name": "Design"}, {"name": "Engineering"}, {"name": "Marketing"}]}}}'
})
app.integrations.notion.query_database(...)
Query a database to retrieve rows (pages). Supports filtering, sorting, and pagination.
| Name | Type | Required | Description |
|---|---|---|---|
database_id | string | yes | The ID of the database to query |
filter | string | no | Filter condition as a JSON object, e.g. {"property": "Status", "select": {"equals": "Done"}} |
sorts | string | no | Sort rules as a JSON array, e.g. [{"property": "Name", "direction": "ascending"}] |
page_size | integer | no | Number of results per page (max 100, default 100) |
start_cursor | string | no | Pagination cursor from a previous response |
-- Query tasks where Status is "Todo", sorted by Due Date
local result = app.integrations.notion.query_database({
database_id = "db123abc456",
filter = '{"property": "Status", "select": {"equals": "Todo"}}',
sorts = '[{"property": "Due Date", "direction": "ascending"}]',
page_size = 25
})
print("Found " .. result.count .. " tasks")
for _, row in ipairs(result.results) do
print(row.id, row.url)
end
-- Compound filter: Status is "In Progress" AND Priority is "High"
local result = app.integrations.notion.query_database({
database_id = "db123abc456",
filter = '{"and": [{"property": "Status", "select": {"equals": "In Progress"}}, {"property": "Priority", "select": {"equals": "High"}}]}'
})
app.integrations.notion.list_databases(...)
List all databases accessible to the integration. Uses the search endpoint filtered to database objects. Optionally filter by name.
| Name | Type | Required | Description |
|---|---|---|---|
query | string | no | Search query to filter database names |
page_size | integer | no | Number of results per page (max 100, default 10) |
start_cursor | string | no | Pagination cursor from a previous response |
local result = app.integrations.notion.list_databases({
query = "projects"
})
for _, db in ipairs(result.databases) do
print(db.id, db.title, db.url)
end
Blocks
app.integrations.notion.get_block_children(...)
Get the child blocks of a page or block. Returns a list of block objects with IDs, types, and has_children flags. Supports pagination.
| Name | Type | Required | Description |
|---|---|---|---|
block_id | string | yes | ID of the block or page to get children for |
page_size | integer | no | Number of results per page (max 100, default 100) |
start_cursor | string | no | Pagination cursor from a previous response |
-- Read all top-level blocks on a page
local result = app.integrations.notion.get_block_children({
block_id = "page123abc",
page_size = 100
})
for _, block in ipairs(result.results) do
print(block.id, block.type, block.has_children)
end
-- result.raw contains the full block data including text content
app.integrations.notion.append_block_children(...)
Append blocks to a page or existing block. Provide children as a JSON array of block objects.
| Name | Type | Required | Description |
|---|---|---|---|
block_id | string | yes | ID of the parent block or page to append children to |
children | string | yes | Array of block objects to append, as a JSON string |
-- Add a heading and a paragraph to a page
local result = app.integrations.notion.append_block_children({
block_id = "page123abc",
children = '[{"object":"block","type":"heading_2","heading_2":{"rich_text":[{"type":"text","text":{"content":"New Section"}}]}},{"object":"block","type":"paragraph","paragraph":{"rich_text":[{"type":"text","text":{"content":"Content goes here."}}]}}]'
})
print("Appended " .. result.count .. " blocks")
-- Add a to-do list
local result = app.integrations.notion.append_block_children({
block_id = "page123abc",
children = '[{"object":"block","type":"to_do","to_do":{"rich_text":[{"type":"text","text":{"content":"Review draft"}}],"checked":false}},{"object":"block","type":"to_do","to_do":{"rich_text":[{"type":"text","text":{"content":"Submit for approval"}}],"checked":false}}]'
})
-- Add a bulleted list
local result = app.integrations.notion.append_block_children({
block_id = "page123abc",
children = '[{"object":"block","type":"bulleted_list_item","bulleted_list_item":{"rich_text":[{"type":"text","text":{"content":"First item"}}]}},{"object":"block","type":"bulleted_list_item","bulleted_list_item":{"rich_text":[{"type":"text","text":{"content":"Second item"}}]}}]'
})
app.integrations.notion.get_block(...)
Retrieve a single block by its ID. Returns the full block object including type-specific content, has_children, and parent info.
| Name | Type | Required | Description |
|---|---|---|---|
block_id | string | yes | The ID of the block to retrieve |
local result = app.integrations.notion.get_block({
block_id = "block123abc"
})
print(result.id, result.type, result.has_children)
-- Type-specific content is under result[result.type]
-- e.g. result.paragraph.rich_text for a paragraph block
app.integrations.notion.update_block(...)
Update a block’s content or archived state. Provide the block type and type-specific content to change.
| Name | Type | Required | Description |
|---|---|---|---|
block_id | string | yes | The ID of the block to update |
type | string | no | Block type to update (e.g. "paragraph", "heading_1", "to_do") |
content | string | no | Type-specific content as a JSON object, e.g. '{"rich_text": [{"text": {"content": "Updated text"}}]}' |
archived | boolean | no | Set to true to archive the block |
-- Update a paragraph block's text
local result = app.integrations.notion.update_block({
block_id = "block123abc",
type = "paragraph",
content = '{"rich_text": [{"text": {"content": "Updated paragraph text."}}]}'
})
print(result.id, result.type, result.updated)
-- Check a to-do item
local result = app.integrations.notion.update_block({
block_id = "block123abc",
type = "to_do",
content = '{"rich_text": [{"text": {"content": "Review draft"}}], "checked": true}'
})
app.integrations.notion.delete_block(...)
Delete a block by its ID. Permanently removes the block (top-level pages are moved to trash).
| Name | Type | Required | Description |
|---|---|---|---|
block_id | string | yes | The ID of the block to delete |
local result = app.integrations.notion.delete_block({
block_id = "block123abc"
})
print(result.id, result.deleted)
Users
app.integrations.notion.get_current_user(...)
Get information about the current integration bot user. Returns the bot’s name, avatar, and workspace info.
| Name | Type | Required | Description |
|---|---|---|---|
| (none) |
local result = app.integrations.notion.get_current_user({})
print(result.name, result.type, result.avatar_url)
-- result.bot contains bot-specific info
app.integrations.notion.list_users(...)
List all users in the Notion workspace. Returns user IDs, names, types, and avatar URLs. Supports pagination.
| Name | Type | Required | Description |
|---|---|---|---|
page_size | integer | no | Number of results per page (max 100, default 100) |
start_cursor | string | no | Pagination cursor from a previous response |
local result = app.integrations.notion.list_users({
page_size = 50
})
for _, user in ipairs(result.users) do
print(user.id, user.name, user.type)
end
app.integrations.notion.get_user(...)
Retrieve a single user by their ID. Returns name, type, avatar URL, and email (if available).
| Name | Type | Required | Description |
|---|---|---|---|
user_id | string | yes | The ID of the user to retrieve |
local result = app.integrations.notion.get_user({
user_id = "user123abc"
})
print(result.name, result.type, result.avatar_url)
Comments
app.integrations.notion.create_comment(...)
Create a comment on a Notion page. Start a new discussion with parent_id, or reply to an existing discussion with discussion_id.
| Name | Type | Required | Description |
|---|---|---|---|
parent_id | string | conditional | Page ID to comment on. Required if discussion_id is not provided |
discussion_id | string | conditional | Discussion ID to reply to. Required if parent_id is not provided |
body_text | string | conditional | Simple text content for the comment. Required if body_children is not provided |
body_children | string | conditional | Rich text block content as a JSON array. Required if body_text is not provided |
-- Add a simple text comment to a page
local result = app.integrations.notion.create_comment({
parent_id = "page123abc",
body_text = "Looks good to me! Ready to merge."
})
print(result.id, result.created_time)
-- Reply to an existing discussion with rich content
local result = app.integrations.notion.create_comment({
discussion_id = "discussion789",
body_children = '[{"text": {"content": "Updated with "}}, {"text": {"content": "new findings"}, "annotations": {"bold": true}}]'
})
app.integrations.notion.get_comments(...)
Retrieve all comments on a page or block. Returns comment text, authors, timestamps, and discussion IDs. Supports pagination.
| Name | Type | Required | Description |
|---|---|---|---|
block_id | string | yes | The ID of the block or page to get comments for |
page_size | integer | no | Number of results per page (max 100, default 100) |
start_cursor | string | no | Pagination cursor from a previous response |
local result = app.integrations.notion.get_comments({
block_id = "page123abc"
})
for _, comment in ipairs(result.comments) do
print(comment.created_time, comment.text, comment.created_by.id)
end
Pagination
Several endpoints return paginated results. When has_more is true, use next_cursor to fetch the next page.
local all_results = {}
local cursor = nil
repeat
local params = {
database_id = "db123abc456",
page_size = 100
}
if cursor then
params.start_cursor = cursor
end
local result = app.integrations.notion.query_database(params)
for _, row in ipairs(result.results) do
table.insert(all_results, row)
end
cursor = result.next_cursor
until not result.has_more
print("Total rows: " .. #all_results)
This pagination pattern applies to:
notion_searchnotion_query_databasenotion_list_databasesnotion_get_block_childrennotion_list_usersnotion_get_comments
Notes
- Object IDs — Notion IDs can be passed with or without hyphens (
abc123def456…orabc123de-f456-…). - JSON parameters — Complex structures (
properties,filter,sorts,children,content) are passed as JSON strings. Use single-quoted Lua strings to wrap JSON. - Block types — Common block types:
paragraph,heading_1,heading_2,heading_3,bulleted_list_item,numbered_list_item,to_do,toggle,quote,callout,code,divider,image. - Rate limits — The Notion API enforces rate limits (approx. 3 requests/sec). If you hit limits, add delays between calls.
- Integration scope — The integration can only access pages and databases it has been explicitly added to via Connections in Notion.
- Archiving vs. deleting — Pages are archived (recoverable). Blocks are permanently deleted.
- Database rows are pages — Each row in a Notion database is a page object. Use
notion_query_databaseto list rows andnotion_update_pageto modify row properties.
Multi-Account Usage
If you have multiple notion accounts configured, use account-specific namespaces:
-- Default account (always works)
app.integrations.notion.function_name({...})
-- Explicit default (portable across setups)
app.integrations.notion.default.function_name({...})
-- Named accounts
app.integrations.notion.work.function_name({...})
app.integrations.notion.personal.function_name({...})
All functions are identical across accounts — only the credentials differ.
Raw agent markdown
# Notion — Lua API Reference
Notion is a workspace for wikis, docs, and databases. This integration lets you search, create, update, and archive pages; manage databases and query rows; manipulate content blocks; read users; and work with comments — all from Lua scripts.
## Authentication
Uses a **Notion Internal Integration Secret** (starts with `secret_…`). Configure it in your integration settings. The integration must be explicitly shared with any pages or databases you want to access — in Notion, open a page → **⋯** → **Connections** → add your integration. Unshared resources return `object_not_found` errors.
---
## Overview
All tools are called via `app.integrations.notion.<tool_name>({ ... })`. Every function takes a single Lua table of named parameters and returns a result table.
```lua
local result = app.integrations.notion.search({ query = "meeting notes" })
```
Errors surface as `result.error` (string). Check for it before using the response.
---
## Search
### `app.integrations.notion.search(...)`
Search pages and databases in the Notion workspace. Returns matching results with IDs, types, titles, and URLs.
| Name | Type | Required | Description |
|------|------|----------|-------------|
| `query` | string | no | Search query text |
| `filter_type` | string | no | Filter by object type: `"page"` or `"database"` |
| `sort_direction` | string | no | `"ascending"` or `"descending"` (default: descending by last edited time) |
| `page_size` | integer | no | Results per page, max 100, default 10 |
| `start_cursor` | string | no | Pagination cursor from a previous response |
```lua
-- Search for pages matching "meeting notes"
local result = app.integrations.notion.search({
query = "meeting notes",
filter_type = "page",
page_size = 5
})
for _, item in ipairs(result.results) do
print(item.title, item.url)
end
```
```lua
-- Search for databases only, sorted oldest first
local result = app.integrations.notion.search({
filter_type = "database",
sort_direction = "ascending"
})
```
---
## Pages
### `app.integrations.notion.create_page(...)`
Create a new page in Notion — either as a row in a database or as a sub-page under another page.
| Name | Type | Required | Description |
|------|------|----------|-------------|
| `parent_type` | string | yes | `"database"` or `"page"` |
| `parent_id` | string | yes | ID of the parent database or page |
| `properties` | string | no | Page properties as a JSON object. For database parents, keys must match database property names |
| `children` | string | no | Page content as a JSON array of block objects |
```lua
-- Create a database row (page in a database)
local result = app.integrations.notion.create_page({
parent_type = "database",
parent_id = "abc123def456",
properties = '{"Name": {"title": [{"text": {"content": "New Task"}}]}, "Status": {"select": {"name": "Todo"}}}'
})
print(result.id, result.url)
```
```lua
-- Create a sub-page under an existing page with content
local result = app.integrations.notion.create_page({
parent_type = "page",
parent_id = "page123abc",
children = '[{"object":"block","type":"heading_2","heading_2":{"rich_text":[{"type":"text","text":{"content":"Section Title"}}]}},{"object":"block","type":"paragraph","paragraph":{"rich_text":[{"type":"text","text":{"content":"Some body text here."}}]}}]'
})
print(result.id, result.url)
```
### `app.integrations.notion.get_page(...)`
Retrieve a page by its ID. Returns the full page object including properties, title, icon, cover, parent info, and timestamps.
| Name | Type | Required | Description |
|------|------|----------|-------------|
| `page_id` | string | yes | The ID of the page to retrieve |
```lua
local result = app.integrations.notion.get_page({
page_id = "abc123def456"
})
print(result.url, result.created_time)
-- result.properties contains all page properties
```
### `app.integrations.notion.update_page(...)`
Update properties on a page and/or change its archived status.
| Name | Type | Required | Description |
|------|------|----------|-------------|
| `page_id` | string | yes | The ID of the page to update |
| `properties` | string | no | Properties to update as a JSON object matching the page/database schema |
| `archived` | boolean | no | Set to `true` to archive or `false` to unarchive |
```lua
-- Update a page's Status property
local result = app.integrations.notion.update_page({
page_id = "abc123def456",
properties = '{"Status": {"select": {"name": "Done"}}}'
})
print(result.id, result.last_edited_time)
```
```lua
-- Unarchive a previously archived page
local result = app.integrations.notion.update_page({
page_id = "abc123def456",
archived = false
})
```
### `app.integrations.notion.archive_page(...)`
Archive a page by setting its archived flag to `true`. To restore, use `notion_update_page` with `archived = false`.
| Name | Type | Required | Description |
|------|------|----------|-------------|
| `page_id` | string | yes | The ID of the page to archive |
```lua
local result = app.integrations.notion.archive_page({
page_id = "abc123def456"
})
print(result.id, result.archived)
```
---
## Databases
### `app.integrations.notion.create_database(...)`
Create a new database as a child of a page. You define the property schema (columns) at creation time.
| Name | Type | Required | Description |
|------|------|----------|-------------|
| `parent_id` | string | yes | ID of the parent page where the database will be created |
| `title` | string | yes | Title of the new database |
| `properties` | string | yes | Database property schema as a JSON object. Each key is a property name with its type configuration |
```lua
local result = app.integrations.notion.create_database({
parent_id = "page123abc",
title = "Project Tracker",
properties = '{"Name": {"title": {}}, "Status": {"select": {"options": [{"name": "Todo"}, {"name": "In Progress"}, {"name": "Done"}]}}, "Priority": {"select": {"options": [{"name": "Low"}, {"name": "Medium"}, {"name": "High"}]}}, "Due Date": {"date": {}}}'
})
print(result.id, result.url)
```
### `app.integrations.notion.get_database(...)`
Retrieve a database's full schema by its ID, including all property definitions (columns), title, and parent info.
| Name | Type | Required | Description |
|------|------|----------|-------------|
| `database_id` | string | yes | The ID of the database to retrieve |
```lua
local result = app.integrations.notion.get_database({
database_id = "db123abc456"
})
-- result.properties contains all column definitions
-- result.title contains the database title
```
### `app.integrations.notion.update_database(...)`
Update a database's title and/or property schema. Only included fields are changed.
| Name | Type | Required | Description |
|------|------|----------|-------------|
| `database_id` | string | yes | The ID of the database to update |
| `title` | string | no | New title for the database |
| `properties` | string | no | Updated property schema as a JSON object. Only included properties will be changed |
```lua
-- Rename the database and add a new column
local result = app.integrations.notion.update_database({
database_id = "db123abc456",
title = "Project Tracker 2025",
properties = '{"Tags": {"multi_select": {"options": [{"name": "Design"}, {"name": "Engineering"}, {"name": "Marketing"}]}}}'
})
```
### `app.integrations.notion.query_database(...)`
Query a database to retrieve rows (pages). Supports filtering, sorting, and pagination.
| Name | Type | Required | Description |
|------|------|----------|-------------|
| `database_id` | string | yes | The ID of the database to query |
| `filter` | string | no | Filter condition as a JSON object, e.g. `{"property": "Status", "select": {"equals": "Done"}}` |
| `sorts` | string | no | Sort rules as a JSON array, e.g. `[{"property": "Name", "direction": "ascending"}]` |
| `page_size` | integer | no | Number of results per page (max 100, default 100) |
| `start_cursor` | string | no | Pagination cursor from a previous response |
```lua
-- Query tasks where Status is "Todo", sorted by Due Date
local result = app.integrations.notion.query_database({
database_id = "db123abc456",
filter = '{"property": "Status", "select": {"equals": "Todo"}}',
sorts = '[{"property": "Due Date", "direction": "ascending"}]',
page_size = 25
})
print("Found " .. result.count .. " tasks")
for _, row in ipairs(result.results) do
print(row.id, row.url)
end
```
```lua
-- Compound filter: Status is "In Progress" AND Priority is "High"
local result = app.integrations.notion.query_database({
database_id = "db123abc456",
filter = '{"and": [{"property": "Status", "select": {"equals": "In Progress"}}, {"property": "Priority", "select": {"equals": "High"}}]}'
})
```
### `app.integrations.notion.list_databases(...)`
List all databases accessible to the integration. Uses the search endpoint filtered to database objects. Optionally filter by name.
| Name | Type | Required | Description |
|------|------|----------|-------------|
| `query` | string | no | Search query to filter database names |
| `page_size` | integer | no | Number of results per page (max 100, default 10) |
| `start_cursor` | string | no | Pagination cursor from a previous response |
```lua
local result = app.integrations.notion.list_databases({
query = "projects"
})
for _, db in ipairs(result.databases) do
print(db.id, db.title, db.url)
end
```
---
## Blocks
### `app.integrations.notion.get_block_children(...)`
Get the child blocks of a page or block. Returns a list of block objects with IDs, types, and `has_children` flags. Supports pagination.
| Name | Type | Required | Description |
|------|------|----------|-------------|
| `block_id` | string | yes | ID of the block or page to get children for |
| `page_size` | integer | no | Number of results per page (max 100, default 100) |
| `start_cursor` | string | no | Pagination cursor from a previous response |
```lua
-- Read all top-level blocks on a page
local result = app.integrations.notion.get_block_children({
block_id = "page123abc",
page_size = 100
})
for _, block in ipairs(result.results) do
print(block.id, block.type, block.has_children)
end
-- result.raw contains the full block data including text content
```
### `app.integrations.notion.append_block_children(...)`
Append blocks to a page or existing block. Provide `children` as a JSON array of block objects.
| Name | Type | Required | Description |
|------|------|----------|-------------|
| `block_id` | string | yes | ID of the parent block or page to append children to |
| `children` | string | yes | Array of block objects to append, as a JSON string |
```lua
-- Add a heading and a paragraph to a page
local result = app.integrations.notion.append_block_children({
block_id = "page123abc",
children = '[{"object":"block","type":"heading_2","heading_2":{"rich_text":[{"type":"text","text":{"content":"New Section"}}]}},{"object":"block","type":"paragraph","paragraph":{"rich_text":[{"type":"text","text":{"content":"Content goes here."}}]}}]'
})
print("Appended " .. result.count .. " blocks")
```
```lua
-- Add a to-do list
local result = app.integrations.notion.append_block_children({
block_id = "page123abc",
children = '[{"object":"block","type":"to_do","to_do":{"rich_text":[{"type":"text","text":{"content":"Review draft"}}],"checked":false}},{"object":"block","type":"to_do","to_do":{"rich_text":[{"type":"text","text":{"content":"Submit for approval"}}],"checked":false}}]'
})
```
```lua
-- Add a bulleted list
local result = app.integrations.notion.append_block_children({
block_id = "page123abc",
children = '[{"object":"block","type":"bulleted_list_item","bulleted_list_item":{"rich_text":[{"type":"text","text":{"content":"First item"}}]}},{"object":"block","type":"bulleted_list_item","bulleted_list_item":{"rich_text":[{"type":"text","text":{"content":"Second item"}}]}}]'
})
```
### `app.integrations.notion.get_block(...)`
Retrieve a single block by its ID. Returns the full block object including type-specific content, `has_children`, and parent info.
| Name | Type | Required | Description |
|------|------|----------|-------------|
| `block_id` | string | yes | The ID of the block to retrieve |
```lua
local result = app.integrations.notion.get_block({
block_id = "block123abc"
})
print(result.id, result.type, result.has_children)
-- Type-specific content is under result[result.type]
-- e.g. result.paragraph.rich_text for a paragraph block
```
### `app.integrations.notion.update_block(...)`
Update a block's content or archived state. Provide the block type and type-specific content to change.
| Name | Type | Required | Description |
|------|------|----------|-------------|
| `block_id` | string | yes | The ID of the block to update |
| `type` | string | no | Block type to update (e.g. `"paragraph"`, `"heading_1"`, `"to_do"`) |
| `content` | string | no | Type-specific content as a JSON object, e.g. `'{"rich_text": [{"text": {"content": "Updated text"}}]}'` |
| `archived` | boolean | no | Set to `true` to archive the block |
```lua
-- Update a paragraph block's text
local result = app.integrations.notion.update_block({
block_id = "block123abc",
type = "paragraph",
content = '{"rich_text": [{"text": {"content": "Updated paragraph text."}}]}'
})
print(result.id, result.type, result.updated)
```
```lua
-- Check a to-do item
local result = app.integrations.notion.update_block({
block_id = "block123abc",
type = "to_do",
content = '{"rich_text": [{"text": {"content": "Review draft"}}], "checked": true}'
})
```
### `app.integrations.notion.delete_block(...)`
Delete a block by its ID. Permanently removes the block (top-level pages are moved to trash).
| Name | Type | Required | Description |
|------|------|----------|-------------|
| `block_id` | string | yes | The ID of the block to delete |
```lua
local result = app.integrations.notion.delete_block({
block_id = "block123abc"
})
print(result.id, result.deleted)
```
---
## Users
### `app.integrations.notion.get_current_user(...)`
Get information about the current integration bot user. Returns the bot's name, avatar, and workspace info.
| Name | Type | Required | Description |
|------|------|----------|-------------|
| *(none)* | | | |
```lua
local result = app.integrations.notion.get_current_user({})
print(result.name, result.type, result.avatar_url)
-- result.bot contains bot-specific info
```
### `app.integrations.notion.list_users(...)`
List all users in the Notion workspace. Returns user IDs, names, types, and avatar URLs. Supports pagination.
| Name | Type | Required | Description |
|------|------|----------|-------------|
| `page_size` | integer | no | Number of results per page (max 100, default 100) |
| `start_cursor` | string | no | Pagination cursor from a previous response |
```lua
local result = app.integrations.notion.list_users({
page_size = 50
})
for _, user in ipairs(result.users) do
print(user.id, user.name, user.type)
end
```
### `app.integrations.notion.get_user(...)`
Retrieve a single user by their ID. Returns name, type, avatar URL, and email (if available).
| Name | Type | Required | Description |
|------|------|----------|-------------|
| `user_id` | string | yes | The ID of the user to retrieve |
```lua
local result = app.integrations.notion.get_user({
user_id = "user123abc"
})
print(result.name, result.type, result.avatar_url)
```
---
## Comments
### `app.integrations.notion.create_comment(...)`
Create a comment on a Notion page. Start a new discussion with `parent_id`, or reply to an existing discussion with `discussion_id`.
| Name | Type | Required | Description |
|------|------|----------|-------------|
| `parent_id` | string | conditional | Page ID to comment on. Required if `discussion_id` is not provided |
| `discussion_id` | string | conditional | Discussion ID to reply to. Required if `parent_id` is not provided |
| `body_text` | string | conditional | Simple text content for the comment. Required if `body_children` is not provided |
| `body_children` | string | conditional | Rich text block content as a JSON array. Required if `body_text` is not provided |
```lua
-- Add a simple text comment to a page
local result = app.integrations.notion.create_comment({
parent_id = "page123abc",
body_text = "Looks good to me! Ready to merge."
})
print(result.id, result.created_time)
```
```lua
-- Reply to an existing discussion with rich content
local result = app.integrations.notion.create_comment({
discussion_id = "discussion789",
body_children = '[{"text": {"content": "Updated with "}}, {"text": {"content": "new findings"}, "annotations": {"bold": true}}]'
})
```
### `app.integrations.notion.get_comments(...)`
Retrieve all comments on a page or block. Returns comment text, authors, timestamps, and discussion IDs. Supports pagination.
| Name | Type | Required | Description |
|------|------|----------|-------------|
| `block_id` | string | yes | The ID of the block or page to get comments for |
| `page_size` | integer | no | Number of results per page (max 100, default 100) |
| `start_cursor` | string | no | Pagination cursor from a previous response |
```lua
local result = app.integrations.notion.get_comments({
block_id = "page123abc"
})
for _, comment in ipairs(result.comments) do
print(comment.created_time, comment.text, comment.created_by.id)
end
```
---
## Pagination
Several endpoints return paginated results. When `has_more` is `true`, use `next_cursor` to fetch the next page.
```lua
local all_results = {}
local cursor = nil
repeat
local params = {
database_id = "db123abc456",
page_size = 100
}
if cursor then
params.start_cursor = cursor
end
local result = app.integrations.notion.query_database(params)
for _, row in ipairs(result.results) do
table.insert(all_results, row)
end
cursor = result.next_cursor
until not result.has_more
print("Total rows: " .. #all_results)
```
This pagination pattern applies to:
- `notion_search`
- `notion_query_database`
- `notion_list_databases`
- `notion_get_block_children`
- `notion_list_users`
- `notion_get_comments`
---
## Notes
- **Object IDs** — Notion IDs can be passed with or without hyphens (`abc123def456…` or `abc123de-f456-…`).
- **JSON parameters** — Complex structures (`properties`, `filter`, `sorts`, `children`, `content`) are passed as JSON strings. Use single-quoted Lua strings to wrap JSON.
- **Block types** — Common block types: `paragraph`, `heading_1`, `heading_2`, `heading_3`, `bulleted_list_item`, `numbered_list_item`, `to_do`, `toggle`, `quote`, `callout`, `code`, `divider`, `image`.
- **Rate limits** — The Notion API enforces rate limits (approx. 3 requests/sec). If you hit limits, add delays between calls.
- **Integration scope** — The integration can only access pages and databases it has been explicitly added to via **Connections** in Notion.
- **Archiving vs. deleting** — Pages are archived (recoverable). Blocks are permanently deleted.
- **Database rows are pages** — Each row in a Notion database is a page object. Use `notion_query_database` to list rows and `notion_update_page` to modify row properties.
---
## Multi-Account Usage
If you have multiple notion accounts configured, use account-specific namespaces:
```lua
-- Default account (always works)
app.integrations.notion.function_name({...})
-- Explicit default (portable across setups)
app.integrations.notion.default.function_name({...})
-- Named accounts
app.integrations.notion.work.function_name({...})
app.integrations.notion.personal.function_name({...})
```
All functions are identical across accounts — only the credentials differ. local result = app.integrations.notion.search({query = "example_query", filter_type = "example_filter_type", sort_direction = "example_sort_direction", page_size = 1, start_cursor = "example_start_cursor"})
print(result) Functions
search Read
Search pages and databases in your Notion workspace. Returns matching results with their IDs, types, and titles. Optionally filter by type (page or database) and control sort direction.
- Lua path
app.integrations.notion.search- Full name
notion.notion_search
| Parameter | Type | Required | Description |
|---|---|---|---|
query | string | no | Search query text. |
filter_type | string | no | Filter results by type: "page" or "database". |
sort_direction | string | no | Sort direction: "ascending" or "descending". Defaults to descending (last edited first). |
page_size | integer | no | Number of results per page (max 100, default 10). |
start_cursor | string | no | Pagination cursor from a previous response. |
create_page Write
Create a new page in Notion. The page can be created as a child of a database (to create a row) or as a child of another page (to create a sub-page). Provide properties as a JSON object matching the database schema when using a database parent. Provide children (block content) as a JSON array of block objects.
- Lua path
app.integrations.notion.create_page- Full name
notion.notion_create_page
| Parameter | Type | Required | Description |
|---|---|---|---|
parent_type | string | yes | Parent type: "database" or "page". |
parent_id | string | yes | ID of the parent database or page. |
properties | string | no | Page properties as a JSON object. For database parents, keys should match database property names. |
children | string | no | Page content as a JSON array of block objects. |
get_page Read
Retrieve a Notion page by its ID. Returns the page object with properties, including title, icon, cover, parent info, and timestamps.
- Lua path
app.integrations.notion.get_page- Full name
notion.notion_get_page
| Parameter | Type | Required | Description |
|---|---|---|---|
page_id | string | yes | The ID of the page to retrieve. |
update_page Write
Update properties on a Notion page. Provide properties as a JSON object matching the database/page schema. Can also archive/unarchive the page.
- Lua path
app.integrations.notion.update_page- Full name
notion.notion_update_page
| Parameter | Type | Required | Description |
|---|---|---|---|
page_id | string | yes | The ID of the page to update. |
properties | string | no | Properties to update as a JSON object. |
archived | boolean | no | Whether to archive the page. |
archive_page Write
Archive a Notion page by setting its archived flag to true. The page can be restored by using notion_update_page with archived=false.
- Lua path
app.integrations.notion.archive_page- Full name
notion.notion_archive_page
| Parameter | Type | Required | Description |
|---|---|---|---|
page_id | string | yes | The ID of the page to archive. |
create_database Write
Create a new database as a child of a page. Provide the parent page ID, a title, and a properties schema. Properties define the columns of the database. Example properties: {"Name": {"title": {}}, "Status": {"select": {"options": [{"name": "Todo"}, {"name": "Done"}]}}}.
- Lua path
app.integrations.notion.create_database- Full name
notion.notion_create_database
| Parameter | Type | Required | Description |
|---|---|---|---|
parent_id | string | yes | ID of the parent page where the database will be created. |
title | string | yes | Title of the database. |
properties | string | yes | Database property schema as a JSON object. Each key is a property name with its type config. |
get_database Read
Retrieve a Notion database by its ID. Returns the full database schema including all property definitions (columns), title, and parent info.
- Lua path
app.integrations.notion.get_database- Full name
notion.notion_get_database
| Parameter | Type | Required | Description |
|---|---|---|---|
database_id | string | yes | The ID of the database to retrieve. |
update_database Write
Update a Notion database's title and/or property schema. Provide a new title and/or modified properties as a JSON object.
- Lua path
app.integrations.notion.update_database- Full name
notion.notion_update_database
| Parameter | Type | Required | Description |
|---|---|---|---|
database_id | string | yes | The ID of the database to update. |
title | string | no | New title for the database. |
properties | string | no | Updated property schema as a JSON object. Only included properties will be updated. |
query_database Read
Query a Notion database to retrieve rows (pages). Supports filtering and sorting. Filter and sorts can be provided as JSON strings or arrays. Example filter: {"property": "Status", "select": {"equals": "Done"}} Example sorts: [{"property": "Name", "direction": "ascending"}]
- Lua path
app.integrations.notion.query_database- Full name
notion.notion_query_database
| Parameter | Type | Required | Description |
|---|---|---|---|
database_id | string | yes | The ID of the database to query. |
filter | string | no | Filter condition as a JSON string or object. |
sorts | string | no | Sort rules as a JSON array string or array. |
page_size | integer | no | Number of results per page (max 100, default 100). |
start_cursor | string | no | Pagination cursor from a previous response. |
list_databases Read
List all databases accessible to the integration. Uses the search endpoint filtered to database objects. Optionally provide a query to filter by name.
- Lua path
app.integrations.notion.list_databases- Full name
notion.notion_list_databases
| Parameter | Type | Required | Description |
|---|---|---|---|
query | string | no | Search query to filter database names. |
page_size | integer | no | Number of results per page (max 100, default 10). |
start_cursor | string | no | Pagination cursor from a previous response. |
get_block_children Read
Get the child blocks of a Notion block or page. Returns a list of block objects. Use this to read the content of a page or to navigate nested block structures. Supports pagination.
- Lua path
app.integrations.notion.get_block_children- Full name
notion.notion_get_block_children
| Parameter | Type | Required | Description |
|---|---|---|---|
block_id | string | yes | ID of the block or page to get children for. |
page_size | integer | no | Number of results per page (max 100, default 100). |
start_cursor | string | no | Pagination cursor from a previous response. |
append_block_children Write
Append blocks to a Notion page or block. Provide children as a JSON array of block objects. Example: [{"object":"block","type":"paragraph","paragraph":{"rich_text":[{"type":"text","text":{"content":"Hello world"}}]}}]
- Lua path
app.integrations.notion.append_block_children- Full name
notion.notion_append_block_children
| Parameter | Type | Required | Description |
|---|---|---|---|
block_id | string | yes | ID of the parent block or page to append children to. |
children | string | yes | Array of block objects to append, as a JSON string or array. |
get_block Read
Retrieve a single Notion block by its ID. Returns the full block object including type-specific content, has_children flag, and parent info.
- Lua path
app.integrations.notion.get_block- Full name
notion.notion_get_block
| Parameter | Type | Required | Description |
|---|---|---|---|
block_id | string | yes | The ID of the block to retrieve. |
update_block Write
Update the content of a Notion block. Provide the block ID and the type-specific content to update. For example, to update a paragraph block, provide: {"type": "paragraph", "paragraph": {"rich_text": [{"text": {"content": "New text"}}]}} Only the fields you include will be updated.
- Lua path
app.integrations.notion.update_block- Full name
notion.notion_update_block
| Parameter | Type | Required | Description |
|---|---|---|---|
block_id | string | yes | The ID of the block to update. |
type | string | no | Block type to update (e.g., "paragraph", "heading_1", "to_do"). |
content | string | no | Type-specific block content as a JSON object. For example: {"rich_text": [{"text": {"content": "Updated text"}}]} |
archived | boolean | no | Whether to archive the block. |
delete_block Write
Delete a Notion block by its ID. This permanently removes the block (moves it to trash if it is a top-level page block).
- Lua path
app.integrations.notion.delete_block- Full name
notion.notion_delete_block
| Parameter | Type | Required | Description |
|---|---|---|---|
block_id | string | yes | The ID of the block to delete. |
get_current_user Read
Get information about the current integration bot user. Returns the bot's name, avatar, and workspace info.
- Lua path
app.integrations.notion.get_current_user- Full name
notion.notion_get_current_user
| Parameter | Type | Required | Description |
|---|---|---|---|
| No parameters. | |||
list_users Read
List all users in the Notion workspace. Returns user IDs, names, types, and avatar URLs. Supports pagination.
- Lua path
app.integrations.notion.list_users- Full name
notion.notion_list_users
| Parameter | Type | Required | Description |
|---|---|---|---|
page_size | integer | no | Number of results per page (max 100, default 100). |
start_cursor | string | no | Pagination cursor from a previous response. |
get_user Read
Retrieve a Notion user by their ID. Returns the user's name, type, avatar URL, and email (if available).
- Lua path
app.integrations.notion.get_user- Full name
notion.notion_get_user
| Parameter | Type | Required | Description |
|---|---|---|---|
user_id | string | yes | The ID of the user to retrieve. |
create_comment Write
Create a comment on a Notion page. You can either start a new discussion (provide parent_id) or reply to an existing discussion (provide discussion_id). Provide body_text for simple text, or body_children for rich content blocks.
- Lua path
app.integrations.notion.create_comment- Full name
notion.notion_create_comment
| Parameter | Type | Required | Description |
|---|---|---|---|
parent_id | string | no | Page ID to create a comment on. Required if discussion_id is not provided. |
discussion_id | string | no | Discussion ID to reply to. Required if parent_id is not provided. |
body_text | string | no | Simple text content for the comment. |
body_children | string | no | Rich text block content as a JSON array of block objects. |
get_comments Read
Retrieve comments on a Notion page or block. Returns all comment objects with their content, authors, and timestamps. Supports pagination.
- Lua path
app.integrations.notion.get_comments- Full name
notion.notion_get_comments
| Parameter | Type | Required | Description |
|---|---|---|---|
block_id | string | yes | The ID of the block or page to get comments for. |
page_size | integer | no | Number of results per page (max 100, default 100). |
start_cursor | string | no | Pagination cursor from a previous response. |