Get your dream built 10x faster

How to integrate Notion CLI with OpenClaw

We build custom applications 5x faster and cheaper 🚀

Book a Free Consultation
4.9
Clutch rating 🌟
600+
Happy partners
17+
Countries served
190+
Team members
Matt Graham, CEO of Rapid Developers

Book a call with an Expert

Stuck on an error? Book a 30-minute call with an engineer and get a direct fix + next steps. No pressure, no commitment.

How to integrate Notion CLI with OpenClaw

To integrate Notion with OpenClaw, expose a small, explicit skill that makes authenticated REST calls to Notion’s public API (using either a Notion integration token or an OAuth flow), store the token(s) securely in ClawHub configuration, and keep any webhooks, schedulers, or persistent state outside the agent runtime (a simple HTTPS endpoint and a durable store or queue). Configure the skill in ClawHub with the required environment variables and scopes, implement and test basic Notion calls (read/search, create/update pages or database rows) using the Notion REST API, and debug by inspecting API responses, logs, and permission/sharing settings in Notion.

 

Overview and architecture

 
  • Components: ClawHub (where you register/configure the OpenClaw skill), the OpenClaw agent runtime (executes the skill logic), Notion (external service with REST API and optional OAuth), and external infrastructure you must provide for webhooks, scheduling, and persistence (HTTPS endpoint, databases/queues, scheduler).
  • Principle: The OpenClaw skill explicitly calls Notion’s REST API. Authentication credentials (integration token or OAuth client secret + access token) are provided to the skill via ClawHub configuration/secrets. Anything requiring continuous uptime, webhooks, or durable data storage should run outside the ephemeral agent runtime.

 

Prerequisites

 
  • Create a Notion integration or prepare to use Notion OAuth for user-level access. You will need either an integration token (internal integration) or client_id/client_secret for OAuth.
  • Identify the Notion database_id or page_id you will operate on, and ensure the integration (or the user who authorizes the OAuth app) has been given access to that database/page in Notion.
  • A ClawHub account and permission to create or configure skills and to set environment variables/secrets for those skills.
  • An external HTTPS endpoint (if you intend to accept Notion webhooks or handle OAuth redirects) and optionally a persistent store (database, object store) or queue for durable state and retries.

 

Authentication options and how to choose

 
  • Internal integration token — simplest for a single workspace. Create a Notion integration, copy its secret token, and store it in ClawHub as a secret (e.g., NOTION\_TOKEN). Use this token in Authorization: Bearer ... headers for API calls. Ensure the integration is explicitly shared to the pages/databases it needs to access in Notion.
  • OAuth (recommended for multi-user or per-user access) — implement the standard OAuth flow: redirect users to Notion’s authorize URL, receive a code at your external redirect URI, exchange the code for an access token at Notion’s token endpoint, and store the returned access token (and refresh token if provided) in a secure store. Register client_id/client_secret in ClawHub so the skill can trigger the auth flow or exchange codes server-side. Request only the scopes you need (for example, pages:read, pages:write, databases:read, databases:write).
  • Storage — keep tokens and long-lived secrets in ClawHub secret storage (or another secret manager). Do not embed secrets in code or commit them to source control.

 

Where code runs and what must be external

 
  • Runs inside OpenClaw agent: short-lived operations that call Notion’s REST API (search, create/update pages, read content) and return results. The skill should be deterministic and stateless where possible.
  • Must be external: webhook receivers (Notion webhook delivery requires a stable HTTPS endpoint), OAuth redirect endpoints and token exchanges, schedulers for periodic tasks, and any durable data stores or queues for retries/long-running processes. For production reliability, run these in a web server or serverless function outside the agent.

 

Step-by-step: simple skill that creates a page in a Notion database

 
  • 1) Prepare credentials: Put your integration token or OAuth access token into ClawHub configuration as NOTION_TOKEN (or store client_id and client\_secret if you’re doing OAuth).
  • 2) Basic API call: Use Notion’s REST API. Example: create a page in a database. This is generic REST; place the code inside your skill so the agent can call it when invoked.
// <b>//</b> Node.js example using fetch (works in modern Node versions)
const fetch = require('node-fetch');

async function createNotionPage(databaseId, title, notionToken) {
  const url = 'https://api.notion.com/v1/pages';
  const body = {
    parent: { database_id: databaseId },
    properties: {
      Name: {
        title: [
          { text: { content: title } }
        ]
      }
      // <b>//</b> Add other properties as required by your database schema
    }
  };

  const res = await fetch(url, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${notionToken}`,
      'Notion-Version': '2022-06-28',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(body)
  });

  if (!res.ok) {
    const text = await res.text();
    throw new Error(`Notion API error ${res.status}: ${text}`);
  }

  return res.json();
}

// <b>//</b> Example usage:
// createNotionPage(process.env.NOTION_DATABASE_ID, 'My page title', process.env.NOTION_TOKEN)
//   .then(r => console.log('created', r))
//   .catch(err => console.error(err));
# <b>//</b> curl example
curl -X POST "https://api.notion.com/v1/pages" \
  -H "Authorization: Bearer $NOTION_TOKEN" \
  -H "Notion-Version: 2022-06-28" \
  -H "Content-Type: application/json" \
  -d '{
    "parent": { "database_id": "'"$NOTION_DATABASE_ID"'" },
    "properties": {
      "Name": { "title": [{ "text": { "content": "Hello from OpenClaw" } }] }
    }
  }'

 

Deploying and configuring the skill in ClawHub

 
  • Package your skill as a small service or script artifact that the OpenClaw agent can execute (the exact packaging mechanism depends on your CI/CD and ClawHub conventions).
  • Set secrets/env vars in ClawHub: NOTION_TOKEN (or NOTION_CLIENT_ID, NOTION_CLIENT_SECRET, and a REDIRECT_URI for OAuth). Use the ClawHub secret store or environment settings — never embed these in code.
  • Provide invocation triggers — configure how the skill is invoked (manual trigger, invoked by another agent flow, or triggered by an incoming webhook queued from your external webhook receiver). Do not rely on the agent to accept direct internet requests for webhooks; route webhooks to your external endpoint and then call or queue to the agent if needed.
  • Grant minimal scopes for the app/integration in Notion and ensure the integration is shared with target pages/databases in Notion’s UI.

 

Webhook handling and OAuth redirect handling

 
  • Webhooks: If you need to react to Notion events, run an external HTTPS endpoint that receives events and validates them according to Notion’s webhook verification method. Once validated, push a message into a queue (e.g., SQS, Pub/Sub) or call an internal ClawHub API/invocation that tells the agent to process the event. This pattern avoids keeping the agent directly exposed to the internet and makes retries and persistence reliable.
  • OAuth redirect: OAuth requires a stable redirect URI hosted outside the agent. The redirect handler exchanges the code for tokens, stores them in a secure store, and then associates the stored token with a user or workspace ID that the agent can use at runtime.

 

Security and operational best practices

 
  • Store tokens in ClawHub secret management or an external secret store and reference them via environment variables.
  • Request the minimal Notion scopes necessary and ensure the integration is only shared with required pages/databases.
  • Rotate credentials periodically and use per-workspace tokens where feasible.
  • Keep webhook receivers resilient: validate signatures, support retries, and put events on a durable queue for agent processing.
  • Do heavy or long-running work outside the agent (e.g., large content syncs), and surface results to the agent via a status/queue system.

 

Debugging checklist

 
  • Confirm token validity: call a small endpoint (e.g., GET https://api.notion.com/v1/users/me) using the same token the skill uses; check for 401/403.
  • Verify the integration or authorized user has been shared to the target pages/databases inside Notion’s UI.
  • Inspect API error responses (body and HTTP status) and add logging in the skill for request URL, headers (not the secret), and response body.
  • For OAuth flows check the redirect URI, client_id/client_secret, and code exchange step responses.
  • If using webhooks, validate the incoming request via the method Notion documents (signature/verification token), and confirm your endpoint is reachable and returns the expected HTTP codes for Notion retries.
  • Confirm the skill in ClawHub sees the expected environment variables and that the agent is invoking the correct entrypoint.

 

Small example flow (summary)

 
  • Decide auth method (integration token vs OAuth).
  • Implement small REST calls to Notion inside your OpenClaw skill and keep the code stateless.
  • Store secrets in ClawHub and configure skill environment.
  • Host webhook and OAuth endpoints externally; validate requests and push events to the agent through a queue or explicit invocation.
  • Monitor logs and Notion API responses, ensure integration is shared with required content, and follow minimal-scope security practices.

Book Your Free 30‑Minute Migration Call

Speak one‑on‑one with a senior engineer about your no‑code app, migration goals, and budget. In just half an hour you’ll leave with clear, actionable next steps—no strings attached.

Book a Free Consultation

Troubleshooting Notion CLI and OpenClaw Integration

1

Configure Notion integration token and Notion-Version for OpenClaw connector

 

Direct answer

 

Set your Notion integration token and Notion-Version as environment variables for the OpenClaw skill (for example NOTION_API_TOKEN and NOTION_VERSION), configure them in ClawHub/agent runtime, and have the skill read those vars and send them as HTTP headers: Authorization: Bearer <token> and Notion-Version: <version>. Ensure the runtime only exposes the token to the skill that needs it.

 

Details & code

 

Set env vars in your connector config; skill code reads them and uses standard Notion headers.

  • Node.js example
```js // Read from runtime env const token = process.env.NOTION_API_TOKEN; const version = process.env.NOTION_VERSION || '2022-06-28'; await fetch('https://api.notion.com/v1/pages', { method: 'GET', headers: { 'Authorization': `Bearer ${token}`, 'Notion-Version': version, 'Content-Type': 'application/json' } }); ```
  • curl test
```bash // test using shell env NOTION_API_TOKEN="secret" NOTION_VERSION="2022-06-28" \ curl -H "Authorization: Bearer $NOTION_API_TOKEN" -H "Notion-Version: $NOTION_VERSION" https://api.notion.com/v1/databases ```

2

Handle Notion block-children pagination and fetch nested blocks for OpenClaw

 

Direct answer

 

Use the Notion Blocks API pagination (results, has_more, next_cursor) and recursively fetch blocks with has_children. In an OpenClaw skill, authenticate with an env var, iterate pages until has_more is false, and fetch nested children on demand—push long-running/stateful work outside the agent runtime.

 

Example (Node.js)

 
// realistic Node.js using global fetch (Node18+)
const NOTION = 'https://api.notion.com/v1';
const KEY = process.env.NOTION_API_KEY;

async function fetchChildren(blockId){
  let cursor = undefined;
  const all = [];
  do{
    const qs = new URLSearchParams();
    qs.set('page_size','100');
    if(cursor) qs.set('start_cursor', cursor);
    const res = await fetch(`${NOTION}/blocks/${blockId}/children?${qs}`,{
      headers:{ 'Authorization':`Bearer ${KEY}`, 'Notion-Version':'2022-06-28' }
    });
    const js = await res.json();
    all.push(...js.results);
    cursor = js.has_more ? js.next_cursor : undefined;
  } while(cursor);
  // fetch nested children
  for(const b of all){
    if(b.has_children){
      b.children = await fetchChildren(b.id);
    }
  }
  return all;
}
  • Use NOTION_API_KEY env var.
  • Respect rate limits and move heavy jobs outside the agent runtime.

3

Download Notion file/embed URLs via Notion CLI and store assets in OpenClaw asset-store

Direct answer: Extract file/embed URLs from a Notion CLI export or via the Notion SDK, download each URL (curl or node-fetch), then POST the file to your OpenClaw asset-store REST upload endpoint using an API key stored in an environment variable; keep state and retries outside the agent runtime.

 

Steps

 
  • Extract URLs from Notion export (look for file.external.url or file.url fields).
  • Download each URL (stream to avoid memory spikes).
  • Upload to OpenClaw asset-store with an env var API key and proper multipart/form-data.

 

Example

 
const fetch = require('node-fetch');
const FormData = require('form-data');
const UPLOAD_URL = process.env.OPENCLAW_ASSET_UPLOAD_URL;
const KEY = process.env.OPENCLAW_ASSET_KEY;

async function mirror(url, filename){
  <b>//</b> download file
  const r = await fetch(url);
  const stream = r.body;
  <b>//</b> upload to asset-store
  const form = new FormData();
  form.append('file', stream, { filename });
  const res = await fetch(UPLOAD_URL, {
    method:'POST',
    headers: { Authorization: `Bearer ${KEY}`, ...form.getHeaders() },
    body: form
  });
  return res.ok? await res.json(): { error: await res.text() };
}

4

Implement incremental sync, deduplication, and Notion rate-limit handling in the OpenClaw connector

Implement incremental sync by persisting a cursor (e.g., Notion's last_edited_time) outside the agent (ClawHub secrets or a small DB), fetch only items newer than the cursor, deduplicate by tracking Notion id + content hash and upserting, and handle Notion rate limits by honoring 429/Retry-After with exponential backoff and retry. Only advance the cursor after successful processing and durable storage of dedupe keys.

 

Details & example

 
  • Steps: persist cursor; page through results; compute hash; skip existing; write upserts; checkpoint.
  • Rate-limit: on 429 read Retry-After, sleep, backoff, then retry.
// Node.js example
async function callNotion(url, opts){
  for(let i=0;i<6;i++){
    const res=await fetch(url,opts);
    if(res.status===429){
      const ra=Number(res.headers.get('Retry-After')||1);
      await new Promise(r=>setTimeout(r,(2**i)*1000*ra));
      continue;
    }
    return res;
  }
  throw new Error('rate limited');
}
Book a Free Consultation

Still stuck?
Copy this prompt into ChatGPT and get a clear, personalized explanation.

This prompt helps an AI assistant understand your setup and guide you through the fix step by step, without assuming technical knowledge.

AI AI Prompt


Recognized by the best

Trusted by 600+ businesses globally

From startups to enterprises and everything in between, see for yourself our incredible impact.

RapidDev was an exceptional project management organization and the best development collaborators I've had the pleasure of working with.

They do complex work on extremely fast timelines and effectively manage the testing and pre-launch process to deliver the best possible product. I'm extremely impressed with their execution ability.

Arkady
CPO, Praction
Working with Matt was comparable to having another co-founder on the team, but without the commitment or cost.

He has a strategic mindset and willing to change the scope of the project in real time based on the needs of the client. A true strategic thought partner!

Donald Muir
Co-Founder, Arc
RapidDev are 10/10, excellent communicators - the best I've ever encountered in the tech dev space.

They always go the extra mile, they genuinely care, they respond quickly, they're flexible, adaptable and their enthusiasm is amazing.

Mat Westergreen-Thorne
Co-CEO, Grantify
RapidDev is an excellent developer for custom-code solutions.

We’ve had great success since launching the platform in November 2023. In a few months, we’ve gained over 1,000 new active users. We’ve also secured several dozen bookings on the platform and seen about 70% new user month-over-month growth since the launch.

Emmanuel Brown
Co-Founder, Church Real Estate Marketplace
Matt’s dedication to executing our vision and his commitment to the project deadline were impressive. 

This was such a specific project, and Matt really delivered. We worked with a really fast turnaround, and he always delivered. The site was a perfect prop for us!

Samantha Fekete
Production Manager, Media Production Company
The pSEO strategy executed by RapidDev is clearly driving meaningful results.

Working with RapidDev has delivered measurable, year-over-year growth. Comparing the same period, clicks increased by 129%, impressions grew by 196%, and average position improved by 14.6%. Most importantly, qualified contact form submissions rose 350%, excluding spam.

Appreciation as well to Matt Graham for championing the collaboration!

Michael W. Hammond
Principal Owner, OCD Tech

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We’ll discuss your project and provide a custom quote at no cost.Â