diff --git a/src/main/java/org/olat/modules/lecture/restapi/LectureBlocksWebService.java b/src/main/java/org/olat/modules/lecture/restapi/LectureBlocksWebService.java
index 929f9c5a5b37ace81573b7929a387154ba701661..3b59736015626d702a2d6e8a99e3e98a29355b39 100644
--- a/src/main/java/org/olat/modules/lecture/restapi/LectureBlocksWebService.java
+++ b/src/main/java/org/olat/modules/lecture/restapi/LectureBlocksWebService.java
@@ -105,7 +105,7 @@ public class LectureBlocksWebService {
 	 * Create or update a lecture block.
 	 * @response.representation.200.qname {http://www.example.com}lectureBlocksVO
 	 * @response.representation.200.mediaType application/xml, application/json
-	 * @response.representation.200.doc The updated configuration
+	 * @response.representation.200.doc The updated lecture block
 	 * @response.representation.200.example {@link org.olat.modules.lecture.restapi.Examples#SAMPLE_LECTUREBLOCKVO}
 	 * @response.representation.401.doc The roles of the authenticated user are not sufficient
 	 * @response.representation.404.doc The course not found
diff --git a/src/main/java/org/olat/modules/reminder/manager/ReminderRulesXStream.java b/src/main/java/org/olat/modules/reminder/manager/ReminderRulesXStream.java
new file mode 100644
index 0000000000000000000000000000000000000000..722226034599c8bb594f0a0f619ea6d0fd6d366c
--- /dev/null
+++ b/src/main/java/org/olat/modules/reminder/manager/ReminderRulesXStream.java
@@ -0,0 +1,67 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.modules.reminder.manager;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.olat.core.util.xml.XStreamHelper;
+import org.olat.modules.reminder.model.ImportExportReminders;
+import org.olat.modules.reminder.model.ReminderRules;
+
+import com.thoughtworks.xstream.XStream;
+
+/**
+ * 
+ * Initial date: 25 mars 2019<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class ReminderRulesXStream {
+	
+	private static final XStream ruleXStream = XStreamHelper.createXStreamInstance();
+	static {
+		ruleXStream.alias("rule", org.olat.modules.reminder.model.ReminderRuleImpl.class);
+		ruleXStream.alias("rules", org.olat.modules.reminder.model.ReminderRules.class);
+		ruleXStream.alias("reminders", org.olat.modules.reminder.model.ImportExportReminders.class);
+		ruleXStream.alias("reminder", org.olat.modules.reminder.model.ImportExportReminder.class);
+	}
+	
+	public static ReminderRules toRules(String rulesXml) {
+		return (ReminderRules)ruleXStream.fromXML(rulesXml);
+	}
+	
+	public static ReminderRules toRules(InputStream in) {
+		return (ReminderRules)ruleXStream.fromXML(in);
+	}
+	
+	public static String toXML(ReminderRules rules) {
+		return ruleXStream.toXML(rules);
+	}
+	
+	public static void toXML(ImportExportReminders reminders, OutputStream out) {
+		ruleXStream.toXML(reminders, out);
+	}
+	
+	public static ImportExportReminders fromXML(InputStream in) {
+		return (ImportExportReminders)ruleXStream.fromXML(in);
+	}
+
+}
diff --git a/src/main/java/org/olat/modules/reminder/manager/ReminderServiceImpl.java b/src/main/java/org/olat/modules/reminder/manager/ReminderServiceImpl.java
index 083952a24acbf478e22882d034e39c5e03af1719..864fc993b4035cb4645edd8cc69762bc773468cd 100644
--- a/src/main/java/org/olat/modules/reminder/manager/ReminderServiceImpl.java
+++ b/src/main/java/org/olat/modules/reminder/manager/ReminderServiceImpl.java
@@ -50,7 +50,6 @@ import org.olat.core.util.mail.MailContextImpl;
 import org.olat.core.util.mail.MailManager;
 import org.olat.core.util.mail.MailTemplate;
 import org.olat.core.util.mail.MailerResult;
-import org.olat.core.util.xml.XStreamHelper;
 import org.olat.modules.reminder.Reminder;
 import org.olat.modules.reminder.ReminderRule;
 import org.olat.modules.reminder.ReminderService;
@@ -69,8 +68,6 @@ import org.olat.user.UserManager;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import com.thoughtworks.xstream.XStream;
-
 /**
  * 
  * Initial date: 08.04.2015<br>
@@ -81,13 +78,6 @@ import com.thoughtworks.xstream.XStream;
 public class ReminderServiceImpl implements ReminderService {
 	
 	private static final OLog log = Tracing.createLoggerFor(ReminderServiceImpl.class);
-	private static final XStream ruleXStream = XStreamHelper.createXStreamInstance();
-	static {
-		ruleXStream.alias("rule", org.olat.modules.reminder.model.ReminderRuleImpl.class);
-		ruleXStream.alias("rules", org.olat.modules.reminder.model.ReminderRules.class);
-		ruleXStream.alias("reminders", org.olat.modules.reminder.model.ImportExportReminders.class);
-		ruleXStream.alias("reminder", org.olat.modules.reminder.model.ImportExportReminder.class);
-	}
 	
 	
 	@Autowired
@@ -174,12 +164,12 @@ public class ReminderServiceImpl implements ReminderService {
 
 	@Override
 	public String toXML(ReminderRules rules) {
-		return ruleXStream.toXML(rules);
+		return ReminderRulesXStream.toXML(rules);
 	}
 	
 	@Override
 	public ReminderRules toRules(String rulesXml) {
-		return (ReminderRules)ruleXStream.fromXML(rulesXml);
+		return ReminderRulesXStream.toRules(rulesXml);
 	}
 	
 	@Override
@@ -192,7 +182,7 @@ public class ReminderServiceImpl implements ReminderService {
 					ImportExportReminder exportReminder = new ImportExportReminder(reminder);
 					exportReminders.getReminders().add(exportReminder);
 				}
-				ruleXStream.toXML(exportReminders, fOut);
+				ReminderRulesXStream.toXML(exportReminders, fOut);
 			} catch(Exception e) {
 				log.error("", e);
 			}
@@ -205,7 +195,7 @@ public class ReminderServiceImpl implements ReminderService {
 		List<Reminder> reminders = new ArrayList<>();
 		if(reminderFile.exists()) {
 			try(InputStream in = new FileInputStream(reminderFile)) {
-				ImportExportReminders importReminders = (ImportExportReminders)ruleXStream.fromXML(in);
+				ImportExportReminders importReminders = ReminderRulesXStream.fromXML(in);
 				List<ImportExportReminder> importReminderList = importReminders.getReminders();
 				for(ImportExportReminder importReminder:importReminderList) {
 					Reminder reminder = reminderDao.createReminder(newEntry, creator);
diff --git a/src/main/java/org/olat/modules/reminder/restapi/Examples.java b/src/main/java/org/olat/modules/reminder/restapi/Examples.java
new file mode 100644
index 0000000000000000000000000000000000000000..9e5bef4138c2f4f0722acf36a077bce3facfdedf
--- /dev/null
+++ b/src/main/java/org/olat/modules/reminder/restapi/Examples.java
@@ -0,0 +1,40 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.modules.reminder.restapi;
+
+/**
+ * 
+ * Initial date: 25 mars 2019<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class Examples {
+
+	public static final ReminderVO SAMPLE_REMINDERVO = new ReminderVO();
+	
+	static {
+		SAMPLE_REMINDERVO.setKey(231l);
+		SAMPLE_REMINDERVO.setRepoEntryKey(264827834l);
+		SAMPLE_REMINDERVO.setDescription("A nice little description");
+		SAMPLE_REMINDERVO.setEmailSubject("The subject");
+		SAMPLE_REMINDERVO.setEmailBody("The body");
+	}
+
+}
diff --git a/src/main/java/org/olat/modules/reminder/restapi/ReminderRuleVO.java b/src/main/java/org/olat/modules/reminder/restapi/ReminderRuleVO.java
new file mode 100644
index 0000000000000000000000000000000000000000..1652974f82880238df2ea9f31f4536466de75450
--- /dev/null
+++ b/src/main/java/org/olat/modules/reminder/restapi/ReminderRuleVO.java
@@ -0,0 +1,101 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.modules.reminder.restapi;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.olat.modules.reminder.ReminderRule;
+import org.olat.modules.reminder.model.ReminderRuleImpl;
+
+/**
+ * 
+ * Initial date: 25 mars 2019<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlRootElement(name = "reminderRuleVO")
+public class ReminderRuleVO {
+	
+	private String type;
+	private String leftOperand;
+	private String operator;
+	private String rightOperand;
+	private String rightUnit;
+	
+	public ReminderRuleVO() {
+		//
+	}
+	
+	public static ReminderRuleVO valueOf(ReminderRule rule) {
+		ReminderRuleVO vo = new ReminderRuleVO();
+		vo.setType(rule.getType());
+		if(rule instanceof ReminderRuleImpl) {
+			ReminderRuleImpl ruleImpl = (ReminderRuleImpl)rule;
+			vo.setLeftOperand(ruleImpl.getLeftOperand());
+			vo.setOperator(ruleImpl.getOperator());
+			vo.setRightOperand(ruleImpl.getRightOperand());
+			vo.setRightUnit(ruleImpl.getRightUnit());
+		}
+		return vo;
+	}
+	
+	public String getType() {
+		return type;
+	}
+	
+	public void setType(String type) {
+		this.type = type;
+	}
+	
+	public String getLeftOperand() {
+		return leftOperand;
+	}
+	
+	public void setLeftOperand(String leftOperand) {
+		this.leftOperand = leftOperand;
+	}
+	
+	public String getOperator() {
+		return operator;
+	}
+	
+	public void setOperator(String operator) {
+		this.operator = operator;
+	}
+	
+	public String getRightOperand() {
+		return rightOperand;
+	}
+	
+	public void setRightOperand(String rightOperand) {
+		this.rightOperand = rightOperand;
+	}
+	
+	public String getRightUnit() {
+		return rightUnit;
+	}
+	
+	public void setRightUnit(String rightUnit) {
+		this.rightUnit = rightUnit;
+	}
+}
diff --git a/src/main/java/org/olat/modules/reminder/restapi/ReminderVO.java b/src/main/java/org/olat/modules/reminder/restapi/ReminderVO.java
new file mode 100644
index 0000000000000000000000000000000000000000..6a639459d4739caeaf6f1eb72272c60fb24ca4be
--- /dev/null
+++ b/src/main/java/org/olat/modules/reminder/restapi/ReminderVO.java
@@ -0,0 +1,126 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.modules.reminder.restapi;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.olat.core.util.StringHelper;
+import org.olat.modules.reminder.Reminder;
+import org.olat.modules.reminder.ReminderRule;
+import org.olat.modules.reminder.manager.ReminderRulesXStream;
+import org.olat.modules.reminder.model.ReminderRules;
+
+/**
+ * 
+ * Initial date: 25 mars 2019<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlRootElement(name = "reminderVO")
+public class ReminderVO {
+	
+	private Long key;
+	private Long repoEntryKey;
+	
+	private String description;
+	private String emailSubject;
+	private String emailBody;
+	
+	private List<ReminderRuleVO> rules = new ArrayList<>();
+	
+	public static ReminderVO valueOf(Reminder reminder, Long repositoryEntryKey) {
+		ReminderVO vo = new ReminderVO();
+		vo.setKey(reminder.getKey());
+		vo.setRepoEntryKey(repositoryEntryKey);
+		vo.setDescription(reminder.getDescription());
+		vo.setEmailSubject(reminder.getEmailSubject());
+		vo.setEmailBody(reminder.getEmailBody());
+		
+		String configuration = reminder.getConfiguration();
+		if(StringHelper.containsNonWhitespace(configuration)) {
+			ReminderRules reminderRules = ReminderRulesXStream.toRules(configuration);
+			List<ReminderRule> rules = reminderRules.getRules();
+			List<ReminderRuleVO> ruleVoes = new ArrayList<>();
+			for(ReminderRule rule:rules) {
+				ruleVoes.add(ReminderRuleVO.valueOf(rule));
+			}
+			vo.setRules(ruleVoes);
+		}
+		
+		return vo;
+	}
+	
+	public Long getKey() {
+		return key;
+	}
+	
+	public void setKey(Long key) {
+		this.key = key;
+	}
+	
+	public Long getRepoEntryKey() {
+		return repoEntryKey;
+	}
+	
+	public void setRepoEntryKey(Long repoEntryKey) {
+		this.repoEntryKey = repoEntryKey;
+	}
+
+	public String getDescription() {
+		return description;
+	}
+
+	public void setDescription(String description) {
+		this.description = description;
+	}
+
+	public String getEmailSubject() {
+		return emailSubject;
+	}
+
+	public void setEmailSubject(String emailSubject) {
+		this.emailSubject = emailSubject;
+	}
+
+	public String getEmailBody() {
+		return emailBody;
+	}
+
+	public void setEmailBody(String emailBody) {
+		this.emailBody = emailBody;
+	}
+
+	public List<ReminderRuleVO> getRules() {
+		return rules;
+	}
+
+	public void setRules(List<ReminderRuleVO> rules) {
+		this.rules = rules;
+	}
+	
+	
+
+}
diff --git a/src/main/java/org/olat/modules/reminder/restapi/RemindersWebService.java b/src/main/java/org/olat/modules/reminder/restapi/RemindersWebService.java
new file mode 100644
index 0000000000000000000000000000000000000000..ed6806921d57ca78eff98b513933811ac486ab63
--- /dev/null
+++ b/src/main/java/org/olat/modules/reminder/restapi/RemindersWebService.java
@@ -0,0 +1,196 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.modules.reminder.restapi;
+
+import static org.olat.restapi.security.RestSecurityHelper.getIdentity;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+
+import org.olat.core.id.Identity;
+import org.olat.modules.reminder.Reminder;
+import org.olat.modules.reminder.ReminderService;
+import org.olat.modules.reminder.manager.ReminderRulesXStream;
+import org.olat.modules.reminder.model.ReminderRuleImpl;
+import org.olat.modules.reminder.model.ReminderRules;
+import org.olat.repository.RepositoryEntry;
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ * 
+ * Initial date: 25 mars 2019<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class RemindersWebService {
+	
+	private RepositoryEntry entry;
+	private final boolean administrator;
+	
+	@Autowired	
+	private ReminderService reminderService;
+	
+	public RemindersWebService(RepositoryEntry entry, boolean administrator) {
+		this.entry = entry;
+		this.administrator = administrator;
+	}
+	
+	/**
+	 * Return the reminders of the specified course or repository entry.
+	 * @response.representation.200.qname {http://www.example.com}reminderVO
+	 * @response.representation.200.mediaType application/xml, application/json
+	 * @response.representation.200.doc An array of lecture blocks
+	 * @response.representation.200.example {@link org.olat.modules.reminder.restapi.Examples#SAMPLE_REMINDERVO}
+	 * @response.representation.401.doc The roles of the authenticated user are not sufficient
+	 * @response.representation.404.doc The resource not found
+	 * @return The reminders
+	 */
+	@GET
+	@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
+	public Response getReminders() {
+		if(!administrator) {
+			return Response.serverError().status(Status.UNAUTHORIZED).build();
+		}
+		
+		List<Reminder> reminders = reminderService.getReminders(entry);
+		List<ReminderVO> voList = new ArrayList<>(reminders.size());
+		for(Reminder reminder:reminders) {
+			voList.add(ReminderVO.valueOf(reminder, entry.getKey()));
+		}
+		ReminderVO[] voes = voList.toArray(new ReminderVO[voList.size()]);
+		return Response.ok(voes).build();
+	}
+	
+	/**
+	 * Create or update a reminder.
+	 * 
+	 * @response.representation.200.qname {http://www.example.com}reminderVO
+	 * @response.representation.200.mediaType application/xml, application/json
+	 * @response.representation.200.doc The updated reminder
+	 * @response.representation.200.example {@link org.olat.modules.reminder.restapi.Examples#SAMPLE_REMINDERVO}
+	 * @response.representation.401.doc The roles of the authenticated user are not sufficient
+	 * @response.representation.404.doc The course or repository entry not found
+	 * @param reminder The reminder
+	 * @param httpRequest The HTTP request
+	 * @return It returns the updated / created reminder.
+	 */
+	@PUT
+	@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
+	@Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
+	public Response putReminder(ReminderVO reminder, @Context HttpServletRequest httpRequest) {
+		if(!administrator) {
+			return Response.serverError().status(Status.UNAUTHORIZED).build();
+		}
+		Reminder updatedReminder = saveReminder(reminder, httpRequest);
+		return Response.ok(ReminderVO.valueOf(updatedReminder, entry.getKey())).build();
+	}
+	
+	/**
+	 * Create or update a reminder.
+	 * 
+	 * @response.representation.200.qname {http://www.example.com}reminderVO
+	 * @response.representation.200.mediaType application/xml, application/json
+	 * @response.representation.200.doc The updated reminder
+	 * @response.representation.200.example {@link org.olat.modules.lecture.restapi.Examples#SAMPLE_REMINDERVO}
+	 * @response.representation.401.doc The roles of the authenticated user are not sufficient
+	 * @response.representation.404.doc The course or repository entry not found
+	 * @param reminder The reminder
+	 * @param httpRequest The HTTP request
+	 * @return It returns the updated / created reminder.
+	 */
+	@POST
+	@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
+	@Consumes({MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
+	public Response postReminder(ReminderVO reminder, @Context HttpServletRequest httpRequest) {
+		if(!administrator) {
+			return Response.serverError().status(Status.UNAUTHORIZED).build();
+		}
+		Reminder updatedReminder = saveReminder(reminder, httpRequest);
+		return Response.ok(ReminderVO.valueOf(updatedReminder, entry.getKey())).build();
+	}
+
+	private Reminder saveReminder(ReminderVO reminderVo, HttpServletRequest httpRequest) {
+		Identity creator = getIdentity(httpRequest);
+		
+		Reminder reminder;
+		if(reminderVo.getKey() == null) {
+			reminder = reminderService.createReminder(entry, creator);
+		} else {
+			reminder = reminderService.loadByKey(reminderVo.getKey());
+		}
+
+		reminder.setDescription(reminderVo.getDescription());
+		reminder.setEmailSubject(reminderVo.getEmailSubject());
+		reminder.setEmailBody(reminderVo.getEmailBody());
+		
+		if(reminderVo.getRules() != null && !reminderVo.getRules().isEmpty()) {
+			ReminderRules rules = new ReminderRules();
+			for(ReminderRuleVO ruleVo:reminderVo.getRules()) {
+				ReminderRuleImpl rule = new ReminderRuleImpl();
+				rule.setType(ruleVo.getType());
+				rule.setLeftOperand(ruleVo.getLeftOperand());
+				rule.setOperator(ruleVo.getOperator());
+				rule.setRightOperand(ruleVo.getRightOperand());
+				rule.setRightUnit(ruleVo.getRightUnit());
+				rules.getRules().add(rule);
+			}
+			String configuration = ReminderRulesXStream.toXML(rules);
+			reminder.setConfiguration(configuration);
+		}
+		return reminderService.save(reminder);
+	}
+	
+	/**
+	 * Delete a specific reminder.
+	 * @response.representation.200.doc Reminder deleted
+	 * @response.representation.401.doc The roles of the authenticated user are not sufficient
+	 * @response.representation.404.doc The course or repository entry not found
+	 * @param reminderKey The reminder primary key
+	 * @return Nothing
+	 */
+	@DELETE
+	@Path("{reminderKey}")
+	public Response deleteReminder(@PathParam("reminderKey") Long reminderKey) {
+		if(!administrator) {
+			return Response.serverError().status(Status.UNAUTHORIZED).build();
+		}
+		Reminder reminder = reminderService.loadByKey(reminderKey);
+		if(reminder == null) {
+			return Response.serverError().status(Status.NOT_FOUND).build();
+		}
+		
+		reminderService.delete(reminder);
+		return Response.ok().build();
+	}
+}
diff --git a/src/main/java/org/olat/restapi/repository/RepositoryEntryWebService.java b/src/main/java/org/olat/restapi/repository/RepositoryEntryWebService.java
index 6001d059306d225166bd401112e25fda56cd28cf..b0ef004cc93a355d4d120121d39bb61ce29649b0 100644
--- a/src/main/java/org/olat/restapi/repository/RepositoryEntryWebService.java
+++ b/src/main/java/org/olat/restapi/repository/RepositoryEntryWebService.java
@@ -81,6 +81,7 @@ import org.olat.modules.curriculum.CurriculumElement;
 import org.olat.modules.curriculum.CurriculumService;
 import org.olat.modules.curriculum.restapi.CurriculumElementVO;
 import org.olat.modules.lecture.restapi.LectureBlocksWebService;
+import org.olat.modules.reminder.restapi.RemindersWebService;
 import org.olat.modules.taxonomy.TaxonomyLevel;
 import org.olat.modules.taxonomy.TaxonomyService;
 import org.olat.modules.taxonomy.model.TaxonomyLevelRefImpl;
@@ -203,6 +204,19 @@ public class RepositoryEntryWebService {
 		return service;
 	}
 	
+	/**
+	 * To get the web service for the reminders of a specific course.
+	 * 
+	 * @return The web service for reminders.
+	 */
+	@Path("reminders")
+	public RemindersWebService getRemindersWebService(@Context HttpServletRequest request) {
+		boolean administrator = isAuthorEditor(request);
+		RemindersWebService service = new RemindersWebService(entry, administrator);
+		CoreSpringFactory.autowireObject(service);
+		return service;
+	}
+	
 	@GET
 	@Path("curriculum/elements")
 	@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
diff --git a/src/main/java/org/olat/restapi/repository/course/CourseWebService.java b/src/main/java/org/olat/restapi/repository/course/CourseWebService.java
index 4e68808cae7e888c599c99183d220163015c7495..2e97a0511dc07881d44deff288af766afbc0daac 100644
--- a/src/main/java/org/olat/restapi/repository/course/CourseWebService.java
+++ b/src/main/java/org/olat/restapi/repository/course/CourseWebService.java
@@ -80,6 +80,7 @@ import org.olat.course.run.userview.UserCourseEnvironment;
 import org.olat.course.run.userview.UserCourseEnvironmentImpl;
 import org.olat.modules.gotomeeting.restapi.GoToTrainingWebService;
 import org.olat.modules.lecture.restapi.LectureBlocksWebService;
+import org.olat.modules.reminder.restapi.RemindersWebService;
 import org.olat.modules.vitero.restapi.ViteroBookingWebService;
 import org.olat.repository.ErrorList;
 import org.olat.repository.RepositoryEntry;
@@ -236,6 +237,20 @@ public class CourseWebService {
 		CoreSpringFactory.autowireObject(service);
 		return service;
 	}
+	
+	/**
+	 * To get the web service for the reminders of a specific course.
+	 * 
+	 * @return The web service for reminders.
+	 */
+	@Path("reminders")
+	public RemindersWebService getRemindersWebService(@Context HttpServletRequest request) {
+		RepositoryEntry courseRe = course.getCourseEnvironment().getCourseGroupManager().getCourseEntry();
+		boolean administrator = isManager(request);
+		RemindersWebService service = new RemindersWebService(courseRe, administrator);
+		CoreSpringFactory.autowireObject(service);
+		return service;
+	}
 
 	/**
 	 * Publish the course.
diff --git a/src/test/java/org/olat/modules/reminder/manager/ReminderRulesXStreamTest.java b/src/test/java/org/olat/modules/reminder/manager/ReminderRulesXStreamTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..1387ed3aed7cd6cad8e5391b03181fe1a8df9a77
--- /dev/null
+++ b/src/test/java/org/olat/modules/reminder/manager/ReminderRulesXStreamTest.java
@@ -0,0 +1,67 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.modules.reminder.manager;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.olat.core.logging.OLog;
+import org.olat.core.logging.Tracing;
+import org.olat.modules.reminder.model.ImportExportReminders;
+import org.olat.modules.reminder.model.ReminderRules;
+
+/**
+ * 
+ * Initial date: 26 mars 2019<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class ReminderRulesXStreamTest {
+	
+	private static final OLog log = Tracing.createLoggerFor(ReminderRulesXStreamTest.class);
+	
+	@Test
+	public void readReminderRulesXml() {
+		ReminderRules reminderRules = null;
+		try(InputStream input=ReminderRulesXStreamTest.class.getResourceAsStream("reminder_rules_1.xml")) {
+			reminderRules = ReminderRulesXStream.toRules(input);
+		} catch(IOException e) {
+			log.error("", e);
+		}
+		
+		Assert.assertNotNull(reminderRules);
+		Assert.assertNotNull(reminderRules.getRules());
+		Assert.assertEquals(3, reminderRules.getRules().size());
+	}
+	
+	@Test
+	public void readImportedReminderRulesXml() {
+		ImportExportReminders reminders = null;
+		try(InputStream input=ReminderRulesXStreamTest.class.getResourceAsStream("import_reminders.xml")) {
+			reminders = ReminderRulesXStream.fromXML(input);
+		} catch(IOException e) {
+			log.error("", e);
+		}
+		
+		Assert.assertNotNull(reminders);
+	}
+}
diff --git a/src/test/java/org/olat/modules/reminder/manager/import_reminders.xml b/src/test/java/org/olat/modules/reminder/manager/import_reminders.xml
new file mode 100644
index 0000000000000000000000000000000000000000..36232b121198f1c41f6417a535b64ef1ca668df1
--- /dev/null
+++ b/src/test/java/org/olat/modules/reminder/manager/import_reminders.xml
@@ -0,0 +1,28 @@
+<reminders>
+  <reminders>
+    <reminder>
+      <description>XML Reminder</description>
+      <configuration>&lt;rules&gt;
+  &lt;rules&gt;
+    &lt;rule&gt;
+      &lt;type&gt;DateRuleSPI&lt;/type&gt;
+      &lt;operator&gt;&amp;gt;&lt;/operator&gt;
+      &lt;rightOperand&gt;2020-03-01T00:00:00&lt;/rightOperand&gt;
+    &lt;/rule&gt;
+    &lt;rule&gt;
+      &lt;type&gt;BeforeDateRuleSPI&lt;/type&gt;
+      &lt;operator&gt;&amp;lt;&lt;/operator&gt;
+      &lt;rightOperand&gt;2020-03-26T00:00:00&lt;/rightOperand&gt;
+    &lt;/rule&gt;
+    &lt;rule&gt;
+      &lt;type&gt;RepositoryEntryRoleRuleSPI&lt;/type&gt;
+      &lt;operator&gt;=&lt;/operator&gt;
+      &lt;rightOperand&gt;coach&lt;/rightOperand&gt;
+    &lt;/rule&gt;
+  &lt;/rules&gt;
+&lt;/rules&gt;</configuration>
+      <emailSubject>E-mail subject</emailSubject>
+      <emailBody>&lt;p&gt;E-mail body&lt;/p&gt;</emailBody>
+    </reminder>
+  </reminders>
+</reminders>
\ No newline at end of file
diff --git a/src/test/java/org/olat/modules/reminder/manager/reminder_rules_1.xml b/src/test/java/org/olat/modules/reminder/manager/reminder_rules_1.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f6afabd98f4c271a49830eb157954d3dbc1710ff
--- /dev/null
+++ b/src/test/java/org/olat/modules/reminder/manager/reminder_rules_1.xml
@@ -0,0 +1,20 @@
+<rules>
+  <rules>
+    <rule>
+      <type>DateRuleSPI</type>
+      <operator>&gt;</operator>
+      <rightOperand>2015-05-13T00:00:00</rightOperand>
+    </rule>
+    <rule>
+      <type>BusinessGroupRoleRuleSPI</type>
+      <operator>=</operator>
+      <rightOperand>128286721</rightOperand>
+    </rule>
+    <rule>
+      <type>PassedRuleSPI</type>
+      <leftOperand>91610795686842</leftOperand>
+      <operator>=</operator>
+      <rightOperand>passed</rightOperand>
+    </rule>
+  </rules>
+</rules>
\ No newline at end of file
diff --git a/src/test/java/org/olat/restapi/RemindersWebServiceTest.java b/src/test/java/org/olat/restapi/RemindersWebServiceTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..022f8684555de30718bc854bfa35df3514e594c3
--- /dev/null
+++ b/src/test/java/org/olat/restapi/RemindersWebServiceTest.java
@@ -0,0 +1,338 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.restapi;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.UriBuilder;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.HttpDelete;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpPut;
+import org.junit.Assert;
+import org.junit.Test;
+import org.olat.core.commons.persistence.DB;
+import org.olat.core.id.Identity;
+import org.olat.core.logging.OLog;
+import org.olat.core.logging.Tracing;
+import org.olat.course.nodes.gta.rule.AssignTaskRuleSPI;
+import org.olat.modules.reminder.Reminder;
+import org.olat.modules.reminder.ReminderRule;
+import org.olat.modules.reminder.ReminderService;
+import org.olat.modules.reminder.manager.ReminderDAO;
+import org.olat.modules.reminder.manager.ReminderRuleEngine;
+import org.olat.modules.reminder.manager.ReminderRulesXStream;
+import org.olat.modules.reminder.model.ReminderImpl;
+import org.olat.modules.reminder.model.ReminderRuleImpl;
+import org.olat.modules.reminder.model.ReminderRules;
+import org.olat.modules.reminder.restapi.ReminderRuleVO;
+import org.olat.modules.reminder.restapi.ReminderVO;
+import org.olat.modules.reminder.rule.DateRuleSPI;
+import org.olat.repository.RepositoryEntry;
+import org.olat.test.JunitTestHelper;
+import org.olat.test.OlatJerseyTestCase;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+/**
+ * 
+ * Initial date: 25 mars 2019<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class RemindersWebServiceTest extends OlatJerseyTestCase {
+	
+	private static final OLog log = Tracing.createLoggerFor(RemindersWebServiceTest.class);
+
+	@Autowired
+	private DB dbInstance;
+	@Autowired
+	private ReminderDAO reminderDao;
+	@Autowired
+	private DateRuleSPI dateRuleSpi;
+	@Autowired
+	private ReminderService reminderService;
+	
+	@Test
+	public void getReminders_repo()
+	throws IOException, URISyntaxException {
+		RestConnection conn = new RestConnection();
+		Assert.assertTrue(conn.login("administrator", "openolat"));
+		
+		Identity creator = JunitTestHelper.createAndPersistIdentityAsRndUser("rest-rem-1");
+		RepositoryEntry entry = JunitTestHelper.createAndPersistRepositoryEntry();
+		Reminder transientReminder = reminderService.createReminder(entry, creator);
+		transientReminder.setDescription("Hello");
+		Reminder reminder = reminderService.save(transientReminder);
+		
+		dbInstance.commitAndCloseSession();
+		
+		URI request = UriBuilder.fromUri(getContextURI()).path("repo").path("entries")
+				.path(entry.getKey().toString()).path("reminders").build();
+		HttpGet method = conn.createGet(request, MediaType.APPLICATION_JSON, true);
+		HttpResponse response = conn.execute(method);
+		Assert.assertEquals(200, response.getStatusLine().getStatusCode());
+
+		List<ReminderVO> reminderVoes = parseReminderArray(response.getEntity());
+		Assert.assertNotNull(reminderVoes);
+		Assert.assertEquals(1, reminderVoes.size());
+		ReminderVO reminderVo = reminderVoes.get(0);
+		Assert.assertNotNull(reminderVo);
+		Assert.assertEquals(reminder.getKey(), reminderVo.getKey());
+	}
+	
+	@Test
+	public void getReminders_course()
+	throws IOException, URISyntaxException {
+		RestConnection conn = new RestConnection();
+		Assert.assertTrue(conn.login("administrator", "openolat"));
+		
+		Identity creator = JunitTestHelper.createAndPersistIdentityAsRndUser("rest-rem-1");
+		RepositoryEntry courseEntry = JunitTestHelper.deployBasicCourse(creator);
+		Reminder transientReminder = reminderService.createReminder(courseEntry, creator);
+		transientReminder.setDescription("Hello");
+		Reminder reminder = reminderService.save(transientReminder);
+		
+		dbInstance.commitAndCloseSession();
+		
+		URI request = UriBuilder.fromUri(getContextURI()).path("repo").path("courses")
+				.path(courseEntry.getOlatResource().getResourceableId().toString()).path("reminders").build();
+		HttpGet method = conn.createGet(request, MediaType.APPLICATION_JSON, true);
+		HttpResponse response = conn.execute(method);
+		Assert.assertEquals(200, response.getStatusLine().getStatusCode());
+
+		List<ReminderVO> reminderVoes = parseReminderArray(response.getEntity());
+		Assert.assertNotNull(reminderVoes);
+		Assert.assertEquals(1, reminderVoes.size());
+		ReminderVO reminderVo = reminderVoes.get(0);
+		Assert.assertNotNull(reminderVo);
+		Assert.assertEquals(reminder.getKey(), reminderVo.getKey());
+	}
+	
+	@Test
+	public void putNewReminder()
+	throws IOException, URISyntaxException {
+		Identity creator = JunitTestHelper.createAndPersistIdentityAsRndAdmin("rest-rem-1");
+		RepositoryEntry entry = JunitTestHelper.createAndPersistRepositoryEntry();
+		dbInstance.commitAndCloseSession();
+		
+		RestConnection conn = new RestConnection();
+		Assert.assertTrue(conn.login(creator.getName(), JunitTestHelper.PWD));
+		
+		ReminderVO reminderVo = new ReminderVO();
+		reminderVo.setDescription("Hello, I'm a reminder");
+		reminderVo.setEmailSubject("Remind me");
+		reminderVo.setEmailBody("<p>To remind you</p>");
+		
+		List<ReminderRuleVO> rulesVo = new ArrayList<>();
+		reminderVo.setRules(rulesVo);
+		ReminderRuleVO ruleVo = new ReminderRuleVO();
+		ruleVo.setType("DateRuleSPI");
+		ruleVo.setOperator(">");
+		ruleVo.setRightOperand("2015-05-13T00:00:00");
+		rulesVo.add(ruleVo);
+		
+		URI request = UriBuilder.fromUri(getContextURI()).path("repo").path("entries")
+				.path(entry.getKey().toString()).path("reminders").build();
+		HttpPut method = conn.createPut(request, MediaType.APPLICATION_JSON, true);
+		conn.addJsonEntity(method, reminderVo);
+		HttpResponse response = conn.execute(method);
+		Assert.assertEquals(200, response.getStatusLine().getStatusCode());
+
+		// check the return value
+		ReminderVO savedReminderVo = conn.parse(response, ReminderVO.class);
+		Assert.assertNotNull(savedReminderVo);
+		Assert.assertNotNull(savedReminderVo.getKey());
+		Assert.assertEquals(entry.getKey(), savedReminderVo.getRepoEntryKey());
+		Assert.assertEquals("Hello, I'm a reminder", savedReminderVo.getDescription());
+		Assert.assertEquals("Remind me", savedReminderVo.getEmailSubject());
+		Assert.assertEquals("<p>To remind you</p>", savedReminderVo.getEmailBody());
+		Assert.assertEquals(1, savedReminderVo.getRules().size());
+		
+		// check the reminder on the database
+		List<Reminder> reminders = reminderService.getReminders(entry);
+		Assert.assertNotNull(reminders);
+		Assert.assertEquals(1, reminders.size());
+		Reminder reminder = reminders.get(0);
+		Assert.assertEquals(savedReminderVo.getKey(), reminder.getKey());
+		Assert.assertEquals("Hello, I'm a reminder", reminder.getDescription());
+		Assert.assertEquals("Remind me", reminder.getEmailSubject());
+		Assert.assertEquals("<p>To remind you</p>", reminder.getEmailBody());
+		Assert.assertEquals(creator, ((ReminderImpl)reminder).getCreator());
+		
+		// check rule configuration
+		String configuration = reminder.getConfiguration();
+		ReminderRules rules = reminderService.toRules(configuration);
+		List<ReminderRule> ruleList = rules.getRules();
+		Assert.assertEquals(1, ruleList.size());
+		ReminderRule rule = ruleList.get(0);
+		Assert.assertEquals(ReminderRuleEngine.DATE_RULE_TYPE, rule.getType());
+		
+		// check if the rule works
+		boolean ok = dateRuleSpi.evaluate(rule);
+		Assert.assertTrue(ok);
+	}
+	
+	@Test
+	public void postReminder()
+	throws IOException, URISyntaxException {
+		Identity creator = JunitTestHelper.createAndPersistIdentityAsRndAdmin("rest-rem-3");
+		RepositoryEntry entry = JunitTestHelper.createAndPersistRepositoryEntry();
+		
+		Reminder reminder = reminderService.createReminder(entry, creator);
+		reminder.setDescription("Hello, I'm a reminder");
+		reminder.setEmailSubject("Remind me");
+		reminder.setEmailBody("<p>To remind you</p>");
+		
+		ReminderRules rules = new ReminderRules();
+		ReminderRuleImpl rule = new ReminderRuleImpl();
+		rule.setType("DateRuleSPI");
+		rule.setOperator("<");
+		rule.setRightOperand("2015-05-13T00:00:00");
+		rules.getRules().add(rule);
+		String configuration = ReminderRulesXStream.toXML(rules);
+		reminder.setConfiguration(configuration);
+		reminder = reminderService.save(reminder);
+		
+		dbInstance.commitAndCloseSession();
+		
+		RestConnection conn = new RestConnection();
+		Assert.assertTrue(conn.login(creator.getName(), JunitTestHelper.PWD));
+		
+		ReminderVO reminderVo = new ReminderVO();
+		reminderVo.setKey(reminder.getKey());
+		reminderVo.setRepoEntryKey(entry.getKey());
+		reminderVo.setDescription("I forgot");
+		reminderVo.setEmailSubject("I forgot the subject");
+		reminderVo.setEmailBody("<p>I forgot the body</p>");
+		
+		List<ReminderRuleVO> rulesVo = new ArrayList<>();
+		reminderVo.setRules(rulesVo);
+		ReminderRuleVO rule1Vo = new ReminderRuleVO();
+		rule1Vo.setType("AssignTaskRuleSPI");
+		rule1Vo.setLeftOperand("937539759");
+		rule1Vo.setOperator("<");
+		rule1Vo.setRightOperand("1");
+		rule1Vo.setRightUnit("day");
+		rulesVo.add(rule1Vo);
+		
+		ReminderRuleVO rule2Vo = new ReminderRuleVO();
+		rule2Vo.setType("DateRuleSPI");
+		rule2Vo.setOperator(">");
+		rule2Vo.setRightOperand("2019-05-15T00:00:00");
+		rulesVo.add(rule2Vo);
+		
+		reminderVo.setRules(rulesVo);
+		
+		URI request = UriBuilder.fromUri(getContextURI()).path("repo").path("entries")
+				.path(entry.getKey().toString()).path("reminders").build();
+		HttpPost method = conn.createPost(request, MediaType.APPLICATION_JSON);
+		conn.addJsonEntity(method, reminderVo);
+		HttpResponse response = conn.execute(method);
+		Assert.assertEquals(200, response.getStatusLine().getStatusCode());
+
+		// check the return value
+		ReminderVO savedReminderVo = conn.parse(response, ReminderVO.class);
+		Assert.assertNotNull(savedReminderVo);
+		Assert.assertNotNull(savedReminderVo.getKey());
+		Assert.assertEquals(entry.getKey(), savedReminderVo.getRepoEntryKey());
+		Assert.assertEquals("I forgot", savedReminderVo.getDescription());
+		Assert.assertEquals("I forgot the subject", savedReminderVo.getEmailSubject());
+		Assert.assertEquals("<p>I forgot the body</p>", savedReminderVo.getEmailBody());
+		Assert.assertEquals(2, savedReminderVo.getRules().size());
+		
+		// check the reminder on the database
+		List<Reminder> reminders = reminderService.getReminders(entry);
+		Assert.assertNotNull(reminders);
+		Assert.assertEquals(1, reminders.size());
+		Reminder updatedReminder = reminders.get(0);
+		Assert.assertEquals(savedReminderVo.getKey(), updatedReminder.getKey());
+		Assert.assertEquals("I forgot", updatedReminder.getDescription());
+		Assert.assertEquals("I forgot the subject", updatedReminder.getEmailSubject());
+		Assert.assertEquals("<p>I forgot the body</p>", updatedReminder.getEmailBody());
+		
+		// check rule configuration
+		String updatedConfiguration = updatedReminder.getConfiguration();
+		ReminderRules updatedRules = reminderService.toRules(updatedConfiguration);
+		List<ReminderRule> updatedRuleList = updatedRules.getRules();
+		Assert.assertEquals(2, updatedRuleList.size());
+		ReminderRuleImpl updatedRule1 = (ReminderRuleImpl)updatedRuleList.get(0);
+		Assert.assertEquals(AssignTaskRuleSPI.class.getSimpleName(), updatedRule1.getType());
+		Assert.assertEquals("937539759", updatedRule1.getLeftOperand());
+		Assert.assertEquals("<", updatedRule1.getOperator());
+		Assert.assertEquals("1", updatedRule1.getRightOperand());
+		Assert.assertEquals("day", updatedRule1.getRightUnit());
+		
+		ReminderRuleImpl updatedRule2 = (ReminderRuleImpl)updatedRuleList.get(1);
+		Assert.assertEquals(DateRuleSPI.class.getSimpleName(), updatedRule2.getType());
+		Assert.assertEquals(">", updatedRule2.getOperator());
+		Assert.assertEquals("2019-05-15T00:00:00", updatedRule2.getRightOperand());	
+	}
+	
+	@Test
+	public void deleteReminder() 
+	throws IOException, URISyntaxException {
+		RestConnection conn = new RestConnection();
+		Assert.assertTrue(conn.login("administrator", "openolat"));
+		
+		Identity creator = JunitTestHelper.createAndPersistIdentityAsRndUser("rest-rem-1");
+		Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("rest-rem-1");
+		RepositoryEntry courseEntry = JunitTestHelper.deployBasicCourse(creator);
+		Reminder transientReminder = reminderService.createReminder(courseEntry, creator);
+		transientReminder.setDescription("Hello");
+		Reminder reminder = reminderService.save(transientReminder);
+
+		//mark as sent
+		reminderDao.markAsSend(reminder, id, "ok");
+		dbInstance.commitAndCloseSession();
+		
+		URI request = UriBuilder.fromUri(getContextURI()).path("repo").path("entries")
+				.path(courseEntry.getKey().toString()).path("reminders")
+				.path(reminder.getKey().toString()).build();
+		HttpDelete method = conn.createDelete(request, MediaType.APPLICATION_JSON);
+		HttpResponse response = conn.execute(method);
+		Assert.assertEquals(200, response.getStatusLine().getStatusCode());
+
+		Reminder deletedReminder = reminderService.loadByKey(reminder.getKey());
+		Assert.assertNull(deletedReminder);
+	}
+	
+	
+	private List<ReminderVO> parseReminderArray(HttpEntity entity) {
+		try(InputStream content=entity.getContent()) {
+			ObjectMapper mapper = new ObjectMapper(jsonFactory); 
+			return mapper.readValue(content, new TypeReference<List<ReminderVO>>(){/* */});
+		} catch (Exception e) {
+			log.error("", e);
+			return null;
+		}
+	}
+}
diff --git a/src/test/java/org/olat/test/AllTestsJunit4.java b/src/test/java/org/olat/test/AllTestsJunit4.java
index dd6a333b5db4c298837dd6be78894d5c39ca91d8..090a9d137cec0fc6b041e4e557225e68888c260f 100644
--- a/src/test/java/org/olat/test/AllTestsJunit4.java
+++ b/src/test/java/org/olat/test/AllTestsJunit4.java
@@ -263,6 +263,7 @@ import org.junit.runners.Suite;
 	org.olat.modules.reminder.ReminderModuleTest.class,
 	org.olat.modules.reminder.manager.ReminderDAOTest.class,
 	org.olat.modules.reminder.manager.ReminderRuleEngineTest.class,
+	org.olat.modules.reminder.manager.ReminderRulesXStreamTest.class,
 	org.olat.modules.taxonomy.manager.TaxonomyDAOTest.class,
 	org.olat.modules.taxonomy.manager.TaxonomyLevelDAOTest.class,
 	org.olat.modules.taxonomy.manager.TaxonomyLevelTypeDAOTest.class,
@@ -391,6 +392,7 @@ import org.junit.runners.Suite;
 	org.olat.restapi.RepositoryEntryLifecycleTest.class,
 	org.olat.restapi.RepositoryEntriesTest.class,
 	org.olat.restapi.RepositoryEntryWebServiceTest.class,
+	org.olat.restapi.RemindersWebServiceTest.class,
 	org.olat.restapi.RestApiLoginFilterTest.class,
 	org.olat.restapi.UserAuthenticationMgmtTest.class,
 	org.olat.restapi.UserFoldersTest.class,