DEV Community

Cover image for Build Your Own 'Notion AI' for $1/month: Notion API + OpenAI in 50 Lines
TrackStack
TrackStack

Posted on • Originally published at trackstack.tech

Build Your Own 'Notion AI' for $1/month: Notion API + OpenAI in 50 Lines

I was paying $20/month for ChatGPT Plus and considering Notion AI Business ($20/user/month) to get the workspace-aware AI features. Then I did the math: Notion's API is free, OpenAI's gpt-4o-mini is $0.15 per million input tokens, and my actual usage is ~5,000 input tokens per query. That's $0.00075 per "ask your notes" call. Even at 100 queries a month, I'd spend less than a dollar in API costs.

This is the build-vs-buy take the SaaS comparison sites won't write. Below is the 50-line implementation, the real token math, where the DIY approach breaks down, and when to just pay the $20.

For the SMB-perspective comparison (no code, full pricing breakdown, the 2025-2026 Notion AI restructuring), the full version of this article covers the non-developer angle.

The build-it-yourself stack

Three pieces:

  1. Notion API for the data layer — read your pages and their content. Free, well-documented, rate-limited at ~3 req/sec.
  2. OpenAI API (or Anthropic) for the AI layer — send your notes as context, get answers. Cheap per token if you stay on gpt-4o-mini or claude-3-5-haiku.
  3. A glue function that combines them. ~50 lines, no framework needed.

You replace "what Notion AI does" (workspace Q&A, summarisation, autofill) with code you own. You lose: the polished UI, inline rendering inside Notion pages, Custom Agents. You gain: ~95% lower cost, full prompt control, choice of model, and your data stops going through Notion's AI pipeline.

Step 1: Pull notes from Notion

Create a Notion integration at notion.so/profile/integrations, share the pages you want to query with it, set the token as NOTION_TOKEN:

import { Client } from '@notionhq/client';

const notion = new Client({ auth: process.env.NOTION_TOKEN });

async function fetchRecentPages(limit = 20) {
  const res = await notion.search({
    filter: { value: 'page', property: 'object' },
    sort: { direction: 'descending', timestamp: 'last_edited_time' },
    page_size: limit,
  });

  return Promise.all(
    res.results.map(async (page) => {
      const blocks = await notion.blocks.children.list({ block_id: page.id });
      const content = blocks.results.map(extractText).filter(Boolean).join('\n');
      return { id: page.id, title: getTitle(page), content };
    })
  );
}

function extractText(block) {
  const type = block.type;
  const rich = block[type]?.rich_text;
  if (rich) return rich.map((r) => r.plain_text).join('');
  return '';
}

function getTitle(page) {
  const titleProp = Object.values(page.properties).find((p) => p.type === 'title');
  return titleProp?.title?.[0]?.plain_text || 'Untitled';
}
Enter fullscreen mode Exit fullscreen mode

Real caveats: the API returns blocks one level deep by default — nested blocks (toggles, callouts) need recursive fetching. Long pages with many blocks hit rate limits if you parallelise too aggressively. For 50+ pages, throttle to ~3 parallel requests.

Step 2: Send notes as context to an LLM

import OpenAI from 'openai';

const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });

async function askYourNotes(question, pages) {
  // Naive truncation — fine for ~50 pages, use embeddings beyond that
  const context = pages
    .map((p) => `# ${p.title}\n${p.content.slice(0, 2000)}`)
    .join('\n\n---\n\n');

  const completion = await openai.chat.completions.create({
    model: 'gpt-4o-mini',
    messages: [
      {
        role: 'system',
        content:
          'Answer using ONLY the user notes provided. Cite page titles when relevant. If the answer is not in the notes, say so.',
      },
      {
        role: 'user',
        content: `My notes:\n\n${context}\n\nQuestion: ${question}`,
      },
    ],
  });

  return completion.choices[0].message.content;
}

// Use it
const pages = await fetchRecentPages(30);
const answer = await askYourNotes('What did I decide about the Q4 roadmap?', pages);
console.log(answer);
Enter fullscreen mode Exit fullscreen mode

That's the entire workspace-Q&A loop. Drop it in a CLI tool, a Slack bot, or an internal web app. Now you have what Notion AI does, minus the inline rendering.

Anthropic version if you prefer Claude:

import Anthropic from '@anthropic-ai/sdk';

const anthropic = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });

const message = await anthropic.messages.create({
  model: 'claude-3-5-haiku-latest',
  max_tokens: 1024,
  messages: [
    { role: 'user', content: `Notes:\n\n${context}\n\nQuestion: ${question}` },
  ],
});
console.log(message.content[0].text);
Enter fullscreen mode Exit fullscreen mode

Both work. OpenAI's gpt-4o-mini is the cheaper option per token; Claude's Haiku is slightly more expensive but I find its summaries more concise.

Step 3: The token math that justifies this

Per query:

  • Input: ~5,000 tokens of notes context + ~50 tokens of question + system prompt
  • Output: ~500 tokens of answer
  • gpt-4o-mini: 5,000 × $0.15/1M + 500 × $0.60/1M = $0.001 per query
  • claude-3-5-haiku: 5,000 × $0.80/1M + 500 × $4/1M = $0.006 per query

At realistic usage:

  • 100 queries/month: $0.10 (OpenAI) or $0.60 (Anthropic)
  • 1,000 queries/month: $1 (OpenAI) or $6 (Anthropic)

Compared to:

  • Notion AI Business: $20/user/month
  • ChatGPT Plus: $20/month

The gap is 95-99% cheaper for OpenAI, 70-95% for Anthropic. Even at 5,000 queries/month (which is a lot) you're under $5 on OpenAI.

The catch: these numbers assume you're stuffing ~5,000 tokens of context per query. If you scale to a 500-page workspace and want full coverage, you need embeddings — embed each page once with text-embedding-3-small ($0.02/1M tokens, basically free), store in pgvector or sqlite-vss, retrieve the top-N relevant pages per query. Adds maybe an hour of setup; cost stays under $5/month for personal use.

Where the SaaS subscriptions still win

Honest list — when paying for Notion AI Business or ChatGPT Plus is worth it:

  • Inline rendering inside Notion. "AI block" that lives in the page, autofill in databases, summarise-on-the-page. You can't replicate this experience with an external script.
  • Polished UI for non-developers. If you're recommending a tool to colleagues who don't write code, the SaaS UX wins.
  • ChatGPT Pro's deep research, voice, image, web search. None of these are workspace-aware AI features — they're separate value. ChatGPT Plus at $20 buys you the model + all those general-purpose AI features, not just note-taking.
  • Custom Agents (Notion's 2026 feature). If your workflow depends on agents that act on Notion data over time, the official integration is more reliable than DIY orchestration.
  • No infra to maintain. A $20/month SaaS bill is one line of book-keeping. Your DIY script needs a host, API keys to rotate, and occasional debugging.

The honest framing: the SaaS pricing is mostly product, not raw AI compute. You pay for the UI, the integration, and someone else maintaining it.

ChatGPT's Notion connector — when to just use it

If you don't want to write code but also don't want to pay for Notion AI Business, ChatGPT Plus ($20/month) added a Notion connector in 2025 that lets it read your workspace. From inside ChatGPT, you can ask questions about your notes and it pulls relevant context.

Pros: zero setup beyond OAuth, works with all of ChatGPT's other features (web search, file analysis, image), uses GPT-5/4o quality.

Cons: sends your notes to OpenAI for processing (data residency concern for some), works one-way (ChatGPT reads Notion, doesn't write back), the retrieval can miss pages you'd expect it to find.

For a single user who already has ChatGPT Plus, the connector is the cheapest "good enough" option. For a team needing workspace-aware AI without paying Notion AI Business per seat, the DIY approach above scales better.

  • Notion AI Business ($20/user/mo) and ChatGPT Plus ($20/mo) both solve workspace-aware AI, at the same price point, very differently.
  • You can wire Notion API + OpenAI gpt-4o-mini for ~$1/month of actual API costs. ~50 lines of code, no framework.
  • Pay for the SaaS when inline rendering, polished UI, or Custom Agents matter more than the 95% cost saving.
  • ChatGPT's Notion connector is the middle ground if you have Plus already and don't want to code.
  • For teams of 5+ doing real note-taking AI work, DIY is genuinely $20–95/month cheaper than Notion AI Business at scale. Build it once, share across the team.

The pattern generalises beyond Notion — Linear API + OpenAI, Asana API + OpenAI, Slack API + OpenAI. Most "AI for $tool" SaaS features can be assembled from $tool's API plus a few cents of tokens per query. Worth knowing before you sign a recurring SaaS contract for a feature you could own.


Originally published on trackstack.tech with the full SMB comparison including pricing reality and use cases.

Top comments (0)