diff --git a/bin/dbus/cx.ring.Ring.ConfigurationManager.xml b/bin/dbus/cx.ring.Ring.ConfigurationManager.xml
index c48e950162021f807c434570586f2ae533fa57e6..f1cf90e3a6dbba6b5a9afcb13f4ddcc8c715f8c2 100644
--- a/bin/dbus/cx.ring.Ring.ConfigurationManager.xml
+++ b/bin/dbus/cx.ring.Ring.ConfigurationManager.xml
@@ -1358,5 +1358,25 @@
            </tp:docstring>
        </method>
 
+       <signal name="migrationEnded" tp:name-for-bindings="migrationEnded">
+           <tp:added version="3.0.0"/>
+           <tp:docstring>
+               Notify clients when migration is ended.
+           </tp:docstring>
+           <arg type="s" name="accountID">
+               <tp:docstring>
+                   An account id.
+               </tp:docstring>
+           </arg>
+           <arg type="s" name="result">
+               <tp:docstring>
+                   The result of the migration.
+                   SUCCESS : account migrated.
+                   INVALID : account migration failed.
+               </tp:docstring>
+           </arg>
+       </signal>
+
+
    </interface>
 </node>
diff --git a/bin/dbus/dbusclient.cpp b/bin/dbus/dbusclient.cpp
index 5dca85827ad27ec991251b90731daf1b8f2def81..edcf3249fc35d19d283de0ceb10a1d2a55ee104e 100644
--- a/bin/dbus/dbusclient.cpp
+++ b/bin/dbus/dbusclient.cpp
@@ -187,6 +187,7 @@ DBusClient::initLibrary(int flags)
         exportable_callback<ConfigurationSignal::CertificateExpired>(bind(&DBusConfigurationManager::certificateExpired, confM, _1 )),
         exportable_callback<ConfigurationSignal::CertificateStateChanged>(bind(&DBusConfigurationManager::certificateStateChanged, confM, _1, _2, _3 )),
         exportable_callback<ConfigurationSignal::MediaParametersChanged>(bind(&DBusConfigurationManager::mediaParametersChanged, confM, _1 )),
+        exportable_callback<ConfigurationSignal::MigrationEnded>(bind(&DBusConfigurationManager::migrationEnded, confM, _1, _2 )),
     };
 
     // Presence event handlers
diff --git a/src/client/ring_signal.cpp b/src/client/ring_signal.cpp
index 5cbbaecbfea97d99fa0e5e16fdb026c088fdcb9a..3a94ff38158a51b58e36ff90b880de1220f1021b 100644
--- a/src/client/ring_signal.cpp
+++ b/src/client/ring_signal.cpp
@@ -70,6 +70,7 @@ getSignalHandlers()
         exported_callback<DRing::ConfigurationSignal::NameRegistrationEnded>(),
         exported_callback<DRing::ConfigurationSignal::RegisteredNameFound>(),
         exported_callback<DRing::ConfigurationSignal::MediaParametersChanged>(),
+        exported_callback<DRing::ConfigurationSignal::MigrationEnded>(),
         exported_callback<DRing::ConfigurationSignal::Error>(),
 #ifdef __ANDROID__
         exported_callback<DRing::ConfigurationSignal::GetHardwareAudioFormat>(),
diff --git a/src/dring/configurationmanager_interface.h b/src/dring/configurationmanager_interface.h
index 502ddb0aea31b37d4a6a6f5d5500d102988b53b6..4d8b2c9d7bf07b681dd81f4f1d6f8fee6a4514fc 100644
--- a/src/dring/configurationmanager_interface.h
+++ b/src/dring/configurationmanager_interface.h
@@ -266,6 +266,10 @@ struct ConfigurationSignal {
                 constexpr static const char* name = "MediaParametersChanged";
                 using cb_type = void(const std::string& /*accountId*/);
         };
+        struct MigrationEnded {
+                constexpr static const char* name = "MigrationEnded";
+                using cb_type = void(const std::string& /*accountId*/, const std::string& /*state*/);
+        };
         /**
          * These are special getters for Android and UWP, so the daemon can retreive
          * information only accessible through their respective platform APIs
diff --git a/src/ringdht/ringaccount.cpp b/src/ringdht/ringaccount.cpp
index d57ade141fba25626400496df3f23b0b710164a9..49005d43cd459c6d5a20e18dc0ca8640d942165c 100644
--- a/src/ringdht/ringaccount.cpp
+++ b/src/ringdht/ringaccount.cpp
@@ -4,6 +4,7 @@
  *  Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
  *  Author: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
  *  Author: Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
+ *  Author: Nicolas Jäger <nicolas.jager@savoirfairelinux.com>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -80,6 +81,34 @@ namespace ring {
 using sip_utils::CONST_PJ_STR;
 using std::chrono::system_clock;
 
+namespace Migration {
+
+enum class State { // Contains all the Migration states
+    SUCCESS,
+    INVALID
+};
+
+std::string
+mapStateNumberToString(const State migrationState)
+{
+#define CASE_STATE(X) case Migration::State::X: \
+                           return #X
+
+switch (migrationState) {
+    CASE_STATE(INVALID);
+    CASE_STATE(SUCCESS);
+}
+}
+
+void
+setState (const std::string& accountID,
+          const State migrationState)
+{
+    emitSignal<DRing::ConfigurationSignal::MigrationEnded>(accountID,
+        mapStateNumberToString(migrationState));
+}
+}
+
 struct RingAccount::BuddyInfo
 {
     /* the buddy id */
@@ -1364,22 +1393,23 @@ RingAccount::updateCertificates(ArchiveContent& archive, dht::crypto::Identity&
     return updated;
 }
 
-bool
+void
 RingAccount::migrateAccount(const std::string& pwd)
 {
     ArchiveContent archive;
     try {
         archive = readArchive(pwd);
     } catch (...) {
-        return false;
+        return;
     }
 
     if (updateCertificates(archive, identity_)) {
         std::tie(tlsPrivateKeyFile_, tlsCertificateFile_) = saveIdentity(identity_, idPath_ + DIR_SEPARATOR_STR "ring_device");
         saveArchive(archive, pwd);
-        return true;
+        setRegistrationState(RegistrationState::UNREGISTERED);
+        Migration::setState(accountID_, Migration::State::SUCCESS);
     }
-    return false;
+    Migration::setState(accountID_, Migration::State::INVALID);
 }
 
 void
diff --git a/src/ringdht/ringaccount.h b/src/ringdht/ringaccount.h
index 92bdca7bda5737de88c4cfb7138864ebe545db95..e1882754de5e681c4dff5cdc4679ea00f0a94bc5 100644
--- a/src/ringdht/ringaccount.h
+++ b/src/ringdht/ringaccount.h
@@ -489,7 +489,7 @@ class RingAccount : public SIPAccountBase {
         std::string makeReceipt(const dht::crypto::Identity& id);
         void createRingDevice(const dht::crypto::Identity& id);
         void initRingDevice(const ArchiveContent& a);
-        bool migrateAccount(const std::string& pwd);
+        void migrateAccount(const std::string& pwd);
         static bool updateCertificates(ArchiveContent& archive, dht::crypto::Identity& device);
 
         void createAccount(const std::string& archive_password);