Notion API¶
The Notion API provides endpoints for converting between Markdown and Notion blocks, duplicating Notion blocks, and managing user permissions.
Authentication¶
All Notion API endpoints require authentication using an API key. Include your API key in the X-API-KEY header of your requests.
curl -X POST "https://magic-meal-kits-xxxxx.run.app/api/v1/notion/convert" \
-H "X-API-KEY: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"markdown": "# Hello World\n\nThis is a test."
}'
Additionally, for operations that interact directly with your Notion workspace (like duplication and user management), you need to provide Notion-specific authentication headers:
X-Notion-Space-ID: Your Notion workspace IDX-Notion-User-ID: Your Notion user IDX-Notion-Token: Your Notion token (from the token_v2 cookie)
Make Notion Auth Helper Chrome Extension¶
To simplify the process of obtaining these Notion authentication credentials, we provide the Make Notion Auth Helper Chrome extension. This extension automatically extracts the required Notion authentication values for you.
You can install the extension from the Chrome Web Store: Make Notion Auth Helper
For detailed instructions on using the extension, see the Authentication Guide.
Endpoints¶
Convert Markdown to Notion Blocks¶
Converts Markdown content to Notion blocks format.
POST /api/v1/notion/convert¶
Request Body:
{
"markdown": "# Hello World\n\nThis is a test markdown.\n\n- List item 1\n- List item 2"
}
| Field | Type | Required | Description |
|---|---|---|---|
| markdown | String | Yes | Markdown content to convert |
Example Request:
curl -X POST "https://magic-meal-kits-xxxxx.run.app/api/v1/notion/convert" \
-H "X-API-KEY: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"markdown": "# Hello World\n\nThis is a test markdown.\n\n- List item 1\n- List item 2"
}'
Example Response:
{
"blocks": [
{
"object": "block",
"type": "heading_1",
"heading_1": {
"rich_text": [
{
"type": "text",
"annotations": {
"bold": false,
"strikethrough": false,
"underline": false,
"italic": false,
"code": false,
"color": "default"
},
"text": {
"content": "Hello World"
}
}
]
}
},
{
"object": "block",
"type": "paragraph",
"paragraph": {
"rich_text": [
{
"type": "text",
"annotations": {
"bold": false,
"strikethrough": false,
"underline": false,
"italic": false,
"code": false,
"color": "default"
},
"text": {
"content": "This is a test markdown."
}
}
]
}
},
{
"object": "block",
"type": "bulleted_list_item",
"bulleted_list_item": {
"rich_text": [
{
"type": "text",
"annotations": {
"bold": false,
"strikethrough": false,
"underline": false,
"italic": false,
"code": false,
"color": "default"
},
"text": {
"content": "List item 1"
}
}
]
}
},
{
"object": "block",
"type": "bulleted_list_item",
"bulleted_list_item": {
"rich_text": [
{
"type": "text",
"annotations": {
"bold": false,
"strikethrough": false,
"underline": false,
"italic": false,
"code": false,
"color": "default"
},
"text": {
"content": "List item 2"
}
}
]
}
}
]
}
Convert Notion Blocks to Markdown¶
Converts Notion blocks to Markdown format.
POST /api/v1/notion/convert¶
Request Body:
{
"action": "notion",
"blocks": [
{
"object": "block",
"type": "heading_1",
"heading_1": {
"rich_text": [
{
"type": "text",
"text": {
"content": "Hello World"
}
}
]
}
},
{
"object": "block",
"type": "paragraph",
"paragraph": {
"rich_text": [
{
"type": "text",
"text": {
"content": "This is a test."
}
}
]
}
}
]
}
| Field | Type | Required | Description |
|---|---|---|---|
| action | String | Yes | Must be "notion" for this conversion direction |
| blocks | Array | Yes | Notion blocks to convert to Markdown |
Example Request:
curl -X POST "https://magic-meal-kits-xxxxx.run.app/api/v1/notion/convert" \
-H "X-API-KEY: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"action": "notion",
"blocks": [
{
"object": "block",
"type": "heading_1",
"heading_1": {
"rich_text": [
{
"type": "text",
"text": {
"content": "Hello World"
}
}
]
}
},
{
"object": "block",
"type": "paragraph",
"paragraph": {
"rich_text": [
{
"type": "text",
"text": {
"content": "This is a test."
}
}
]
}
}
]
}'
Example Response:
# Hello World
This is a test.
Duplicate Notion Block¶
Duplicates a Notion block (page, database, etc.) to a specified parent.
POST /api/v1/notion/duplicate¶
Request Headers:
X-API-KEY: your-api-key
X-Notion-Space-ID: your-notion-space-id
X-Notion-User-ID: your-notion-user-id
X-Notion-Token: your-notion-token
Request Body:
{
"parentId": "parent-block-id",
"sourceId": "source-block-id"
}
| Field | Type | Required | Description |
|---|---|---|---|
| parentId | String | Yes | ID of the parent block where the duplicate will be placed |
| sourceId | String | Yes | ID of the block to duplicate |
Example Request:
curl -X POST "https://magic-meal-kits-xxxxx.run.app/api/v1/notion/duplicate" \
-H "X-API-KEY: your-api-key" \
-H "X-Notion-Space-ID: your-notion-space-id" \
-H "X-Notion-User-ID: your-notion-user-id" \
-H "X-Notion-Token: your-notion-token" \
-H "Content-Type: application/json" \
-d '{
"parentId": "parent-block-id",
"sourceId": "source-block-id"
}'
Example Response:
{
"message": "Duplicate request sent successfully",
"parentId": "parent-block-id",
"sourceId": "source-block-id",
"newBlockId": "new-block-id"
}
Invite User to Notion Block¶
Invites a user to a specific Notion block (page, database, etc.) with specified permissions.
POST /api/v1/notion/invite¶
Request Headers:
X-API-KEY: your-api-key
X-Notion-Space-ID: your-notion-space-id
X-Notion-User-ID: your-notion-user-id
X-Notion-Token: your-notion-token
Request Body:
{
"email": "user@example.com",
"role": "editor",
"blockId": "block-id"
}
| Field | Type | Required | Description |
|---|---|---|---|
| String | Yes | Email of the user to invite | |
| role | String | Yes | Permission role (editor, reader, or commenter) |
| blockId | String | Yes | ID of the block to share |
Example Request:
curl -X POST "https://magic-meal-kits-xxxxx.run.app/api/v1/notion/invite" \
-H "X-API-KEY: your-api-key" \
-H "X-Notion-Space-ID: your-notion-space-id" \
-H "X-Notion-User-ID: your-notion-user-id" \
-H "X-Notion-Token: your-notion-token" \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"role": "editor",
"blockId": "block-id"
}'
Example Response:
{
"message": "User invited successfully",
"user": {
"ID": "user-id",
"Email": "user@example.com"
},
"blockID": "block-id"
}
Revoke User Access to Notion Block¶
Revokes a user's access to a specific Notion block.
POST /api/v1/notion/revoke¶
Request Headers:
X-API-KEY: your-api-key
X-Notion-Space-ID: your-notion-space-id
X-Notion-User-ID: your-notion-user-id
X-Notion-Token: your-notion-token
Request Body:
{
"email": "user@example.com",
"blockId": "block-id"
}
| Field | Type | Required | Description |
|---|---|---|---|
| String | Yes | Email of the user to revoke access from | |
| blockId | String | Yes | ID of the block to revoke access to |
Example Request:
curl -X POST "https://magic-meal-kits-xxxxx.run.app/api/v1/notion/revoke" \
-H "X-API-KEY: your-api-key" \
-H "X-Notion-Space-ID: your-notion-space-id" \
-H "X-Notion-User-ID: your-notion-user-id" \
-H "X-Notion-Token: your-notion-token" \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"blockId": "block-id"
}'
Example Response:
{
"message": "User revoked successfully",
"user": {
"ID": "user-id",
"Email": "user@example.com"
},
"blockID": "block-id"
}
Notion API v3 (Official)¶
The v3 endpoints use the official Notion API (not the internal/unofficial API). The Notion API token is resolved server-side from Secret Manager — no X-Notion-Token header is needed.
Authentication¶
X-API-Key: Required (standard API key middleware)X-Notion-Token: Optional override for development/testing. If omitted, the server automatically retrieves the token from Secret Manager (notion.access_token).
Get Page Transcript¶
Retrieves transcription blocks from a Notion page and returns their content (summary, notes, transcript) as flattened markdown.
GET /api/v3/notion/page/:page_id/transcript¶
URL Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| page_id | String | Yes | The ID of the Notion page |
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| include | String | No | Comma-separated sections to include: summary, notes, transcript. Defaults to all three if omitted. |
Example Request:
curl "https://magic-meal-kits-xxxxx.run.app/api/v3/notion/page/PAGE_ID/transcript?include=summary,transcript" \
-H "X-API-KEY: your-api-key"
Example Response:
{
"transcriptions": [
{
"id": "block-id",
"title": "Meeting Recording",
"status": "complete",
"summary": "Discussion about project milestones...",
"transcript": "Speaker 1: Let's start with..."
}
],
"count": 1
}
Get Page Markdown¶
Retrieves the full content of a Notion page as cleaned markdown using the official Notion Retrieve Page as Markdown API. Noise tags (e.g., Notion internal markup) are stripped from the output.
GET /api/v3/notion/page/:page_id/markdown¶
URL Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| page_id | String | Yes | The ID of the Notion page |
Example Request:
curl "https://magic-meal-kits-xxxxx.run.app/api/v3/notion/page/PAGE_ID/markdown" \
-H "X-API-KEY: your-api-key"
Example Response:
{
"id": "page-id",
"markdown": "# Meeting Notes\n\nAttendees: Alice, Bob\n\n## Agenda\n\n- Project update\n- Next steps",
"truncated": false
}
Error Handling¶
All endpoints return a standard error format:
{
"error": "Error message description"
}
Common error codes:
- 400 Bad Request: Invalid parameters or request body
- 401 Unauthorized: Missing or invalid API key or Notion credentials
- 500 Internal Server Error: Server-side error
Rate Limiting¶
API endpoints have rate limiting applied. If you exceed the rate limit, you will receive a 429 Too Many Requests response.
Pro User Requirement¶
Note that the duplicate, invite, and revoke endpoints require a Magic Meal Kits PRO subscription. If you attempt to use these endpoints without a PRO subscription, you will receive a 400 Bad Request response with an error message indicating that you are not a PRO user.