How it works
- Step 1Fork the blueprint — Open this workflow and click Fork. The from-blueprint route copies the two-node chain (
rss-feed→notion-page-create) into a private draft you own, snapshots it as version 1, and carries the0 8 * * *schedule across. Any signed-in account can fork it. - Step 2Pair a runner — Both nodes are connector tools and run runner-only, so they execute on your paired runner — not in the browser and not on the JAD server. Pair a runner before you run, or the connector nodes have nowhere to execute.
- Step 3Set the feed URL — On the RSS node, set
urlto your feed. Optionally caplimit(default 50, max 500) and setsinceto an ISO date so only items newer than that timestamp come through — the cheapest way to avoid re-importing old posts. - Step 4Store the Notion token and point the node at it — Create a Notion integration, share your target database with it, and store the secret on your runner as a credential. On the Notion node, set
databaseIdand setcredentialRefto that credential's name (the blueprint default isnotion-prod). - Step 5Decide the page title and body — Set
titleon the Notion node, or leave it blank to fall back to the first line of the upstream text. Setcontentfor the page body, or leave it to inherit the upstream item text. Notion finds the title-typed property in your database schema automatically. - Step 6Confirm tier, then run or let cron fire —
notion-page-createrequires Pro, so the run pre-check gates the whole workflow at Pro. Once you're on Pro with a runner paired, run it manually to verify, then leave the daily cron to fire0 8 * * *every morning.
The real node chain
Exactly what the rss-to-notion-digest blueprint wires, in order. Both nodes are connector-category tools and run runner-only.
| # | Node (tool slug) | Input → Output port | Blueprint config | Credential / tier |
|---|---|---|---|---|
| 1 | RSS / Atom Feed (rss-feed) | in * → out json | url: https://example.com/feed.xml, limit: 20 | none · free |
| 2 | Notion: Create Page (notion-page-create) | in * → out json | databaseId: (yours), title: "Daily RSS digest", credentialRef: notion-prod | Notion integration token · Pro |
Schedule, credential & tier matrix
How the orchestrator runtime actually treats this workflow — verified against the cron tick route, fork route, and tier pre-check.
| Concern | What the blueprint sets | How it works at runtime |
|---|---|---|
| Schedule | scheduleCron 0 8 * * * (daily 08:00) | Carried into the workflow's schedule_cron on fork; Cloudflare Cron Triggers hit /api/orchestrator/cron/tick, which enqueues a run when isDueSince() says it's due and stamps last_fired_at. |
| Forking | Anyone authenticated may fork | from-blueprint builds the graph, creates a row you own, snapshots v1, and writes a forked audit event tagged with the blueprint slug. |
| Credentials | credentialRef: notion-prod | Resolved on the paired runner via ctx.credentials[ref]; only the ref name is stored in the graph, never the token value. |
| Tier to run | rss-feed free, notion-page-create Pro | precheckWorkflowTier returns the strictest minTier across nodes — Pro here — and blocks the run with one upgrade CTA if you're below it. |
| History | — | Per-fork forked audit events plus a per-run step trace; both are server-side records, not files on your machine. |
Per-node config fields
The configurable fields each node exposes in the orchestrator registry. Unknown keys are ignored, so a blueprint can wire fields a tool grows later.
| Node | Field | Type | Default / note |
|---|---|---|---|
| rss-feed | url | text | required — the feed URL |
| rss-feed | limit | number | default 50, max 500 (blueprint sets 20) |
| rss-feed | since | text | optional ISO date; only items with pubDate ≥ since |
| notion-page-create | databaseId | text | required — target Notion database |
| notion-page-create | title | text | falls back to first line of upstream text |
| notion-page-create | content | textarea | falls back to upstream text; chunked at 2000 chars per block |
| notion-page-create | credentialRef | text | name of the stored integration-token credential (e.g. notion-prod) |
Cookbook
Five recipes that match how the chain actually behaves. The shipped blueprint is two nodes and one page per run — everything fancier (multi-feed fan-out, dedupe, per-feed error isolation) is something you add on the canvas after forking, using JAD's real logic nodes. Each recipe notes which part is stock and which part you build.
Stock daily digest, one feed
ExampleThe blueprint as-shipped: poll one feed each morning and create a Notion page. Set only the fields below; leave everything else default.
rss-feed: url: https://blog.example.com/feed.xml limit: 20 notion-page-create: databaseId: 1a2b3c... # your DB title: "Daily RSS digest" credentialRef: notion-prod schedule: 0 8 * * * # fires daily at 08:00 via the cron tick
Only import items newer than yesterday
ExampleThere is no built-in dedupe in this blueprint, so the cheapest dedupe is the RSS node's since filter — set it to your last run time so old posts are dropped before they ever reach Notion.
rss-feed: url: https://blog.example.com/feed.xml since: 2026-06-16T08:00:00Z # only pubDate >= this limit: 50 # items older than `since` are filtered out by the runner before Notion is touched
Let the page title come from the feed item
ExampleLeave the Notion title blank and the node uses the first line of the upstream text. The title-typed property in your database is auto-detected from the schema.
notion-page-create: databaseId: 1a2b3c... title: "" # blank -> first line of upstream text content: "" # blank -> upstream item text becomes the body credentialRef: notion-prod # runner does one GET on the DB schema to find the property where type == 'title'
Add real per-feed dedupe on the canvas (not stock)
ExampleThe seed copy of this page claimed a Filter node dedupes by URL — that node is NOT in the blueprint. To actually dedupe, fork, then drop a Filter logic node between the feed and Notion and route matches to its rejected port. This is a manual add.
# After forking, on the canvas: rss-feed -> [Filter: link not already in Notion] -> notion-page-create # \-> (rejected) -> drop # You wire the query/compare yourself; the shipped chain has no Filter node.
Fan out across many feeds (not stock)
ExampleThe shipped chain handles one URL. To pull 5–10 publications, fork and wrap the feed+Notion pair in a For-Each (the runner runs iterations with bounded concurrency, 1–32) over a list of URLs.
# After forking, on the canvas:
for-each (concurrency: 4) over [feedA, feedB, feedC, ...]:
rss-feed(url=item) -> notion-page-create(...)
# The blueprint itself is a single rss-feed -> notion-page-create edge.Edge cases and verbatim errors
Notion node has no credentialRef set
missing_credential (fail)If credentialRef is empty the notion-page-create runner returns the error code missing_credential before any network call. The blueprint default is notion-prod — set it to the name of a credential you actually stored on the runner.
credentialRef points at a credential the runner doesn't have
credential_missing (error)The runner looks the ref up in ctx.credentials and returns credential_missing if it isn't there. Because credentials live on the paired runner, a workflow that runs on a different runner than the one holding the token will fail here — store the credential on the runner that executes the schedule.
Integration token is present but malformed
bad_credential (fail)extractToken pulls the value from api_key / oauth2 / custom credential shapes. If it can't find a usable token the runner returns bad_credential. Re-create the Notion integration secret and re-store it.
Database ID missing or the integration isn't shared with it
missing_database / notion_404 (fail)An empty databaseId returns missing_database up front. A real ID that the integration can't see returns a Notion API error surfaced as notion_404 (or whatever status Notion sends). Share the database with the integration in Notion's connections panel.
Target database has no title-typed property
no_title_property (fail)The runner GETs the database schema and looks for a property with type 'title'. Every Notion database has one by default, but if it was removed the node returns no_title_property. Add a title column back to the database.
Feed URL is wrong or the host is down
rss_404 / network_error (error)A non-2xx response becomes rss_<status> (e.g. rss_404); a DNS/connection failure becomes network_error. In the shipped two-node chain this aborts the run because there's no Try/Catch wrapping the feed node — add one on the canvas if you want a bad feed to be non-fatal.
Feed parses but has zero items (or all older than `since`)
empty feed (ok)rss-feed returns ok with count 0 and summary 'no items'. notion-page-create then runs with whatever title you set; if both title and upstream text are empty it returns missing_title. Set a static title to keep empty runs harmless, or gate the Notion node behind a Filter.
Custom-namespace or unusual feed XML
partial parse (ok)The RSS node uses lightweight regex parsing for common RSS 2.0 / Atom shapes (title, link, description, pubDate/updated, guid, enclosure). Custom-namespace fields simply come through empty rather than erroring — verify the fields you care about populate before scheduling.
You're on Free (or below Pro) when you try to run
tier blocked (rejected)precheckWorkflowTier finds notion-page-create's Pro requirement and blocks the run with a single upgrade CTA naming the gated node. You can still fork and edit on Free; you just can't execute the Notion write until you upgrade.
Cron looks set but nothing fires
not due / no runner (silent)The tick route only enqueues when isDueSince() is true relative to last_fired_at, and a queued run still needs a paired runner to execute the connector nodes. If a feed runs daily but you expected hourly, check the cron expression; if it enqueues but never executes, check that a runner is paired and online.
Frequently asked questions
How many nodes are actually in this workflow?
Two: an RSS / Atom Feed node (rss-feed) and a Notion: Create Page node (notion-page-create), wired feed-output → Notion-input. That's the entire shipped blueprint. Anything more — multiple feeds, dedupe, retries — is something you add after forking.
Does it dedupe so I don't get the same article twice?
Not on its own. The shipped blueprint has no Filter node and no Notion-query step, so each run creates pages for whatever items the feed returns. The practical dedupe is the RSS node's since filter (only items newer than an ISO timestamp). For true URL-based dedupe, add a Filter logic node on the canvas after forking.
Where is my Notion token stored?
On your paired runner. The Notion node resolves it at run time via ctx.credentials[credentialRef]; the workflow graph saved on the server holds only the reference name (e.g. notion-prod), never the secret value.
What tier do I need?
Pro to run. notion-page-create is a Pro tool, and the run pre-check applies the strictest minTier across the whole graph, so the workflow gates at Pro. The RSS node by itself is free-tier.
Is the daily schedule real, or just a label?
Real. The blueprint sets 0 8 * * *, which becomes the workflow's schedule_cron on fork. Cloudflare Cron Triggers call /api/orchestrator/cron/tick, which checks each scheduled workflow with isDueSince() and enqueues a run when it's due, then stamps last_fired_at.
Can I change the schedule?
Yes — edit schedule_cron on your forked workflow to any standard cron expression. The tick route parses it with parseCron and fires accordingly. Hourly, weekday-only, twice-daily all work.
How do I fork it?
Click Fork on this page. The from-blueprint route copies the two-node chain into a private draft you own, snapshots it as version 1, and records a forked audit event tagged with the blueprint slug. Any authenticated account can fork.
Why do I need a runner paired?
Both nodes are connector-category tools, which run runner-only — they execute on your paired runner, not in the browser or on the JAD server. Without a paired runner the connector nodes have nowhere to run, so a queued run won't execute.
Can I pull from several feeds at once?
The blueprint handles one URL. To cover 5–10 publications, fork and wrap the feed+Notion pair in a For-Each over a list of URLs — the runner executes iterations with bounded concurrency (configurable 1–32). The seed copy mentioned a Parallel node; that node isn't part of this blueprint and you'd build the fan-out yourself.
What happens if one feed is down?
In the shipped two-node chain a non-2xx feed (rss_<status>) or a network failure (network_error) aborts the run, because there's no Try/Catch around the feed node. JAD does have a real Try/Catch logic node and per-node retry/skip error policies — add one on the canvas if you want a single bad feed to be non-fatal.
How does the page title get set?
Set title on the Notion node, or leave it blank to use the first line of the upstream text. The node then GETs your database schema once to find the property whose type is 'title' and writes there, so you never hard-code which column is the title.
Where can I see what ran?
Each fork writes a forked audit event and each run records a step trace (the runs trace endpoint). These are server-side records for history and attribution, not files written to your local machine — useful for confirming the 8am run actually fired and which node, if any, errored.
Local-first by design
This workflow executes entirely on your jadapps-runner. API keys, database credentials, and OAuth tokens are stored in an AES-GCM-encrypted vault on your device — they are never uploaded to JAD Apps' servers. The server only stores the workflow graph (the recipe), not the secrets.