Dinobase Connector Builder
kappa90/dinobase
Writes a new Dinobase YAML connector for a REST API that has no verified dlt source, covering auth, pagination, read and write endpoints and incremental loading.
Guides the design of Notion Workers syncs, from choosing a simple replace sync or a backfill plus delta pair to pagination, consistency buffers, pacing and deletion handling.
$ npx skills add makenotion/workers-template --skill sync-guide -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install makenotion/workers-template sync-guide --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/makenotion/workers-template.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/sync-guide .claude/skills/sync-guide && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "sync-guide" agent skill from https://github.com/makenotion/workers-template/tree/main/.agents/skills/sync-guide into .claude/skills/sync-guide/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "sync-guide", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/makenotion/workers-template/tree/main/.agents/skills/sync-guideType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add makenotion/workers-template --skill sync-guide -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install makenotion/workers-template sync-guide --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/makenotion/workers-template.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.agents/skills/sync-guide .agents/skills/sync-guide && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "sync-guide" agent skill from https://github.com/makenotion/workers-template/tree/main/.agents/skills/sync-guide into .agents/skills/sync-guide/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "sync-guide", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add makenotion/workers-template --skill sync-guide -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install makenotion/workers-template sync-guide --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/makenotion/workers-template.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.agents/skills/sync-guide .cursor/skills/sync-guide && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "sync-guide" agent skill from https://github.com/makenotion/workers-template/tree/main/.agents/skills/sync-guide into .cursor/skills/sync-guide/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "sync-guide", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/makenotion/workers-template.git --path .agents/skills/sync-guide--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add makenotion/workers-template --skill sync-guide -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install makenotion/workers-template sync-guide --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/makenotion/workers-template.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.agents/skills/sync-guide .gemini/skills/sync-guide && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "sync-guide" agent skill from https://github.com/makenotion/workers-template/tree/main/.agents/skills/sync-guide into .gemini/skills/sync-guide/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "sync-guide", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install makenotion/workers-template sync-guideInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add makenotion/workers-template --skill sync-guide -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/makenotion/workers-template.git skills-src && mkdir -p .github/skills && cp -r skills-src/.agents/skills/sync-guide .github/skills/sync-guide && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "sync-guide" agent skill from https://github.com/makenotion/workers-template/tree/main/.agents/skills/sync-guide into .github/skills/sync-guide/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "sync-guide", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add makenotion/workers-template --skill sync-guide -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install makenotion/workers-template sync-guide --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/makenotion/workers-template.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.agents/skills/sync-guide .opencode/skills/sync-guide && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "sync-guide" agent skill from https://github.com/makenotion/workers-template/tree/main/.agents/skills/sync-guide into .opencode/skills/sync-guide/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "sync-guide", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
sync-guideGuides the design of Notion Workers syncs, from choosing a simple replace sync or a backfill plus delta pair to pagination, consistency buffers, pacing and deletion handling.
A sync is a recurring execute function that returns changes, a hasMore flag and the next state to fill a Notion database, and the runtime loops until hasMore is false to complete one cycle. The skill's first decision is architecture. A small source of under 1k records, or an API without change tracking, uses one replace sync that deletes unseen records after the last page. Anything with updated timestamps or change feeds uses a backfill and delta pair writing to one database: a manual replace-mode backfill and a frequent incremental delta.
Safeguards include initializing the delta cursor before the backfill starts and putting an upstreamUpdatedAt value on upserts so a stale backfill cannot overwrite newer delta data. Pagination advice is to return batches of about 100 changes and to recognize opaque cursors, page numbers or offsets and keyset paging. Example TypeScript files show incremental, bimodal, event-based and replace-based syncs. The description adds pacers, deletion strategies and pitfalls, which fall in the cut-off part of the excerpt.
4 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit 681d89d. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Ships script files (TypeScript), which the agent can run.
From the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Notion Workers Sync Guide loads about 3k tokens when it runs. Until then it costs about 65 tokens; SKILL.md has 1,008 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from makenotion/workers-template at commit 681d89d, republished under its MIT licence (© makenotion). 1,008 words, ~2,996 tokens.
.claude/skills/sync-guide/SKILL.md (or your agent's skills folder). This skill also uses 6 other files; get the full folder from GitHub.A sync is a recurring execute function that returns data changes to populate a Notion database. The runtime calls execute in a loop:
const db = worker.database("myDb", {
type: "managed",
initialTitle: "My Data",
primaryKeyProperty: "ID",
schema: {
properties: {
Name: Schema.title(),
ID: Schema.richText(),
},
},
});
worker.sync("mySync", {
database: db,
execute: async (state, { notion }) => ({
changes: [
{ type: "upsert", key: "1", properties: { Name: Builder.title("Item 1"), ID: Builder.richText("1") } },
],
hasMore: false,
nextState: undefined,
}),
});Each call returns { changes, hasMore, nextState }. If hasMore is true, the runtime calls execute again with nextState. This continues until hasMore is false, completing a cycle. The next cycle begins at the scheduled interval with the state from the end of the previous cycle.
Imports:
import { Worker } from "@notionhq/workers";
import * as Builder from "@notionhq/workers/builder";
import * as Schema from "@notionhq/workers/schema";The deciding factor is API capability and dataset size. Two tiers:
| Condition | Architecture |
|---|---|
| Small source (<1k records) or API with no change tracking | Simple replace sync — one sync, mode: "replace" |
Everything else (API supports updated_at, change feeds, events) | Backfill + delta pair — two syncs writing to the same database |
Simple replace sync: One sync returns the full dataset each cycle. After the final hasMore: false, any records not seen are deleted automatically. Use when the dataset is small enough to re-fetch entirely.
Backfill + delta pair: Two syncs share a single database. The backfill sync (mode: "replace", schedule: "manual") re-fetches everything when triggered. The delta sync (mode: "incremental", frequent schedule) fetches only changes since the last run. This separates concerns cleanly — no bi-modal state machine, no backfill-to-delta transition bugs.
Initialize the delta cursor before starting the backfill. When both syncs can
write the same record, include upstreamUpdatedAt on each upsert so a stale
backfill response cannot overwrite a newer delta response.
Most APIs require paginating through results. Return batches of ~100 changes. Returning too many changes in one execute call will fail.
Backfill pagination (full dataset load):
endCursor, Stripe starting_after?page=N&limit=100WHERE created_at > X OR (created_at = X AND id > Y) — the gold standard for timestamp-sorted mutable dataDelta pagination (change-only loads, incremental mode):
?updated_since=<cursor> with consistency bufferGET /events?after=<eventId>updated_at, the backfill cursor works for delta tooAPIs tend to be eventually consistent. A record that was just written or updated may not appear in query results immediately. Since the cursor never resets in incremental mode, if it advances past a record that hasn't been indexed yet, that record is skipped permanently. Lag the cursor 10-60 seconds behind "now":
const bufferMs = 15_000;
const maxCursor = new Date(Date.now() - bufferMs).toISOString();
function minTimestamp(a: string, b: string): string {
return Date.parse(a) <= Date.parse(b) ? a : b;
}
const nextCursor = records.length > 0
? minTimestamp(lastRecord.updatedAt, maxCursor)
: maxCursor;{ type: "delete", key } markers. If the delete signal comes from a separate endpoint (audit log, archived filter), use the flip-flop pattern: run the main delta stream until caught up (hasMore: false), then switch to the delete stream for a cycle, then back. Both cursors persist in state independently.Simple: fetch everything, return it all, let the runtime handle deletes. Use as a standalone sync for small sources, or as the backfill half of a backfill+delta pair.
const db = worker.database("records", {
type: "managed",
initialTitle: "Records",
primaryKeyProperty: "ID",
schema: {
properties: { Name: Schema.title(), ID: Schema.richText() },
},
});
const apiPacer = worker.pacer("myApi", {
allowedRequests: 10,
intervalMs: 1000,
});
worker.sync("recordsBackfill", {
database: db,
mode: "replace",
schedule: "manual", // trigger manually or on a slow schedule
execute: async (state) => {
const page = state?.page ?? 1;
await apiPacer.wait();
const { items, totalPages } = await fetchPage(page, 100);
const hasMore = page < totalPages;
return {
changes: items.map((item) => ({
type: "upsert" as const,
key: item.id,
properties: { Name: Builder.title(item.name), ID: Builder.richText(item.id) },
})),
hasMore,
nextState: hasMore ? { page: page + 1 } : undefined,
};
},
});See examples/replace-simple.ts and examples/replace-paginated.ts for complete working examples.
The delta sync fetches only changes since the last run. When paired with a replace-mode backfill sync on the same database, this replaces the old bi-modal single-sync pattern.
// Reuses the same `db` and `apiPacer` from above
worker.sync("recordsDelta", {
database: db,
mode: "incremental",
schedule: "5m",
execute: async (state: { cursor: string } | undefined) => {
const cursor = state?.cursor ?? new Date(0).toISOString();
const bufferTs = new Date(Date.now() - 15_000).toISOString();
await apiPacer.wait();
// fetchChanges must apply bufferTs as an upstream upper bound.
const { items, nextCursor } = await fetchChanges(cursor, bufferTs);
const done = !nextCursor;
return {
changes: items.map(toUpsert),
hasMore: !done,
nextState: {
// This example assumes nextCursor is an ISO timestamp. Opaque cursors
// must not be compared with the timestamp buffer.
cursor: done ? minTimestamp(nextCursor ?? cursor, bufferTs) : nextCursor,
},
};
},
});Key points:
db handle.See examples/incremental-basic.ts, examples/incremental-bimodal.ts, and examples/incremental-events.ts for complete patterns.
Define the Notion database shape with Schema types and build values with Builder:
| Schema type | Builder value | Notes |
|---|---|---|
Schema.title() | Builder.title("text") | Primary display field. Every schema needs exactly one. |
Schema.richText() | Builder.richText("text") | Text content, IDs |
Schema.url() | Builder.url("https://...") | URL field |
Schema.email() | Builder.email("a@b.com") | Email field |
Schema.phoneNumber() | Builder.phoneNumber("+1...") | Phone field |
Schema.checkbox() | Builder.checkbox(true) | Boolean |
Schema.file() | Builder.file("https://...", "name") | File URL + optional display name |
Schema.number() | Builder.number(42) | Number. Optional format: Schema.number("percent") |
Schema.date() | Builder.date("2024-01-15") | Date (YYYY-MM-DD). Also: Builder.dateTime("2024-01-15T10:30:00Z"), Builder.dateRange(start, end) |
Schema.select([...]) | Builder.select("Option A") | Single select. Define options: Schema.select([{ name: "A" }, { name: "B" }]). Options must have non-empty name values — Schema.select([]) and { name: "" } are not supported. |
Schema.multiSelect([...]) | Builder.multiSelect("A", "B") | Multi select |
Schema.status(...) | Builder.status("Done") | Status with groups |
Schema.people() | Builder.people("email@co.com") | People by email |
Schema.place() | Builder.place({ lat: 40.7, lon: -74.0 }) | Geographic location |
Schema.relation("databaseKey") | [Builder.relation("pk")] | Relation to another managed database. Value is an array. |
Relations use the related database key. Two-way relations are configured the same way:
Schema.relation("otherDatabase", { twoWay: true, relatedPropertyName: "Back Link" })Row-level icons and page content:
changes: [{
type: "upsert", key: "1",
properties: {
Name: Builder.title("Example"),
// ... other properties ...
},
icon: Builder.emojiIcon("🎯"), // or Builder.notionIcon("rocket", "blue")
pageContentMarkdown: "## Details\nSome text", // Markdown body for the page
}]execute should be preceded by await apiPacer.wait(). Without it, syncs will hit rate limits and fail.nextState changes between iterations.state is undefined on first call. Use state?.cursor ?? null.worker.database() handle and the same key/properties shape.schedule: "manual" won't run automatically. Trigger it on deploy or periodically to clean up deleted records.Schema.select() requires at least one option with a non-empty name. Schema.select([]) and { name: "" } are not supported.# Deploy
ntn workers deploy
# Preview (test without writing)
ntn workers sync trigger <key> --preview
ntn workers sync trigger <key> --preview --context '<json>' # continue pagination
# Trigger a sync run
ntn workers sync trigger <key>
# Check sync status
ntn workers sync status
# View run logs
ntn workers runs list
ntn workers runs list --plain | head -n1 | cut -f1 | xargs -I{} ntn workers runs logs {}
# Reset state (full re-backfill)
ntn workers sync state reset <key>
# Manage secrets
ntn workers env set KEY=value
ntn workers env pushSee api-pagination-patterns.md for detailed strategies drawn from production syncs with Salesforce, Stripe, HubSpot, GitHub, and ServiceNow.
© makenotion, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 6 other files in .agents/skills/sync-guide of makenotion/workers-template.
Open the folder on GitHubat commit 681d89d
We found 1 copy of this SKILL.md (exact, near-identical or edited) in other folders, from 1 other GitHub owner. This page covers the copy in makenotion/workers-template, which our catalogue first saw on October 7, 2026.
Notion Workers Sync Guide next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Notion Workers Sync Guide this skillmakenotion/workers-template | 439 | 1 repos | ~3k | Automated safety check: Pass | MIT | |
| Dinobase Connector Builderkappa90/dinobase | 263 | — | ~1.9k | Automated safety check: Pass | Custom licence | |
| API Integrationsickn33/agentic-awesome-skills | 47k | 1 repos | ~1.3k | Automated safety check: Pass | MIT | |
| Integration PatternsJoelLewis/finance_skills | 205 | — | ~10k | Automated safety check: Pass | MIT | |
| Finta SDK Patternsjeremylongshore/tons-of-skills-marketplace | 2.8k | — | ~1.2k | Automated safety check: Pass | MIT | |
| LangBot EBA Adapter Developmentlangbot-app/LangBot | 18k | — | ~4k | Automated safety check: Pass | Apache-2.0 |
kappa90/dinobase
Writes a new Dinobase YAML connector for a REST API that has no verified dlt source, covering auth, pagination, read and write endpoints and incremental loading.
sickn33/agentic-awesome-skills
Designs event-driven architectures, webhook systems, API chaining flows, ETL pipelines, and integration patterns between services.
JoelLewis/finance_skills
Design and implement integration architectures connecting financial systems — APIs, FIX protocol, ISO 20022, event-driven patterns, batch feeds, idempotency, and resilience.
jeremylongshore/tons-of-skills-marketplace
Integration patterns for Finta fundraising CRM with email and calendar APIs.
langbot-app/LangBot
Guides building, migrating and testing LangBot messaging-platform adapters for the Event-Based Agents layout, with unified event and message conversion.
Yourdaylight/stock_datasource
Turns a Tushare API doc URL into a full data plugin for the stock_datasource repo: extractor, ClickHouse schema, query service, config and curl examples.
makenotion/workers-template
Decides whether a Notion Worker should use a brokered credential, a plaintext environment secret, or OAuth to authenticate against a non-Notion service.
makenotion/workers-template
Walks you through designing a new sync for a Notion Worker, covering data source, mode, pagination and cursors, and then generates working code.
makenotion/workers-template
Works out why a Workers sync is failing or returning wrong data by reading run logs through the ntn CLI, matching errors to the sync code and proposing fixes.
makenotion/workers-template
Checks a Workers sync capability against a list of common bugs, such as stuck cursors, endless pagination and lost deletions, and reports by severity.
Works with
Categories
Guides the design of Notion Workers syncs, from choosing a simple replace sync or a backfill plus delta pair to pagination, consistency buffers, pacing and deletion handling. A sync is a recurring execute function that returns changes, a hasMore flag and the next state to fill a Notion database, and the runtime loops until hasMore is false to complete one cycle. The skill's first decision is architecture.
Notion Workers Sync Guide fits situations like: building a Notion Workers sync from an external API; choosing between a replace sync and a backfill plus delta pair; paginating a large API without exceeding the per-call change limit; preventing stale backfill data from overwriting recent updates.
Run `npx skills add makenotion/workers-template --skill sync-guide -a claude-code`. Or copy the skill folder (.agents/skills/sync-guide in makenotion/workers-template) into .claude/skills/sync-guide in your project. Claude Code loads it when a task matches its description.
Run `npx skills add makenotion/workers-template --skill sync-guide -a codex`. Or copy the skill folder (.agents/skills/sync-guide in makenotion/workers-template) into .agents/skills/sync-guide in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add makenotion/workers-template --skill sync-guide -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/sync-guide, .gemini/skills/sync-guide, .github/skills/sync-guide and .opencode/skills/sync-guide in your project.
Going by SKILL.md and its folder, Notion Workers Sync Guide needs TypeScript for the scripts in its folder. Our summary lists: A Notion Workers project using the @notionhq/workers package.
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Notion Workers Sync Guide is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 3k tokens (SKILL.md is roughly 12k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Notion Workers Sync Guide: Dinobase Connector Builder (kappa90/dinobase, 263 stars), API Integration (sickn33/agentic-awesome-skills, 47k stars), Integration Patterns (JoelLewis/finance_skills, 205 stars) and Finta SDK Patterns (jeremylongshore/tons-of-skills-marketplace, 2.8k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
makenotion (a GitHub organization, an official publisher) maintains it in makenotion/workers-template, which has 439 GitHub stars. The repository holds 5 skills in this directory. The repository was last updated on September 11, 2026.
Source: makenotion/workers-template on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.