diff --git a/Telegram/SourceFiles/data/data_cloud_themes.cpp b/Telegram/SourceFiles/data/data_cloud_themes.cpp
index 2fe5f2ced9..691d4a0e44 100644
--- a/Telegram/SourceFiles/data/data_cloud_themes.cpp
+++ b/Telegram/SourceFiles/data/data_cloud_themes.cpp
@@ -63,6 +63,7 @@ void CloudThemes::setupReload() {
 	}) | rpl::map([=] {
 		return needReload();
 	}) | rpl::start_with_next([=](bool need) {
+		install();
 		if (need) {
 			scheduleReload();
 		} else {
@@ -76,6 +77,29 @@ bool CloudThemes::needReload() const {
 	return fields.id && fields.documentId;
 }
 
+void CloudThemes::install() {
+	using namespace Window::Theme;
+
+	const auto &fields = Background()->themeObject().cloud;
+	auto &themeId = IsNightMode()
+		? _installedNightThemeId
+		: _installedDayThemeId;
+	const auto cloudId = fields.documentId ? fields.id : uint64(0);
+	if (themeId == cloudId) {
+		return;
+	}
+	themeId = cloudId;
+	using Flag = MTPaccount_InstallTheme::Flag;
+	const auto flags = (IsNightMode() ? Flag::f_dark : Flag(0))
+		| Flag::f_format
+		| (themeId ? Flag::f_theme : Flag(0));
+	_session->api().request(MTPaccount_InstallTheme(
+		MTP_flags(flags),
+		MTP_string(Format()),
+		MTP_inputTheme(MTP_long(cloudId), MTP_long(fields.accessHash))
+	)).send();
+}
+
 void CloudThemes::reloadCurrent() {
 	if (!needReload()) {
 		return;
diff --git a/Telegram/SourceFiles/data/data_cloud_themes.h b/Telegram/SourceFiles/data/data_cloud_themes.h
index a34366d5ea..3e87b1690c 100644
--- a/Telegram/SourceFiles/data/data_cloud_themes.h
+++ b/Telegram/SourceFiles/data/data_cloud_themes.h
@@ -46,6 +46,7 @@ public:
 private:
 	void parseThemes(const QVector<MTPTheme> &list);
 
+	void install();
 	void setupReload();
 	[[nodiscard]] bool needReload() const;
 	void scheduleReload();
@@ -63,6 +64,8 @@ private:
 	base::Timer _reloadCurrentTimer;
 	DocumentData *_updatingFrom = nullptr;
 	rpl::lifetime _updatingFromLifetime;
+	uint64 _installedDayThemeId = 0;
+	uint64 _installedNightThemeId = 0;
 
 	rpl::lifetime _lifetime;