diff --git a/src/api/conversationmodel.h b/src/api/conversationmodel.h
index 958228b2e4cd70c068e5b4ead7b81329a1436d78..9457f659485213f9b296e62da121ac63b46a7dc0 100644
--- a/src/api/conversationmodel.h
+++ b/src/api/conversationmodel.h
@@ -52,6 +52,25 @@ class Lrc;
 class BehaviorController;
 class NewAccountModel;
 
+enum class ConferenceableItem {
+    CALL,
+    CONTACT
+};
+
+struct AccountConversation
+{
+    std::string convId;
+    std::string accountId;
+};
+
+/*
+  * vector of conversationId and accountId.
+  * for calls and contacts contain only one element
+  * for conferences contains multiple entries
+  */
+
+typedef std::vector<std::vector<AccountConversation>> ConferenceableValue;
+
 /**
   *  @brief Class that manages conversation informations.
   */
@@ -74,6 +93,21 @@ public:
      * @return conversations filtered with the current filter
      */
     const ConversationQueue& allFilteredConversations() const;
+
+    /**
+     * Get conversation for a given identifier
+     * @param  conversation id
+     * @return conversations with given id
+     */
+    conversation::Info getConversationForUID(const std::string& uid) const;
+
+    /**
+     * Get conversations that could be added to conference
+     * @param  current conversation id
+     * @param  search name filter
+     * @return filtered conversations
+     */
+    std::map<ConferenceableItem, ConferenceableValue> getConferenceableConversations(std::string convId, std::string filter = {}) const;
     /**
      * Get a custom filtered set of conversations
      * @return conversations filtered
diff --git a/src/conversationmodel.cpp b/src/conversationmodel.cpp
index 86b35a7d8673a05acceefdce10aa2b90030f637a..cab2a72568b9414bff273bb8268c914f2d504559 100644
--- a/src/conversationmodel.cpp
+++ b/src/conversationmodel.cpp
@@ -361,6 +361,136 @@ ConversationModel::allFilteredConversations() const
     return pimpl_->filteredConversations;
 }
 
+std::map<ConferenceableItem, ConferenceableValue>
+ConversationModel::getConferenceableConversations(std::string convId, std::string filter) const
+{
+    auto conversationIdx = pimpl_->indexOf(convId);
+    if (conversationIdx == -1 || !owner.enabled) {
+        return {};
+    }
+    std::map<ConferenceableItem, ConferenceableValue> result;
+    ConferenceableValue callsVector, contactsVector;
+
+    auto currentConfId = pimpl_->conversations.at(conversationIdx).confId;
+    auto currentCallId = pimpl_->conversations.at(conversationIdx).callId;
+    auto calls = pimpl_->lrc.getCalls();
+    auto conferences = pimpl_->lrc.getConferences();
+    auto conversations = pimpl_->conversations;
+    auto currentAccountID = pimpl_->linked.owner.id;
+    //add contacts for current account
+    for (const auto &conv : conversations) {
+        // conversations with calls will be added in call section
+        if(!conv.callId.empty() || !conv.confId.empty()) {
+            continue;
+        }
+        auto contact = owner.contactModel->getContact(conv.participants.front());
+        if(contact.isBanned || contact.profileInfo.type == profile::Type::PENDING) {
+            continue;
+        }
+        std::vector<AccountConversation> cv;
+        AccountConversation accConv = {conv.uid, currentAccountID};
+        cv.emplace_back(accConv);
+        if (filter.empty()) {
+            contactsVector.emplace_back(cv);
+            continue;
+        }
+        bool result = contact.profileInfo.alias.find(filter) != std::string::npos ||
+                      contact.profileInfo.uri.find(filter) != std::string::npos ||
+                      contact.registeredName.find(filter) != std::string::npos;
+        if (result) {
+            contactsVector.emplace_back(cv);
+        }
+    }
+
+    if (calls.empty() && conferences.empty()) {
+        result.insert(std::pair<ConferenceableItem, ConferenceableValue>(ConferenceableItem::CONTACT, contactsVector));
+        return result;
+    }
+
+    //filter out calls from conference
+    for (const auto& c : conferences) {
+        for (const std::string subcal : pimpl_->lrc.getConferenceSubcalls(c)) {
+            auto position = std::find(calls.begin(), calls.end(), subcal);
+            if (position != calls.end()) {
+                calls.erase(position);
+            }
+        }
+    }
+
+    //found conversations and account for calls and conferences
+    std::map<std::string, std::vector<AccountConversation>> tempConferences;
+    for (const auto &account_id : pimpl_->lrc.getAccountModel().getAccountList()) {
+        try {
+            auto &accountInfo = pimpl_->lrc.getAccountModel().getAccountInfo(account_id);
+            auto accountConv = accountInfo.conversationModel->getFilteredConversations(accountInfo.profileInfo.type);
+            for (const auto &conv : accountConv) {
+                bool confFilterPredicate = !conv.confId.empty() && conv.confId != currentConfId &&
+                    std::find(conferences.begin(), conferences.end(), conv.confId) != conferences.end();
+                bool callFilterPredicate = !conv.callId.empty() && conv.callId != currentCallId &&
+                std::find(calls.begin(), calls.end(), conv.callId) != calls.end();
+
+                if (!confFilterPredicate && !callFilterPredicate) {
+                    continue;
+                }
+
+                // vector of conversationID accountID pair
+                // for call has only one entry, for conference multyple
+                std::vector<AccountConversation> cv;
+                AccountConversation accConv = {conv.uid, account_id};
+                cv.emplace_back(accConv);
+
+                bool isConference = !conv.confId.empty();
+                //call could be added if it is not conference and in active state
+                bool shouldAddCall = false;
+                if (!isConference && accountInfo.callModel->hasCall(conv.callId)) {
+                    const auto& call = accountInfo.callModel->getCall(conv.callId);
+                    shouldAddCall = call.status == lrc::api::call::Status::PAUSED ||
+                                    call.status == lrc::api::call::Status::IN_PROGRESS;
+                }
+
+                auto contact = accountInfo.contactModel->getContact(conv.participants.front());
+                //check if contact satisfy filter
+                bool result = (filter.empty() || isConference) ? true :
+                              (contact.profileInfo.alias.find(filter) != std::string::npos ||
+                              contact.profileInfo.uri.find(filter) != std::string::npos ||
+                              contact.registeredName.find(filter) != std::string::npos);
+                if (!result) {
+                    continue;
+                }
+                if (isConference && tempConferences.count(conv.confId)) {
+                    tempConferences.find(conv.confId)->second.emplace_back(accConv);
+                } else if (isConference) {
+                    tempConferences.insert(std::pair<std::string, std::vector<AccountConversation>>(conv.confId, cv));
+                } else if (shouldAddCall) {
+                    callsVector.emplace_back(cv);
+                }
+            }
+        } catch (...) {}
+    }
+    for(auto it : tempConferences) {
+        if (filter.empty()) {
+            callsVector.emplace_back(it.second);
+            continue;
+        }
+        for(AccountConversation accConv : it.second) {
+            try {
+                auto &account = pimpl_->lrc.getAccountModel().getAccountInfo(accConv.accountId);
+                auto conv = account.conversationModel->getConversationForUID(accConv.convId);
+                auto cont = account.contactModel->getContact(conv.participants.front());
+                if (cont.profileInfo.alias.find(filter) != std::string::npos ||
+                    cont.profileInfo.uri.find(filter) != std::string::npos ||
+                    cont.registeredName.find(filter) != std::string::npos) {
+                    callsVector.emplace_back(it.second);
+                    continue;
+                }
+            } catch (...) {}
+        }
+    }
+    result.insert(std::pair<ConferenceableItem, ConferenceableValue>(ConferenceableItem::CALL, callsVector));
+    result.insert(std::pair<ConferenceableItem, ConferenceableValue>(ConferenceableItem::CONTACT, contactsVector));
+    return result;
+}
+
 const ConversationModel::ConversationQueue&
 ConversationModel::getFilteredConversations(const profile::Type& filter, bool forceUpdate, const bool includeBanned) const
 {
@@ -383,6 +513,20 @@ ConversationModel::getFilteredConversations(const profile::Type& filter, bool fo
     return pimpl_->customFilteredConversations;
 }
 
+conversation::Info
+ConversationModel::getConversationForUID(const std::string& uid) const
+{
+    auto conversationIdx = pimpl_->indexOf(uid);
+    if (conversationIdx == -1 || !owner.enabled) {
+        return {};
+    }
+    try {
+        return pimpl_->conversations.at(conversationIdx);
+    } catch (...) {
+        return {};
+    }
+}
+
 conversation::Info
 ConversationModel::filteredConversation(const unsigned int row) const
 {