Getting Started
Prerequisites
Section titled “Prerequisites”- Docker installed and running
- At least one Radarr or Sonarr instance with API access enabled
- The API key for that instance (found in Settings → General → API Key)
Quick start
Section titled “Quick start”Create your config
Section titled “Create your config”Create a roombarr.yml config file. Roombarr reads its config from /config/roombarr.yml inside the container. How you get the file there depends on your platform — the Docker Compose example below uses a bind mount.
dry_run: true
services: radarr: base_url: http://radarr:7878 api_key: your-radarr-api-key
schedule: "0 3 * * *"
rules: - name: Delete old unmonitored movies target: radarr action: delete conditions: operator: AND children: - field: radarr.added operator: older_than value: 1y - field: radarr.monitored operator: equals value: falseStart the container
Section titled “Start the container”Here’s a Docker Compose example. If you use another container platform (Unraid, TrueNAS, Portainer), the same image and settings apply — consult your platform’s docs for container configuration.
services: roombarr: image: ghcr.io/roombarr/roombarr:latest container_name: roombarr restart: unless-stopped ports: - "3000:3000" volumes: - ./config:/config environment: - PUID=1000 - PGID=1000 - TZ=America/New_Yorkimage— Official image from GitHub Container Registry.ports— Exposes the HTTP API on port 3000 for health checks and manual evaluations.volumes— Maps a host directory to/configinside the container. Roombarr readsroombarr.yml, stores its SQLite database, and writes audit logs here.PUID/PGID— User and group ID inside the container. Match to your host user (idcommand) to avoid permission issues.TZ— Timezone for cron scheduling and log timestamps. Use IANA timezone names.
Start the container:
docker compose up -dVerify and test
Section titled “Verify and test”Check that Roombarr is healthy:
curl http://localhost:3000/health{ "status": "ok", "version": "x.y.z" }With dry_run: true, trigger a manual evaluation to see what your rules would do:
curl -X POST http://localhost:3000/evaluateYou’ll receive a 202 Accepted response with a run ID:
{ "run_id": "550e8400-e29b-41d4-a716-446655440000", "status": "running" }Poll for results using the run ID:
curl http://localhost:3000/evaluate/550e8400-e29b-41d4-a716-446655440000{ "run_id": "550e8400-e29b-41d4-a716-446655440000", "status": "completed", "started_at": "2026-02-17T03:00:00.000Z", "completed_at": "2026-02-17T03:00:12.000Z", "dry_run": true, "summary": { "items_evaluated": 142, "items_matched": 7, "actions": { "delete": 7, "unmonitor": 0, "keep": 0 }, "rules_skipped_missing_data": 0 }, "results": [...]}This tells you 142 items were evaluated, 7 matched and would be deleted. Because dry_run is true, nothing was actually removed. See the API reference for the full response shape.