API Documentation
Last Updated: 2026-02-03 | Reading Time: 25 minutes
Complete API reference for PasteShelf integrations and automation.
Table of Contents
Section titled βTable of Contentsβ- Overview
- Plugin API
- AppleScript API
- Shortcuts Integration
- URL Scheme
- Webhooks
- JavaScript Actions
- CLI Interface
Overview
Section titled βOverviewβPasteShelf provides multiple integration points for automation and extensibility:
| API | Tier | Use Case |
|---|---|---|
| Plugin API | β Pro | Custom transformations and integrations |
| AppleScript | β Pro | System automation |
| Shortcuts | β Pro | Visual automation |
| URL Scheme | π CE | Deep linking |
| Webhooks | π’ Enterprise | External integrations |
| JavaScript Actions | β Pro | In-app transformations |
| CLI | π CE | Terminal access |
Plugin API β
Section titled βPlugin API ββPlugin Architecture
Section titled βPlugin Architectureβββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Plugin Architecture ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€β ββ βββββββββββββββββββββββββββββββββββββββββββββββββββββββ ββ β PasteShelf Host β ββ β β ββ β βββββββββββββββββββββββββββββββββββββββββββββββββ β ββ β β Plugin Manager β β ββ β β β β ββ β β ββββββββββββ ββββββββββββ ββββββββββββ β β ββ β β β Plugin A β β Plugin B β β Plugin C β β β ββ β β β (Bundle) β β (Bundle) β β (Bundle) β β β ββ β β ββββββ¬ββββββ ββββββ¬ββββββ ββββββ¬ββββββ β β ββ β β β β β β β ββ β β ββββββ΄βββββββββββββ΄βββββββββββββ΄ββββββββββ β β ββ β β β Plugin Protocol β β β ββ β β β β’ transform(content:) -> Content β β β ββ β β β β’ supports(contentType:) -> Bool β β β ββ β β β β’ menuItems() -> [MenuItem] β β β ββ β β ββββββββββββββββββββββββββββββββββββββββββ β β ββ β βββββββββββββββββββββββββββββββββββββββββββββββββ β ββ βββββββββββββββββββββββββββββββββββββββββββββββββββββββ ββ ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββPlugin Protocol
Section titled βPlugin Protocolβ/// Protocol that all PasteShelf plugins must conform topublic protocol PasteShelfPlugin { /// Unique identifier for the plugin static var identifier: String { get }
/// Human-readable name static var name: String { get }
/// Plugin version static var version: String { get }
/// Supported content types static var supportedTypes: [ContentType] { get }
/// Initialize the plugin init()
/// Transform clipboard content /// - Parameter content: The content to transform /// - Returns: Transformed content or nil if transformation fails func transform(content: ClipboardContent) async throws -> ClipboardContent?
/// Check if plugin supports a specific content type /// - Parameter type: The content type to check /// - Returns: true if the plugin can handle this type func supports(contentType: ContentType) -> Bool
/// Menu items to display in context menu /// - Returns: Array of menu items func menuItems() -> [PluginMenuItem]
/// Called when plugin is loaded func didLoad()
/// Called when plugin is unloaded func willUnload()}
/// Default implementationspublic extension PasteShelfPlugin { func supports(contentType: ContentType) -> Bool { Self.supportedTypes.contains(contentType) }
func didLoad() {} func willUnload() {}}Creating a Plugin
Section titled βCreating a Pluginβ1. Create Plugin Bundle
Section titled β1. Create Plugin BundleβMyPlugin.pasteshelfplugin/βββ Contents/β βββ Info.plistβ βββ MacOS/β β βββ MyPluginβ βββ Resources/β βββ icon.png2. Info.plist
Section titled β2. Info.plistβ<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"><plist version="1.0"><dict> <key>CFBundleIdentifier</key> <string>com.example.myplugin</string> <key>CFBundleName</key> <string>My Plugin</string> <key>CFBundleVersion</key> <string>1.0.0</string> <key>PSPluginClass</key> <string>MyPlugin.MyPlugin</string> <key>PSSupportedContentTypes</key> <array> <string>public.plain-text</string> <string>public.utf8-plain-text</string> </array></dict></plist>3. Plugin Implementation
Section titled β3. Plugin Implementationβimport Foundationimport PasteShelfPluginKit
@objc(MyPlugin)public final class MyPlugin: NSObject, PasteShelfPlugin { public static let identifier = "com.example.myplugin" public static let name = "My Plugin" public static let version = "1.0.0" public static let supportedTypes: [ContentType] = [.plainText, .richText]
public override init() { super.init() }
public func transform(content: ClipboardContent) async throws -> ClipboardContent? { guard let text = content.text else { return nil }
// Transform the text let transformed = text.uppercased()
return ClipboardContent(text: transformed) }
public func menuItems() -> [PluginMenuItem] { return [ PluginMenuItem( title: "Uppercase", icon: "textformat.abc.dottedunderline", action: { [weak self] content in try await self?.transform(content: content) } ) ] }}Plugin Installation
Section titled βPlugin InstallationβPlugins are installed to:
~/Library/Application Support/PasteShelf/Plugins/// Programmatic installationlet pluginManager = PluginManager.shared
do { try await pluginManager.install(from: pluginURL) print("Plugin installed successfully")} catch { print("Installation failed: \(error)")}Plugin API Reference
Section titled βPlugin API ReferenceβClipboardContent
Section titled βClipboardContentβpublic struct ClipboardContent { /// Text content (if applicable) public var text: String?
/// RTF data (if applicable) public var rtfData: Data?
/// HTML content (if applicable) public var html: String?
/// Image data (if applicable) public var imageData: Data?
/// File URLs (if applicable) public var fileURLs: [URL]?
/// Raw data with UTI type public var rawData: [String: Data]
/// Content type public var contentType: ContentType
/// Metadata public var metadata: [String: Any]}PluginMenuItem
Section titled βPluginMenuItemβpublic struct PluginMenuItem { /// Menu item title public let title: String
/// SF Symbol icon name public let icon: String?
/// Keyboard shortcut public let shortcut: KeyboardShortcut?
/// Action to perform public let action: (ClipboardContent) async throws -> ClipboardContent?
/// Submenu items (optional) public let submenu: [PluginMenuItem]?}AppleScript API β
Section titled βAppleScript API ββAppleScript Dictionary
Section titled βAppleScript Dictionaryβ-- PasteShelf AppleScript Suite
-- Applicationapplication "PasteShelf" -- Properties clipboard history : list of clipboard items current item : clipboard item is monitoring : boolean
-- Commands search for : search clipboard history paste item : paste a clipboard item delete item : delete a clipboard item clear history : clear all historyExamples
Section titled βExamplesβGet Recent Items
Section titled βGet Recent Itemsβtell application "PasteShelf" set recentItems to clipboard history
repeat with item in recentItems log "Content: " & (text content of item) log "Date: " & (created date of item) end repeatend tellSearch Clipboard
Section titled βSearch Clipboardβtell application "PasteShelf" set results to search for "important" with limit 10
if (count of results) > 0 then set firstResult to item 1 of results paste item firstResult end ifend tellAdd Custom Content
Section titled βAdd Custom Contentβtell application "PasteShelf" set newItem to make new clipboard item with properties { text content: "Custom content", is favorite: true }end tellMonitor Clipboard Changes
Section titled βMonitor Clipboard Changesβtell application "PasteShelf" -- Enable monitoring set is monitoring to true
-- Wait for new item repeat set currentContent to text content of current item if currentContent contains "trigger" then -- Do something display notification "Trigger detected!" end if delay 1 end repeatend tellShortcuts Integration β
Section titled βShortcuts Integration ββAvailable Actions
Section titled βAvailable Actionsβ| Action | Description | Parameters |
|---|---|---|
| Get Clipboard History | Retrieve recent items | limit: Int |
| Search Clipboard | Search by query | query: String, limit: Int |
| Paste Item | Paste specific item | item: ClipboardItem |
| Add to Clipboard | Add new item | content: String/Image |
| Transform Content | Apply transformation | action: String |
| Get Current Item | Get most recent | - |
Example Shortcuts
Section titled βExample ShortcutsββSave to PasteShelfβ Shortcut
Section titled ββSave to PasteShelfβ Shortcutβββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Shortcut: Save to PasteShelf ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€β ββ 1. Get Clipboard ββ βββ Output: Clipboard Content ββ ββ 2. Add to Clipboard (PasteShelf) ββ βββ Content: [Clipboard Content] ββ βββ Favorite: Yes ββ βββ Tags: "shortcut", "important" ββ ββ 3. Show Notification ββ βββ "Saved to PasteShelf" ββ βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββSmart Pasteβ Shortcut
Section titled ββSmart Pasteβ Shortcutβββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Shortcut: Smart Paste ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€β ββ 1. Search Clipboard (PasteShelf) ββ βββ Query: [Ask for Input] ββ βββ Limit: 5 ββ ββ 2. Choose from List ββ βββ [Search Results] ββ ββ 3. Paste Item (PasteShelf) ββ βββ [Chosen Item] ββ ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββAppIntents Implementation
Section titled βAppIntents Implementationβimport AppIntents
struct SearchClipboardIntent: AppIntent { static var title: LocalizedStringResource = "Search Clipboard" static var description = IntentDescription("Search PasteShelf clipboard history")
@Parameter(title: "Search Query") var query: String
@Parameter(title: "Maximum Results", default: 10) var limit: Int
func perform() async throws -> some IntentResult & ReturnsValue<[ClipboardItemEntity]> { let items = try await ClipboardManager.shared.search(query: query, limit: limit) let entities = items.map { ClipboardItemEntity(item: $0) } return .result(value: entities) }}URL Scheme π
Section titled βURL Scheme πβBase URL
Section titled βBase URLβpasteshelf://Supported Actions
Section titled βSupported Actionsβ| URL | Action | Parameters |
|---|---|---|
pasteshelf://open | Open main window | - |
pasteshelf://search?q= | Search clipboard | q: query |
pasteshelf://paste?id= | Paste specific item | id: UUID |
pasteshelf://add?text= | Add text to clipboard | text: String |
pasteshelf://preferences | Open preferences | - |
pasteshelf://upgrade | Open upgrade dialog | - |
Examples
Section titled βExamplesβ# Open PasteShelfopen "pasteshelf://open"
# Search for "email"open "pasteshelf://search?q=email"
# Add textopen "pasteshelf://add?text=Hello%20World"
# Paste by IDopen "pasteshelf://paste?id=550e8400-e29b-41d4-a716-446655440000"URL Handling
Section titled βURL Handlingβ// In AppDelegate or Scenefunc handleURL(_ url: URL) { guard url.scheme == "pasteshelf" else { return }
switch url.host { case "open": windowManager.showMainWindow()
case "search": if let query = url.queryParameters["q"] { searchManager.search(query: query) }
case "paste": if let idString = url.queryParameters["id"], let id = UUID(uuidString: idString) { clipboardManager.paste(itemWithId: id) }
case "add": if let text = url.queryParameters["text"]?.removingPercentEncoding { clipboardManager.add(text: text) }
default: break }}Webhooks π’
Section titled βWebhooks π’βConfiguration
Section titled βConfigurationβAdmin Console β Integrations β Webhooks β Add WebhookWebhook Events
Section titled βWebhook Eventsβ| Event | Description | Payload |
|---|---|---|
clipboard.created | New item captured | Item data |
clipboard.deleted | Item deleted | Item ID |
clipboard.synced | Sync completed | Sync status |
user.activated | License activated | User info |
team.member.joined | Team member added | Member info |
Payload Format
Section titled βPayload Formatβ{ "event": "clipboard.created", "timestamp": "2026-02-03T12:00:00Z", "data": { "id": "550e8400-e29b-41d4-a716-446655440000", "contentType": "public.plain-text", "preview": "Hello World...", "sourceApp": "com.apple.Safari", "createdAt": "2026-02-03T12:00:00Z" }, "user": { "id": "user_123", }, "signature": "sha256=..."}Webhook Security
Section titled βWebhook Securityβ// Verify webhook signaturefunc verifySignature(payload: Data, signature: String, secret: String) -> Bool { let hmac = HMAC<SHA256>.authenticationCode( for: payload, using: SymmetricKey(data: Data(secret.utf8)) ) let expectedSignature = "sha256=" + Data(hmac).hexString return signature == expectedSignature}Example: Slack Integration
Section titled βExample: Slack Integrationβ{ "url": "https://hooks.slack.com/services/xxx", "events": ["clipboard.created"], "filters": { "contentTypes": ["public.plain-text"], "sourceApps": ["com.apple.Safari"] }, "transform": { "text": "New clipboard item from {sourceApp}: {preview}" }}JavaScript Actions β
Section titled βJavaScript Actions ββAction Structure
Section titled βAction Structureβ(function() { return { // Action metadata name: "Format JSON", description: "Pretty-print JSON content", icon: "curlybraces", supportedTypes: ["public.json", "public.plain-text"],
// Transform function transform: function(content) { try { const parsed = JSON.parse(content.text); return { text: JSON.stringify(parsed, null, 2), contentType: "public.json" }; } catch (e) { return { error: "Invalid JSON: " + e.message }; } } };})();Built-in Functions
Section titled βBuilt-in Functionsβ// Available in action contextconst PasteShelf = { // Clipboard operations clipboard: { getText: () => String, setText: (text) => void, getHTML: () => String, setHTML: (html) => void },
// HTTP requests http: { get: async (url, options) => Response, post: async (url, body, options) => Response },
// Storage (per-action) storage: { get: (key) => Any, set: (key, value) => void, remove: (key) => void },
// UI ui: { alert: (message) => void, prompt: (message, defaultValue) => String, confirm: (message) => Boolean, notify: (title, body) => void },
// Utilities utils: { base64Encode: (text) => String, base64Decode: (text) => String, urlEncode: (text) => String, urlDecode: (text) => String, md5: (text) => String, sha256: (text) => String }};Example Actions
Section titled βExample ActionsβURL Shortener
Section titled βURL Shortenerβ(function() { return { name: "Shorten URL", description: "Shorten URL using TinyURL", icon: "link", supportedTypes: ["public.url", "public.plain-text"],
transform: async function(content) { const url = content.text; if (!url.match(/^https?:\/\//)) { return { error: "Not a valid URL" }; }
const response = await PasteShelf.http.get( `https://tinyurl.com/api-create.php?url=${encodeURIComponent(url)}` );
return { text: response.text }; } };})();Markdown to HTML
Section titled βMarkdown to HTMLβ(function() { return { name: "Markdown to HTML", description: "Convert Markdown to HTML", icon: "text.badge.checkmark", supportedTypes: ["public.plain-text"],
transform: function(content) { // Simple markdown conversion let html = content.text .replace(/^### (.*$)/gim, '<h3>$1</h3>') .replace(/^## (.*$)/gim, '<h2>$1</h2>') .replace(/^# (.*$)/gim, '<h1>$1</h1>') .replace(/\*\*(.*)\*\*/gim, '<strong>$1</strong>') .replace(/\*(.*)\*/gim, '<em>$1</em>') .replace(/\n/gim, '<br>');
return { text: html, html: html, contentType: "public.html" }; } };})();CLI Interface π
Section titled βCLI Interface πβInstallation
Section titled βInstallationβ# Symlink CLI toolsudo ln -s /Applications/PasteShelf.app/Contents/MacOS/pasteshelf-cli /usr/local/bin/pasteshelfCommands
Section titled βCommandsβ# Helppasteshelf --help
# List recent itemspasteshelf list [--limit N] [--type TYPE]
# Searchpasteshelf search "query" [--limit N]
# Get item by IDpasteshelf get <id> [--format json|text|raw]
# Add contentpasteshelf add "content" [--type text|image|file]pasteshelf add --file /path/to/file
# Paste itempasteshelf paste <id>
# Delete itempasteshelf delete <id> [--force]
# Clear historypasteshelf clear [--before DATE] [--confirm]
# Exportpasteshelf export --output /path/to/backup.json [--format json|csv]
# Importpasteshelf import /path/to/backup.json
# Statuspasteshelf status
# Versionpasteshelf --versionExamples
Section titled βExamplesβ# List last 5 text itemspasteshelf list --limit 5 --type text
# Search and paste first resultID=$(pasteshelf search "email" --limit 1 --format json | jq -r '.[0].id')pasteshelf paste $ID
# Export historypasteshelf export --output ~/Desktop/clipboard-backup.json
# Pipe contentecho "Hello World" | pasteshelf add --stdincat file.txt | pasteshelf add --stdin
# Watch for changespasteshelf watch --on-change 'echo "New item: $PASTESHELF_PREVIEW"'Exit Codes
Section titled βExit Codesβ| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | General error |
| 2 | Invalid arguments |
| 3 | Item not found |
| 4 | Permission denied |
| 5 | Not authenticated |
Related Documentation
Section titled βRelated Documentationβ| Document | Description |
|---|---|
| Plugin System | Plugin development |
| Automation Engine | Automation details |
| Enterprise Admin | Webhook setup |
Last updated: 2026-02-03