Workspace API
friday-platform/friday-studio
Create, list, update, delete, and clean up workspaces via the daemon HTTP API at $FRIDAYDURL.
A skill your agent uses when wiring server code or a cron job to Notion as an ops backend over its HTTP API: pushing or mirroring database rows, two-way sync without duplicates, page blocks, or an…
$ npx skills add ericrisco/rsc-harness --skill notion-connector -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install ericrisco/rsc-harness notion-connector --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/ericrisco/rsc-harness.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/notion-connector .claude/skills/notion-connector && 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 "notion-connector" agent skill from https://github.com/ericrisco/rsc-harness/tree/main/skills/notion-connector into .claude/skills/notion-connector/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "notion-connector", 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/ericrisco/rsc-harness/tree/main/skills/notion-connectorType 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 ericrisco/rsc-harness --skill notion-connector -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install ericrisco/rsc-harness notion-connector --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/ericrisco/rsc-harness.git skills-src && mkdir -p .agents/skills && cp -r skills-src/skills/notion-connector .agents/skills/notion-connector && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "notion-connector" agent skill from https://github.com/ericrisco/rsc-harness/tree/main/skills/notion-connector into .agents/skills/notion-connector/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "notion-connector", 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 ericrisco/rsc-harness --skill notion-connector -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install ericrisco/rsc-harness notion-connector --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/ericrisco/rsc-harness.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/skills/notion-connector .cursor/skills/notion-connector && 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 "notion-connector" agent skill from https://github.com/ericrisco/rsc-harness/tree/main/skills/notion-connector into .cursor/skills/notion-connector/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "notion-connector", 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/ericrisco/rsc-harness.git --path skills/notion-connector--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 ericrisco/rsc-harness --skill notion-connector -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install ericrisco/rsc-harness notion-connector --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/ericrisco/rsc-harness.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/skills/notion-connector .gemini/skills/notion-connector && 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 "notion-connector" agent skill from https://github.com/ericrisco/rsc-harness/tree/main/skills/notion-connector into .gemini/skills/notion-connector/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "notion-connector", 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 ericrisco/rsc-harness notion-connectorInstalls 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 ericrisco/rsc-harness --skill notion-connector -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/ericrisco/rsc-harness.git skills-src && mkdir -p .github/skills && cp -r skills-src/skills/notion-connector .github/skills/notion-connector && 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 "notion-connector" agent skill from https://github.com/ericrisco/rsc-harness/tree/main/skills/notion-connector into .github/skills/notion-connector/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "notion-connector", 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 ericrisco/rsc-harness --skill notion-connector -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install ericrisco/rsc-harness notion-connector --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/ericrisco/rsc-harness.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/skills/notion-connector .opencode/skills/notion-connector && 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 "notion-connector" agent skill from https://github.com/ericrisco/rsc-harness/tree/main/skills/notion-connector into .opencode/skills/notion-connector/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "notion-connector", 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.
notion-connectorA skill your agent uses when wiring server code or a cron job to Notion as an ops backend over its HTTP API: pushing or mirroring database rows, two-way sync without duplicates, page blocks, or an…
Notion Connector is an agent skill from ericrisco/rsc-harness. Use when wiring server code or a cron job to Notion as an ops backend over its HTTP API: pushing or mirroring database rows, two-way sync without duplicates, page blocks, or an integration broken by the 2025-09-03 data-source split. NOT generic REST wiring (that is api-connector-builder), NOT inbound Notion webhook events (that is webhooks).
Its SKILL.md is about 2.4k tokens, which your agent loads only when the skill is triggered. The skill folder holds 9 other files, including scripts and reference files (for example `evals/README.md`, `evals/cases.yaml` and `references/api-versions.md`).
It sits in Backend & APIs, covering Webhooks, REST APIs and Scheduled and recurring tasks. It works with Notion. The repository describes itself as: Your agent invents things because it has no memory, and can't touch your database because it has no arms. rsc is the meta-harness that gives it both, plus the trade to know the… The licence is MIT.
4 steps, taken from the first numbered list in SKILL.md.
Read from SKILL.md and the folder at commit e3d5b33. 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 1 file in scripts/ (Shell), 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 these keys or tokens, usually read from environment variables:
NOTION_TOKENFrom names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Notion Connector loads about 2.4k tokens when it runs, and up to ~5.1k if it reads all its reference files. Until then it costs about 91 tokens; SKILL.md has 878 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); the scripts in this folder are not scanned.
The full file from ericrisco/rsc-harness at commit e3d5b33, republished under its MIT licence (© ericrisco). 878 words, ~2,432 tokens.
.claude/skills/notion-connector/SKILL.md (or your agent's skills folder). This skill also uses 6 other files; get the full folder from GitHub.Wire server code to the Notion HTTP API so a database behaves like a small operational store: push rows, pull rows, sync both ways idempotently, read and write page blocks. This skill owns the outbound Notion API surface only — the database/data-source data model, property-type write shapes, and the rate-limit/pagination discipline that the API forces on you.
| Situation | Route to |
|---|---|
| Generic "call any REST API", nothing Notion-specific | ../api-connector-builder/SKILL.md |
| Receiving + verifying inbound Notion webhook events | ../webhooks/SKILL.md |
| Notion is one node in a multi-tool sequence | ../automation-flows/SKILL.md |
| CSV/tabular bulk transforms, column mechanics | ../spreadsheet-ops/SKILL.md |
| Token handling, secret rotation, never-client-side rules | ../secure-coding/SKILL.md |
ntn_... (older ones secret_...).../secure-coding/SKILL.md.••• menu → Connections). Skip this and every call 404s or
returns empty — the integration sees nothing it was not explicitly granted.Notion-Version. Official JS SDK
is @notionhq/client v5.12.0+ (latest 5.22.0, 2026-05-19); its default
notionVersion is the current major 2025-09-03, and it supports the
latest 2026-03-11 if you opt in. The default and method names below are
stable across the whole 5.x line. Behavior differs across versions, so pin it
per client (or per request) — an unpinned client drifts when the default moves.import { Client } from "@notionhq/client"; // v5.12.0+ (latest 5.22.0)
const notion = new Client({
auth: process.env.NOTION_TOKEN, // ntn_... — env only, never inlined
notionVersion: "2025-09-03", // pin it; do not ride the default
});Post 2025-09-03 a database is a container of one or more data sources, not
a queryable table: it holds a data_sources array and each data source has its
own schema. Resolve the data source before you query — query and read
schema against it, not against the database, or code that worked last year 404s
silently.
| You have… | Do this |
|---|---|
A database_id | GET /v1/databases/:id → read data_sources[] ({id,name}) → use that id |
Already a data_source_id | Use it directly for query/schema/pages |
| A DB with >1 data source | Pick the right one by name; never assume index 0 |
Endpoints moved to /v1/data_sources:
- POST /v1/databases/:database_id/query # 2022-06-28 — 404s on 2025-09-03+
+ POST /v1/data_sources/:data_source_id/query # query rows
+ GET /v1/data_sources/:data_source_id # schema (properties)
+ PATCH /v1/data_sources/:data_source_id # update schema / title// Resolve once, then reuse the data_source_id everywhere downstream.
const db = await notion.databases.retrieve({ database_id: DATABASE_ID });
const dataSourceId = db.data_sources[0].id; // verify by name if >1 existsSend filter + sorts in the body. Page size maxes at 100; results are
cursor-based. Always loop on has_more + next_cursor or you silently drop
every row past the first 100. Filter operand shapes per property type live in
references/property-shapes.md.
async function queryAll(dataSourceId: string, filter?: object) {
const rows: any[] = [];
let cursor: string | undefined = undefined;
do {
const res = await notion.dataSources.query({
data_source_id: dataSourceId,
filter,
page_size: 100, // hard max
start_cursor: cursor,
});
rows.push(...res.results);
cursor = res.has_more ? res.next_cursor ?? undefined : undefined;
} while (cursor);
return rows;
}Most write failures (HTTP 400) are a wrong property envelope. Each type has its own JSON shape. The high-frequency ones:
| Type | Write shape (abridged) |
|---|---|
title | { title: [{ text: { content } }] } |
rich_text | { rich_text: [{ text: { content } }] } |
number | { number: 42 } |
select | { select: { name } } |
multi_select | { multi_select: [{ name }] } |
status | { status: { name } } |
date | { date: { start, end? } } (ISO 8601) |
checkbox | { checkbox: true } |
relation | { relation: [{ id }] } |
people | { people: [{ id }] } |
url | { url: "https://…" } |
Full write + read-parse JSON for every type → references/property-shapes.md.
A page's parent is the data source, not the database:
// CREATE a row
await notion.pages.create({
parent: { type: "data_source_id", data_source_id: dataSourceId },
properties: {
Name: { title: [{ text: { content: "Ship invoice export" } }] },
Status: { status: { name: "In progress" } },
ExternalId: { rich_text: [{ text: { content: extId } }] },
},
});
// UPDATE a row: PATCH the page by id; send only changed properties
await notion.pages.update({
page_id,
properties: { Status: { status: { name: "Done" } } },
});To soft-delete: on 2025-09-03 set { archived: true }; on 2026-03-11 that
field is renamed { in_trash: true }. Match the field to the version you pinned
(see references/api-versions.md).
Idempotency is the whole game. Store the Notion page_id keyed by your
external id (a column in your DB, or a rich_text "ExternalId" property in
Notion). An upsert is: query-by-external-key → if a row exists, pages.update;
else pages.create. Never blind-create on a re-run — that is how you get
duplicate rows.
last_edited_time watermark on each side; last-writer
wins, or flag conflicts for review. Cursor-checkpoint large pulls.Dedupe, two-way reconcile, and checkpointing → references/sync-patterns.md.
The integration is capped at ~3 requests/second average. Over-limit calls
return HTTP 429 with a Retry-After header (seconds) — honor it, do not
guess a fixed sleep. Cap concurrency, batch reads, back off on 429.
async function withRetry<T>(fn: () => Promise<T>, tries = 5): Promise<T> {
for (let i = 0; ; i++) {
try {
return await fn();
} catch (e: any) {
const after = Number(e?.headers?.["retry-after"]);
if (e?.status === 429 && i < tries) {
const wait = Number.isFinite(after) ? after * 1000 : 2 ** i * 500;
await new Promise((r) => setTimeout(r, wait));
continue;
}
throw e;
}
}
}| From → To | What changed |
|---|---|
2022-06-28 → 2025-09-03 | DB is a container; query/schema move to /v1/data_sources; page parent is data_source_id; search filter value "database" → "data_source" |
2025-09-03 → 2026-03-11 | block after param → position object (after_block/start/end); archived → in_trash (pages/dbs/blocks/data sources); block type transcription → meeting_notes |
Exact field/endpoint diffs → references/api-versions.md.
| Anti-pattern | Why it bites | Do instead |
|---|---|---|
Unpinned Notion-Version | Behavior shifts when the default moves | Pin per request/client |
POST /v1/databases/:id/query on 2025-09-03+ | 404 — that path is gone | Resolve data source → /v1/data_sources/:id/query |
| Forgetting to share the DB with the integration | 404 / empty results, looks like an auth bug | Share in the UI (step 3) |
| No pagination loop | Silently drops every row past 100 | Loop on has_more + next_cursor |
| Ignoring 429 / fixed sleep | Hammers the 3 req/s ceiling, gets banned | Honor Retry-After, exponential backoff |
Blind pages.create on every sync | Duplicate rows on re-run | Upsert: query-by-external-key first |
| Token in client-side JS or committed | Leaked bearer secret = full workspace access | Env var + secret manager |
| Assuming one DB = one schema | Breaks on multi-data-source DBs | Resolve and select by data-source name |
Using database_id as a page parent | Rejected on 2025-09-03+ | { type: "data_source_id", data_source_id } |
archived on 2026-03-11 | Field renamed | Use in_trash for that version |
scripts/verify.sh <file-or-dir> statically lints a connector you (or the agent)
wrote: it flags a missing pinned Notion-Version/notionVersion, a deprecated
databases/:id/query query path, a query without a has_more/next_cursor
loop, and missing 429/Retry-After handling. Read-only; exits 0 on a clean or
empty target. It does not call Notion.
© ericrisco, 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 (scripts, references) in skills/notion-connector of ericrisco/rsc-harness.
Open the folder on GitHubat commit e3d5b33
Notion Connector 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 Connector this skillericrisco/rsc-harness | 174 | — | ~2.4k | Automated safety check: Pass | MIT | |
| Workspace APIfriday-platform/friday-studio | 104 | — | ~9.3k | Automated safety check: Notes | Custom licence | |
| Function Devbutterbase-ai/butterbase-skills | 534 | — | ~2.8k | Automated safety check: Pass | MIT | |
| Nextclaw Self ManagePeiiii/nextclaw | 260 | — | ~3.5k | Automated safety check: Pass | MIT | |
| Wp Performancegambitph/Stackable | 351 | 3 repos | ~1.5k | Automated safety check: Pass | GPL-3.0 | |
| API Patternsdilolabs/nosia | 213 | 1 repos | ~2.5k | Automated safety check: Pass | MIT |
friday-platform/friday-studio
Create, list, update, delete, and clean up workspaces via the daemon HTTP API at $FRIDAYDURL.
butterbase-ai/butterbase-skills
A skill your agent uses when developing, deploying, or debugging Butterbase serverless functions, or when the user needs to add backend logic like webhooks, scheduled jobs, or custom API endpoints
Peiiii/nextclaw
Self-manage NextClaw runtime via CLI guide. An agent skill from Peiiii/nextclaw.
gambitph/Stackable
A skill your agent uses when investigating or improving WordPress performance (backend-only agent): profiling and measurement (WP-CLI profile/doctor, Server-Timing, Query Monitor via REST headers)…
dilolabs/nosia
Builds REST APIs using respondto blocks with Jbuilder templates following the 37signals same-controllers-different-formats philosophy.
openinary/openinary
A skill your agent uses whenever the user wants to integrate Loops from application code, backend services, webhook handlers, or server-side automation.
ericrisco/rsc-harness
A skill your agent uses when designing or analyzing a controlled experiment — falsifiable hypothesis, sample size from an MDE, reading significance/CI/power, CUPED, or rescuing tests that won't go…
ericrisco/rsc-harness
A skill your agent uses when making a web UI conform to WCAG 2.2 Level AA — axe-core or Lighthouse a11y violations, keyboard operability, focus management, ARIA roles/names/live regions, contrast…
ericrisco/rsc-harness
A skill your agent uses when running or fixing paid acquisition on Google or Meta — campaign structure (Performance Max, Demand Gen, Search, Advantage+), platform-fit creative, budget/scaling rules…
ericrisco/rsc-harness
A skill your agent uses when measuring whether an LLM or agent system actually got better and gating merges on it: golden sets, fixing an inflated LLM-as-judge, scoring RAG (faithfulness, contextual…
ericrisco/rsc-harness
A skill your agent uses when a creative goal must become a finished media file: pick and order generative-media models per modality — AI voiceover, image-to-video clips, score — then glue them with…
ericrisco/rsc-harness
A skill your agent uses when instrumenting product or web analytics — GA4/PostHog SDK wiring, event taxonomy, funnels, double-counted events, consent gating, PII scrubbing.
Works with
Categories
A skill your agent uses when wiring server code or a cron job to Notion as an ops backend over its HTTP API: pushing or mirroring database rows, two-way sync without duplicates, page blocks, or an…. Notion Connector is an agent skill from ericrisco/rsc-harness. Use when wiring server code or a cron job to Notion as an ops backend over its HTTP API: pushing or mirroring database rows, two-way sync without duplicates, page blocks, or an integration broken by the 2025-09-03 data-source split.
Notion Connector fits situations like: wiring server code; A cron job to Notion as an ops backend over its HTTP API: pushing; mirroring database rows; two-way sync without duplicates.
Run `npx skills add ericrisco/rsc-harness --skill notion-connector -a claude-code`. Or copy the skill folder (skills/notion-connector in ericrisco/rsc-harness) into .claude/skills/notion-connector in your project. Claude Code loads it when a task matches its description.
Run `npx skills add ericrisco/rsc-harness --skill notion-connector -a codex`. Or copy the skill folder (skills/notion-connector in ericrisco/rsc-harness) into .agents/skills/notion-connector 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 ericrisco/rsc-harness --skill notion-connector -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/notion-connector, .gemini/skills/notion-connector, .github/skills/notion-connector and .opencode/skills/notion-connector in your project.
Going by SKILL.md and its folder, Notion Connector needs a shell for the scripts in its folder and credentials named NOTION_TOKEN. Our summary lists: A Bash shell; A credential in NOTION_TOKEN.
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. The check reads SKILL.md only: the scripts in the folder are not scanned, so read them before running anything.
Notion Connector is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 2.4k tokens (SKILL.md is roughly 9.7k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 2.6k tokens, read only when the agent opens those files.
Skills that share tags, products or a category with Notion Connector: Workspace API (friday-platform/friday-studio, 104 stars), Function Dev (butterbase-ai/butterbase-skills, 534 stars), Nextclaw Self Manage (Peiiii/nextclaw, 260 stars) and Wp Performance (gambitph/Stackable, 351 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
ericrisco (a GitHub user) maintains it in ericrisco/rsc-harness, which has 174 GitHub stars. The repository holds 233 skills in this directory. The repository was last updated on October 7, 2026.
Source: ericrisco/rsc-harness on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.