Skip to main content
Many teams draft blog posts, case studies, and internal docs in Notion — it’s great for collaborative writing, but it’s not a public website. This integration lets you write in Notion and auto-publish to your Hiveku site, so you never have to copy-paste content again.
This works in both directions. You can pull from Notion into Hiveku (publish a blog), or push from Hiveku into Notion (log form submissions as database rows).

Step 1: Create a Notion Integration

1

Go to Notion integrations

Open notion.so/my-integrations and click New integration.
2

Name and configure it

  • Name: Hiveku Publisher (or whatever makes sense)
  • Associated workspace: the workspace with the content you want to sync
  • Capabilities: at minimum check Read content. Add Update content if you also want to write back to Notion (e.g., mark a page as “Live” after publishing).
3

Copy the Internal Integration Token

Token looks like secret_abc123.... Treat it like a password — don’t commit it to git.
4

Share your database with the integration

Open the Notion database you want Hiveku to read. Click the menu at the top right, go to Connections, and add Hiveku Publisher.
This step is easy to forget and is the most common cause of 404 errors later. The integration can only see databases that have been explicitly shared with it.

Step 2: Find Your Database ID

Open the Notion database as a full page (not embedded). The URL looks like:
https://www.notion.so/yourworkspace/abc123def456.../...?v=...
The 32-character string between the slash and the ? is your database ID. Copy it.

Step 3: Store Credentials in Hiveku

1

Open your project's env vars

Go to Settings > Environment Variables in your Hiveku project.
2

Add two variables

  • NOTION_API_KEY — the integration token from Step 1
  • NOTION_DATABASE_ID — the database ID from Step 2
3

Save and deploy

Env vars take effect on the next deploy. Click Deploy.

Step 4: Build the Auto-Publish Workflow

This workflow polls Notion hourly and publishes any page marked Status = Published.
1

Create a new workflow

Name it Notion Publisher.
2

Add a Schedule trigger

Every hour (or every 15 minutes for faster turnaround).
3

Query Notion for published pages

Add an HTTP Request action:
POST https://api.notion.com/v1/databases/{{env.NOTION_DATABASE_ID}}/query

Headers:
  Authorization: Bearer {{env.NOTION_API_KEY}}
  Notion-Version: 2022-06-28
  Content-Type: application/json

Body:
{
  "filter": {
    "property": "Status",
    "select": { "equals": "Published" }
  }
}
4

Fetch block content for each page

For each result, fetch the page’s blocks:
GET https://api.notion.com/v1/blocks/{{page.id}}/children
5

Convert blocks to Markdown

Notion blocks are a JSON tree. Convert to Markdown using a library like notion-to-md, or write inline transformation for simple cases (headings, paragraphs, lists, code).
6

Create or update the blog post

Insert into your blog_posts table (or whatever your schema uses), keyed by the Notion page ID so re-publishes update rather than duplicate.
7

Mark the Notion page as Live

Update the page’s Status property to Live so it doesn’t re-publish on the next run:
PATCH https://api.notion.com/v1/pages/{{page.id}}
Body: { "properties": { "Status": { "select": { "name": "Live" } } } }

Reverse Direction: Hiveku to Notion

Useful for logging: push form submissions, CRM updates, or workflow events into a Notion database as new rows.
POST https://api.notion.com/v1/pages

Headers:
  Authorization: Bearer {{env.NOTION_API_KEY}}
  Notion-Version: 2022-06-28

Body:
{
  "parent": { "database_id": "{{env.NOTION_LOGS_DATABASE_ID}}" },
  "properties": {
    "Name": { "title": [{ "text": { "content": "{{trigger.name}}" }}] },
    "Email": { "email": "{{trigger.email}}" },
    "Submitted": { "date": { "start": "{{now}}" }}
  }
}

Handling Images

Notion image URLs expire after 1 hour. If you link directly, your blog images will break the next day.
1

Download each image

When converting blocks, detect image blocks and fetch the image binary before the URL expires.
2

Re-upload to your assets storage

Push to your Hiveku media bucket, Cloudinary, S3, or wherever you host site assets.
3

Replace the URL in your Markdown

Use the permanent URL in your published post, not the Notion-hosted one.
Notion’s API has strict rate limits (3 requests/sec average). Batch where possible, and add a small delay (350ms) between requests in high-volume workflows. Hitting the limit returns 429 Too Many Requests.

Verify It Worked

1

Create a test page in Notion

Add a new row to your synced database with Status = Published. Give it a title, some paragraph content, and save.
2

Trigger the workflow

Either wait for the next hourly run, or hit Run Now on the workflow page.
3

Check your site

Visit your blog listing page. The new post should appear.
4

Confirm Notion was updated

Back in Notion, the page’s Status should now read Live.

Troubleshooting

The integration doesn’t have access to the database. Open the database in Notion, click > Connections, and add Hiveku Publisher. This is the single most common cause of 404s on the Notion API.
Either the NOTION_API_KEY env var is wrong, or the integration has been revoked. Go to notion.so/my-integrations, check the integration exists, and regenerate the secret if needed.
You linked directly to Notion-hosted images instead of re-uploading. Fix the workflow to download and re-upload images to your own asset storage. See the “Handling Images” section above.
Notion’s block-to-HTML conversion is lossy out of the box. Use a mature library like notion-to-md rather than rolling your own parser — it handles callouts, toggles, bookmarks, and nested lists correctly.
You’re inserting rather than upserting. Use the Notion page ID as a unique key in your blog_posts table, and either UPDATE on conflict or skip if already present.

What’s Next?

Webhook Patterns

Handle inbound webhooks from Notion and other tools

Post a Blog

Other ways to publish content on your site