diff --git a/src/app/commoncomponents/DataTransferMessageDelegate.qml b/src/app/commoncomponents/DataTransferMessageDelegate.qml
index 38caa8941a4bf97bf94ab41d192789a6ef1fa4cb..9710e19a01d7e91504b640d814717e1249c60f41 100644
--- a/src/app/commoncomponents/DataTransferMessageDelegate.qml
+++ b/src/app/commoncomponents/DataTransferMessageDelegate.qml
@@ -40,9 +40,9 @@ Loader {
     property int seq: MsgSeq.single
     property string author: Author
     property string body: Body
-    property int transferStatus: Status
+    property int transferStatus: TransferStatus
     onTransferStatusChanged: {
-        if (transferStatus === Interaction.Status.TRANSFER_FINISHED) {
+        if (transferStatus === Interaction.TransferStatus.TRANSFER_FINISHED) {
             mediaInfo = MessagesAdapter.getMediaInfo(root.body);
             if (Object.keys(mediaInfo).length !== 0 && WITH_WEBENGINE) {
                 sourceComponent = localMediaMsgComp;
@@ -66,7 +66,7 @@ Loader {
 
             transferId: Id
             property var transferStats: MessagesAdapter.getTransferStats(transferId, root.transferStatus)
-            property bool canOpen: root.transferStatus === Interaction.Status.TRANSFER_FINISHED || isOutgoing
+            property bool canOpen: root.transferStatus === Interaction.TransferStatus.TRANSFER_FINISHED || isOutgoing
             property real maxMsgWidth: root.width - senderMargin -
                                        2 * hPadding - avatarBlockWidth
                                        - buttonsLoader.width - 24 - 6 - 24
@@ -112,18 +112,18 @@ Loader {
 
                         sourceComponent: {
                             switch (root.transferStatus) {
-                            case Interaction.Status.TRANSFER_CREATED:
-                            case Interaction.Status.TRANSFER_FINISHED:
+                            case Interaction.TransferStatus.TRANSFER_CREATED:
+                            case Interaction.TransferStatus.TRANSFER_FINISHED:
                                 iconSource = JamiResources.link_black_24dp_svg
                                 return terminatedComp
-                            case Interaction.Status.TRANSFER_CANCELED:
-                            case Interaction.Status.TRANSFER_ERROR:
-                            case Interaction.Status.TRANSFER_UNJOINABLE_PEER:
-                            case Interaction.Status.TRANSFER_TIMEOUT_EXPIRED:
-                            case Interaction.Status.TRANSFER_AWAITING_HOST:
+                            case Interaction.TransferStatus.TRANSFER_CANCELED:
+                            case Interaction.TransferStatus.TRANSFER_ERROR:
+                            case Interaction.TransferStatus.TRANSFER_UNJOINABLE_PEER:
+                            case Interaction.TransferStatus.TRANSFER_TIMEOUT_EXPIRED:
+                            case Interaction.TransferStatus.TRANSFER_AWAITING_HOST:
                                 iconSource = JamiResources.download_black_24dp_svg
                                 return optionsComp
-                            case Interaction.Status.TRANSFER_ONGOING:
+                            case Interaction.TransferStatus.TRANSFER_ONGOING:
                                 iconSource = JamiResources.close_black_24dp_svg
                                 return optionsComp
                             default:
@@ -158,7 +158,7 @@ Loader {
                                 normalColor: JamiTheme.chatviewBgColor
                                 imageColor: JamiTheme.chatviewButtonColor
                                 onClicked: {
-                                    if (root.transferStatus === Interaction.Status.TRANSFER_ONGOING) {
+                                    if (root.transferStatus === Interaction.TransferStatus.TRANSFER_ONGOING) {
                                         return MessagesAdapter.cancelFile(transferId)
                                     } else {
                                         return MessagesAdapter.acceptFile(transferId)
@@ -227,7 +227,7 @@ Loader {
                 ,ProgressBar {
                     id: progressBar
 
-                    visible: root.transferStatus === Interaction.Status.TRANSFER_ONGOING
+                    visible: root.transferStatus === Interaction.TransferStatus.TRANSFER_ONGOING
                     height: visible * implicitHeight
                     value: transferStats.progress / transferStats.totalSize
                     width: transferItem.width
diff --git a/src/app/commoncomponents/ShowMoreMenu.qml b/src/app/commoncomponents/ShowMoreMenu.qml
index a40c35c6ed6e5de4b82531c4033c1485b15b8e38..22f95d0c1b62e26bb3d712f90b99ae592fcdac43 100644
--- a/src/app/commoncomponents/ShowMoreMenu.qml
+++ b/src/app/commoncomponents/ShowMoreMenu.qml
@@ -153,7 +153,7 @@ BaseContextMenu {
         GeneralMenuItem {
             id: removeLocally
 
-            canTrigger: type === Interaction.Type.DATA_TRANSFER && Status === Interaction.Status.TRANSFER_FINISHED
+            canTrigger: type === Interaction.Type.DATA_TRANSFER && TransferStatus === Interaction.TransferStatus.TRANSFER_FINISHED
             iconSource: JamiResources.trash_black_24dp_svg
             itemName: JamiStrings.removeLocally
             onClicked: {
diff --git a/src/app/mainview/components/DocumentsScrollview.qml b/src/app/mainview/components/DocumentsScrollview.qml
index e3a9badc0cfc4920d53c9f74e48c183d9b1c2cfb..2bfa7aa3ca199344587130a1dd22b0f7981984cc 100644
--- a/src/app/mainview/components/DocumentsScrollview.qml
+++ b/src/app/mainview/components/DocumentsScrollview.qml
@@ -60,7 +60,7 @@ JamiListView {
 
         property var messageListModel: MessagesAdapter.mediaMessageListModel
         readonly property int documentType: Interaction.Type.DATA_TRANSFER
-        readonly property int transferFinishedType: Interaction.Status.TRANSFER_FINISHED
+        readonly property int transferFinishedType: Interaction.TransferStatus.TRANSFER_FINISHED
         readonly property int transferSuccesType: Interaction.Status.SUCCESS
 
         onMessageListModelChanged: sourceModel = root.visible && messageListModel ? messageListModel : null
diff --git a/src/app/messagesadapter.cpp b/src/app/messagesadapter.cpp
index a735c02c5ed0ba9fee2e8ed3ab2cf7c3baae0453..037dcd7d1f095e77b979be7f5a2b3bc7ec447422 100644
--- a/src/app/messagesadapter.cpp
+++ b/src/app/messagesadapter.cpp
@@ -335,40 +335,6 @@ MessagesAdapter::onPaste()
     }
 }
 
-QString
-MessagesAdapter::getStatusString(int status)
-{
-    switch (static_cast<interaction::Status>(status)) {
-    case interaction::Status::SENDING:
-        return QObject::tr("Sending");
-    case interaction::Status::FAILURE:
-        return QObject::tr("Failure");
-    case interaction::Status::SUCCESS:
-        return QObject::tr("Sent");
-    case interaction::Status::TRANSFER_CREATED:
-        return QObject::tr("Connecting");
-    case interaction::Status::TRANSFER_ACCEPTED:
-        return QObject::tr("Accept");
-    case interaction::Status::TRANSFER_CANCELED:
-        return QObject::tr("Canceled");
-    case interaction::Status::TRANSFER_ERROR:
-    case interaction::Status::TRANSFER_UNJOINABLE_PEER:
-        return QObject::tr("Unable to make contact");
-    case interaction::Status::TRANSFER_ONGOING:
-        return QObject::tr("Ongoing");
-    case interaction::Status::TRANSFER_AWAITING_PEER:
-        return QObject::tr("Waiting for contact");
-    case interaction::Status::TRANSFER_AWAITING_HOST:
-        return QObject::tr("Incoming transfer");
-    case interaction::Status::TRANSFER_TIMEOUT_EXPIRED:
-        return QObject::tr("Timed out waiting for contact");
-    case interaction::Status::TRANSFER_FINISHED:
-        return QObject::tr("Finished");
-    default:
-        return {};
-    }
-}
-
 QVariantMap
 MessagesAdapter::getTransferStats(const QString& msgId, int status)
 {
diff --git a/src/app/messagesadapter.h b/src/app/messagesadapter.h
index e612a4cdfe5a6bd0638876b51a52f32c0435b140..c35f3f31d14772b32e934497c9c5be7d55c18af8 100644
--- a/src/app/messagesadapter.h
+++ b/src/app/messagesadapter.h
@@ -159,7 +159,6 @@ public:
                                   const QColor& linkColor = QColor(0x06, 0x45, 0xad),
                                   const QColor& backgroundColor = QColor(0x0, 0x0, 0x0));
     Q_INVOKABLE void onPaste();
-    Q_INVOKABLE QString getStatusString(int status);
     Q_INVOKABLE QVariantMap getTransferStats(const QString& messageId, int);
     Q_INVOKABLE QVariant dataForInteraction(const QString& interactionId,
                                             int role = Qt::DisplayRole) const;
diff --git a/src/libclient/api/interaction.h b/src/libclient/api/interaction.h
index 7d2f68dae4c9d45010042f19be7cf4a7a6e47507..f4ff6074c642e986c153b052cd0c1335c988e71c 100644
--- a/src/libclient/api/interaction.h
+++ b/src/libclient/api/interaction.h
@@ -119,6 +119,12 @@ enum class Status {
     FAILURE,
     SUCCESS,
     DISPLAYED,
+    COUNT__
+};
+Q_ENUM_NS(Status)
+
+enum class TransferStatus {
+    INVALID,
     TRANSFER_CREATED,
     TRANSFER_ACCEPTED,
     TRANSFER_CANCELED,
@@ -131,7 +137,7 @@ enum class Status {
     TRANSFER_FINISHED,
     COUNT__
 };
-Q_ENUM_NS(Status)
+Q_ENUM_NS(TransferStatus)
 
 static inline const QString
 to_string(const Status& status)
@@ -147,26 +153,6 @@ to_string(const Status& status)
         return "SUCCESS";
     case Status::DISPLAYED:
         return "DISPLAYED";
-    case Status::TRANSFER_CREATED:
-        return "TRANSFER_CREATED";
-    case Status::TRANSFER_ACCEPTED:
-        return "TRANSFER_ACCEPTED";
-    case Status::TRANSFER_CANCELED:
-        return "TRANSFER_CANCELED";
-    case Status::TRANSFER_ERROR:
-        return "TRANSFER_ERROR";
-    case Status::TRANSFER_UNJOINABLE_PEER:
-        return "TRANSFER_UNJOINABLE_PEER";
-    case Status::TRANSFER_ONGOING:
-        return "TRANSFER_ONGOING";
-    case Status::TRANSFER_AWAITING_HOST:
-        return "TRANSFER_AWAITING_HOST";
-    case Status::TRANSFER_AWAITING_PEER:
-        return "TRANSFER_AWAITING_PEER";
-    case Status::TRANSFER_TIMEOUT_EXPIRED:
-        return "TRANSFER_TIMEOUT_EXPIRED";
-    case Status::TRANSFER_FINISHED:
-        return "TRANSFER_FINISHED";
     case Status::INVALID:
     case Status::COUNT__:
     default:
@@ -187,28 +173,66 @@ to_status(const QString& status)
         return Status::SUCCESS;
     else if (status == "DISPLAYED")
         return Status::DISPLAYED;
-    else if (status == "TRANSFER_CREATED")
-        return Status::TRANSFER_CREATED;
+    else
+        return Status::INVALID;
+}
+
+static inline const QString
+to_string(const TransferStatus& status)
+{
+    switch (status) {
+    case TransferStatus::TRANSFER_CREATED:
+        return "TRANSFER_CREATED";
+    case TransferStatus::TRANSFER_ACCEPTED:
+        return "TRANSFER_ACCEPTED";
+    case TransferStatus::TRANSFER_CANCELED:
+        return "TRANSFER_CANCELED";
+    case TransferStatus::TRANSFER_ERROR:
+        return "TRANSFER_ERROR";
+    case TransferStatus::TRANSFER_UNJOINABLE_PEER:
+        return "TRANSFER_UNJOINABLE_PEER";
+    case TransferStatus::TRANSFER_ONGOING:
+        return "TRANSFER_ONGOING";
+    case TransferStatus::TRANSFER_AWAITING_HOST:
+        return "TRANSFER_AWAITING_HOST";
+    case TransferStatus::TRANSFER_AWAITING_PEER:
+        return "TRANSFER_AWAITING_PEER";
+    case TransferStatus::TRANSFER_TIMEOUT_EXPIRED:
+        return "TRANSFER_TIMEOUT_EXPIRED";
+    case TransferStatus::TRANSFER_FINISHED:
+        return "TRANSFER_FINISHED";
+    case TransferStatus::INVALID:
+    case TransferStatus::COUNT__:
+    default:
+        return "INVALID";
+    }
+}
+
+static inline TransferStatus
+to_transferStatus(const QString& status)
+{
+    if (status == "TRANSFER_CREATED")
+        return TransferStatus::TRANSFER_CREATED;
     else if (status == "TRANSFER_ACCEPTED")
-        return Status::TRANSFER_ACCEPTED;
+        return TransferStatus::TRANSFER_ACCEPTED;
     else if (status == "TRANSFER_CANCELED")
-        return Status::TRANSFER_CANCELED;
+        return TransferStatus::TRANSFER_CANCELED;
     else if (status == "TRANSFER_ERROR")
-        return Status::TRANSFER_ERROR;
+        return TransferStatus::TRANSFER_ERROR;
     else if (status == "TRANSFER_UNJOINABLE_PEER")
-        return Status::TRANSFER_UNJOINABLE_PEER;
+        return TransferStatus::TRANSFER_UNJOINABLE_PEER;
     else if (status == "TRANSFER_ONGOING")
-        return Status::TRANSFER_ONGOING;
+        return TransferStatus::TRANSFER_ONGOING;
     else if (status == "TRANSFER_AWAITING_HOST")
-        return Status::TRANSFER_AWAITING_HOST;
+        return TransferStatus::TRANSFER_AWAITING_HOST;
     else if (status == "TRANSFER_AWAITING_PEER")
-        return Status::TRANSFER_AWAITING_PEER;
+        return TransferStatus::TRANSFER_AWAITING_PEER;
     else if (status == "TRANSFER_TIMEOUT_EXPIRED")
-        return Status::TRANSFER_TIMEOUT_EXPIRED;
+        return TransferStatus::TRANSFER_TIMEOUT_EXPIRED;
     else if (status == "TRANSFER_FINISHED")
-        return Status::TRANSFER_FINISHED;
+        return TransferStatus::TRANSFER_FINISHED;
     else
-        return Status::INVALID;
+        return TransferStatus::INVALID;
 }
 
 enum class ContactAction { ADD, JOIN, LEAVE, BANNED, UNBANNED, INVALID };
@@ -366,6 +390,7 @@ public:
  * @var duration
  * @var type
  * @var status
+ * @var transferStatus
  * @var isRead
  * @var commit
  * @var linkPreviewInfo
@@ -381,6 +406,7 @@ struct Info
     std::time_t duration = 0;
     Type type = Type::INVALID;
     Status status = Status::INVALID;
+    TransferStatus transferStatus = TransferStatus::INVALID;
     bool isRead = false;
     MapStringString commit;
     QVariantMap linkPreviewInfo = {};
@@ -397,7 +423,8 @@ struct Info
          std::time_t duration,
          Type type,
          Status status,
-         bool isRead)
+         bool isRead,
+         TransferStatus transferStatus = TransferStatus::INVALID)
     {
         this->authorUri = authorUri;
         this->body = body;
@@ -406,6 +433,15 @@ struct Info
         this->type = type;
         this->status = status;
         this->isRead = isRead;
+        this->transferStatus = transferStatus;
+    }
+
+    static Info contact(const QString& authorUri,
+                        std::time_t timestamp)
+    {
+        return Info(authorUri, "", timestamp, 0,
+                    Type::CONTACT, authorUri.isEmpty() ? Status::UNKNOWN : Status::SUCCESS,
+                    authorUri.isEmpty());
     }
 
     Info(const Info& other) = default;
@@ -415,7 +451,7 @@ struct Info
 
     bool sent() const
     {
-        return status == Status::SUCCESS || status == Status::DISPLAYED || status == Status::TRANSFER_FINISHED;
+        return status == Status::SUCCESS || status == Status::DISPLAYED;
     }
 
     void init(const MapStringString& message, const QString& accountURI)
diff --git a/src/libclient/api/messagelistmodel.h b/src/libclient/api/messagelistmodel.h
index f765702e6b9969798bb6d6babd50a40997461d24..96f7adf54e6f362321fadf4a8021f6903bafb330 100644
--- a/src/libclient/api/messagelistmodel.h
+++ b/src/libclient/api/messagelistmodel.h
@@ -40,6 +40,7 @@ struct Info;
     X(Duration) \
     X(Type) \
     X(Status) \
+    X(TransferStatus) \
     X(IsRead) \
     X(ContactAction) \
     X(ActionUri) \
@@ -101,6 +102,7 @@ public:
     bool append(const QString& id, const interaction::Info& interaction);
     bool update(const QString& id, const interaction::Info& interaction);
     bool updateStatus(const QString& id, interaction::Status newStatus, const QString& newBody = {});
+    bool updateTransferStatus(const QString& id, interaction::TransferStatus newStatus, const QString& newBody = {});
     QPair<bool, bool> addOrUpdate(const QString& id, const interaction::Info& interaction);
 
     // Thread-safe access to interactions.
diff --git a/src/libclient/authority/storagehelper.cpp b/src/libclient/authority/storagehelper.cpp
index 1500a502fd059565768a398d1a253778695ed27e..88f0c31c98da925a776bdb061641d3e02058b4bd 100644
--- a/src/libclient/authority/storagehelper.cpp
+++ b/src/libclient/authority/storagehelper.cpp
@@ -482,14 +482,7 @@ beginConversationWithPeer(Database& db,
     db.insertInto("conversations",
                   {{":id", "id"}, {":participant", "participant"}},
                   {{":id", newConversationsId}, {":participant", peer_uri}});
-    api::interaction::Info msg {isOutgoing ? "" : peer_uri,
-                                {},
-                                timestamp ? timestamp : std::time(nullptr),
-                                0,
-                                api::interaction::Type::CONTACT,
-                                isOutgoing ? api::interaction::Status::SUCCESS
-                                           : api::interaction::Status::UNKNOWN,
-                                isOutgoing};
+    api::interaction::Info msg = api::interaction::Info::contact(isOutgoing ? "" : peer_uri, timestamp);
     // Add first interaction
     addMessageToConversation(db, newConversationsId, msg);
     return newConversationsId;
@@ -696,9 +689,9 @@ updateDataTransferInteractionForDaemonId(Database& db,
         return;
     }
     auto body = result[0];
-    auto status = api::interaction::to_status(result[1]);
+    auto status = api::interaction::to_transferStatus(result[1]);
     interaction.body = body;
-    interaction.status = status;
+    interaction.transferStatus = status;
 }
 
 QString
@@ -731,6 +724,16 @@ updateInteractionStatus(Database& db, const QString& id, api::interaction::Statu
               {{":id", id}});
 }
 
+void
+updateInteractionTransferStatus(Database& db, const QString& id, api::interaction::TransferStatus newStatus)
+{
+    db.update("interactions",
+              {"status=:status"},
+              {{":status", api::interaction::to_string(newStatus)}},
+              "id=:id",
+              {{":id", id}});
+}
+
 void
 setInteractionRead(Database& db, const QString& id)
 {
diff --git a/src/libclient/authority/storagehelper.h b/src/libclient/authority/storagehelper.h
index 0aa40b7b4d80e07ac7747235efc0bcde94ea964d..bb9bd34ce924b8781490a159b5bc3833f409d632 100644
--- a/src/libclient/authority/storagehelper.h
+++ b/src/libclient/authority/storagehelper.h
@@ -310,6 +310,7 @@ void updateInteractionBody(Database& db, const QString& id, const QString& newBo
  * @param isRead
  */
 void updateInteractionStatus(Database& db, const QString& id, api::interaction::Status newStatus);
+void updateInteractionTransferStatus(Database& db, const QString& id, api::interaction::TransferStatus newStatus);
 
 /**
  * Set interaction to the read state
diff --git a/src/libclient/conversationmodel.cpp b/src/libclient/conversationmodel.cpp
index 093f1d7d095a809ec73d1530daa2d0325415d3e5..5214fe0b03e4ede9bd25f06f774d354987546662 100644
--- a/src/libclient/conversationmodel.cpp
+++ b/src/libclient/conversationmodel.cpp
@@ -342,7 +342,7 @@ public Q_SLOTS:
     void slotTransferStatusUnjoinable(const QString& fileId, api::datatransfer::Info info);
     bool updateTransferStatus(const QString& fileId,
                               datatransfer::Info info,
-                              interaction::Status newStatus,
+                              interaction::TransferStatus newStatus,
                               bool& updated);
     void slotSwarmLoaded(uint32_t requestId,
                          const QString& accountId,
@@ -2047,17 +2047,17 @@ ConversationModelPimpl::initConversations()
         // Resolve any file transfer interactions were left in an incorrect state
         auto& interactions = conversations[convIdx].interactions;
         interactions->forEach([&](const QString& id, interaction::Info& interaction) {
-            if (interaction.status == interaction::Status::TRANSFER_CREATED
-                || interaction.status == interaction::Status::TRANSFER_AWAITING_HOST
-                || interaction.status == interaction::Status::TRANSFER_AWAITING_PEER
-                || interaction.status == interaction::Status::TRANSFER_ONGOING
-                || interaction.status == interaction::Status::TRANSFER_ACCEPTED) {
+            if (interaction.transferStatus == interaction::TransferStatus::TRANSFER_CREATED
+                || interaction.transferStatus == interaction::TransferStatus::TRANSFER_AWAITING_HOST
+                || interaction.transferStatus == interaction::TransferStatus::TRANSFER_AWAITING_PEER
+                || interaction.transferStatus == interaction::TransferStatus::TRANSFER_ONGOING
+                || interaction.transferStatus == interaction::TransferStatus::TRANSFER_ACCEPTED) {
                 // If a datatransfer was left in a non-terminal status in DB, we switch this status
                 // to ERROR
                 // TODO : Improve for DBus clients as daemon and transfer may still be ongoing
-                storage::updateInteractionStatus(db, id, interaction::Status::TRANSFER_ERROR);
+                storage::updateInteractionTransferStatus(db, id, interaction::TransferStatus::TRANSFER_ERROR);
 
-                interaction.status = interaction::Status::TRANSFER_ERROR;
+                interaction.transferStatus = interaction::TransferStatus::TRANSFER_ERROR;
             }
         });
     }
@@ -2292,9 +2292,9 @@ ConversationModelPimpl::slotSwarmLoaded(uint32_t requestId,
                 } else {
                     msg.body = path;
                 }
-                msg.status = bytesProgress == 0 ? interaction::Status::TRANSFER_AWAITING_HOST
-                             : bytesProgress == totalSize ? interaction::Status::TRANSFER_FINISHED
-                                                          : interaction::Status::TRANSFER_ONGOING;
+                msg.transferStatus = bytesProgress == 0 ? interaction::TransferStatus::TRANSFER_AWAITING_HOST
+                                   : bytesProgress == totalSize ? interaction::TransferStatus::TRANSFER_FINISHED
+                                                                : interaction::TransferStatus::TRANSFER_ONGOING;
                 linked.owner.dataTransferModel->registerTransferId(fileId, msgId);
                 downloadFile = (bytesProgress == 0);
             }
@@ -2406,9 +2406,9 @@ ConversationModelPimpl::slotMessageReceived(const QString& accountId,
             } else {
                 msg.body = path;
             }
-            msg.status = bytesProgress == 0           ? interaction::Status::TRANSFER_AWAITING_HOST
-                         : bytesProgress == totalSize ? interaction::Status::TRANSFER_FINISHED
-                                                      : interaction::Status::TRANSFER_ONGOING;
+            msg.transferStatus = bytesProgress == 0         ? interaction::TransferStatus::TRANSFER_AWAITING_HOST
+                               : bytesProgress == totalSize ? interaction::TransferStatus::TRANSFER_FINISHED
+                                                            : interaction::TransferStatus::TRANSFER_ONGOING;
             linked.owner.dataTransferModel->registerTransferId(fileId, msgId);
         }
 
@@ -2431,7 +2431,7 @@ ConversationModelPimpl::slotMessageReceived(const QString& accountId,
         }
         Q_EMIT linked.newInteraction(conversationId, msgId, msg);
         Q_EMIT linked.modelChanged();
-        if (msg.status == interaction::Status::TRANSFER_AWAITING_HOST && updateUnread) {
+        if (msg.transferStatus == interaction::TransferStatus::TRANSFER_AWAITING_HOST && updateUnread) {
             handleIncomingFile(conversationId,
                                msgId,
                                QString(message.body.value("totalSize")).toInt());
@@ -3496,25 +3496,20 @@ ConversationModelPimpl::updateInteractionStatus(const QString& accountId,
         using namespace libjami::Account;
         auto msgState = static_cast<MessageStates>(status);
         auto& interactions = conversation.interactions;
-        interactions->with(messageId, [&](const QString& id, const interaction::Info& interaction) {
-            if (interaction.type != interaction::Type::DATA_TRANSFER) {
-                interaction::Status newState;
-                if (msgState == MessageStates::SENDING) {
-                    newState = interaction::Status::SENDING;
-                } else if (msgState == MessageStates::SENT) {
-                    newState = interaction::Status::SUCCESS;
-                } else if (msgState == MessageStates::DISPLAYED) {
-                    newState = interaction::Status::DISPLAYED;
-                } else {
-                    return;
-                }
-                if (interactions->updateStatus(id, newState)
-                    && newState == interaction::Status::DISPLAYED) {
-                    emitDisplayed = true;
-                }
+        interactions->with(messageId, [&](const QString& id, const interaction::Info&) {
+            interaction::Status newState;
+            if (msgState == MessageStates::SENDING) {
+                newState = interaction::Status::SENDING;
+            } else if (msgState == MessageStates::SENT) {
+                newState = interaction::Status::SUCCESS;
             } else if (msgState == MessageStates::DISPLAYED) {
-                emitDisplayed = true; // Status for file transfer is managed otherwise,
-                // But at least set interaction as read
+                newState = interaction::Status::DISPLAYED;
+            } else {
+                return;
+            }
+            if (interactions->updateStatus(id, newState)
+                && newState == interaction::Status::DISPLAYED) {
+                emitDisplayed = true;
             }
         });
 
@@ -3683,11 +3678,11 @@ ConversationModel::cancelTransfer(const QString& convUid, const QString& fileId)
     bool emitUpdated = false;
     if (conversationIdx != -1) {
         auto& interactions = pimpl_->conversations[conversationIdx].interactions;
-        if (interactions->updateStatus(fileId, interaction::Status::TRANSFER_CANCELED)) {
+        if (interactions->updateTransferStatus(fileId, interaction::TransferStatus::TRANSFER_CANCELED)) {
             // update information in the db
-            storage::updateInteractionStatus(pimpl_->db,
+            storage::updateInteractionTransferStatus(pimpl_->db,
                                              fileId,
-                                             interaction::Status::TRANSFER_CANCELED);
+                                             interaction::TransferStatus::TRANSFER_CANCELED);
             emitUpdated = true;
         }
     }
@@ -3735,7 +3730,7 @@ ConversationModel::removeFile(const QString& conversationId,
         return;
 
     QFile::remove(path);
-    convOpt->get().interactions->updateStatus(interactionId, interaction::Status::TRANSFER_CANCELED);
+    convOpt->get().interactions->updateTransferStatus(interactionId, interaction::TransferStatus::TRANSFER_CANCELED);
 }
 
 int
@@ -3809,8 +3804,9 @@ ConversationModelPimpl::slotTransferStatusCreated(const QString& fileId, datatra
                                           std::time(nullptr),
                                           0,
                                           interaction::Type::DATA_TRANSFER,
-                                          interaction::Status::TRANSFER_CREATED,
-                                          false};
+                                          interaction::Status::SENDING,
+                                          false,
+                                          interaction::TransferStatus::TRANSFER_CREATED};
 
     // prepare interaction Info and emit signal for the client
     auto conversationIdx = indexOf(convId);
@@ -3839,7 +3835,7 @@ ConversationModelPimpl::slotTransferStatusAwaitingPeer(const QString& fileId,
     if (info.accountId != linked.owner.id)
         return;
     bool intUpdated;
-    updateTransferStatus(fileId, info, interaction::Status::TRANSFER_AWAITING_PEER, intUpdated);
+    updateTransferStatus(fileId, info, interaction::TransferStatus::TRANSFER_AWAITING_PEER, intUpdated);
 }
 
 void
@@ -3876,7 +3872,7 @@ ConversationModelPimpl::awaitingHost(const QString& fileId, datatransfer::Info i
 
     if (!updateTransferStatus(fileId,
                               info,
-                              interaction::Status::TRANSFER_AWAITING_HOST,
+                              interaction::TransferStatus::TRANSFER_AWAITING_HOST,
                               intUpdated)) {
         return;
     }
@@ -3969,7 +3965,7 @@ ConversationModelPimpl::slotTransferStatusOngoing(const QString& fileId, datatra
         return;
     bool intUpdated;
 
-    if (!updateTransferStatus(fileId, info, interaction::Status::TRANSFER_ONGOING, intUpdated)) {
+    if (!updateTransferStatus(fileId, info, interaction::TransferStatus::TRANSFER_ONGOING, intUpdated)) {
         return;
     }
     if (!intUpdated) {
@@ -3996,14 +3992,14 @@ ConversationModelPimpl::slotTransferStatusFinished(const QString& fileId, datatr
     auto conversationIdx = indexOf(conversationId);
     if (conversationIdx != -1) {
         bool emitUpdated = false;
-        auto newStatus = interaction::Status::TRANSFER_FINISHED;
+        auto newStatus = interaction::TransferStatus::TRANSFER_FINISHED;
         auto& interactions = conversations[conversationIdx].interactions;
         interactions->with(interactionId, [&](const QString& id, interaction::Info& interaction) {
             // We need to check if current status is ONGOING as CANCELED must not be
             // transformed into FINISHED
-            if (interaction.status == interaction::Status::TRANSFER_ONGOING) {
+            if (interaction.transferStatus == interaction::TransferStatus::TRANSFER_ONGOING) {
                 emitUpdated = true;
-                interactions->updateStatus(id, newStatus);
+                interactions->updateTransferStatus(id, newStatus);
             }
         });
         if (emitUpdated) {
@@ -4011,10 +4007,10 @@ ConversationModelPimpl::slotTransferStatusFinished(const QString& fileId, datatr
             if (conversations[conversationIdx].mode != conversation::Mode::NON_SWARM) {
                 if (transfIdToDbIntId.find(fileId) != transfIdToDbIntId.end()) {
                     auto dbIntId = transfIdToDbIntId[fileId];
-                    storage::updateInteractionStatus(db, dbIntId, newStatus);
+                    storage::updateInteractionTransferStatus(db, dbIntId, newStatus);
                 }
             } else {
-                storage::updateInteractionStatus(db, interactionId, newStatus);
+                storage::updateInteractionTransferStatus(db, interactionId, newStatus);
             }
             transfIdToDbIntId.remove(fileId);
         }
@@ -4027,7 +4023,7 @@ ConversationModelPimpl::slotTransferStatusCanceled(const QString& fileId, datatr
     if (info.accountId != linked.owner.id)
         return;
     bool intUpdated;
-    updateTransferStatus(fileId, info, interaction::Status::TRANSFER_CANCELED, intUpdated);
+    updateTransferStatus(fileId, info, interaction::TransferStatus::TRANSFER_CANCELED, intUpdated);
 }
 
 void
@@ -4036,7 +4032,7 @@ ConversationModelPimpl::slotTransferStatusError(const QString& fileId, datatrans
     if (info.accountId != linked.owner.id)
         return;
     bool intUpdated;
-    updateTransferStatus(fileId, info, interaction::Status::TRANSFER_ERROR, intUpdated);
+    updateTransferStatus(fileId, info, interaction::TransferStatus::TRANSFER_ERROR, intUpdated);
 }
 
 void
@@ -4045,7 +4041,7 @@ ConversationModelPimpl::slotTransferStatusUnjoinable(const QString& fileId, data
     if (info.accountId != linked.owner.id)
         return;
     bool intUpdated;
-    updateTransferStatus(fileId, info, interaction::Status::TRANSFER_UNJOINABLE_PEER, intUpdated);
+    updateTransferStatus(fileId, info, interaction::TransferStatus::TRANSFER_UNJOINABLE_PEER, intUpdated);
 }
 
 void
@@ -4055,13 +4051,13 @@ ConversationModelPimpl::slotTransferStatusTimeoutExpired(const QString& fileId,
     if (info.accountId != linked.owner.id)
         return;
     bool intUpdated;
-    updateTransferStatus(fileId, info, interaction::Status::TRANSFER_TIMEOUT_EXPIRED, intUpdated);
+    updateTransferStatus(fileId, info, interaction::TransferStatus::TRANSFER_TIMEOUT_EXPIRED, intUpdated);
 }
 
 bool
 ConversationModelPimpl::updateTransferStatus(const QString& fileId,
                                              datatransfer::Info info,
-                                             interaction::Status newStatus,
+                                             interaction::TransferStatus newStatus,
                                              bool& updated)
 {
     QString interactionId;
@@ -4076,10 +4072,10 @@ ConversationModelPimpl::updateTransferStatus(const QString& fileId,
     }
     auto& conversation = conversations[conversationIdx];
     if (conversation.isLegacy()) {
-        storage::updateInteractionStatus(db, interactionId, newStatus);
+        storage::updateInteractionTransferStatus(db, interactionId, newStatus);
     }
     auto& interactions = conversations[conversationIdx].interactions;
-    bool emitUpdated = interactions->updateStatus(interactionId,
+    bool emitUpdated = interactions->updateTransferStatus(interactionId,
                                                   newStatus,
                                                   conversation.isSwarm() ? info.path : QString());
     if (emitUpdated) {
@@ -4099,9 +4095,9 @@ ConversationModelPimpl::updateTransferProgress(QTimer* timer,
         {
             const auto& interactions = conversations[conversationIdx].interactions;
             interactions->with(interactionId, [&](const QString& id, interaction::Info& interaction) {
-                if (interaction.status == interaction::Status::TRANSFER_ONGOING) {
+                if (interaction.transferStatus == interaction::TransferStatus::TRANSFER_ONGOING) {
                     emitUpdated = true;
-                    interactions->updateStatus(id, interaction::Status::TRANSFER_ONGOING);
+                    interactions->updateTransferStatus(id, interaction::TransferStatus::TRANSFER_ONGOING);
                 }
             });
         }
diff --git a/src/libclient/messagelistmodel.cpp b/src/libclient/messagelistmodel.cpp
index 51f93090f2cc032ebe27b63c62d4c2d218014590..ce726dbb9931fd4d53236e4eb138bc358b060980 100644
--- a/src/libclient/messagelistmodel.cpp
+++ b/src/libclient/messagelistmodel.cpp
@@ -249,6 +249,29 @@ MessageListModel::updateStatus(const QString& id,
     return true;
 }
 
+bool
+MessageListModel::updateTransferStatus(const QString& id,
+                               interaction::TransferStatus newStatus,
+                               const QString& newBody)
+{
+    const std::lock_guard<std::recursive_mutex> lk(mutex_);
+    auto it = find(id);
+    if (it == interactions_.end()) {
+        return false;
+    }
+    VectorInt roles;
+    if (it->second.transferStatus == newStatus) {
+        return false;
+    }
+    it->second.transferStatus = newStatus;
+    roles.push_back(Role::TransferStatus);
+    if (!newBody.isEmpty()) {
+        it->second.body = newBody;
+        roles.push_back(Role::Body);
+    }
+    return true;
+}
+
 QPair<bool, bool>
 MessageListModel::addOrUpdate(const QString& id, const interaction::Info& interaction)
 {
@@ -529,6 +552,8 @@ MessageListModel::dataForItem(const item_t& item, int, int role) const
         return QVariant(static_cast<int>(item.second.type));
     case Role::Status:
         return QVariant(static_cast<int>(item.second.status));
+    case Role::TransferStatus:
+        return QVariant(static_cast<int>(item.second.transferStatus));
     case Role::IsRead:
         return QVariant(item.second.isRead);
     case Role::LinkPreviewInfo:
diff --git a/tests/qml/src/tst_DataTransferMessageDelegate.qml b/tests/qml/src/tst_DataTransferMessageDelegate.qml
index 8842267552a1b826870616e697333efb01505018..5c3fc3b6fa898acb1942e2b7a1ddd15e08572dea 100644
--- a/tests/qml/src/tst_DataTransferMessageDelegate.qml
+++ b/tests/qml/src/tst_DataTransferMessageDelegate.qml
@@ -31,7 +31,7 @@ import "../../../src/app/commoncomponents"
 DataTransferMessageDelegate {
     id: uut
     timestamp: 0
-    transferStatus: Interaction.Status.TRANSFER_FINISHED
+    transferStatus: Interaction.TransferStatus.TRANSFER_FINISHED
     author: ""
     body: ""
 
@@ -39,9 +39,9 @@ DataTransferMessageDelegate {
         name: "Check basic visibility for header buttons"
         function test_checkBasicVisibility() {
             var buttonsLoader = findChild(uut, "buttonsLoader")
-            uut.transferStatus = Interaction.Status.TRANSFER_AWAITING_HOST
+            uut.transferStatus = Interaction.TransferStatus.TRANSFER_AWAITING_HOST
             compare(buttonsLoader.iconSource, JamiResources.download_black_24dp_svg)
-            uut.transferStatus = Interaction.Status.TRANSFER_FINISHED
+            uut.transferStatus = Interaction.TransferStatus.TRANSFER_FINISHED
             compare(buttonsLoader.iconSource, JamiResources.link_black_24dp_svg)
         }
     }