A TypeScript CLI tool that duplicates Notion database entries from templates. It uses a two-database architecture where one database stores your master templates, and another receives the duplicated entries with updated dates.
The tool uses two separate Notion databases:
- Templates Database: Contains your master template entries (read-only)
- Target Database: Where new entries are created based on templates (write-only)
When you run the tool with a target date, it:
- Reads all entries from the Templates Database
- Duplicates each entry to the Target Database
- Updates any date/datetime properties to the target date
- Preserves all other properties (text, numbers, selections, etc.)
- Handles multi-day date ranges correctly
Create recurring daily schedules without manual copying.
- Templates DB: "Morning standup 9:00-9:30", "Focus time 10:00-12:00"
- Target DB: Daily time blocks for each workday
- Use: Run daily via cron to populate your schedule
Generate task lists for regular intervals (daily, weekly, monthly).
- Templates DB: Standard project setup tasks
- Target DB: Task lists for each new project
- Use: Run when starting a new project or sprint
Duplicate standard meeting agendas with updated dates.
- Templates DB: Standard agenda items for different meeting types
- Target DB: Specific meeting instances with actual dates
- Use: Run before scheduling a recurring meeting
Clone event planning checklists for recurring events.
- Templates DB: Master event checklist with relative timings
- Target DB: Specific event instances with actual dates
- Use: Run when planning a new instance of a recurring event
Generate periodic reports from templates.
- Templates DB: Report structure with data points to collect
- Target DB: Monthly/quarterly report instances
- Use: Run at the start of each reporting period
Create two Notion databases with identical schemas:
Templates Database:
- Create a database with your desired properties
- Include at least one date/datetime property (e.g., "Date", "When", "Due Date")
- Add your template entries with sample dates
- These templates will be duplicated to the target database
Target Database:
- Create another database with the exact same schema
- All property names and types must match the Templates Database
- Can be empty initially
- This is where duplicated entries will be created
Example for Time Blocks:
- Both databases have: Title (text), When (date with time), Duration (number), Category (select)
- Templates DB contains: "Morning standup 9:00-9:30", "Focus time 10:00-12:00"
- Target DB will receive these entries with updated dates
- Go to https://www.notion.so/my-integrations
- Create a new integration and copy the API key
- Share both databases with your integration:
- Open each database in Notion
- Click "..." menu → "Add connections" → Select your integration
# Clone or download this repository
npm install
npm run build
# Set up environment variables
cp .env.example .envEdit .env and add your credentials:
NOTION_API_KEY: Your integration API keyNOTION_TEMPLATES_DATABASE_ID: Database ID from Templates Database URLNOTION_TIME_BLOCKS_DATABASE_ID: Database ID from Target Database URL
Finding Database IDs:
Database IDs are in the URL when viewing a database in Notion:
https://www.notion.so/workspace/DATABASE_ID?v=...
Copy the 32-character ID between the workspace name and the ?v=
# 1. Initialize: Save templates locally
npm start -- --init
# 2. Create entries for today
npm start
# 3. Create entries for a specific date
npm start -- 2024-03-15
# 4. Clean up: Delete all entries from target database
npm start -- --purge --confirm# Initialize mode: Save schema and templates locally
npm start -- --init
node dist/index.js --init
# Create entries for today (default behavior)
npm start
node dist/index.js
# Create entries for a specific date (ISO format: YYYY-MM-DD)
npm start -- 2024-03-15
npm start -- 2024-12-25
node dist/index.js 2024-03-15
# Purge all entries from target database (requires confirmation)
npm start -- --purge --confirm
node dist/index.js --purge --confirm
# View help
npm start -- --helpPurpose: Download and save templates locally
What it does:
- Connects to the Templates Database
- Reads the database schema and saves it to
.notion-schema.json - Downloads all template entries and saves them to
.notion-templates.yaml
When to run:
- First time setup
- After adding/modifying templates in the Templates Database
- After changing the database schema
Example:
npm start -- --initPurpose: Duplicate templates to target database with updated dates
What it does:
- Reads the saved template YAML file (from init mode)
- Sorts templates by start time (ascending order)
- For each template, creates a new entry in the Target Database
- Updates all date/datetime properties to the target date
- Preserves time portions (e.g., 9:00 AM stays 9:00 AM)
- Handles multi-day date ranges (e.g., events spanning midnight)
- Copies all other properties unchanged (text, numbers, selections, etc.)
When to run:
- Daily via cron for recurring schedules
- On-demand when you need to create entries for a specific date
- After running init mode for the first time
Examples:
# Create entries for today
npm start
# Create entries for specific date
npm start -- 2024-03-15
# Create entries for next Monday
npm start -- 2024-03-18Output example:
Running scheduled mode...
Target date: 2024-03-15
Reference date: 2024-01-01
Templates sorted by start time
Creating time blocks in time blocks database (in order)...
Creating: Morning Standup
Property: When
Template start: 2024-01-01 09:00:00
New start: 2024-03-15 09:00:00
Template end: 2024-01-01 09:30:00
New end: 2024-03-15 09:30:00
✓ Successfully created
✓ Created 5 of 5 time blocks
Purpose: Delete all entries from the target database
What it does:
- Fetches all entries from the Target Database
- Archives (deletes) each entry one by one
- Shows progress for each deletion
When to use:
- Testing the script
- Cleaning up test data
- Starting fresh after experimenting
- Clearing out old entries before regenerating
Safety features:
- Requires
--confirmflag to prevent accidental deletion - Only affects the Target Database (templates are safe)
- Deleted entries are archived in Notion (recoverable from trash)
- Shows warning if confirmation is missing
Examples:
# Without confirmation - shows warning and exits safely
npm start -- --purge
# Output: ⚠️ WARNING: This will delete ALL entries...
# With confirmation - actually deletes all entries
npm start -- --purge --confirm
# Output: Found 15 time blocks to delete...You can automate the tool to run on a schedule using cron (macOS/Linux).
Run every weekday at 6 AM to create today's time blocks:
# Edit crontab
crontab -e
# Add this line (adjust path to your project):
0 6 * * 1-5 cd /path/to/notion-time-blocks && /usr/local/bin/node dist/index.js >> /tmp/notion-duplicator.log 2>&1Run on the 1st of each month at 9 AM:
0 9 1 * * cd /path/to/notion-time-blocks && /usr/local/bin/node dist/index.js >> /tmp/notion-duplicator.log 2>&1Run every Monday at 8 AM:
0 8 * * 1 cd /path/to/notion-time-blocks && /usr/local/bin/node dist/index.js >> /tmp/notion-duplicator.log 2>&1Before setting up cron, make sure:
- Replace
/path/to/notion-time-blockswith your actual project path - The
.envfile exists in the project directory with correct credentials - You've run
--initmode at least once to save templates - Test the command manually first to ensure it works
- Check the log file (
/tmp/notion-duplicator.log) after the first automated run
The tool intelligently handles date/datetime properties:
Single Dates:
- Template:
2024-01-15 - Target date:
2024-03-20 - Result:
2024-03-20
Date Ranges with Times:
- Template:
2024-01-15 09:00to2024-01-15 10:30 - Target date:
2024-03-20 - Result:
2024-03-20 09:00to2024-03-20 10:30
Multi-Day Ranges:
- Template:
2024-01-15 23:00to2024-01-16 02:00(spans midnight) - Target date:
2024-03-20 - Result:
2024-03-20 23:00to2024-03-21 02:00(preserves span)
Reference Date: The tool automatically finds the earliest date in your templates and uses it as a reference point. All other dates are calculated as offsets from this reference.
The tool handles all standard Notion property types:
✅ Supported (copied as-is):
- Title
- Rich Text
- Number
- Select / Multi-select
- Checkbox
- URL
- Phone Number
- People
- Files
- Relation
- Status
✅ Supported (date updated):
- Date (with or without time)
❌ Skipped (read-only/computed):
- Formula
- Rollup
- Created Time
- Created By
- Last Edited Time
- Last Edited By
Best Practice Workflow:
- Design your template database schema carefully
- Add template entries with sample dates
- Run
--initto save templates - Test with
--purge --confirmand create mode on a test date - Verify results in Notion
- Set up cron for automation
Updating Templates:
- Modify entries in the Templates Database
- Run
--initagain to update local cache - Templates are now updated for future runs
Schema Changes:
- Update both Templates and Target databases with new schema
- Run
--initto save the new schema - Existing templates will work with new properties
# Run in development mode with ts-node
npm run dev -- --init
npm run dev -- 2024-03-15
# Watch mode for development
npm run watch
# Build for production
npm run build
# Clean build artifacts
npm run clean- Make sure
.envfile exists in the project root - Verify the file contains
NOTION_API_KEY=your_key_here
- Run
npm start -- --initto download templates - Verify Templates Database has entries
- Check that the integration has access to the Templates Database
- Check your template dates - ensure start < end
- The tool will skip invalid date properties and show a warning
- Fix the template entry and run
--initagain
- Verify Target Database ID is correct in
.env - Check that integration has access to Target Database
- Look for error messages in the output
- The tool includes automatic rate limiting (350ms between requests)
- For very large template sets (100+ entries), the process may take several minutes
- This is normal and prevents hitting Notion's API limits
Issues and pull requests are welcome! Please ensure:
- TypeScript compiles without errors (
npm run build) - Code follows existing patterns and style
- Updates to functionality include README updates
MIT