diff --git a/src/client/app/desktop/views/components/note-detail.vue b/src/client/app/desktop/views/components/note-detail.vue
index f4494c395b..bcff8c8774 100644
--- a/src/client/app/desktop/views/components/note-detail.vue
+++ b/src/client/app/desktop/views/components/note-detail.vue
@@ -129,9 +129,9 @@ export default Vue.extend({
 	mounted() {
 		// Get replies
 		if (!this.compact) {
-			this.$root.api('notes/replies', {
+			this.$root.api('notes/children', {
 				noteId: this.appearNote.id,
-				limit: 8
+				limit: 30
 			}).then(replies => {
 				this.replies = replies;
 			});
diff --git a/src/client/app/desktop/views/components/note.vue b/src/client/app/desktop/views/components/note.vue
index 9dc831db73..7e00087b9f 100644
--- a/src/client/app/desktop/views/components/note.vue
+++ b/src/client/app/desktop/views/components/note.vue
@@ -123,9 +123,9 @@ export default Vue.extend({
 
 	created() {
 		if (this.detail) {
-			this.$root.api('notes/replies', {
+			this.$root.api('notes/children', {
 				noteId: this.appearNote.id,
-				limit: 8
+				limit: 30
 			}).then(replies => {
 				this.replies = replies;
 			});
diff --git a/src/client/app/mobile/views/components/note-detail.vue b/src/client/app/mobile/views/components/note-detail.vue
index b6f9dc4434..e14e1beff8 100644
--- a/src/client/app/mobile/views/components/note-detail.vue
+++ b/src/client/app/mobile/views/components/note-detail.vue
@@ -135,9 +135,9 @@ export default Vue.extend({
 	methods: {
 		fetchReplies() {
 			if (this.compact) return;
-			this.$root.api('notes/replies', {
+			this.$root.api('notes/children', {
 				noteId: this.appearNote.id,
-				limit: 8
+				limit: 30
 			}).then(replies => {
 				this.replies = replies;
 			});
diff --git a/src/client/app/mobile/views/components/note.vue b/src/client/app/mobile/views/components/note.vue
index de556f170c..c207eb10d7 100644
--- a/src/client/app/mobile/views/components/note.vue
+++ b/src/client/app/mobile/views/components/note.vue
@@ -115,9 +115,9 @@ export default Vue.extend({
 
 	created() {
 		if (this.detail) {
-			this.$root.api('notes/replies', {
+			this.$root.api('notes/children', {
 				noteId: this.appearNote.id,
-				limit: 8
+				limit: 30
 			}).then(replies => {
 				this.replies = replies;
 			});
diff --git a/src/server/api/endpoints/notes/children.ts b/src/server/api/endpoints/notes/children.ts
new file mode 100644
index 0000000000..3738459b71
--- /dev/null
+++ b/src/server/api/endpoints/notes/children.ts
@@ -0,0 +1,132 @@
+import $ from 'cafy';
+import ID, { transform } from '../../../../misc/cafy-id';
+import Note, { packMany } from '../../../../models/note';
+import define from '../../define';
+import { getFriends } from '../../common/get-friends';
+import { getHideUserIds } from '../../common/get-hide-users';
+
+export const meta = {
+	desc: {
+		'ja-JP': '指定した投稿への返信/引用を取得します。',
+		'en-US': 'Get replies/quotes of a note.'
+	},
+
+	tags: ['notes'],
+
+	requireCredential: false,
+
+	params: {
+		noteId: {
+			validator: $.type(ID),
+			transform: transform,
+			desc: {
+				'ja-JP': '対象の投稿のID',
+				'en-US': 'Target note ID'
+			}
+		},
+
+		limit: {
+			validator: $.optional.num.range(1, 100),
+			default: 10
+		},
+
+		sinceId: {
+			validator: $.optional.type(ID),
+			transform: transform,
+		},
+
+		untilId: {
+			validator: $.optional.type(ID),
+			transform: transform,
+		},
+	},
+
+	res: {
+		type: 'array',
+		items: {
+			type: 'Note',
+		},
+	},
+};
+
+export default define(meta, async (ps, user) => {
+	const [followings, hideUserIds] = await Promise.all([
+		// フォローを取得
+		// Fetch following
+		user ? getFriends(user._id) : [],
+
+		// 隠すユーザーを取得
+		getHideUserIds(user)
+	]);
+
+	const visibleQuery = user == null ? [{
+		visibility: { $in: [ 'public', 'home' ] }
+	}] : [{
+		visibility: { $in: [ 'public', 'home' ] }
+	}, {
+		// myself (for followers/specified/private)
+		userId: user._id
+	}, {
+		// to me (for specified)
+		visibleUserIds: { $in: [ user._id ] }
+	}, {
+		visibility: 'followers',
+		$or: [{
+			// フォロワーの投稿
+			userId: { $in: followings.map(f => f.id) },
+		}, {
+			// 自分の投稿へのリプライ
+			'_reply.userId': user._id,
+		}, {
+			// 自分へのメンションが含まれている
+			mentions: { $in: [ user._id ] }
+		}]
+	}];
+
+	const q = {
+		$and: [{
+			$or: [{
+				replyId: ps.noteId,
+			}, {
+				renoteId: ps.noteId,
+				$or: [{
+					text: { $ne: null }
+				}, {
+					fileIds: { $ne: [] }
+				}, {
+					poll: { $ne: null }
+				}]
+			}]
+		}, {
+			$or: visibleQuery
+		}]
+	} as any;
+
+	if (hideUserIds && hideUserIds.length > 0) {
+		q['userId'] = {
+			$nin: hideUserIds
+		};
+	}
+
+	const sort = {
+		_id: -1
+	};
+
+	if (ps.sinceId) {
+		sort._id = 1;
+		q._id = {
+			$gt: ps.sinceId
+		};
+	} else if (ps.untilId) {
+		q._id = {
+			$lt: ps.untilId
+		};
+	}
+
+	const notes = await Note.find(q, {
+		limit: ps.limit,
+		sort: sort
+	});
+
+	return await packMany(notes, user);
+});