diff --git a/apps/contactsinteraction/lib/AddressBook.php b/apps/contactsinteraction/lib/AddressBook.php
index e8479cb186a34bc78811723784c5729bb4ba9d17..3e581c930218324b3081283f4629706150eb6842 100644
--- a/apps/contactsinteraction/lib/AddressBook.php
+++ b/apps/contactsinteraction/lib/AddressBook.php
@@ -130,8 +130,8 @@ class AddressBook extends ExternalAddressBook implements IACL {
 	/**
 	 * @inheritDoc
 	 */
-	public function getLastModified() {
-		throw new NotImplemented();
+	public function getLastModified(): ?int {
+		return $this->mapper->findLastUpdatedForUserId($this->getUid());
 	}
 
 	/**
@@ -149,6 +149,7 @@ class AddressBook extends ExternalAddressBook implements IACL {
 			'principaluri' => $this->principalUri,
 			'{DAV:}displayname' => $this->l10n->t('Recently contacted'),
 			'{' . Plugin::NS_OWNCLOUD . '}read-only' => true,
+			'{' . \OCA\DAV\CalDAV\Plugin::NS_CALENDARSERVER . '}getctag' => 'http://sabre.io/ns/sync/' . ($this->getLastModified() ?? 0),
 		];
 	}
 
diff --git a/apps/contactsinteraction/lib/Card.php b/apps/contactsinteraction/lib/Card.php
index 6285025f1eb30c2ae787c66de11120dcf1e08338..2cacd7ad54612e998bcac56751df570d0c10643c 100644
--- a/apps/contactsinteraction/lib/Card.php
+++ b/apps/contactsinteraction/lib/Card.php
@@ -95,7 +95,7 @@ class Card implements ICard, IACL {
 	 * @inheritDoc
 	 */
 	public function getETag(): ?string {
-		return null;
+		return '"' . md5((string) $this->getLastModified()) . '"';
 	}
 
 	/**
diff --git a/apps/contactsinteraction/lib/Db/RecentContactMapper.php b/apps/contactsinteraction/lib/Db/RecentContactMapper.php
index 18a5bf6cedcb6e0441fe181ab34afb491feb43b7..19cd30ea701bb5655d903263557b5e216490376c 100644
--- a/apps/contactsinteraction/lib/Db/RecentContactMapper.php
+++ b/apps/contactsinteraction/lib/Db/RecentContactMapper.php
@@ -104,6 +104,30 @@ class RecentContactMapper extends QBMapper {
 		return $this->findEntities($select);
 	}
 
+	/**
+	 * @param string $uid
+	 * @return int|null
+	 */
+	public function findLastUpdatedForUserId(string $uid):?int {
+		$qb = $this->db->getQueryBuilder();
+
+		$select = $qb
+			->select('last_contact')
+			->from($this->getTableName())
+			->where($qb->expr()->eq('actor_uid', $qb->createNamedParameter($uid)))
+			->orderBy('last_contact', 'DESC')
+			->setMaxResults(1);
+
+		$cursor = $select->execute();
+		$row = $cursor->fetch();
+
+		if ($row === false) {
+			return null;
+		}
+
+		return (int)$row['last_contact'];
+	}
+
 	public function cleanUp(int $olderThan): void {
 		$qb = $this->db->getQueryBuilder();