Scheduled playlist synchronization¶
Open Playlist Engine can persist a one-way relationship from a source playlist to a target playlist and run it inside the existing self-hosted worker. Rules, checkpoints, credentials and execution history stay on the instance.
The Library workspace can create these relationships across every connected writable account at once. The selected provider copy remains the source of truth; see Unified playlists.
Create and manage a rule¶
- Complete a migration for one full playlist.
- Open Sync and choose that completed migration.
- Choose a mode, cadence and IANA timezone, then create the rule.
- Use Run now, Pause/Resume, Save, or Delete from the rule card.
- Inspect the latest migration when tracks need review or a provider reports a partial failure.
Partial-track and multi-playlist migrations cannot become rules because they do not provide a deterministic baseline. The same endpoint pair can have only one rule, and an inverse target-to-source rule is rejected to avoid feedback loops.
Modes¶
Add only matches and writes source tracks first observed after the prior applied checkpoint. Target-only tracks and target ordering are preserved. Existing target tracks are reconciled through the migration duplicate logic, so retries do not add another copy.
Mirror matches new source occurrences without appending them, then replaces the target with the complete mapped URI sequence. It is available only for standard playlists when the target advertises removal and reordering and implements ordered replacement. Spotify is the initial mirror target. Liked/saved collections remain add-only.
Spotify replaces the first 100 items and appends later chunks. A failed multi-batch replace is marked ambiguous, the worker attempts to restore the prior ordered sequence, and the retry restarts from the first replacement call.
Scheduling and restarts¶
The ARQ worker checks due rules when it starts and every minute. A rule that became due while the instance was stopped runs once after the worker returns; its next run is calculated from completion rather than replaying every missed interval.
Postgres stores rules, runs and checkpoints. Valkey stores queued work. Docker Compose
uses restart: unless-stopped for the application services, and both backend and
worker apply Alembic migrations before starting.
Only one queued/running execution may exist for a rule. Database uniqueness and row locks prevent normal overlap. Each active run also owns a lease token; stale recovery invalidates that lease before scheduling a retry, so an old worker cannot commit a checkpoint later.
Failures and review¶
| State | Behavior |
|---|---|
review_required |
Scheduling waits. Resolve the linked migration items; finalization then updates the checkpoint and resumes cadence. |
failed / partial_failure |
The rule retains its last successful target state and receives a shorter retry time. Already-written additions are reconciled on retry. |
reconnect_required |
Expired or missing credentials auto-pause the rule. Reconnect the account, then resume. |
paused |
No scheduled run is created. A manual run may still be started. |
Last/next run timestamps, added/removed/reordered counts and the latest error are shown on each rule.
Configuration¶
All values use the OPE_ prefix:
| Setting | Default | Purpose |
|---|---|---|
SYNC_MIN_CADENCE_MINUTES |
5 |
Smallest accepted interval |
SYNC_MAX_CADENCE_MINUTES |
10080 |
Largest accepted interval (one week) |
SYNC_RETRY_DELAY_S |
300 |
Default transient-failure retry |
SYNC_STALE_RUN_AFTER_S |
3900 |
Active-run recovery threshold; keep above worker timeout |
SYNC_SCHEDULER_BATCH_SIZE |
20 |
Due rules claimed per scheduler tick |
The timezone is validated and stored with the rule for schedule presentation. Cadence is an elapsed interval, so daylight-saving changes do not alter the time between runs.
API¶
| Method | Path | Action |
|---|---|---|
GET |
/api/syncs |
List rules with latest run |
POST |
/api/syncs |
Create from a completed migration |
GET |
/api/syncs/{id} |
Get one rule |
PATCH |
/api/syncs/{id} |
Change mode, cadence or timezone |
POST |
/api/syncs/{id}/run |
Queue a manual run |
POST |
/api/syncs/{id}/pause |
Pause |
POST |
/api/syncs/{id}/resume |
Resume |
DELETE |
/api/syncs/{id} |
Delete |