diff --git a/trigger/poll/watcher.go b/trigger/poll/watcher.go
index 2290c351..3e457b14 100644
--- a/trigger/poll/watcher.go
+++ b/trigger/poll/watcher.go
@@ -18,6 +18,96 @@ type RepositoryWatcher struct {
 
 	cron *cron.Cron
 }
+
+// Watch - starts watching repository for changes, if it's already watching - ignores,
+// if details changed - updates details
+func (w *RepositoryWatcher) Watch(imageName, schedule, registryUsername, registryPassword string) error {
+
+	imageRef, err := image.Parse(imageName)
+	if err != nil {
+		log.WithFields(log.Fields{
+			"error":      err,
+			"image_name": imageName,
+		}).Error("trigger.poll.RepositoryWatcher.Watch: failed to parse image")
+		return err
+	}
+
+	key := getImageIdentifier(imageRef)
+
+	// checking whether it's already being watched
+	details, ok := w.watched[key]
+	if !ok {
+		err = w.addJob(imageRef, registryUsername, registryPassword, schedule)
+		if err != nil {
+			log.WithFields(log.Fields{
+				"error":             err,
+				"image_name":        imageName,
+				"registry_username": registryUsername,
+			}).Error("trigger.poll.RepositoryWatcher.Watch: failed to add image watch job")
+
+		}
+		return err
+	}
+
+	// checking schedule
+	if details.schedule != schedule {
+		w.cron.UpdateJob(key, schedule)
+	}
+
+	// checking auth details, if changed - need to update
+	if details.registryPassword != registryPassword || details.registryUsername != registryUsername {
+		// recreating job
+		w.cron.DeleteJob(key)
+		err = w.addJob(imageRef, registryUsername, registryPassword, schedule)
+		if err != nil {
+			log.WithFields(log.Fields{
+				"error":             err,
+				"image_name":        imageName,
+				"registry_username": registryUsername,
+			}).Error("trigger.poll.RepositoryWatcher.Watch: failed to add image watch job")
+		}
+		return err
+	}
+
+	// nothing to do
+
+	return nil
+}
+
+func (w *RepositoryWatcher) addJob(ref *image.Reference, registryUsername, registryPassword, schedule string) error {
+	// getting initial digest
+	digest, err := w.registryClient.Digest(registry.Opts{
+		Registry: ref.Registry(),
+		Name:     ref.ShortName(),
+		Tag:      ref.Tag(),
+	})
+	if err != nil {
+		log.WithFields(log.Fields{
+			"error": err,
+			"image": ref.Remote(),
+		}).Error("trigger.poll.RepositoryWatcher.addJob: failed to get image digest")
+		return err
+	}
+
+	key := getImageIdentifier(ref)
+	details := &watchDetails{
+		imageRef:         ref,
+		digest:           digest, // current image digest
+		registryUsername: registryUsername,
+		registryPassword: registryPassword,
+		schedule:         schedule,
+	}
+	// adding new job
+	job := NewWatchTagJob(w.providers, w.registryClient, details)
+	log.WithFields(log.Fields{
+		"job_name": key,
+		"image":    ref.Remote(),
+		"schedule": schedule,
+	}).Info("trigger.poll.RepositoryWatcher: new job added")
+	return w.cron.AddJob(key, schedule, job)
+
+}
+
 // Watch specific tag job
 type WatchTagJob struct {
 	providers      provider.Providers