'Handle Apple Notes data formats: HTML body, attachments, and rich content.
Scanned 9/2/2026
Install to Claude Code
npx -y skills add jeremylongshore/tons-of-skills-marketplace --skill apple-notes-data-handling --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Apple Notes Data Handling?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/jeremylongshore-apple-notes-data-handling-41d4ca40)More formats (shields.io, HTML) on the badges page.
---
name: apple-notes-data-handling
description: 'Handle Apple Notes data formats: HTML body, attachments, and rich content.
Trigger: "apple notes data handling".
'
allowed-tools: Read, Write, Edit, Bash(osascript:*), Grep
version: 1.6.0
license: MIT
author: Jeremy Longshore <jeremy@intentsolutions.io>
tags:
- saas
- macos
- apple-notes
- automation
compatibility: Designed for Claude Code
---
# Apple Notes Data Handling
## Overview
Apple Notes stores note content as a restricted subset of HTML internally. The `body()` property in JXA returns this HTML, which includes `<div>`, `<h1>`-`<h3>`, `<b>`, `<i>`, `<ul>`, `<li>`, and Apple-specific classes for checklists and tables. Attachments (images, PDFs, sketches, scans) are embedded as `<img>` or object references but cannot be directly extracted via JXA — they require the `attachments()` property. Understanding these data formats is essential for building reliable import, export, and backup pipelines.
## Prerequisites
- Written authorization for the accounts, folders, and note categories to be exported or transformed.
- An encrypted destination outside a shared directory, a retention limit, and a tested restore path.
- A conversion test corpus containing only synthetic notes; do not use the examples as proof that Apple Notes HTML is a stable public format.
## Instructions
1. Scope reads to named folders and minimize collected fields before invoking `osascript`.
2. Write exports to a pre-created, owner-only directory and validate permissions before any data is emitted.
3. Treat HTML and attachment metadata as untrusted content: sanitize before rendering, and never execute embedded links or markup.
4. Hash or redact identifiers in operational logs; record only counts and completion state.
## Note Body HTML Format
```html
<!-- Apple Notes uses a subset of HTML wrapped in <div> blocks -->
<div><h1>Title</h1></div>
<div><br></div>
<div>Paragraph text here.</div>
<div><b>Bold text</b> and <i>italic text</i></div>
<div><br></div>
<div><ul><li>List item 1</li><li>List item 2</li></ul></div>
<!-- Checklists use Apple's custom class -->
<div><ul class="com-apple-note-checklist">
<li class="done">Completed item</li>
<li>Incomplete item</li>
</ul></div>
<!-- Tables (macOS Ventura+) use standard HTML tables -->
<div><table><tr><td>Cell 1</td><td>Cell 2</td></tr></table></div>
<!-- Tags (macOS Sonoma+) are stored as hashtags in body text -->
<div>#project #important</div>
```
## Export All Notes to JSON
```bash
#!/bin/bash
# Full export with metadata — useful for backups and migration
osascript -l JavaScript -e '
const Notes = Application("Notes");
const results = Notes.defaultAccount.notes().map(n => ({
id: n.id(),
title: n.name(),
body: n.body(),
plaintext: n.plaintext(),
folder: n.container().name(),
created: n.creationDate().toISOString(),
modified: n.modificationDate().toISOString(),
attachmentCount: n.attachments().length,
}));
JSON.stringify(results, null, 2);
' > "$HOME/notes-export-$(date +%Y%m%d).json"
```
## HTML to Markdown Converter
```typescript
// src/data/html-to-markdown.ts
function notesHtmlToMarkdown(html: string): string {
return html
.replace(/<h1>(.*?)<\/h1>/g, "# $1")
.replace(/<h2>(.*?)<\/h2>/g, "## $1")
.replace(/<h3>(.*?)<\/h3>/g, "### $1")
.replace(/<b>(.*?)<\/b>/g, "**$1**")
.replace(/<strong>(.*?)<\/strong>/g, "**$1**")
.replace(/<i>(.*?)<\/i>/g, "*$1*")
.replace(/<em>(.*?)<\/em>/g, "*$1*")
.replace(/<li class="done">(.*?)<\/li>/g, "- [x] $1")
.replace(/<li>(.*?)<\/li>/g, "- [ ] $1")
.replace(/<br\s*\/?>/g, "\n")
.replace(/<div>/g, "").replace(/<\/div>/g, "\n")
.replace(/<[^>]*>/g, "")
.replace(/\n{3,}/g, "\n\n")
.trim();
}
```
## Attachment Handling
```bash
# List all notes with attachments and their counts
osascript -l JavaScript -e '
const Notes = Application("Notes");
Notes.defaultAccount.notes()
.filter(n => n.attachments().length > 0)
.map(n => n.name() + ": " + n.attachments().length + " attachments (" +
n.attachments().map(a => a.name()).join(", ") + ")")
.join("\n");
'
# Note: JXA cannot directly save attachment binary data.
# For full attachment export, use Shortcuts:
# shortcuts run "Export Note Attachments" --input-type text --input "Note Title"
```
## Error Handling
| Issue | Cause | Solution |
|-------|-------|----------|
| `body()` returns empty string | Note contains only attachments (no text) | Check `attachments().length`; use `plaintext()` as fallback |
| HTML contains unexpected tags | Note created on iOS with unsupported formatting | Strip unknown tags; keep only known Apple Notes subset |
| `plaintext()` truncated | Very large note body | Export via `body()` HTML instead; convert after |
| Checklist state lost in export | Custom class not preserved in conversion | Map `class="done"` to `[x]` before stripping HTML |
| Attachment names are generic | Auto-generated names like `Image.png` | Use note title + index for meaningful filenames |
## Output
An export produces a scoped, encrypted artifact plus a separate receipt containing the folder scope, record count, checksum, and expiration—not note bodies, titles, or attachment names. A conversion produces Markdown only after the source has been sanitized and its unsupported constructs have been recorded for review.
## Examples
For a migration rehearsal, export a synthetic test folder to an owner-only staging directory, convert it, validate the expected count and checksum, then securely remove the rehearsal artifact under the retention policy. For a live backup, use a job-owned encrypted volume and report only `completed: 42 records` to monitoring.
## Resources
- [Mac Automation Scripting Guide](https://developer.apple.com/library/archive/documentation/LanguagesUtilities/Conceptual/MacAutomationScriptingGuide/)
- [JXA Cookbook](https://github.com/JXA-Cookbook/JXA-Cookbook)
- [Apple Notes File Format (reverse-engineered)](https://ciofecaforensics.com/2020/08/05/apple-notes-format/)
## Next Steps
For migrating between note platforms, see `apple-notes-migration-deep-dive`. For backup automation, see `apple-notes-deploy-integration`.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!