← Back to Blog
Tutorials·15 min read

Notion Workers for Small Business: A Hands-On Guide

Some of the small businesses I work with run their operations on Notion. Docs, project tracking, content calendars, lightweight CRMs, the whole operational layer of the company. So when Notion shipped a real developer platform last week, the obvious question was whether it changes the automation advice I give those clients.

I watched the videos walking through Workers and the new CLI, read the docs, and built a real worker against a Shopify store I help with. This article is the version of that work I'd hand to a client asking whether they should care.

I'll cover what Notion actually shipped, why it matters if you're running a small business on top of Notion already, and where Custom Agents plus Workers genuinely change what's possible for SMB automation. Then I'll walk through the build with code excerpts and the CLI commands that mattered.

The thesis up front, because I hate articles that bury it. Workers don't make Notion the right tool if it wasn't already. But if Notion is already where your business operates, this is the most consequential thing Notion has shipped for developers, period.

What Notion Actually Launched

On May 13, Notion launched four things at once under the Developer Platform banner. Notion Workers is a hosted Node/TypeScript runtime where you write a small program and Notion runs it on their infrastructure (Vercel Sandbox under the hood, according to Vercel). The ntn CLI is the only way you interact with it. The External Agent API brings Claude Code, Cursor, Codex, and Decagon into Notion as workspace participants. And the Agent SDK, still on a waitlist, goes the other direction so you can embed Notion's agents into your own products.

The Workers SDK gives you six primitives. A worker is a single TypeScript file that wires up some combination of them:

  • worker.database() declares a Notion database whose schema lives in your code.
  • worker.sync() pulls data from an external API into that database on a schedule.
  • worker.tool() exposes a function a Notion Custom Agent can call.
  • worker.webhook() exposes an HTTPS endpoint other services can post to.
  • worker.oauth() configures OAuth 2.0 against any third-party API.
  • worker.pacer() is a built-in rate limiter for your outbound calls.

You write one src/index.ts that exports a Worker, run ntn workers deploy, and that's the whole pipeline. No Dockerfile. No CI. No log shipping setup. ntn workers runs logs <id> is your observability layer, which is either liberating or terrifying depending on your background.

Why this isn't just another Notion API update: until now, if you wanted Notion AI to do something Notion didn't ship as a built-in connector, you either hosted a Model Context Protocol server yourself or you didn't. Workers replace that pattern entirely. You write a function, attach the worker to a Custom Agent, and the agent calls it. That's the actual unlock.

What are Notion Workers?

Notion Workers are TypeScript programs that Notion hosts and runs in a sandboxed runtime. A single worker can sync external data into a Notion database, expose deterministic functions as tools for Notion's AI agents, and receive webhooks from outside services. You deploy them with the ntn CLI and they run on Notion's infrastructure with no servers, queues, or containers to manage.

What is the Notion CLI?

The ntn CLI is Notion's command-line tool for the Developer Platform. It scaffolds Worker projects, deploys them, manages secrets and OAuth, triggers syncs for testing, and inspects run logs. It's available on every Notion plan including Free for direct API calls. Deploying Workers requires the Business plan or higher.

Why Notion Already Owns Small Business Operations

Step back from the developer angle for a second. The reason Workers matter at all is that a surprising number of small businesses already run their operational layer on Notion. Not just docs. Not just notes. The whole "where work actually happens" surface.

Documentation and wikis is the obvious one. Onboarding docs, SOPs, meeting notes, runbooks. Notion's block editor and nested pages beat every alternative for non-engineering teams, and AI search across the workspace makes that content genuinely useful instead of a graveyard of stale pages nobody opens.

Then there's the lightweight database story. Content calendars, light CRMs, project trackers, customer feedback logs. You get table, kanban, calendar, gallery, and timeline views from the same underlying data, and most small teams never need anything more sophisticated than that.

Agencies and consultancies have been quietly building entire client-facing operations on Notion for years. Per-client workspaces, deliverable tracking, project portals, retainer dashboards. With Workers, you can now sync each client's billing and time tracking into their portal without resorting to Zapier glue.

Marketing teams run content calendars where briefs, drafts, SEO targets, and publishing dates all live in one place. Sales teams under a hundred contacts run lightweight CRMs from it. Customer support uses it for knowledge base pages that the team and customers both reference. Finance teams build dashboards summing Stripe and bank data into a monthly view. None of these are best-in-class against dedicated tools, but the value of having them all in one searchable workspace beats best-in-class fragmentation for most small teams.

The honest counterweight: heavy relational data above a few thousand rows gets slow. Real project management with dependencies and sprint planning stays Linear or Jira territory. CRM at any serious scale needs Attio or HubSpot. The Electron app is famously laggy on older hardware. Data portability is a known weak point because Notion's export-to-Markdown degrades structure and the underlying block format is proprietary.

If you've ever tried to migrate off Notion after a few years, you know.

What is Notion best for in small business?

Notion is best for small businesses needing a unified workspace covering wikis, lightweight project management, content calendars, simple CRMs, and AI-augmented knowledge search. It particularly shines for teams under fifty people, agencies running client portals, and content-driven businesses where docs and operational data live side by side. It's a poor fit for heavy relational data, scaled CRM, and engineering-team project management.

The pattern I keep seeing in SMB stacks: Notion as the operational hub, Stripe or Shopify as the financial source of truth, GitHub or Linear for the engineering work that doesn't belong in Notion, Slack for the synchronous stuff. Workers connect the first one to all the others in a way that finally feels native. If you want the bigger picture on how this fits the broader landscape, I wrote a piece on AI agents for small business in 2026 covering the surrounding ecosystem.

The AI Automation Shift That Workers Unlocks

This is where I think the article needs to land hardest, because this is the actual story. Three phases of small business automation, roughly.

The first era was Zapier-style trigger and action. Something happens in app A, do something in app B. Mostly mechanical, mostly worked, mostly billed by the task. Fine until your "if this then that" turned into "if this then check three things and maybe do one of four things depending on context", and then you were eight Zaps deep in something nobody understood six months later.

The second era was AI agents that could read your data. Notion Agent, ChatGPT with connectors, Claude with MCP. Useful for summarisation and Q&A across your workspace, but they couldn't actually do anything beyond what their built-in connectors supported. Want the agent to look up an order in your custom commerce platform? Tough.

The third era is right now: AI agents that can call your code. That's what Workers add. A Custom Agent runs in your workspace, you ask it a question, and underneath it calls a deterministic function you wrote that hits Shopify, Stripe, your internal database, whatever, and returns structured data the agent then summarises for you. From Notion's own framing, Workers are deterministic, which makes them more reliable than LLM reasoning and a fraction of the token cost.

The before-and-after is concrete. Before Workers, a "what's this customer's history?" workflow meant gluing together a Shopify lookup, a support inbox query, an email thread search, and somebody's memory. After Workers, you type the question in Notion and the agent calls a function that aggregates all of it. Same data, different effort.

For online retail specifically the implications spiral outward fast. Order lookups, refund pattern analysis, customer LTV summaries, churn risk flags, restock recommendations. I went deeper on what this means for online stores in agentic commerce in 2026, but the short version is that the agent layer is finally getting cheap enough to deploy on actual SMB workflows.

Can Notion Workers replace Zapier?

For workflows where Notion is one end of the pipe, often yes. Workers handle Notion-attached automation more cleanly than Zapier with better code quality, version control, and AI agent integration. For arbitrary SaaS-to-SaaS workflows where Notion isn't involved, Zapier still wins on prebuilt integrations and accessibility for non-developers. The honest split is to keep your "Slack to Twilio to Google Sheets" Zaps on Zapier and build new Notion-adjacent automation as Workers.

A Hands-On Build

OK enough abstract. Here's the actual worker.

The brief: I wanted to ask a Custom Agent in Notion "what's the history of jane@example.com?" or "how bad was our refund week?" and get a real answer, backed by actual Shopify data, without anyone alt-tabbing to Shopify admin. One worker, three capabilities. A managed Notion database that holds Shopify orders, a sync that keeps it current every fifteen minutes, and two tools the agent can call.

The whole worker is one file. Here's the skeleton, with the verbose middle bits trimmed so you can see the shape:

import { Worker } from "@notionhq/workers";
import * as Schema from "@notionhq/workers/schema";

const worker = new Worker();
export default worker;

// 1. Pacer: stay under Shopify's 2 req/sec REST limit
const shopify = worker.pacer("shopifyApi", {
  allowedRequests: 2,
  intervalMs: 1000,
});

// 2. Managed database: schema lives in code
const orders = worker.database("orders", {
  type: "managed",
  initialTitle: "Shopify Orders",
  primaryKeyProperty: "Order ID",
  schema: {
    properties: {
      /* ... */
    },
  },
});

// 3. Sync: keep the database fresh
worker.sync("shopifyOrders", {
  /* ... */
});

// 4. Tools: what the agent can call
worker.tool("getCustomerSnapshot", {
  /* ... */
});
worker.tool("getRecentRefundReport", {
  /* ... */
});

Four blocks. The full source is on GitHub, so I'll skip the rest and call out the bits worth understanding.

The sync. The execute function pulls orders from Shopify, transforms them into upsert changes, and returns them. The piece worth knowing about is the cursor pattern. Shopify's updated_at index is eventually consistent, which means if you naively store "the latest updated_at I saw" as your cursor, you'll occasionally miss records that get indexed a second or two late. The Notion docs recommend holding your cursor a buffer behind "now" (I use fifteen seconds) so those records have time to settle before the next cycle picks them up. Within a single cycle, I follow Shopify's Link: <…>; rel="next" header for pagination because page_info can't be combined with other filters. This took me longer to get right than the rest of the worker combined.

The tools. Each tool is a function with a JSON schema for its input. The agent picks one based on the conversation and calls it with arguments it generates. Here's the meat of getCustomerSnapshot:

worker.tool("getCustomerSnapshot", {
  description: "Get an order history snapshot for a Shopify customer by email...",
  hints: { readOnlyHint: true },
  schema: j.object({
    email: j.email().describe("The customer's email address."),
  }),
  execute: async (input, { notion }) => {
    const results = await collectPaginatedAPI(notion.dataSources.query, {
      data_source_id: ORDERS_DATA_SOURCE_ID,
      filter: { property: "Customer Email", email: { equals: input.email } },
      sorts: [{ property: "Order Date", direction: "descending" }],
    });
    // aggregate orders, compute lifetime value, return structured payload
  },
});

Two things to internalise. First, readOnlyHint: true lets the agent execute this tool without asking the user for permission each time, which is right for read-only lookups. Write tools should leave it off so the agent has to ask. Second, the description and the schema descriptions are what the LLM reads to decide whether to call the tool. Treat them like API documentation written for a literal-minded colleague who hasn't had coffee yet.

The CLI commands that mattered. Not a tour, just the five I actually touched:

ntn login                                       # once
ntn workers env set SHOPIFY_STORE=...            # secret setup
ntn workers deploy                              # the whole pipeline
ntn workers sync trigger shopifyOrders --local   # test against Shopify, no writes to Notion
ntn workers runs logs <run-id>                   # debug a specific run

The local sync trigger is the most underrated. It runs my code against Shopify but doesn't write to Notion, so I can dry-run, inspect transformed output, and fix bugs without polluting the database. --preview does the same thing post-deploy.

The moment it actually works. After deploying, I created a Custom Agent in Notion, attached the worker, and enabled both tools. Then I typed in a Notion page: "What's the order history for [customer email]?" The agent called getCustomerSnapshot, got back a structured payload (eight orders, $340 lifetime value, two refunds, VIP flag), and wrote that into the page as a clean summary. Question to answer, maybe four seconds.

This is the bit I struggled to communicate to people who weren't already on Notion. It's not "automated Slack message when a customer signs up." It's a real-time, conversational interface to your own business data, where the agent figures out which tool to call and what arguments to use. The Zapier comparison breaks down because Zapier was never trying to do this.

Going further. A webhook for refund events is in the repo as webhook.going-further.ts. It receives Shopify's refunds/create event, verifies the HMAC, and creates a triage page in a separate managed database. From there the obvious next moves are more tools (product performance, churn risk, cohort metrics) and a scheduled Custom Agent that builds a daily briefing page.

The whole thing took me about two hours, most of which was reading docs and untangling Shopify's pagination. The code is shorter than this article section about the code.

The Honest Verdict

I've been using this for less than a week, so anything I tell you about reliability or hidden gotchas is preliminary. Here's where I've landed after one real build and several reads of the docs.

Adopt now if you're already on Notion Business or Enterprise, you currently glue with Zapier or hand-rolled scripts, you use Custom Agents and have hit the limits of built-in connectors, or you run an agency delivering client-facing dashboards. The August 2026 free window is a gift. Use it to learn the surface before the meter starts.

Wait if your source of truth lives somewhere else (Salesforce, HubSpot, a custom app) and you use Notion lightly. You'll be better off keeping integration logic in your actual source of truth instead of building a Notion-shaped layer on top.

Skip if vendor lock-in is a hard line for you, or your workflows don't touch Notion at all. Workers code is @notionhq/workers-specific and won't run anywhere else without rewriting. Every worker you ship deepens the commitment.

The cost reality is straightforward but the unknowns matter. Business plan at $20 per user per month is the floor. Custom Agents already moved to credit-metered billing on May 4 at $10 per thousand credits. Workers join the same meter on August 11, 2026. Notion has said per-call Workers cost will be a fraction of agent token cost but hasn't published numbers. For a small store running something like the example above, I'd budget $5 to $15 a month in credits, but verify against your own usage during the free beta.

How much do Notion Workers cost?

Notion Workers are free during the beta through August 11, 2026. After that they join the Custom Agent credit system at $10 per 1,000 credits, purchased as a workspace add-on. Workers themselves cost less per call than full agent runs because they're deterministic code, not LLM reasoning. The Business plan at $20 per user per month is required to deploy Workers at all.

What I'm watching over the next six months: the August credit pricing, whether Notion publishes hard operational limits (concurrent executions, CPU time, response size are all currently unspecified), the first SLA, and whether a marketplace emerges. The platform is two days old at the time of writing. It deserves benefit of the doubt and skepticism in equal measure.

Workers won't replace your entire stack. They probably won't replace Zapier either, unless most of your Zaps already had Notion on one end. What they will do, if Notion is already where your business actually operates, is turn it from a great document-and-database tool into a genuinely programmable workspace where AI agents can call your code on real data. For the Shopify stores I work with, that's enough.

Thomas Wiegold

AI Solutions Developer & Full-Stack Engineer with 14+ years of experience building custom AI systems, chatbots, and modern web applications. Based in Sydney, Australia.

Ready to Transform Your Business?

Let's discuss how AI solutions and modern web development can help your business grow.

Get in Touch