-
-
Notifications
You must be signed in to change notification settings - Fork 5
Home
kei syncs iCloud Photos media to local storage.
Coming from Python icloudpd? See Migration from Python.
Upgrading from v0.19 or older? See v0.20 Migration.
Current release: v0.21.0.
# Homebrew (macOS and Linux)
brew install rhoopr/kei/kei
# Generate a TOML config
kei config setup
# Run one sync
kei syncA minimal ~/.config/kei/config.toml:
[auth]
username = "you@example.com"
[download]
directory = "/photos"Docker users mount the same file at /config/config.toml. See Docker.
See Install for pre-built binaries, source builds, Docker, and the FreeBSD --no-default-features build.
Use --dry-run to preview one run. Use kei login to verify credentials without starting a download.
kei requires ADP to be off and "Access iCloud Data on the Web" to be on. See Authentication.
kei uses a small CLI surface:
- TOML is for settings you want to keep.
- CLI flags are for one run or one action.
- Env vars are for secrets, config path/bootstrap, process-manager glue, and tests.
kei config show prints the resolved TOML. kei config setup writes a starter file.
kei uses subcommands for different operations. Running without a subcommand defaults to sync.
| Command | Description |
|---|---|
sync |
Download photos from iCloud |
login |
Authenticate and complete 2FA (get-code, submit-code) |
list |
List albums (albums) or libraries (libraries) |
password |
Manage stored credentials (set, clear, backend) |
config |
Show resolved config (show) or run the setup wizard (setup) |
install |
Register a background service |
uninstall |
Remove the registered background service; --purge also removes state and credentials |
service |
Run the service worker or inspect service registration |
reset |
Delete state database (state) or clear sync tokens (sync-token) |
status |
Show sync status and database summary |
verify |
Verify downloaded files exist and optionally check checksums |
reconcile |
Mark missing local files as failed so the next sync re-downloads them |
import-existing |
Import existing local files into the state database |
These apply broadly and are still CLI flags:
| Flag | Description |
|---|---|
--config |
TOML config file path, default ~/.config/kei/config.toml
|
--log-level |
debug, info, warn, or error
|
-v, --verbose |
Alias for --log-level info with full log formatting |
--friendly, --no-friendly
|
Force the friendly terminal UI on or off |
-p, --password |
One-run password input. Prefer safer sources when possible |
--password-file |
Read the password from a file or Docker secret |
--password-command |
Read the password from an external command |
--dry-run |
Preview without writing files or state |
--only-print-filenames |
Print planned paths for scripting |
--retry-failed |
Re-sync only previously failed assets |
--recent, --recent-scope, --skip-created-before, --skip-created-after
|
One-run date or recency scope |
Persistent sync settings live in Configuration.
| Topic | Description |
|---|---|
| State Tracking | SQLite database for sync state and resume |
| Authentication & 2FA | SRP-6a, trusted device codes, session persistence |
| Credentials | Password sources, OS keyring, encrypted file store |
| Download Pipeline | Streaming, resumable, concurrent downloads |
| Content Validation | Magic byte, Content-Length, and HTML rejection checks |
| Live Photos | MOV companion file handling |
| Content Filtering | Media type, date range, album filters |
| Retry & Resilience | Exponential backoff, checksum verification |
| Reports and Metrics | JSON reports, health checks, metrics, and notification scripts |
| Watch Mode | Continuous sync with interval |
| Service | Background service behavior, logs, status, and restarts |
| EXIF Handling | Date tag reading and writing |
| Folder Structure | Date-based directory organization |
| Configuration | TOML config file guide |
| Docker | Container setup and docker-compose |