• Blog
  • Docs
  • Pricing
  • We’re hiring!
Log inSign up
jdan

jdan

jrsn-api

Public
Like
jrsn-api
Home
Code
10
.claude
1
.git
7
.gitignore
.vtignore
CLAUDE.md
badge.ts
colors.ts
deno.json
H
main.ts
render.ts
Environment variables
Branches
1
Pull requests
Remixes
History
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.
Sign up now
Code
/
.claude
/
commands
/
populate-line.md
Code
/
.claude
/
commands
/
populate-line.md
Search
…
Viewing readonly version of main branch: v123
View latest version
populate-line.md

Populate a rail line's stations in the Notion database.

The user will provide: $ARGUMENTS (a line name, e.g. "Yamanote", "Ginza", "Yurikamome")

Steps

  1. Look up the line in the Notion Lines database to get its page ID. First list ALL existing lines (query the Lines DB with no filter) and match against them, because line names in Notion use macrons/diacritics (e.g. "Chūō Rapid", "Tōkaidō", "Ōedo") which won't match a plain ASCII search like "Chuo Rapid". If no existing line matches, create it (using the correct diacritics in the name).

  2. Research stations by searching the web for the complete station list for this line, including:

    • English station name
    • Japanese station name (kanji/kana)
    • Station number (e.g. JY 01, G 09, U 16)
  3. Determine badge style from the line code:

    • JR lines (codes starting with J, like JY, JK, JO, JT, JC, JE, JH, etc.) use jre style (square badges)
    • Metro/subway/other lines (single letters like G, M, A, Z, U, etc.) use tssn style (circle badges)
  4. Create stations and StationLine entries using the Notion API:

    • For each station, check if it already exists in the Stations database (match by name)
    • If the station doesn't exist, create it with a 🚉 emoji icon
    • Create a StationLine entry linking the station to the line, with the stop number
    • Set the StationLine icon to the badge PNG: {BASE}/{style}/{code}/{number}.png?size=120
  5. Research station coordinates for each station (latitude/longitude). Then set the Place property on each StationLine entry using the Notion private API (see "Setting Place on StationLine" below).

  6. Show a summary of what was created.

API Details

Read the token from .env file (NOTION_TOKEN=...).

  • Notion API base: https://api.notion.com/v1
  • Notion-Version header: 2022-06-28
  • Badge API base: https://jdan--73a2eeba09df11f1a30442dde27851f2.web.val.run

Database IDs

  • Stations: 3076fc0faa7d8093b3afce6b0c25966d
  • Lines: 3076fc0faa7d8073b3eed1db67a8bcbc
  • StationLine: 3076fc0faa7d80bda742cc7fa4041b06

Creating a Station

POST /pages
{
  "parent": {"database_id": "<STATIONS_DB>"},
  "icon": {"type": "emoji", "emoji": "🚉"},
  "properties": {
    "Name": {"title": [{"text": {"content": "Shiodome 汐留"}}]}
  }
}

Creating a StationLine entry with icon

POST /pages
{
  "parent": {"database_id": "<STATIONLINE_DB>"},
  "icon": {"type": "external", "external": {"url": "<badge_url>"}},
  "properties": {
    "Name": {"title": [{"text": {"content": ""}}]},
    "Station": {"relation": [{"id": "<station_id>"}]},
    "Line": {"relation": [{"id": "<line_id>"}]},
    "Stop": {"number": <stop_number>}
  }
}

Setting Place on StationLine

The Place property (dsOX) on StationLine entries is not writable via the public Notion API. Use the private API instead. Read token_v2 from .env (NOTION_TOKEN_V2=...).

POST https://www.notion.so/api/v3/saveTransactionsFanout
Headers:
  Content-Type: application/json
  Cookie: token_v2=<NOTION_TOKEN_V2>
  x-notion-space-id: e8bd2e4a-c367-4d7e-8c8b-ef47b27ac37a
  x-notion-active-user-header: 84cb4838-4dc9-4d38-8cf8-c186b662dee9
  notion-client-version: 23.13.20260214.1755
  notion-audit-log-platform: web

Body:
{
  "requestId": "<uuid>",
  "transactions": [{
    "id": "<uuid>",
    "spaceId": "e8bd2e4a-c367-4d7e-8c8b-ef47b27ac37a",
    "debug": {"userAction": "BlockPropertyValueOverlay.handlePlaceChange"},
    "operations": [
      {
        "pointer": {"table": "block", "id": "<stationline_page_id>", "spaceId": "e8bd2e4a-c367-4d7e-8c8b-ef47b27ac37a"},
        "path": ["properties", "dsOX"],
        "command": "set",
        "args": [["\u2023", [["plc", {"lat": <lat>, "lon": <lon>, "name": "<Station Name>"}]]]]
      },
      {
        "pointer": {"table": "block", "id": "<stationline_page_id>", "spaceId": "e8bd2e4a-c367-4d7e-8c8b-ef47b27ac37a"},
        "path": [],
        "command": "update",
        "args": {"last_edited_time": <epoch_ms>, "last_edited_by_id": "84cb4838-4dc9-4d38-8cf8-c186b662dee9", "last_edited_by_table": "notion_user"}
      }
    ]
  }],
  "unretryable_error_behavior": "continue"
}

The name field should be the English station name (e.g. "Shinjuku Station"). The awsPlaceId and address fields are optional and can be omitted.

Important

  • Use a single Python script with urllib.request for all API calls (no external dependencies).
  • Zero-pad stop numbers in badge URLs (e.g. 01, 02).
  • Station names should be formatted as "English 日本語" (e.g. "Shimbashi 新橋").
  • Always check for existing stations before creating duplicates.
  • Always check for existing StationLine entries before creating duplicates (query StationLine DB and check if a record with the same Line and Stop already exists).
FeaturesVersion controlCode intelligenceCLIMCP
Use cases
TeamsAI agentsSlackGTM
DocsShowcaseTemplatesNewestTrendingAPI examplesNPM packages
PricingNewsletterBlogAboutCareers
We’re hiring!
Brandhi@val.townStatus
X (Twitter)
Discord community
GitHub discussions
YouTube channel
Bluesky
Open Source Pledge
Terms of usePrivacy policyAbuse contact
© 2026 Val Town, Inc.