diff --git a/src/dring/account_const.h b/src/dring/account_const.h
index fd065e7dac36ad52d2f23e15a06dc1db81efdae5..e835b8a8669ebde6ee85ed72e3d2e413d99ff9d2 100644
--- a/src/dring/account_const.h
+++ b/src/dring/account_const.h
@@ -74,6 +74,7 @@ enum class MessageStates : int {
 namespace VolatileProperties {
 
 constexpr static const char ACTIVE[] = "Account.active";
+constexpr static const char DEVICE_ANNOUNCED[] = "Account.deviceAnnounced";
 constexpr static const char REGISTERED_NAME[] = "Account.registeredName";
 
 // Volatile parameters
diff --git a/src/jamidht/account_manager.cpp b/src/jamidht/account_manager.cpp
index dfbc3a90591ecd2e8460e8b1ec7606aa7f0c1bb9..0e00ae66682429b27376c1891a93499c86b3a746 100644
--- a/src/jamidht/account_manager.cpp
+++ b/src/jamidht/account_manager.cpp
@@ -190,13 +190,25 @@ AccountManager::useIdentity(const dht::crypto::Identity& identity,
 }
 
 void
-AccountManager::startSync(const OnNewDeviceCb& cb)
+AccountManager::startSync(const OnNewDeviceCb& cb, const OnDeviceAnnouncedCb& dcb)
 {
     // Put device announcement
     if (info_->announce) {
         auto h = dht::InfoHash(info_->accountId);
         JAMI_DBG("announcing device at %s", h.toString().c_str());
-        dht_->put(h, info_->announce, dht::DoneCallback {}, {}, true);
+        dht_->put(
+            h,
+            info_->announce,
+            [dcb = std::move(dcb), h](bool ok) {
+                if (ok)
+                    JAMI_DBG("device announced at %s", h.toString().c_str());
+                // We do not care about the status, it's a permanent put, if this fail,
+                // this means the DHT is disconnected but the put will be retried when connected.
+                if (dcb)
+                    dcb();
+            },
+            {},
+            true);
         for (const auto& crl : info_->identity.second->issuer->getRevocationLists())
             dht_->put(h, crl, dht::DoneCallback {}, {}, true);
         dht_->listen<DeviceAnnouncement>(h, [this, cb = std::move(cb)](DeviceAnnouncement&& dev) {
diff --git a/src/jamidht/account_manager.h b/src/jamidht/account_manager.h
index 6d9bb8df71897b98f3519bfb225b73eae126dbe6..2adcf39f9ad16dc563ea579ebd2ed9fe83fc6570 100644
--- a/src/jamidht/account_manager.h
+++ b/src/jamidht/account_manager.h
@@ -77,6 +77,7 @@ public:
     using clock = std::chrono::system_clock;
     using time_point = clock::time_point;
     using OnNewDeviceCb = std::function<void(const std::shared_ptr<dht::crypto::Certificate>&)>;
+    using OnDeviceAnnouncedCb = std::function<void()>;
 
     AccountManager(const std::string& path, OnAsync&& onAsync, const std::string& nameServer)
         : path_(path)
@@ -137,7 +138,7 @@ public:
 
     void setDht(const std::shared_ptr<dht::DhtRunner>& dht) { dht_ = dht; }
 
-    virtual void startSync(const OnNewDeviceCb& cb);
+    virtual void startSync(const OnNewDeviceCb& cb, const OnDeviceAnnouncedCb& dcb);
 
     const AccountInfo* getInfo() const { return info_.get(); }
 
diff --git a/src/jamidht/archive_account_manager.cpp b/src/jamidht/archive_account_manager.cpp
index 66c07f4170f98a567400e850f05a53ec5f8b7e23..661df6347407734c96dba6e1cc8d7d4154c6e50c 100644
--- a/src/jamidht/archive_account_manager.cpp
+++ b/src/jamidht/archive_account_manager.cpp
@@ -451,9 +451,9 @@ ArchiveAccountManager::syncDevices()
 }
 
 void
-ArchiveAccountManager::startSync(const OnNewDeviceCb& cb)
+ArchiveAccountManager::startSync(const OnNewDeviceCb& cb, const OnDeviceAnnouncedCb& dcb)
 {
-    AccountManager::startSync(std::move(cb));
+    AccountManager::startSync(std::move(cb), std::move(dcb));
 
     dht_->listen<DeviceSync>(dht::InfoHash::get("inbox:" + info_->deviceId), [this](DeviceSync&& sync) {
         // Received device sync data.
diff --git a/src/jamidht/archive_account_manager.h b/src/jamidht/archive_account_manager.h
index e10c357fa56ddbbe43c418396d60d0d92c3fbc2d..85145cc5bca83035012bc2eca3df1b3f0c353a02 100644
--- a/src/jamidht/archive_account_manager.h
+++ b/src/jamidht/archive_account_manager.h
@@ -49,7 +49,7 @@ public:
                             AuthFailureCallback onFailure,
                             OnChangeCallback onChange) override;
 
-    void startSync(const OnNewDeviceCb&) override;
+    void startSync(const OnNewDeviceCb&, const OnDeviceAnnouncedCb& dcb = {}) override;
 
     bool changePassword(const std::string& password_old, const std::string& password_new) override;
 
diff --git a/src/jamidht/jamiaccount.cpp b/src/jamidht/jamiaccount.cpp
index 740e67f317a19ae5885c1a578b803088a3d4fc13..9afee70c80874d590e007de3e96fc2495764f1a8 100644
--- a/src/jamidht/jamiaccount.cpp
+++ b/src/jamidht/jamiaccount.cpp
@@ -1535,6 +1535,9 @@ JamiAccount::getVolatileAccountDetails() const
     if (not registeredName_.empty())
         a.emplace(DRing::Account::VolatileProperties::REGISTERED_NAME, registeredName_);
 #endif
+    a.emplace(DRing::Account::VolatileProperties::DEVICE_ANNOUNCED,
+              deviceAnnounced_ ? TRUE_STR : FALSE_STR);
+
     return a;
 }
 
@@ -2142,7 +2145,11 @@ JamiAccount::doRegister_()
         context.identityAnnouncedCb = [this](bool ok) {
             if (!ok)
                 return;
-            accountManager_->startSync({});
+            accountManager_->startSync({}, [this] {
+                deviceAnnounced_ = true;
+                emitSignal<DRing::ConfigurationSignal::VolatileDetailsChanged>(
+                    accountID_, getVolatileAccountDetails());
+            });
             /*[this](const std::shared_ptr<dht::crypto::Certificate>& crt) {
                 if (!crt)
                     return;
diff --git a/src/jamidht/jamiaccount.h b/src/jamidht/jamiaccount.h
index 1ecf86c23974eebb5cd934f60656a860c3192097..e6ccbe073402056be01d3f598e6676c39a4f4afb 100644
--- a/src/jamidht/jamiaccount.h
+++ b/src/jamidht/jamiaccount.h
@@ -980,6 +980,8 @@ private:
      * @return the conversation id if found else empty
      */
     std::string getOneToOneConversation(const std::string& uri) const;
+
+    std::atomic_bool deviceAnnounced_ {false};
 };
 
 static inline std::ostream&