Photo Added
Triggerimage
trigger.photo_added
Fires when a new photo is added to your macOS Photos library. This includes photos that sync in from your iPhone or other devices via iCloud, images saved to Photos from Messages, Safari, or Mail, and photos brought in through an import.
Unlike the file-system triggers, Photo Added watches the Photos library through PhotoKit — not a folder on disk. It reacts to the photo as a managed Photos asset (a PHAsset), which is why it can see photos that never touch the file system as loose files.
macOS screenshots are not in the Photos library
Screenshots taken with ⌘⇧3 / ⌘⇧4 land on the Desktop as loose files — they are not added to the Photos library, so they do not fire this trigger. To react to loose Desktop screenshots, point a Directory Changed trigger at your screenshot folder instead.
Permissions
Photo Added requires Full Photos access. macOS shows a permission prompt the first time the trigger is used. If you grant only “Selected Photos” (limited access), the trigger will not arm and surfaces that it needs full access — by design, because limited access hides new photos from the app and the trigger would never see them.
For photos that sync from your iPhone or another device, the trigger catches them once they sync down while Watchflows is running. If the original is stored only in iCloud (when Optimize Mac Storage is on), the Download iCloud originals config controls whether Watchflows downloads the full-resolution image to work with (see Configuration below).
Ports
| Direction | Name | Data Type | Description |
|---|---|---|---|
| Outlet | Output | Image | Payload emitted when a new photo is added to the library |
Configuration
| Field | Type | Default | Description |
|---|---|---|---|
| Download iCloud originals | Boolean |
true | When a photo lives only in iCloud (Optimize Mac Storage), download the original to work with it. Uses your internet connection and may use cellular or metered data. Turn off to skip photos that aren’t already on this Mac — those fire with an empty filePath. |
| Screenshots Only | Boolean |
false | When on, only fires for screenshots that are already in the Photos library |
| Album | Text |
— | Optional. Limit the trigger to photos added to a named album |
| Custom Arguments | Key-Value |
— | Additional key-value pairs included in the output payload |
Output Variables
| Variable | Type | Description |
|---|---|---|
filePath |
String | Path to a temporary working copy of the image (under the system temp directory) — not the original in the Photos library. Downstream Move File, Copy, Delete, Extract Text (OCR), and AI nodes can all read it. The copy is cleaned up automatically after the run completes, so Move or Copy it to a real folder to keep the file. Empty for cloud-only photos that were skipped because Download iCloud originals is off. |
localImageAvailable |
Boolean | false when a cloud-only photo was skipped because Download iCloud originals is off; true otherwise. Branch on it to handle skipped photos. |
fileName |
String | Name of the photo file |
assetIdentifier |
String | The PhotoKit PHAsset local identifier — the stable handle to the photo |
isScreenshot |
Boolean | Whether the photo is a screenshot |
creationDate |
String | ISO 8601 date the photo was created |
timestamp |
String | ISO 8601 timestamp of when the trigger fired |
Example
Read text out of every new photo, classify it with AI, and file the result into Apple Notes: