Full CRUD lifecycle for OneNote notebooks, section groups, sections, and pages via Graph API.
Use when building notebook management features, creating page hierarchies, or working with XHTML content.
Trigger with "onenote crud", "onenote page management", "onenote notebook workflow".
Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.
Quelldateien prüfen
Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.
Mit Codex oder Claude installieren Kopieren Sie diesen Prompt, fügen Sie ihn in Codex, Claude oder einen anderen Assistant ein und lassen Sie die Skill-Seite prüfen und installieren.
Ein direkter Befehl überspringt den Prüf-Prompt. Prüfen Sie die Quelle, bevor Sie ihn ausführen.
Full CRUD lifecycle for OneNote notebooks, section groups, sections, and pages via Graph API.
Use when building notebook management features, creating page hierarchies, or working with XHTML content.
Trigger with "onenote crud", "onenote page management", "onenote notebook workflow".
allowed-tools
Read, Write, Edit, Bash(npm:*), Bash(pip:*), Grep
version
1.6.0
license
MIT
author
Jeremy Longshore <jeremy@intentsolutions.io>
tags
["saas","onenote","microsoft"]
compatibility
Designed for Claude Code
OneNote — Full CRUD Lifecycle (Notebooks, Sections, Pages)
Overview
OneNote's hierarchy — Notebook, Section Group, Section, Page — maps cleanly to Graph API endpoints, but the implementation has sharp edges. Section groups created via API sometimes don't render in the desktop client. Page content must be strict XHTML with self-closing tags, and the HTML you send in differs from the HTML you get back. This skill covers the full create/read/update/delete lifecycle with production-safe patterns for every level of the hierarchy.
Key pain points addressed:
Page content requires XHTML (all tags must close, UTF-8 encoded, no rowspan/colspan)
Section groups support API nesting depths that the desktop app cannot render beyond two levels
Output HTML from GET /pages/{id}/content contains Graph-injected data-id attributes and rewritten image URLs that differ from your input HTML
PATCH page updates use a JSON array with target/action/content — not raw HTML
Prerequisites
Azure app registration with delegated permissions: Notes.ReadWrite or Notes.ReadWrite.All
App-only auth deprecated March 31, 2025 — use delegated auth only (DeviceCodeCredential or InteractiveBrowserCredential)
const notebook = await client.api("/me/onenote/notebooks").post({
displayName: "Project Notes Q2 2026",
});
// notebook.id is the resource identifier for all child operationsconsole.log(`Created notebook: ${notebook.id}`);
Notebook names must be unique per user. Attempting to create a duplicate returns 400 Bad Request with code 20117.
Step 3 — Create Section Groups and Sections
// Create a section group (top-level organization)const group = await client.api(
`/me/onenote/notebooks/${notebook.id}/sectionGroups`
).post({ displayName: "Engineering" });
// Create a section inside the groupconst section = await client.api(
`/me/onenote/sectionGroups/${group.id}/sections`
).post({ displayName: "Sprint 1" });
// Create a section directly in the notebook (no group)const standaloneSection = await client.api(
`/me/onenote/notebooks/${notebook.id}/sections`
).post({ displayName: "Quick Notes" });
Gotcha: The API allows nesting section groups three or more levels deep, but the OneNote desktop app only renders two levels. The web app may show deeper nesting inconsistently. Stick to a maximum of two levels for cross-client compatibility.
Step 4 — Create a Page with XHTML Content
OneNote pages use strict XHTML. Every tag must close. Use data-tag attributes for checkboxes and note tags.
XHTML rules that cause silent failures if violated:
All tags must self-close or have closing tags (<br />, not <br>)
No rowspan or colspan on <td> — use separate rows instead
<img> tags must include alt attribute
Content must be UTF-8 encoded
Step 5 — Retrieve Page Content
// Metadata (title, timestamps, parent info) — fast, cacheableconst metadata = await client.api(`/me/onenote/pages/${page.id}`).get();
// Full HTML content — separate endpoint, slowerconst content = await client.api(`/me/onenote/pages/${page.id}/content`).get();
// content is a ReadableStream — pipe or buffer it
Important: The HTML returned by GET /content differs from your input. Graph injects data-id attributes on every element, rewrites image src URLs to Graph resource endpoints, and may restructure your table markup. Never diff input vs output HTML for change detection — compare lastModifiedDateTime instead.
Step 6 — Update Page Content (PATCH)
Updates use a JSON array describing targeted changes, not raw HTML replacement:
Valid action values: append, replace, delete, insert, prepend. The target is a CSS selector matching data-id attributes from the output HTML — you must GET /content first to obtain valid targets.
Step 7 — List and Filter Pages with OData
const pages = await client.api("/me/onenote/sections/{sectionId}/pages")
.select("id,title,lastModifiedDateTime,createdDateTime")
.top(25)
.orderby("lastModifiedDateTime desc")
.get();
for (const p of pages.value) {
console.log(`${p.title} — Last modified: ${p.lastModifiedDateTime}`);
}
Step 8 — Delete a Page
await client.api(`/me/onenote/pages/${page.id}`).delete();
// Returns 204 No Content on success// Deleted pages may still appear in LIST results for up to 30 minutes
Output
Successful CRUD operations return:
Create notebook/section/page:201 Created with resource JSON (includes id, self, createdDateTime)
Get content:200 OK with XHTML stream
Patch:204 No Content on success
Delete:204 No Content on success
Error Handling
Status
Cause
Fix
400
Invalid XHTML, unclosed tags, duplicate notebook name
Validate HTML before sending; check notebook name uniqueness
403
Missing Notes.ReadWrite permission, wrong tenant
Verify Azure app permissions and consent status
404
Notebook/section/page deleted or wrong ID
Confirm resource exists with a GET before mutation
429
Rate limit hit (600/min per user)
Read Retry-After header, wait that many seconds
507
Section page limit exceeded
Archive old pages to a new section; see onenote-performance-tuning