diff --git a/src/Content/Conversation.php b/src/Content/Conversation.php
index 249190b1ad..cdc6e6351f 100644
--- a/src/Content/Conversation.php
+++ b/src/Content/Conversation.php
@@ -985,6 +985,8 @@ class Conversation
 		$condition = DBA::mergeConditions($condition,
 			["`uid` IN (0, ?) AND (NOT `vid` IN (?, ?, ?) OR `vid` IS NULL)", $uid, Verb::getID(Activity::FOLLOW), Verb::getID(Activity::VIEW), Verb::getID(Activity::READ)]);
 
+		$condition = DBA::mergeConditions($condition, ["(`uid` != ? OR `private` != ?)", 0, ItemModel::PRIVATE]);
+
 		$condition = DBA::mergeConditions($condition,
 			["`visible` AND NOT `deleted` AND NOT `author-blocked` AND NOT `owner-blocked`
 			AND ((NOT `contact-pending` AND (`contact-rel` IN (?, ?))) OR `self` OR `contact-uid` = ?)",
diff --git a/src/Protocol/ActivityPub/Processor.php b/src/Protocol/ActivityPub/Processor.php
index f96bb196c2..42ff0ee12d 100644
--- a/src/Protocol/ActivityPub/Processor.php
+++ b/src/Protocol/ActivityPub/Processor.php
@@ -863,11 +863,6 @@ class Processor
 					Logger::warning('Unknown parent item.', ['uri' => $parent_uri]);
 					return false;
 				}
-				if (!empty($activity['type']) && in_array($activity['type'], Receiver::CONTENT_TYPES) && ($item['private'] == Item::PRIVATE) && ($parent['private'] != Item::PRIVATE)) {
-					Logger::warning('Item is private but the parent is not. Dropping.', ['item-uri' => $item['uri'], 'thr-parent' => $item['thr-parent']]);
-					return false;
-				}
-
 				$content = self::removeImplicitMentionsFromBody($content, $parent);
 			}
 			$item['content-warning'] = HTML::toBBCode($activity['summary'] ?? '');
diff --git a/src/Protocol/ActivityPub/Receiver.php b/src/Protocol/ActivityPub/Receiver.php
index 4b8f1557b8..b1de036fd6 100644
--- a/src/Protocol/ActivityPub/Receiver.php
+++ b/src/Protocol/ActivityPub/Receiver.php
@@ -1085,14 +1085,6 @@ class Receiver
 			$reply[] = $object_id;
 		}
 
-		if (!empty($reply)) {
-			$parents = Post::select(['uid'], DBA::mergeConditions(['uri' => $reply], ["`uid` != ?", 0]));
-			while ($parent = Post::fetch($parents)) {
-				$receivers[$parent['uid']] = ['uid' => $parent['uid'], 'type' => self::TARGET_ANSWER];
-			}
-			DBA::close($parents);
-		}
-
 		if (!empty($actor)) {
 			$profile   = APContact::getByURL($actor);
 			$followers = $profile['followers'] ?? '';
@@ -1178,6 +1170,14 @@ class Receiver
 			}
 		}
 
+		if (!empty($reply) && (!empty($receivers[0]) || !empty($receivers[-1]))) {
+			$parents = Post::select(['uid'], DBA::mergeConditions(['uri' => $reply], ["`uid` != ?", 0]));
+			while ($parent = Post::fetch($parents)) {
+				$receivers[$parent['uid']] = ['uid' => $parent['uid'], 'type' => self::TARGET_ANSWER];
+			}
+			DBA::close($parents);
+		}
+
 		self::switchContacts($receivers, $actor);
 
 		// "birdsitelive" is a service that mirrors tweets into the fediverse
diff --git a/src/Protocol/ActivityPub/Transmitter.php b/src/Protocol/ActivityPub/Transmitter.php
index 7da110f671..fb4ed0b4c0 100644
--- a/src/Protocol/ActivityPub/Transmitter.php
+++ b/src/Protocol/ActivityPub/Transmitter.php
@@ -717,7 +717,12 @@ class Transmitter
 		}
 
 		if (!empty($item['parent'])) {
-			$parents = Post::select(['id', 'author-link', 'owner-link', 'gravity', 'uri'], ['parent' => $item['parent']], ['order' => ['id']]);
+			if ($item['private'] == Item::PRIVATE) {
+				$condition = ['parent' => $item['parent'], 'uri-id' => $item['thr-parent-id']];
+			} else {
+				$condition = ['parent' => $item['parent']];
+			}
+			$parents = Post::select(['id', 'author-link', 'owner-link', 'gravity', 'uri'], $condition, ['order' => ['id']]);
 			while ($parent = Post::fetch($parents)) {
 				if ($parent['gravity'] == Item::GRAVITY_PARENT) {
 					$profile = APContact::getByURL($parent['owner-link'], false);
diff --git a/src/Worker/Notifier.php b/src/Worker/Notifier.php
index 2e42c225fc..3f5b0fa829 100644
--- a/src/Worker/Notifier.php
+++ b/src/Worker/Notifier.php
@@ -170,13 +170,15 @@ class Notifier
 		// Deliver directly to a forum, don't PuSH
 		$direct_forum_delivery = false;
 
+		$only_ap_delivery = false;
+
 		$followup = false;
 		$recipients_followup = [];
 
 		if (!empty($target_item) && !empty($items)) {
 			$parent = $items[0];
 
-			$fields = ['network', 'author-id', 'author-link', 'author-network', 'owner-id'];
+			$fields = ['network', 'private', 'author-id', 'author-link', 'author-network', 'owner-id'];
 			$condition = ['uri' => $target_item['thr-parent'], 'uid' => $target_item['uid']];
 			$thr_parent = Post::selectFirst($fields, $condition);
 			if (empty($thr_parent)) {
@@ -189,6 +191,11 @@ class Notifier
 				$apdelivery = self::activityPubDelivery($cmd, $target_item, $parent, $thr_parent, $a->getQueueValue('priority'), $a->getQueueValue('created'), $owner);
 				$ap_contacts = $apdelivery['contacts'];
 				$delivery_queue_count += $apdelivery['count'];
+				if (($thr_parent['network'] == Protocol::ACTIVITYPUB) && ($thr_parent['private'] == Item::PRIVATE)) {
+					$only_ap_delivery   = true;
+					$public_message     = false;
+					$diaspora_delivery  = false;
+				}
 			}
 
 			// Only deliver threaded replies (comment to a comment) to Diaspora
@@ -421,7 +428,9 @@ class Notifier
 		}
 
 		if (empty($delivery_contacts_stmt)) {
-			if ($followup) {
+			if ($only_ap_delivery) {
+				$recipients = $ap_contacts;
+			} elseif ($followup) {
 				$recipients = $recipients_followup;
 			}
 			$condition = ['id' => $recipients, 'self' => false, 'uid' => [0, $uid],