How to Connect Notion to Azure Functions
- Sophie Ricci
- Views : 28,543
Table of Contents
You built a Notion workspace that your whole team lives in. You have Azure Functions already running parts of your backend. But they don’t talk to each other — and every time you need to move data between them, someone has to do it manually.
That’s the kind of friction that quietly kills productivity.
The good news: connecting Notion to Azure Functions is entirely doable, and once it’s set up, it unlocks real automation — things like auto-creating Notion pages when a form is submitted, syncing CRM data into your Notion database, or triggering serverless workflows straight from Notion properties.
This guide walks you through exactly how to do it, from getting your API credentials to writing the function code that makes the connection work.
Why Connect Notion to Azure Functions
Notion has grown into one of the most widely used knowledge and project management platforms in the world, with over 35 million users across teams of every size. Azure Functions, Microsoft’s serverless compute service, processes trillions of function executions per month across global infrastructure spanning 60+ regions.
Individually, both tools are powerful. Together, they become something much more useful.
Here’s what the combination makes possible:
- Triggered automation — A new row appears in your Notion database, and Azure Functions fires off a downstream task automatically
- Two-way data sync — Keep Notion databases current with data from external APIs, CRMs, or internal systems
- Event-driven workflows — Use Notion as a lightweight control panel that triggers serverless logic in the background
- Webhook processing — Capture Notion events and route them to other services without managing a server
According to McKinsey, employees spend roughly 28% of their workweek managing email and data tasks that could be automated. Businesses that connect tools like Notion with serverless compute platforms report up to 20% improvement in team productivity by eliminating manual data transfers.
The integration pattern is straightforward: Notion exposes its data through an official API, and Azure Functions can call or respond to that API based on any trigger you define.
What You Need Before You Start
Before writing a single line of code, make sure you have these in place:
- A Notion account with admin access to at least one workspace
- An Azure account with an active subscription (the free tier works for testing)
- Node.js (v16+) or Python (3.8+) installed locally — pick whichever you’re more comfortable with
- Azure Functions Core Tools installed on your machine
- Basic familiarity with REST APIs and environment variables
No prior serverless experience is required, but knowing what a function trigger is will help you follow along faster.
How to Connect Notion to Azure Functions
Create a Notion Integration
The Notion API requires an integration to authenticate requests. Think of it as registering your Azure Function as a trusted application inside your Notion workspace.
Go to https://www.notion.so/my-integrations and click “New Integration.”
Fill in:
- Name — Something descriptive like Azure Function Sync
- Associated Workspace — Select the workspace you want to connect
- Capabilities — Enable Read, Update, or Insert content depending on what your function needs to do
Click Submit and Notion will generate an Internal Integration Token (your API key). Copy this — you’ll need it shortly.
Important: This token has the same access as the integration permissions you set. Treat it like a password. Never hardcode it directly in your function code.
Share a Notion Database with Your Integration
This is the step most people miss the first time.
Even after creating your integration, it has no access to any content by default. You need to explicitly share each database or page with it.
Open the Notion database you want to connect. Click the “…” menu in the top right corner, go to Connections, and select your integration from the list.
Once shared, the integration can read from and write to that database via the API.
Get the Database ID
Every Notion database has a unique ID embedded in its URL. You’ll need this to make API calls to the right place.
Open your database in Notion. Look at the URL — it follows this pattern:
https://www.notion.so/{workspace}/{database_id}?v={view_id}
The database ID is the 32-character string before the ?v= parameter. Copy it.
Set Up Your Azure Function Project
If you don’t already have Azure Functions Core Tools installed, run:
npm install -g azure-functions-core-tools@4 –unsafe-perm true
Create a new function project:
func init NotionAzureIntegration –javascript
cd NotionAzureIntegration
func new –name NotionSync –template “HTTP trigger”
This scaffolds a basic HTTP-triggered function. You can swap the trigger type later (Timer, Queue, Event Grid, etc.) depending on what you need.
Install the Notion SDK
Inside your function project directory, install the official Notion client:
npm install @notionhq/client
This SDK wraps the Notion API in a clean interface and handles authentication for you.
Configure Environment Variables
Never put your Notion API key directly in your code. Use environment variables instead.
Open local.settings.json in your project and add:
{
“IsEncrypted”: false,
“Values”: {
“AzureWebJobsStorage”: “”,
“FUNCTIONS_WORKER_RUNTIME”: “node”,
“NOTION_API_KEY”: “your_integration_token_here”,
“NOTION_DATABASE_ID”: “your_database_id_here”
}
}
When you deploy to Azure, you’ll add these same values under Configuration → Application Settings in the Azure Portal — not in this local file.
Write the Integration Code
Open NotionSync/index.js and replace the default code with:
const { Client } = require(“@notionhq/client”);
const notion = new Client({
auth: process.env.NOTION_API_KEY,
});
module.exports = async function (context, req) {
const databaseId = process.env.NOTION_DATABASE_ID;
try {
// Query the Notion database
const response = await notion.databases.query({
database_id: databaseId,
filter: {
property: “Status”,
select: {
equals: “Active”,
},
},
});
const pages = response.results.map((page) => ({
id: page.id,
title: page.properties?.Name?.title?.[0]?.plain_text || “Untitled”,
status: page.properties?.Status?.select?.name || “Unknown”,
}));
context.res = {
status: 200,
headers: { “Content-Type”: “application/json” },
body: { success: true, count: pages.length, data: pages },
};
} catch (error) {
context.log.error(“Notion API error:”, error.message);
context.res = {
status: 500,
body: { success: false, error: error.message },
};
}
};
This function queries your Notion database and returns all pages where the Status property equals “Active.” Adjust the filter and property names to match your actual database structure.
Test the Connection Locally
Run your function locally:
func start
Azure Functions Core Tools will start a local server, typically at http://localhost:7071. Open your browser or use a tool like Postman to hit:
http://localhost:7071/api/NotionSync
If the connection is working, you’ll get back a JSON response with your Notion database records. If you see an authentication error, double-check your integration token and that the database has been shared with your integration.
Deploy to Azure
Once local testing passes, deploy to Azure:
az login
func azure functionapp publish <YourFunctionAppName>
If you haven’t created a Function App yet, do that first through the Azure Portal or with the Azure CLI:
az functionapp create \
–resource-group MyResourceGroup \
–consumption-plan-location eastus \
–runtime node \
–runtime-version 18 \
–functions-version 4 \
–name YourFunctionAppName \
–storage-account YourStorageAccount
After deployment, add your environment variables in the Azure Portal under Function App → Configuration → Application Settings.
Writing Data Back to Notion
Reading from Notion is useful. Writing back is where automation gets powerful.
Here’s how to create a new page in your Notion database from Azure Functions:
const newPage = await notion.pages.create({
parent: { database_id: databaseId },
properties: {
Name: {
title: [{ text: { content: “New Entry from Azure” } }],
},
Status: {
select: { name: “Pending” },
},
Created: {
date: { start: new Date().toISOString() },
},
},
});
This creates a new row in your Notion database every time the function runs. You can trigger this from a form submission, a webhook, a timer, or any event Azure Functions supports.
Common Integration Patterns
Once the basic connection is working, the possibilities expand quickly:
Timer-triggered sync — Run a function on a schedule (every hour, every morning) that pulls data from an external API and writes it into a Notion database. Teams use this to keep project trackers, pipeline dashboards, and status boards up to date automatically.
Webhook receiver — Point external tools (Stripe, GitHub, HubSpot) at your Azure Function endpoint. The function processes the webhook payload and creates or updates Notion pages accordingly.
Notion as a trigger — Use Notion’s API to poll for changes on a schedule. When a record’s status changes to “Ready for Review,” fire an Azure Function that notifies a Slack channel or kicks off a downstream process.
Data aggregation — Pull data from multiple sources into a single Notion database for reporting. Azure Functions handles the aggregation logic; Notion becomes the readable, shareable output.
Troubleshooting Common Issues
“Could not find database” — The database ID in your environment variable is wrong, or you haven’t shared the database with your integration. Both need to be correct.
401 Unauthorized — Your API key is invalid or wasn’t loaded from environment variables correctly. Add a console.log(process.env.NOTION_API_KEY) temporarily to confirm it’s being read (then remove it before deploying).
403 Forbidden on specific properties — The integration doesn’t have permission to access that property type. Go back to your integration settings and verify capabilities.
Rate limiting (429 errors) — The Notion API has a limit of 3 requests per second per integration. If you’re making bulk queries, add delay logic between requests or batch your operations.
Timeout errors in Azure — The default execution timeout for Azure Functions on the Consumption plan is 5 minutes. For long-running sync operations, switch to a Premium or Dedicated plan or break the task into smaller chunks.
🚀 Stop Managing Data. Start Closing Deals.
We book qualified meetings for you using proven cold outbound systems
7-day Free Trial |No Credit Card Needed.
FAQs
Does Notion have an official API?
Can I use Python instead of JavaScript for this integration?
How often can I poll the Notion API?
Can Azure Functions listen for changes in Notion in real time?
We deliver 100–400+ qualified appointments in a year through tailored omnichannel strategies
- blog
- Sales Development
- How to Connect Notion to Azure Functions