diff --git a/bin/dbus/cx.ring.Ring.ConfigurationManager.xml b/bin/dbus/cx.ring.Ring.ConfigurationManager.xml
index d78238d2748f051533f9dd554e970ac49e0b69c7..83d2702cdcc695eaaa27284b16cc972b3ae4cc57 100644
--- a/bin/dbus/cx.ring.Ring.ConfigurationManager.xml
+++ b/bin/dbus/cx.ring.Ring.ConfigurationManager.xml
@@ -540,6 +540,13 @@
           </arg>
        </method>
 
+       <method name="getLastMessages" tp:name-for-bindings="getLastMessages">
+           <arg type="s" name="accountID" direction="in"/>
+           <arg type="t" name="base_timestamp" direction="in"/>
+           <arg type="a(sa{ss}t)" name="messages" direction="out"/>
+           <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="messages"/>
+        </method>
+
        <method name="getMessageStatus" tp:name-for-bindings="getMessageStatus">
           <arg type="t" name="id" direction="in"/>
           <arg type="i" name="status" direction="out">
diff --git a/bin/dbus/dbusconfigurationmanager.cpp b/bin/dbus/dbusconfigurationmanager.cpp
index 0d11510b0a7e701c73cd28ed768b5d9ea0fa62cf..1e30e75ecbf3d758f9cb56247496eb71b316990e 100644
--- a/bin/dbus/dbusconfigurationmanager.cpp
+++ b/bin/dbus/dbusconfigurationmanager.cpp
@@ -153,6 +153,21 @@ DBusConfigurationManager::sendTextMessage(const std::string& accountID, const st
     return DRing::sendAccountTextMessage(accountID, to, payloads);
 }
 
+std::vector<RingDBusMessage>
+DBusConfigurationManager::getLastMessages(const std::string& accountID, const uint64_t& base_timestamp)
+{
+    auto messages = DRing::getLastMessages(accountID, base_timestamp);
+    std::vector<RingDBusMessage> result;
+    for (const auto& message : messages) {
+        RingDBusMessage m;
+        m._1 = message.from;
+        m._2 = message.payloads;
+        m._3 = message.received;
+        result.emplace_back(m);
+    }
+    return result;
+}
+
 auto
 DBusConfigurationManager::getMessageStatus(const uint64_t& id) -> decltype(DRing::getMessageStatus(id))
 {
diff --git a/bin/dbus/dbusconfigurationmanager.h b/bin/dbus/dbusconfigurationmanager.h
index 2d76ab8d2b00a5d68214a25fc000b1be6a612d8f..894241d2cfa9af2c4e3e2e9c27b0e6fccfebdaa1 100644
--- a/bin/dbus/dbusconfigurationmanager.h
+++ b/bin/dbus/dbusconfigurationmanager.h
@@ -49,6 +49,8 @@
 #pragma GCC diagnostic warning "-Wunused-but-set-variable"
 #endif
 
+using RingDBusMessage = DBus::Struct<std::string, std::map<std::string, std::string>, long unsigned int>;
+
 class DBusConfigurationManager :
     public cx::ring::Ring::ConfigurationManager_adaptor,
     public DBus::IntrospectableAdaptor,
@@ -80,6 +82,7 @@ class DBusConfigurationManager :
         void sendRegister(const std::string& accoundID, const bool& enable);
         void registerAllAccounts(void);
         uint64_t sendTextMessage(const std::string& accoundID, const std::string& to, const std::map<std::string, std::string>& payloads);
+        std::vector<RingDBusMessage> getLastMessages(const std::string& accountID, const uint64_t& base_timestamp);
         int getMessageStatus(const uint64_t& id);
         std::map<std::string, std::string> getTlsDefaultSettings();
         std::vector<std::string> getSupportedCiphers(const std::string& accountID);
diff --git a/bin/jni/configurationmanager.i b/bin/jni/configurationmanager.i
index 71179f58a6aa6e0d9d6218ab4b8c5543aeb9f7fa..600ac6315d19eb9847b8a3f1ccb46da85322ad36 100644
--- a/bin/jni/configurationmanager.i
+++ b/bin/jni/configurationmanager.i
@@ -60,9 +60,17 @@ public:
 %}
 
 %feature("director") ConfigurationCallback;
+%template(MessageVect) std::vector<DRing::Message>;
 
 namespace DRing {
 
+struct Message
+{
+    std::string from;
+    std::map<std::string, std::string> payloads;
+    uint64_t received;
+};
+
 std::map<std::string, std::string> getAccountDetails(const std::string& accountID);
 std::map<std::string, std::string> getVolatileAccountDetails(const std::string& accountID);
 void setAccountDetails(const std::string& accountID, const std::map<std::string, std::string>& details);
@@ -74,6 +82,7 @@ std::vector<std::string> getAccountList();
 void sendRegister(const std::string& accountID, bool enable);
 void registerAllAccounts(void);
 uint64_t sendAccountTextMessage(const std::string& accountID, const std::string& to, const std::map<std::string, std::string>& message);
+std::vector<DRing::Message> getLastMessages(const std::string& accountID, uint64_t base_timestamp);
 int getMessageStatus(uint64_t id);
 
 bool lookupName(const std::string& account, const std::string& nameserver, const std::string& name);
diff --git a/bin/nodejs/configurationmanager.i b/bin/nodejs/configurationmanager.i
index c56c99e81ea15f7b4010fcb28b34a003e671ad64..5170e1f239baba78753a47968237c71f275644e5 100644
--- a/bin/nodejs/configurationmanager.i
+++ b/bin/nodejs/configurationmanager.i
@@ -60,6 +60,13 @@ public:
 
 namespace DRing {
 
+struct Message
+{
+    std::string from;
+    std::map<std::string, std::string> payloads;
+    uint64_t received;
+};
+
 std::map<std::string, std::string> getAccountDetails(const std::string& accountID);
 std::map<std::string, std::string> getVolatileAccountDetails(const std::string& accountID);
 void setAccountDetails(const std::string& accountID, const std::map<std::string, std::string>& details);
@@ -71,6 +78,7 @@ std::vector<std::string> getAccountList();
 void sendRegister(const std::string& accountID, bool enable);
 void registerAllAccounts(void);
 uint64_t sendAccountTextMessage(const std::string& accountID, const std::string& to, const std::map<std::string, std::string>& message);
+std::vector<Message> getLastMessages(const std::string& accountID, const uint64_t& base_timestamp);
 int getMessageStatus(uint64_t id);
 
 bool lookupName(const std::string& account, const std::string& nameserver, const std::string& name);
diff --git a/src/account.h b/src/account.h
index c71d8e55da945f885109ffc22eaf14b4269e258e..027b429ca3ff18e9a4fc7934c08cf74d2668907f 100644
--- a/src/account.h
+++ b/src/account.h
@@ -27,6 +27,7 @@
 #include "config.h"
 #endif
 
+#include "configurationmanager_interface.h"
 #include "noncopyable.h"
 #include "config/serializable.h"
 #include "registration_states.h"
@@ -34,7 +35,7 @@
 #include "ip_utils.h"
 #include "media_codec.h"
 #include "logger.h"
-#include "compiler_intrinsics.h" // UNUSED
+#include "compiler_intrinsics.h" // include the "UNUSED" macro
 
 #include <functional>
 #include <string>
@@ -155,6 +156,10 @@ class Account : public Serializable, public std::enable_shared_from_this<Account
         virtual uint64_t sendTextMessage(const std::string& to UNUSED,
                                      const std::map<std::string, std::string>& payloads UNUSED) { return 0; }
 
+        virtual std::vector<DRing::Message> getLastMessages(const uint64_t& base_timestamp) {
+            return {};
+        }
+
         /**
          * Return the status corresponding to the token.
          */
diff --git a/src/client/configurationmanager.cpp b/src/client/configurationmanager.cpp
index 1f4d11c341326a4ab3fd930f5ebef256592979ca..6cb22bd5426104ee221f1c69e1d7d4963357e069 100644
--- a/src/client/configurationmanager.cpp
+++ b/src/client/configurationmanager.cpp
@@ -270,6 +270,12 @@ sendAccountTextMessage(const std::string& accountID, const std::string& to, cons
     return ring::Manager::instance().sendTextMessage(accountID, to, payloads);
 }
 
+std::vector<Message>
+getLastMessages(const std::string& accountID, const uint64_t& base_timestamp)
+{
+    return ring::Manager::instance().getLastMessages(accountID, base_timestamp);
+}
+
 int
 getMessageStatus(uint64_t id)
 {
diff --git a/src/dring/configurationmanager_interface.h b/src/dring/configurationmanager_interface.h
index 1e107cbe4900f3e6d24c42cb858dd10cb5420ffc..971e081eacee82cd2b854f564dd65ee98ea3b386 100644
--- a/src/dring/configurationmanager_interface.h
+++ b/src/dring/configurationmanager_interface.h
@@ -40,6 +40,13 @@
 
 namespace DRing {
 
+struct Message
+{
+    std::string from;
+    std::map<std::string, std::string> payloads;
+    uint64_t received;
+};
+
 void registerConfHandlers(const std::map<std::string, std::shared_ptr<CallbackWrapperBase>>&);
 
 std::map<std::string, std::string> getAccountDetails(const std::string& accountID);
@@ -65,6 +72,7 @@ std::vector<std::string> getAccountList();
 void sendRegister(const std::string& accountID, bool enable);
 void registerAllAccounts(void);
 uint64_t sendAccountTextMessage(const std::string& accountID, const std::string& to, const std::map<std::string, std::string>& payloads);
+std::vector<Message> getLastMessages(const std::string& accountID, const uint64_t& base_timestamp);
 int getMessageStatus(uint64_t id);
 
 
diff --git a/src/manager.cpp b/src/manager.cpp
index 40e7081a1616564b2d0eda999782bb00ee595e5f..2b42471b5824908fa3ef3bed51c3ebe2f323f38e 100644
--- a/src/manager.cpp
+++ b/src/manager.cpp
@@ -3150,4 +3150,12 @@ Manager::getVideoManager() const
 }
 #endif
 
+std::vector<DRing::Message>
+Manager::getLastMessages(const std::string& accountID, const uint64_t& base_timestamp)
+{
+    if (const auto acc = getAccount(accountID))
+        return acc->getLastMessages(base_timestamp);
+    return {};
+}
+
 } // namespace ring
diff --git a/src/manager.h b/src/manager.h
index 5f35d2619cece7aac6e0f525b1dd34ec2516adc9..23df1ac6f2b6b825793ea0b710e569459c3a78df 100644
--- a/src/manager.h
+++ b/src/manager.h
@@ -893,6 +893,8 @@ class Manager {
 
         std::unique_ptr<DataTransferFacade> dataTransfers;
 
+        std::vector<DRing::Message> getLastMessages(const std::string& accountID, const uint64_t& base_timestamp);
+
 private:
         Manager();
         ~Manager();
diff --git a/src/ringdht/ringaccount.cpp b/src/ringdht/ringaccount.cpp
index a5d84e69d22f1c389b86f479f9fc59788d022c08..22dfc80d0af4645853d9a98a18164b525e632aaf 100644
--- a/src/ringdht/ringaccount.cpp
+++ b/src/ringdht/ringaccount.cpp
@@ -3457,6 +3457,7 @@ void RingAccount::pushNotificationReceived(const std::string& from, const std::m
     dht_.pushNotificationReceived(data);
 }
 
+
 std::string
 RingAccount::getUserUri() const
 {
@@ -3467,4 +3468,10 @@ RingAccount::getUserUri() const
     return username_;
 }
 
+
+std::vector<DRing::Message>
+RingAccount::getLastMessages(const uint64_t& base_timestamp)
+{
+    return SIPAccountBase::getLastMessages(base_timestamp);
+}
 } // namespace ring
diff --git a/src/ringdht/ringaccount.h b/src/ringdht/ringaccount.h
index d6021a78c43608a0226025a07aa368b6b724362f..bd99f8dda234d749c67664f172f262780cab8830 100644
--- a/src/ringdht/ringaccount.h
+++ b/src/ringdht/ringaccount.h
@@ -378,6 +378,12 @@ class RingAccount : public SIPAccountBase {
 
         std::string getUserUri() const override;
 
+        /**
+         * Get last messages (should be used to retrieve messages when launching the client)
+         * @param base_timestamp
+         */
+        std::vector<DRing::Message> getLastMessages(const uint64_t& base_timestamp);
+
     private:
         NON_COPYABLE(RingAccount);
 
diff --git a/src/sip/sipaccountbase.cpp b/src/sip/sipaccountbase.cpp
index 4457fadbe10b115688e631ac9059f13f54ddec56..0799e571cd8db527d9316d9077220822c7b3ef97 100644
--- a/src/sip/sipaccountbase.cpp
+++ b/src/sip/sipaccountbase.cpp
@@ -42,6 +42,7 @@
 #include "fileutils.h"
 #include "sip_utils.h"
 
+#include <ctime>
 #include <type_traits>
 
 namespace ring {
@@ -386,6 +387,15 @@ SIPAccountBase::onTextMessage(const std::string& from,
 {
     RING_DBG("Text message received from %s, %zu part(s)",  from.c_str(), payloads.size());
     emitSignal<DRing::ConfigurationSignal::IncomingAccountMessage>(accountID_, from, payloads);
+    DRing::Message message;
+    message.from = from;
+    message.payloads = payloads;
+    message.received = std::time(nullptr);
+    std::lock_guard<std::mutex> lck(mutexLastMessages_);
+    lastMessages_.emplace_back(message);
+    while (lastMessages_.size() > MAX_WAITING_MESSAGES_SIZE) {
+        lastMessages_.pop_front();
+    }
 }
 
 void
diff --git a/src/sip/sipaccountbase.h b/src/sip/sipaccountbase.h
index a1ecedcb30591d259b810037b1f421e6f8af9c46..181269890d2ecdac9f2b8199618e819361491f5b 100644
--- a/src/sip/sipaccountbase.h
+++ b/src/sip/sipaccountbase.h
@@ -18,8 +18,7 @@
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
  */
 
-#ifndef SIPACCOUNTBASE_H
-#define SIPACCOUNTBASE_H
+#pragma once
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -35,9 +34,11 @@
 #include <pjsip/sip_types.h>
 
 #include <array>
-#include <vector>
+#include <deque>
 #include <map>
 #include <memory>
+#include <mutex>
+#include <vector>
 
 #ifdef _WIN32
 typedef uint16_t in_port_t;
@@ -276,6 +277,19 @@ public:
 
     virtual std::string getUserUri() const = 0;
 
+    std::vector<DRing::Message> getLastMessages(const uint64_t& base_timestamp) {
+        std::lock_guard<std::mutex> lck(mutexLastMessages_);
+        auto it = lastMessages_.begin();
+        size_t num = lastMessages_.size();
+        while (it != lastMessages_.end() and it->received <= base_timestamp) {
+            num--;
+            ++it;
+        }
+        if (num == 0)
+            return {};
+        return {it, lastMessages_.end()};
+    }
+
 public: // overloaded methods
     virtual void flush() override;
 
@@ -416,11 +430,19 @@ protected:
     uint16_t getRandomEvenPort(const std::pair<uint16_t, uint16_t>& range) const;
     uint16_t acquireRandomEvenPort(const std::pair<uint16_t, uint16_t>& range) const;
 
+    /**
+     * The deamon can be launched without any client (or with a non ready client)
+     * Like call and file transfer, a client should be able to retrieve current messages.
+     * To avoid to explode the size in memory, this container should be limited.
+     * We don't want to see monsters in memory.
+     */
+    std::mutex mutexLastMessages_;
+    static constexpr size_t MAX_WAITING_MESSAGES_SIZE = 1000;
+    std::deque<DRing::Message> lastMessages_;
+
 private:
     NON_COPYABLE(SIPAccountBase);
 
 };
 
 } // namespace ring
-
-#endif