Make Notion the single source of truth for Roblox monetization assets.
Sync Developer Products, Game Passes, Badges, and free Open Cloud Assets from Notion databases to Roblox.
NotionToRoblox is a CLI that treats Notion databases as the source of truth and synchronizes Developer Products, Game Passes, Badges, and Assets (Animation, Audio, Decal, Image, Model) to Roblox through the Open Cloud API. Edit rows in Notion; run sync to create missing Roblox items and update to push current Notion fields onto existing ones. Results are written back to Notion.
Distribution: Distributed via Rokit / GitHub Releases. Not published to npm (private: true in package.json).
- Rokit
- Notion Internal Integration with access to your parent page and databases (see Notion setup)
- Roblox Creator Dashboard API Key (see Roblox setup; required for
sync/update, not forinit/create-db)
rokit add Zac134/NotionToRoblox ntn-roblox
rokit installOr in rokit.toml:
[tools]
ntn-roblox = "Zac134/NotionToRoblox@0.2.1"rokit install
ntn-roblox --version
ntn-roblox sync --helpntn-roblox init- Run
ntn-roblox init. - Set
NOTION_TOKENin.env(see Notion setup). - Share a parent page with your integration; set
notion.parent_page_idinntn-roblox.toml. - Configure
[roblox.universes]beforecreate-dbif using multi-universe (optional). - Run
ntn-roblox create-db— creates four databases and writes IDs to TOML. - Set
ROBLOX_API_KEYin.env,roblox.universe_id(or[roblox.universes]), and[roblox.asset_creator]if using Assets. - Run
ntn-roblox syncto create Roblox items; runntn-roblox updateafter editing Notion rows.
See Notion setup and Roblox setup for details.
Notion setup
- Create an Internal integration at notion.so/my-integrations.
- Set
NOTION_TOKENin.env. - Capabilities: Read content, Update content (sync/update); Insert content (
create-db). - Share the parent page and each database with the integration.
- Run
ntn-roblox create-db(recommended) or create databases manually per Notion database schema.
Roblox setup
- Create an API key with scopes for resources you sync (see Roblox API Key scopes).
- Set
ROBLOX_API_KEYin.env. - Set
roblox.universe_idor[roblox.universes]for Dev Products / Game Passes / Badges. - Set
[roblox.asset_creator]for Assets (is_group+id— user or group upload target). - For group-owned badges:
roblox.badge_payment_source = "group".
| Key | Required for | Purpose |
|---|---|---|
notion.parent_page_id |
create-db |
Parent page for database creation |
notion.is_inline |
create-db |
Inline DBs on parent (default true) |
notion.dev_product_db_id |
sync, update |
Developer Products database ID |
notion.game_pass_db_id |
sync, update |
Game Passes database ID |
notion.badge_db_id |
sync, update |
Badges database ID |
notion.asset_db_id |
sync, update |
Assets database ID |
roblox.universe_id |
sync, update |
Single universe (monetization types) |
roblox.universes |
sync, update |
Multi-universe map (alternative to universe_id) |
roblox.asset_creator |
Assets | is_group + id for upload ownership |
roblox.badge_payment_source |
Badges | user or group (free quota) |
logging.level |
No | debug / info / warn / error |
Example:
[notion]
parent_page_id = "your-parent-page-id"
dev_product_db_id = "..."
game_pass_db_id = "..."
badge_db_id = "..."
asset_db_id = "..."
[roblox]
universe_id = 1234567890
[roblox.asset_creator]
is_group = false
id = 123456789
[logging]
# level = "info"Property names are case-sensitive. Extra columns are ignored — you may add your own properties freely.
| Property | Type | Description |
|---|---|---|
Name |
title | Required |
Description |
rich_text | Roblox description |
Icon |
files | First file only (Dev Product / Game Pass / Badge) |
Roblox ID |
number | Single-universe mode |
Roblox ID (Key) |
number | Multi-universe: one column per TOML key |
Sync Status |
select | Pending / Synced / Error / Skipped |
Sync Error |
rich_text | Cleared on success |
Last Synced At |
date | Success timestamp |
Create vs update is decided by whether the Roblox ID column is set, not by Sync Status.
| Property | Type | Description |
|---|---|---|
Name |
title | Roblox displayName |
File |
files | Upload file (first attachment). Create only |
Asset Type |
select | Animation, Audio, Decal, Image, Model |
Roblox ID |
number | Always single column (even in multi-universe) |
Description |
rich_text | Optional; empty sends "" |
Sync Status / Sync Error / Last Synced At |
— | Same as above |
Not supported: Video (paid), Mesh (Roblox-delivery only).
| Resource | Scopes |
|---|---|
| Developer Product | developer-product:read, developer-product:write |
| Game Pass | game-pass:read, game-pass:write |
| Badge | legacy-universe.badge:write, legacy-universe.badge:manage-and-spend-robux, legacy-badge:manage |
| Assets | asset:read, asset:write |
Global options (all commands): --help, -h, --version, -V
Create Roblox items for rows without a Roblox ID.
ntn-roblox sync [--dry-run] [--report-only] [--type=...] [--target=Key]| Option | Description |
|---|---|
--dry-run |
Log planned creates only |
--report-only |
Orphan report only (monetization types) |
--type=<type> |
developer-product, game-pass, badge, or asset |
--target=<Key> |
One universe (requires [roblox.universes]) |
Push current Notion fields to existing Roblox items (ID set).
ntn-roblox update [--dry-run] [--type=...] [--target=Key]Assets: metadata only (Name, Description). File is ignored on update.
Creates four Notion databases. Alias: create-databases.
ntn-roblox create-db [--parent-page-id=<id>] [--force][roblox.universes]
Prod = 111111111
Dev = 222222222- Dev Product / Game Pass / Badge:
Roblox ID (Prod)etc.;--target=Prodlimits scope. - Assets: single
Roblox IDcolumn; creator-scoped, not per-universe.
Upload free asset types via Open Cloud Assets API. Configure [roblox.asset_creator]:
[roblox.asset_creator]
is_group = true # true = groupId, false = userId
id = 987654321| Asset Type | Upload | Update content |
|---|---|---|
| Decal, Image, Audio, Animation, Model | ✅ | Metadata only (update) |
Video (2000 Robux) and Mesh are excluded.
sync --forceremoved — useupdateto push changes to existing items.synccreates only;updateupdates only.- Add
asset_db_idandasset_creatorfor Assets. - Multi-universe: switch from
universe_idto[roblox.universes]and rename ID columns.
Exit code 1 on config errors, mapping failures, or any row ending in Error / Skipped.
Contributing & development
npm install
npm run check
npm test
npm run sync -- --dry-run
npm run update -- --dry-runRelease: npm run compile -- 0.2.1 bun-darwin-arm64 ./release
MIT — see LICENSE.