diff --git a/daemon/bin/dbus/configurationmanager-introspec.xml b/daemon/bin/dbus/configurationmanager-introspec.xml
index 3c219b4809747d6db78122aadce6a29fddadd29e..72091673fcf76103f20981c39f39723e4e6ecdaf 100644
--- a/daemon/bin/dbus/configurationmanager-introspec.xml
+++ b/daemon/bin/dbus/configurationmanager-introspec.xml
@@ -516,9 +516,21 @@
            </arg>
        </method>
 
+       <method name="getHistory" tp:name-for-bindings="getHistory">
+           <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="VectorMapStringString"/>
+           <!-- Return a List of type Dict<string, string> >...a List of Dicts -->
+           <arg type="aa{ss}" name="entries" direction="out"/>
+       </method>
+
+       <method name="clearHistory" tp:name-for-bindings="clearHistory">
+       </method>
+
        <signal name="accountsChanged" tp:name-for-bindings="accountsChanged">
        </signal>
 
+       <signal name="historyChanged" tp:name-for-bindings="historyChanged">
+       </signal>
+
        <!-- FIXME: we should rethink these two signals -->
        <!-- Used by IAX and SIP accounts -->
        <signal name="registrationStateChanged" tp:name-for-bindings="registrationStateChanged">
diff --git a/daemon/bin/dbus/dbusclient.cpp b/daemon/bin/dbus/dbusclient.cpp
index 6cc83ddc35baa0bbe2b8a994ee7b22caa80deaa3..7b809186e50aeb28d5fb8315f095e0f520fdb7a2 100644
--- a/daemon/bin/dbus/dbusclient.cpp
+++ b/daemon/bin/dbus/dbusclient.cpp
@@ -175,6 +175,7 @@ int DBusClient::initLibrary(int sflphFlags)
             DRing::EventHandlerKey::CONFIG, {
                 exportable_callback<ConfigurationSignal::VolumeChanged>(bind(&DBusConfigurationManager::volumeChanged, confM, _1, _2)),
                 exportable_callback<ConfigurationSignal::AccountsChanged>(bind(&DBusConfigurationManager::accountsChanged, confM)),
+                exportable_callback<ConfigurationSignal::HistoryChanged>(bind(&DBusConfigurationManager::historyChanged, confM)),
                 exportable_callback<ConfigurationSignal::StunStatusFailed>(bind(&DBusConfigurationManager::stunStatusFailure, confM, _1)),
                 exportable_callback<ConfigurationSignal::RegistrationStateChanged>(bind(&DBusConfigurationManager::registrationStateChanged, confM, _1, _2)),
                 exportable_callback<ConfigurationSignal::SipRegistrationStateChanged>(bind(&DBusConfigurationManager::sipRegistrationStateChanged, confM, _1, _2, _3)),
diff --git a/daemon/bin/dbus/dbusconfigurationmanager.cpp b/daemon/bin/dbus/dbusconfigurationmanager.cpp
index 856a0be490c8edd92d51ff9a2940c0588132484a..219510344ebe529b05b0cdfdcc88eabcc65ed7ba 100644
--- a/daemon/bin/dbus/dbusconfigurationmanager.cpp
+++ b/daemon/bin/dbus/dbusconfigurationmanager.cpp
@@ -330,6 +330,12 @@ DBusConfigurationManager::getHistoryLimit() -> decltype(DRing::getHistoryLimit()
     return DRing::getHistoryLimit();
 }
 
+void
+DBusConfigurationManager::clearHistory()
+{
+    DRing::clearHistory();
+}
+
 void
 DBusConfigurationManager::setAccountsOrder(const std::string& order)
 {
@@ -348,6 +354,12 @@ DBusConfigurationManager::setHookSettings(const std::map<std::string, std::strin
     DRing::setHookSettings(settings);
 }
 
+auto
+DBusConfigurationManager::getHistory() -> decltype(DRing::getHistory())
+{
+    return DRing::getHistory();
+}
+
 auto
 DBusConfigurationManager::getTlsSettings() -> decltype(DRing::getTlsSettings())
 {
diff --git a/daemon/bin/dbus/dbusconfigurationmanager.h b/daemon/bin/dbus/dbusconfigurationmanager.h
index 18447aa96c15c21899501316bf064408488a8989..0dad0d1d9461ec90f8e80eb75c1eb39ac7ce9ba2 100644
--- a/daemon/bin/dbus/dbusconfigurationmanager.h
+++ b/daemon/bin/dbus/dbusconfigurationmanager.h
@@ -112,9 +112,11 @@ class DBusConfigurationManager :
         void setIsAlwaysRecording(const bool& rec);
         void setHistoryLimit(const int32_t& days);
         int32_t getHistoryLimit();
+        void clearHistory();
         void setAccountsOrder(const std::string& order);
         std::map<std::string, std::string> getHookSettings();
         void setHookSettings(const std::map<std::string, std::string>& settings);
+        std::vector<std::map<std::string, std::string>> getHistory();
         std::map<std::string, std::string> getTlsSettings();
         void setTlsSettings(const std::map<std::string, std::string>& details);
         std::map<std::string, std::string> getIp2IpDetails();
diff --git a/daemon/configure.ac b/daemon/configure.ac
index 6d2c7b970ab2ddb5a3cd3e42a6e45acf6cc43159..349c19d0032c6cc845384d6183eb60c04288424c 100644
--- a/daemon/configure.ac
+++ b/daemon/configure.ac
@@ -591,6 +591,7 @@ AC_CONFIG_FILES([Makefile \
                  src/config/Makefile \
                  src/client/Makefile \
                  src/hooks/Makefile \
+                 src/history/Makefile \
                  src/media/video/Makefile \
                  src/media/video/v4l2/Makefile \
                  src/media/video/test/Makefile \
diff --git a/daemon/src/Makefile.am b/daemon/src/Makefile.am
index 7f1bd34a6a37baf0e9e565310ae99e78ede21ed0..d0b6c9ff7f1f8c0f9537fca3d2292fb8fe572a56 100644
--- a/daemon/src/Makefile.am
+++ b/daemon/src/Makefile.am
@@ -35,7 +35,7 @@ TLS_LIB = @GNUTLS_LIBS@
 TLS_CFLAGS = @GNUTLS_CFLAGS@
 endif
 
-SUBDIRS = client media config hooks sip upnp $(IAX_SUBDIR) $(RINGACC_SUBDIR) $(INSTANT_MESSAGING_SUBDIR) $(RING_VIDEO_SUBDIR)
+SUBDIRS = client media config hooks history sip upnp $(IAX_SUBDIR) $(RINGACC_SUBDIR) $(INSTANT_MESSAGING_SUBDIR) $(RING_VIDEO_SUBDIR)
 
 # libring
 
@@ -47,6 +47,7 @@ libring_la_LIBADD = \
 	./client/libclient.la \
 	./config/libconfig.la \
 	./hooks/libhooks.la \
+	./history/libhistory.la \
 	./upnp/libupnpcontrol.la \
 	$(RINGACC_LIBA) \
 	$(IAX_LIBA) \
diff --git a/daemon/src/call.cpp b/daemon/src/call.cpp
index 2cb97602d59d870fb40c267b06d0534e3420787e..8180628a393ded9414bca9a5db956bdbba861023 100644
--- a/daemon/src/call.cpp
+++ b/daemon/src/call.cpp
@@ -34,6 +34,7 @@
 #include "account.h"
 #include "manager.h"
 #include "audio/ringbufferpool.h"
+#include "history/historyitem.h"
 
 #include "sip/sip_utils.h"
 #include "ip_utils.h"
@@ -243,6 +244,35 @@ timestamp_to_string(const time_t &timestamp)
     return time_str.str();
 }
 
+std::map<std::string, std::string> Call::createHistoryEntry() const
+{
+    std::map<std::string, std::string> result;
+
+    result[HistoryItem::ACCOUNT_ID_KEY] = getAccountId();
+    result[HistoryItem::CONFID_KEY] = confID_;
+    result[HistoryItem::CALLID_KEY] = id_;
+    result[HistoryItem::DISPLAY_NAME_KEY] = displayName_;
+    result[HistoryItem::PEER_NUMBER_KEY] = peerNumber_;
+    result[HistoryItem::RECORDING_PATH_KEY] = recAudio_.fileExists() ? getFilename() : "";
+    result[HistoryItem::TIMESTAMP_START_KEY] = timestamp_to_string(timestamp_start_);
+    result[HistoryItem::TIMESTAMP_STOP_KEY] = timestamp_to_string(timestamp_stop_);
+
+    // FIXME: state will no longer exist, it will be split into
+    // a boolean field called "missed" and a direction field "incoming" or "outgoing"
+    if (connectionState_ == RINGING) {
+        result[HistoryItem::STATE_KEY] = HistoryItem::MISSED_STRING;
+        result[HistoryItem::MISSED_KEY] = "true";
+    } else {
+        result[HistoryItem::STATE_KEY] = getTypeStr();
+        result[HistoryItem::MISSED_KEY] = "false";
+    }
+
+    // now "missed" and direction are independent
+    result[HistoryItem::DIRECTION_KEY] = getTypeStr();
+
+    return result;
+}
+
 std::map<std::string, std::string>
 Call::getDetails()
 {
diff --git a/daemon/src/call.h b/daemon/src/call.h
index aeacc08183c333472357a869ce356a9d29b7c5cc..d1bd08e1b9e43a8f1291eeeef89e2ede7a5c8dac 100644
--- a/daemon/src/call.h
+++ b/daemon/src/call.h
@@ -234,6 +234,9 @@ class Call : public Recordable, public std::enable_shared_from_this<Call> {
         virtual std::map<std::string, std::string> getDetails();
         static std::map<std::string, std::string> getNullDetails();
 
+        virtual std::map<std::string, std::string>
+        createHistoryEntry() const;
+
         virtual bool toggleRecording();
 
         /**
diff --git a/daemon/src/client/configurationmanager.cpp b/daemon/src/client/configurationmanager.cpp
index 4f73face4411ffc190d6fd9204e2ecf01c3d0597..e3c2d7cd550ebe0a461afb8258f968c988b44d9c 100644
--- a/daemon/src/client/configurationmanager.cpp
+++ b/daemon/src/client/configurationmanager.cpp
@@ -435,6 +435,12 @@ getHistoryLimit()
     return ring::Manager::instance().getHistoryLimit();
 }
 
+void
+clearHistory()
+{
+    return ring::Manager::instance().clearHistory();
+}
+
 void
 setHistoryLimit(int32_t days)
 {
@@ -556,6 +562,12 @@ void setAccountsOrder(const std::string& order)
     ring::Manager::instance().setAccountsOrder(order);
 }
 
+std::vector<std::map<std::string, std::string>>
+getHistory()
+{
+    return ring::Manager::instance().getHistory();
+}
+
 std::string
 getAddrFromInterfaceName(const std::string& interface)
 {
diff --git a/daemon/src/client/configurationmanager.h b/daemon/src/client/configurationmanager.h
deleted file mode 100644
index 3e626b61bd15d645ef0d9e81516bf5ea254801bb..0000000000000000000000000000000000000000
--- a/daemon/src/client/configurationmanager.h
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- *  Copyright (C) 2004-2015 Savoir-Faire Linux Inc.
- *  Author: Pierre-Luc Beaudoin <pierre-luc.beaudoin@savoirfairelinux.com>
- *  Author: Alexandre Bourget <alexandre.bourget@savoirfairelinux.com>
- *  Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
- *  Author: Guillaume Carmel-Archambault <guillaume.carmel-archambault@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
- *  the Free Software Foundation; either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
- *
- *  Additional permission under GNU GPL version 3 section 7:
- *
- *  If you modify this program, or any covered work, by linking or
- *  combining it with the OpenSSL project's OpenSSL library (or a
- *  modified version of that library), containing parts covered by the
- *  terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
- *  grants you additional permission to convey the resulting work.
- *  Corresponding Source for a non-source form of such a combination
- *  shall include the source code for the parts of OpenSSL used as well
- *  as that of the covered work.
- */
-
-#ifndef CONFIGURATIONMANAGER_H
-#define CONFIGURATIONMANAGER_H
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <vector>
-#include <map>
-#include <string>
-
-#include "dring.h"
-
-namespace ring {
-
-class ConfigurationManager
-{
-    public:
-        void registerEvHandlers(struct ring_config_ev_handlers* evHandlers);
-
-    // Methods
-    public:
-        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);
-        std::map<std::string, std::string> getAccountTemplate();
-        std::string addAccount(const std::map< std::string, std::string >& details);
-        void removeAccount(const std::string& accoundID);
-        std::vector< std::string > getAccountList();
-        void sendRegister(const std::string& accoundID, bool enable);
-        void registerAllAccounts(void);
-
-        std::map< std::string, std::string > getTlsSettingsDefault();
-
-        std::vector< int32_t > getAudioCodecList();
-        std::vector< std::string > getSupportedTlsMethod();
-        std::vector< std::string > getSupportedCiphers(const std::string& accountID) const;
-        std::vector< std::string > getAudioCodecDetails(int32_t payload);
-        std::vector< int32_t > getActiveAudioCodecList(const std::string& accountID);
-
-        void setActiveAudioCodecList(const std::vector< std::string >& list, const std::string& accountID);
-
-        std::vector< std::string > getAudioPluginList();
-        void setAudioPlugin(const std::string& audioPlugin);
-        std::vector< std::string > getAudioOutputDeviceList();
-        void setAudioOutputDevice(int32_t index);
-        void setAudioInputDevice(int32_t index);
-        void setAudioRingtoneDevice(int32_t index);
-        std::vector< std::string > getAudioInputDeviceList();
-        std::vector< std::string > getCurrentAudioDevicesIndex();
-        int32_t getAudioInputDeviceIndex(const std::string& name);
-        int32_t getAudioOutputDeviceIndex(const std::string& name);
-        std::string getCurrentAudioOutputPlugin();
-        bool getNoiseSuppressState();
-        void setNoiseSuppressState(bool state);
-
-        bool isAgcEnabled();
-        void setAgcState(bool enabled);
-
-        void muteDtmf(bool mute);
-        bool isDtmfMuted();
-
-        bool isCaptureMuted();
-        void muteCapture(bool mute);
-        bool isPlaybackMuted();
-        void mutePlayback(bool mute);
-
-        std::map<std::string, std::string> getRingtoneList();
-
-        std::string getAudioManager();
-        bool setAudioManager(const std::string& api);
-
-        int32_t isIax2Enabled();
-        std::string getRecordPath();
-        void setRecordPath(const std::string& recPath);
-        bool getIsAlwaysRecording();
-        void setIsAlwaysRecording(bool rec);
-
-        void setHistoryLimit(int32_t days);
-        int32_t getHistoryLimit();
-
-        void setAccountsOrder(const std::string& order);
-
-        std::map<std::string, std::string> getHookSettings();
-        void setHookSettings(const std::map<std::string, std::string>& settings);
-
-        std::map<std::string, std::string> getTlsSettings();
-        void setTlsSettings(const std::map< std::string, std::string >& details);
-        std::map< std::string, std::string > getIp2IpDetails();
-
-        std::vector< std::map< std::string, std::string > > getCredentials(const std::string& accountID);
-        void setCredentials(const std::string& accountID, const std::vector< std::map< std::string, std::string > >& details);
-
-        std::string getAddrFromInterfaceName(const std::string& interface);
-
-        std::vector<std::string> getAllIpInterface();
-        std::vector<std::string> getAllIpInterfaceByName();
-
-        std::map<std::string, std::string> getShortcuts();
-        void setShortcuts(const std::map<std::string, std::string> &shortcutsMap);
-
-        void setVolume(const std::string& device, double value);
-        double getVolume(const std::string& device);
-
-        /*
-         * Security
-         */
-        std::map<std::string, std::string> validateCertificate(const std::string& accountId,
-            const std::string& certificate, const std::string& privateKey);
-        std::map<std::string, std::string> getCertificateDetails(const std::string& certificate);
-
-
-    // Signals
-    public:
-        void volumeChanged(const std::string& device, double value);
-
-        void accountsChanged();
-
-        void stunStatusFailure(const std::string& accoundID);
-
-        void registrationStateChanged(const std::string& accoundID, int state);
-        void sipRegistrationStateChanged(const std::string&, const std::string&, int32_t state);
-        void volatileAccountDetailsChanged(const std::string& accountID, const std::map<std::string, std::string> &details);
-        void errorAlert(int alert);
-
-        std::vector< int32_t > getHardwareAudioFormat();
-
-    private:
-#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
-        // Event handlers; needed by the library API
-        ring_config_ev_handlers evHandlers_{};
-#pragma GCC diagnostic warning "-Wmissing-field-initializers"
-};
-
-} // namespace ring
-
-#endif //CONFIGURATIONMANAGER_H
diff --git a/daemon/src/dring/dring.h b/daemon/src/dring/dring.h
index e15d02809efe8a599e0151e280154282edd86765..818fa0183425265d2834705d678db00d80628695 100644
--- a/daemon/src/dring/dring.h
+++ b/daemon/src/dring/dring.h
@@ -160,124 +160,6 @@ void fini(void) noexcept;
  */
 void poll_events(void);
 
-/* call API */
-bool ring_call_place(const std::string& account_id, const std::string& call_id, const std::string& to);
-bool ring_call_refuse(const std::string& call_id);
-bool ring_call_accept(const std::string& call_id);
-bool ring_call_hang_up(const std::string& call_id);
-bool ring_call_hold(const std::string& call_id);
-bool ring_call_unhold(const std::string& call_id);
-bool ring_call_transfer(const std::string& call_id, const std::string& to);
-bool ring_call_attended_transfer(const std::string& transfer_id, const std::string& target_id);
-std::map<std::string, std::string> ring_call_get_call_details(const std::string& call_id);
-std::vector<std::string> ring_call_get_call_list(void);
-void ring_call_remove_conference(const std::string& conf_id);
-bool ring_call_join_participant(const std::string& sel_call_id, const std::string& drag_call_id);
-void ring_call_create_conf_from_participant_list(const std::vector<std::string>& participants);
-bool ring_call_is_conference_participant(const std::string& call_id);
-bool ring_call_add_participant(const std::string& call_id, const std::string& conf_id);
-bool ring_call_add_main_participant(const std::string& conf_id);
-bool ring_call_detach_participant(const std::string& call_id);
-bool ring_call_join_conference(const std::string& sel_conf_id, const std::string& drag_conf_id);
-bool ring_call_hang_up_conference(const std::string& conf_id);
-bool ring_call_hold_conference(const std::string& conf_id);
-bool ring_call_unhold_conference(const std::string& conf_id);
-std::vector<std::string> ring_call_get_conference_list(void);
-std::vector<std::string> ring_call_get_participant_list(const std::string& conf_id);
-std::vector<std::string> ring_call_get_display_names(const std::string& conf_id);
-std::string ring_call_get_conference_id(const std::string& call_id);
-std::map<std::string, std::string> ring_call_get_conference_details(const std::string& call_id);
-bool ring_call_play_recorded_file(const std::string& path);
-void ring_call_stop_recorded_file(const std::string& path);
-bool ring_call_toggle_recording(const std::string& call_id);
-void ring_call_set_recording(const std::string& call_id);
-void ring_call_record_playback_seek(double pos);
-bool ring_call_is_recording(const std::string& call_id);
-std::string ring_call_get_current_audio_codec_name(const std::string& call_id);
-void ring_call_play_dtmf(const std::string& key);
-void ring_call_start_tone(int start, int type);
-void ring_call_set_sas_verified(const std::string& call_id);
-void ring_call_reset_sas_verified(const std::string& call_id);
-void ring_call_set_confirm_go_clear(const std::string& call_id);
-void ring_call_request_go_clear(const std::string& call_id);
-void ring_call_accept_enrollment(const std::string& call_id, bool accepted);
-void ring_call_send_text_message(const std::string& call_id, const std::string& message);
-
-/* configuration API */
-std::map<std::string, std::string> ring_config_get_account_details(const std::string& account_id);
-std::map<std::string, std::string> ring_config_get_volatile_account_details(const std::string& account_id);
-void ring_config_set_account_details(const std::string& account_id, const std::map<std::string, std::string>& details);
-std::map<std::string, std::string> ring_config_get_account_template(void);
-std::string ring_config_add_account(const std::map<std::string, std::string>& details);
-void ring_config_remove_account(const std::string& account_id);
-std::vector<std::string> ring_config_get_account_list(void);
-void ring_config_send_register(const std::string& account_id, bool enable);
-void ring_config_register_all_accounts(void);
-std::map<std::string, std::string> ring_config_get_tls_default_settings(void);
-std::vector<int> ring_config_get_audio_codec_list(void);
-std::vector<std::string> ring_config_get_supported_tls_method(void);
-std::vector<std::string> ring_config_get_supported_ciphers(const std::string& account_id);
-std::vector<std::string> ring_config_get_audio_codec_details(int payload);
-std::vector<int> ring_config_get_active_audio_codec_list(const std::string& account_id);
-void ring_config_set_active_audio_codec_list(const std::vector<std::string>& list, const std::string& account_id);
-std::vector<std::string> ring_config_get_audio_plugin_list(void);
-void ring_config_set_audio_plugin(const std::string& audio_plugin);
-std::vector<std::string> ring_config_get_audio_output_device_list();
-void ring_config_set_audio_output_device(int index);
-void ring_config_set_audio_input_device(int index);
-void ring_config_set_audio_ringtone_device(int index);
-std::vector<std::string> ring_config_get_audio_input_device_list(void);
-std::vector<std::string> ring_config_get_current_audio_devices_index(void);
-int ring_config_get_audio_input_device_index(const std::string& name);
-int ring_config_get_audio_output_device_index(const std::string& name);
-std::string ring_config_get_current_audio_output_plugin(void);
-bool ring_config_get_noise_suppress_state(void);
-void ring_config_set_noise_suppress_state(bool state);
-bool ring_config_is_agc_enabled(void);
-void ring_config_enable_agc(bool enabled);
-void ring_config_mute_dtmf(bool mute);
-bool ring_config_is_dtmf_muted(void);
-bool ring_config_is_capture_muted(void);
-void ring_config_mute_capture(bool mute);
-bool ring_config_is_playback_muted(void);
-void ring_config_mute_playback(int mute);
-std::map<std::string, std::string> ring_config_get_ringtone_list(void);
-std::string ring_config_get_audio_manager(void);
-bool ring_config_set_audio_manager(const std::string& api);
-std::vector<std::string> ring_config_get_supported_audio_managers(void);
-int ring_config_is_iax2_enabled(void);
-std::string ring_config_get_record_path(void);
-void ring_config_set_record_path(const std::string& path);
-bool ring_config_is_always_recording(void);
-void ring_config_set_always_recording(bool rec);
-void ring_config_set_history_limit(int days);
-int ring_config_get_history_limit(void);
-void ring_config_set_accounts_order(const std::string& order);
-std::map<std::string, std::string> ring_config_get_hook_settings(void);
-void ring_config_set_hook_settings(const std::map<std::string, std::string>& settings);
-std::map<std::string, std::string> ring_config_get_tls_settings();
-std::map<std::string, std::string> ring_config_validate_certificate(const std::string& accountId,
-    const std::string& certificate, const std::string& private_key);
-std::map<std::string, std::string> ring_config_get_certificate_details(const std::string& certificate);
-void ring_config_set_tls_settings(const std::map< std::string, std::string >& settings);
-std::map<std::string, std::string> ring_config_get_ip2ip_details(void);
-std::vector<std::map<std::string, std::string>> ring_config_get_credentials(const std::string& account_id);
-void ring_config_set_credentials(const std::string& account_id, const std::vector<std::map<std::string, std::string>>& details);
-std::string ring_config_get_addr_from_interface_name(const std::string& interface);
-std::vector<std::string> ring_config_get_all_ip_interface(void);
-std::vector<std::string> ring_config_get_all_ip_interface_by_name(void);
-std::map<std::string, std::string> ring_config_get_shortcuts();
-void ring_config_set_shortcuts(const std::map<std::string, std::string>& shortcuts);
-void ring_config_set_volume(const std::string& device, double value);
-double ring_config_get_volume(const std::string& device);
-
-/* presence API */
-void ring_pres_publish(const std::string& account_id, int status, const std::string& note);
-void ring_pres_answer_server_request(const std::string& uri, int flag);
-void ring_pres_subscribe_buddy(const std::string& account_id, const std::string& uri, int flag);
-std::vector<std::map<std::string, std::string>> ring_pres_get_subscriptions(const std::string& account_id);
-void ring_pres_set_subscriptions(const std::string& account_id, const std::vector<std::string>& uris);
-
 } // namespace DRing
 
 #endif /* DRING_H */
diff --git a/daemon/src/history/Makefile.am b/daemon/src/history/Makefile.am
new file mode 100644
index 0000000000000000000000000000000000000000..4a405ae6307527070fa1dc1ee29aefacf605b7c8
--- /dev/null
+++ b/daemon/src/history/Makefile.am
@@ -0,0 +1,9 @@
+include ../../globals.mak
+
+noinst_LTLIBRARIES = libhistory.la
+
+libhistory_la_SOURCES =   \
+    historyitem.h         \
+    historyitem.cpp       \
+    history.h             \
+    history.cpp
diff --git a/daemon/src/history/history.cpp b/daemon/src/history/history.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..48a6ce25e8db9dd62e3333ef9e0f8450cde77d17
--- /dev/null
+++ b/daemon/src/history/history.cpp
@@ -0,0 +1,172 @@
+/*
+ *  Copyright (C) 2004-2015 Savoir-Faire Linux Inc.
+ *
+ *  Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
+ *  Author: Alexandre Savard <alexandre.savard@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
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ *
+ *  Additional permission under GNU GPL version 3 section 7:
+ *
+ *  If you modify this program, or any covered work, by linking or
+ *  combining it with the OpenSSL project's OpenSSL library (or a
+ *  modified version of that library), containing parts covered by the
+ *  terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
+ *  grants you additional permission to convey the resulting work.
+ *  Corresponding Source for a non-source form of such a combination
+ *  shall include the source code for the parts of OpenSSL used as well
+ *  as that of the covered work.
+ */
+
+#include "history.h"
+#include <cerrno>
+#include <algorithm>
+#include <fstream>
+#include <sys/stat.h> // for mkdir
+#include <ctime>
+#include <cstring>
+#include "fileutils.h"
+#include "logger.h"
+#include "call.h"
+
+namespace ring {
+
+History::History() : historyItemsMutex_(), items_(), path_() {}
+
+
+using std::map;
+using std::string;
+using std::vector;
+
+bool History::load(int limit)
+{
+    // load only once
+    if (!items_.empty())
+        return true;
+
+    ensurePath();
+    std::ifstream infile(path_.c_str());
+    if (!infile) {
+        RING_DBG("No history file to load");
+        return false;
+    }
+
+    while (!infile.eof()) {
+        HistoryItem item(infile);
+        addEntry(item, limit);
+    }
+
+    return true;
+}
+
+bool History::save()
+{
+    std::lock_guard<std::mutex> lock(historyItemsMutex_);
+    RING_DBG("Saving history in XDG directory: %s", path_.c_str());
+    ensurePath();
+    std::sort(items_.begin(), items_.end());
+    std::ofstream outfile(path_.c_str());
+    if (outfile.fail())
+        return false;
+    for (const auto &item : items_)
+        outfile << item << std::endl;
+    return true;
+}
+
+void History::addEntry(const HistoryItem &item, int oldest)
+{
+    std::lock_guard<std::mutex> lock(historyItemsMutex_);
+    if (item.hasPeerNumber() and item.youngerThan(oldest)) {
+        items_.push_back(item);
+        auto im = item.toMap();
+        string name(im["display_name"]);
+        string account(im["accountid"]);
+        string number(im["peer_number"]);
+        if (nameCache_[account][number].empty() and not name.empty() and not number.empty())
+            nameCache_[account][number] = name;
+    }
+}
+
+void History::ensurePath()
+{
+    if (path_.empty()) {
+        const string userdata = fileutils::get_data_dir();
+        if (!fileutils::check_dir(userdata.c_str())) {
+            RING_DBG("Cannot create directory: %s", userdata.c_str());
+            return;
+        }
+        path_ = userdata + DIR_SEPARATOR_STR + "history";
+    }
+}
+
+vector<map<string, string> > History::getSerialized()
+{
+    std::lock_guard<std::mutex> lock(historyItemsMutex_);
+    vector<map<string, string> > result;
+    for (const auto &item : items_)
+        result.push_back(item.toMap());
+
+    return result;
+}
+
+void History::setPath(const std::string &path)
+{
+    path_ = path;
+}
+
+void History::addCall(Call *call, int limit)
+{
+    if (!call) {
+        RING_ERR("Call is NULL, ignoring");
+        return;
+    }
+    call->time_stop();
+    HistoryItem item(call->createHistoryEntry());
+    addEntry(item, limit);
+}
+
+void History::clear()
+{
+    std::lock_guard<std::mutex> lock(historyItemsMutex_);
+    items_.clear();
+}
+
+bool History::empty()
+{
+    std::lock_guard<std::mutex> lock(historyItemsMutex_);
+    return items_.empty();
+}
+
+
+size_t History::numberOfItems()
+{
+    std::lock_guard<std::mutex> lock(historyItemsMutex_);
+    return items_.size();
+}
+
+std::string
+History::getNameFromHistory(const std::string &number,
+                            const std::string &accountid) const {
+    const auto& it1 = nameCache_.find(accountid);
+    if (it1 == nameCache_.cend())
+        return "";
+    const auto& map = it1->second;
+    const auto& it2 = map.find(number);
+    if (it2 == map.cend())
+        return "";
+    return it2->second;
+}
+
+} // namespace ring
diff --git a/daemon/src/history/history.h b/daemon/src/history/history.h
new file mode 100644
index 0000000000000000000000000000000000000000..6e4c2acab70fc5e54f0209576776e1bd55d05cce
--- /dev/null
+++ b/daemon/src/history/history.h
@@ -0,0 +1,106 @@
+/*
+ *  Copyright (C) 2004-2015 Savoir-Faire Linux Inc.
+ *
+ *  Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
+ *  Author: Alexandre Savard <alexandre.savard@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
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ *
+ *  Additional permission under GNU GPL version 3 section 7:
+ *
+ *  If you modify this program, or any covered work, by linking or
+ *  combining it with the OpenSSL project's OpenSSL library (or a
+ *  modified version of that library), containing parts covered by the
+ *  terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
+ *  grants you additional permission to convey the resulting work.
+ *  Corresponding Source for a non-source form of such a combination
+ *  shall include the source code for the parts of OpenSSL used as well
+ *  as that of the covered work.
+ */
+
+#ifndef HISTORY_
+#define HISTORY_
+
+#include "historyitem.h"
+#include <mutex>
+#include <vector>
+
+namespace ring {
+
+namespace test {
+class HistoryTest;
+}
+
+class Call;
+
+class History {
+
+    public:
+        History();
+        /** Load history from file */
+        bool load(int limit);
+
+        /**
+         *@return True if the history has been successfully saved in the file
+         */
+        bool save();
+
+        /*
+         *@return The number of items found in the history file
+         */
+        size_t numberOfItems();
+
+        bool empty();
+
+        std::vector<std::map<std::string, std::string> > getSerialized();
+
+        void addCall(Call *call, int limit);
+        void clear();
+        void setPath(const std::string &path);
+
+        std::string getNameFromHistory(const std::string &number,
+                                       const std::string &accountid) const;
+
+    private:
+        /* Mutex to protect the history items */
+        std::mutex historyItemsMutex_;
+
+        /* If no path has been set, this will initialize path to a
+         * system-dependent location */
+        void ensurePath();
+        /*
+         * Add a new history item in the data structure
+         */
+        void addEntry(const HistoryItem &new_item, int limit);
+
+        /*
+         * Vector containing the history items
+         */
+        std::vector<HistoryItem> items_;
+
+        /*
+         * Reverse mapping of display name for given account id and peer number.
+         */
+        std::map<std::string, std::map<std::string, std::string>> nameCache_ {};
+
+        /* The path to the history file */
+        std::string path_;
+
+        friend class test::HistoryTest;
+};
+
+}
+
+#endif // HISTORY_
diff --git a/daemon/src/history/historyitem.cpp b/daemon/src/history/historyitem.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2bbc702df5fa8cf543de04badb22f3a689d1a9d7
--- /dev/null
+++ b/daemon/src/history/historyitem.cpp
@@ -0,0 +1,124 @@
+/*
+ *  Copyright (C) 2004-2015 Savoir-Faire Linux Inc.
+ *
+ *  Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
+ *  Author: Alexandre Savard <alexandre.savard@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
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ *
+ *  Additional permission under GNU GPL version 3 section 7:
+ *
+ *  If you modify this program, or any covered work, by linking or
+ *  combining it with the OpenSSL project's OpenSSL library (or a
+ *  modified version of that library), containing parts covered by the
+ *  terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
+ *  grants you additional permission to convey the resulting work.
+ *  Corresponding Source for a non-source form of such a combination
+ *  shall include the source code for the parts of OpenSSL used as well
+ *  as that of the covered work.
+ */
+
+#include "historyitem.h"
+#include <unistd.h>
+#include <cstdlib>
+#include <istream>
+
+namespace ring {
+
+const char * const HistoryItem::ACCOUNT_ID_KEY =        "accountid";
+const char * const HistoryItem::CALLID_KEY =            "callid";
+const char * const HistoryItem::CONFID_KEY =            "confid";
+const char * const HistoryItem::DISPLAY_NAME_KEY =      "display_name";
+const char * const HistoryItem::PEER_NUMBER_KEY =       "peer_number";
+const char * const HistoryItem::RECORDING_PATH_KEY =    "recordfile";
+// FIXME: Deprecated
+const char * const HistoryItem::STATE_KEY =             "state";
+// New version:
+const char * const HistoryItem::MISSED_KEY =            "missed";
+const char * const HistoryItem::DIRECTION_KEY =         "direction";
+const char * const HistoryItem::TIMESTAMP_START_KEY =   "timestamp_start";
+const char * const HistoryItem::TIMESTAMP_STOP_KEY =    "timestamp_stop";
+const char * const HistoryItem::AUDIO_CODEC_KEY =       "audio_codec";
+const char * const HistoryItem::VIDEO_CODEC_KEY =       "video_codec";
+
+const char * const HistoryItem::MISSED_STRING =         "missed";
+const char * const HistoryItem::INCOMING_STRING =       "incoming";
+const char * const HistoryItem::OUTGOING_STRING =       "outgoing";
+
+using std::map;
+using std::string;
+
+static bool
+file_exists(const std::string &str)
+{
+    return access(str.c_str(), F_OK) != -1;
+}
+
+HistoryItem::HistoryItem(const map<string, string> &args) : entryMap_(args),
+    timestampStart_(std::atol(entryMap_[TIMESTAMP_START_KEY].c_str()))
+{}
+
+HistoryItem::HistoryItem(std::istream &entry) : entryMap_(), timestampStart_(0)
+{
+    string tmp;
+    while (std::getline(entry, tmp, '\n')) {
+        size_t pos = tmp.find('=');
+        if (pos == string::npos)
+            break;
+        else if (pos < tmp.length() - 1) {
+            string key(tmp.substr(0, pos));
+            string val(tmp.substr(pos + 1, tmp.length() - pos - 1));
+            if (key == RECORDING_PATH_KEY and not file_exists(val))
+                val = "";
+            entryMap_[key] = val;
+        }
+    }
+    timestampStart_ = std::atol(entryMap_[TIMESTAMP_START_KEY].c_str());
+}
+
+map<string, string> HistoryItem::toMap() const
+{
+    return entryMap_;
+}
+
+bool HistoryItem::youngerThan(unsigned long otherTime) const
+{
+    return timestampStart_ > otherTime;
+}
+
+bool HistoryItem::hasPeerNumber() const
+{
+    return entryMap_.find(PEER_NUMBER_KEY) != entryMap_.end();
+}
+
+void HistoryItem::print(std::ostream &o) const
+{
+    // every entry starts with "[" + random integer = "]"
+    for (const auto &item : entryMap_) {
+        // if the file does not exist anymore, we do not save it
+        if (item.first == RECORDING_PATH_KEY and not file_exists(item.second))
+            o << item.first << "=" << "" << std::endl;
+        else
+            o << item.first << "=" << item.second << std::endl;
+    }
+}
+
+std::ostream& operator << (std::ostream& o, const HistoryItem& item)
+{
+    item.print(o);
+    return o;
+}
+
+} // namespace ring
diff --git a/daemon/src/history/historyitem.h b/daemon/src/history/historyitem.h
new file mode 100644
index 0000000000000000000000000000000000000000..a5cc81c4c1a06e627e331dfdfaac952f7f993697
--- /dev/null
+++ b/daemon/src/history/historyitem.h
@@ -0,0 +1,86 @@
+/*
+ *  Copyright (C) 2004-2015 Savoir-Faire Linux Inc.
+ *
+ *  Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
+ *  Author: Alexamdre Savard <alexandre.savard@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
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ *
+ *  Additional permission under GNU GPL version 3 section 7:
+ *
+ *  If you modify this program, or any covered work, by linking or
+ *  combining it with the OpenSSL project's OpenSSL library (or a
+ *  modified version of that library), containing parts covered by the
+ *  terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
+ *  grants you additional permission to convey the resulting work.
+ *  Corresponding Source for a non-source form of such a combination
+ *  shall include the source code for the parts of OpenSSL used as well
+ *  as that of the covered work.
+ */
+
+#ifndef HISTORY_ITEM_H_
+#define HISTORY_ITEM_H_
+
+#include <string>
+#include <map>
+
+namespace ring {
+
+class HistoryItem {
+    public:
+        static const char * const ACCOUNT_ID_KEY;
+        static const char * const CONFID_KEY;
+        static const char * const CALLID_KEY;
+        static const char * const DISPLAY_NAME_KEY;
+        static const char * const PEER_NUMBER_KEY;
+        static const char * const RECORDING_PATH_KEY;
+        static const char * const TIMESTAMP_START_KEY;
+        static const char * const TIMESTAMP_STOP_KEY;
+        static const char * const AUDIO_CODEC_KEY;
+        static const char * const VIDEO_CODEC_KEY;
+        static const char * const STATE_KEY;
+        static const char * const MISSED_KEY;
+        static const char * const DIRECTION_KEY;
+
+        static const char * const MISSED_STRING;
+        static const char * const INCOMING_STRING;
+        static const char * const OUTGOING_STRING;
+        HistoryItem(const std::map<std::string, std::string> &args);
+        HistoryItem(std::istream &stream);
+
+        bool hasPeerNumber() const;
+
+        bool youngerThan(unsigned long otherTime) const;
+
+        std::map<std::string, std::string> toMap() const;
+        void print(std::ostream &o) const;
+        bool operator< (const HistoryItem &other) const {
+            return timestampStart_ > other.timestampStart_;
+        }
+
+        bool operator> (const HistoryItem &other) const {
+            return not (*this < other);
+        }
+
+    private:
+        std::map<std::string, std::string> entryMap_;
+        unsigned long timestampStart_; // cached as we use this a lot, avoids string ops
+};
+
+std::ostream& operator << (std::ostream& o, const HistoryItem& item);
+
+} // namespace ring
+
+#endif // HISTORY_ITEM
diff --git a/daemon/src/managerimpl.cpp b/daemon/src/managerimpl.cpp
index c42b89b1399a768ced2f4ca7a9af7bbed31da54e..790718c3ecf8061da2b55258ade850cc5d7c5900 100644
--- a/daemon/src/managerimpl.cpp
+++ b/daemon/src/managerimpl.cpp
@@ -68,6 +68,7 @@
 #include "audio/sound/audiofile.h"
 #include "audio/sound/dtmf.h"
 #include "audio/ringbufferpool.h"
+#include "history/history.h"
 #include "manager.h"
 
 #ifdef RING_VIDEO
@@ -161,7 +162,7 @@ ManagerImpl::ManagerImpl() :
     toneMutex_(), telephoneTone_(), audiofile_(), audioLayerMutex_(),
     waitingCalls_(), waitingCallsMutex_(), path_()
     , ringbufferpool_(new RingBufferPool)
-    , callFactory(), conferenceMap_()
+    , callFactory(), conferenceMap_(), history_()
     , accountFactory_(), ice_tf_()
 {
     // initialize random generator
@@ -268,13 +269,15 @@ ManagerImpl::init(const std::string &config_file)
         }
     }
 
+    history_.load(preferences.getHistoryLimit());
+
     registerAccounts();
 }
 
 void
-ManagerImpl::setPath(const std::string&)
+ManagerImpl::setPath(const std::string &path)
 {
-    // FIME: needed?
+    history_.setPath(path);
 }
 
 void
@@ -294,7 +297,9 @@ ManagerImpl::finish() noexcept
             hangupCall(call->getCallId());
         callFactory.clear();
 
+        // Save accounts config and call's history
         saveConfig();
+        saveHistory();
 
         // Disconnect accounts, close link stacks and free allocated ressources
         unregisterAccounts();
@@ -403,20 +408,14 @@ ManagerImpl::outgoingCall(const std::string& preferred_account_id,
             detachParticipant(RingBufferPool::DEFAULT_ID);
     }
 
-    try {
-        /* RING_WARN: after this call the account_id is obsolete
-         * as the factory may decide to use another account (like IP2IP).
-         */
-        RING_DBG("New outgoing call to %s", to_cleaned.c_str());
-        call = newOutgoingCall(to_cleaned, preferred_account_id);
-    } catch (const std::exception &e) {
-        RING_ERR("%s", e.what());
-        return {};
+    // try to reverse match the peer name using the cache
+    if (call->getDisplayName().empty()) {
+        const auto& name = history_.getNameFromHistory(call->getPeerNumber(),
+                                                       call->getAccountId());
+        const std::string pseudo_contact_name(name);
+        if (not pseudo_contact_name.empty())
+            call->setDisplayName(pseudo_contact_name);
     }
-
-    if (not call)
-        return {};
-
     switchCall(call);
     call->setConfId(conf_id);
 
@@ -527,8 +526,10 @@ ManagerImpl::hangupCall(const std::string& callId)
     }
 
     try {
+        history_.addCall(call.get(), preferences.getHistoryLimit());
         call->hangup(0);
         checkAudio();
+        saveHistory();
     } catch (const VoipLinkException &e) {
         RING_ERR("%s", e.what());
         return false;
@@ -1673,7 +1674,9 @@ ManagerImpl::peerHungupCall(Call& call)
         unsetCurrentCall();
     }
 
+    history_.addCall(&call, preferences.getHistoryLimit());
     call.peerHungup();
+    saveHistory();
 
     emitSignal<DRing::CallSignal::StateChange>(call_id, "HUNGUP");
 
@@ -2609,6 +2612,12 @@ ManagerImpl::getCallDetails(const std::string &callID)
     }
 }
 
+std::vector<std::map<std::string, std::string> >
+ManagerImpl::getHistory()
+{
+    return history_.getSerialized();
+}
+
 std::vector<std::string>
 ManagerImpl::getCallList() const
 {
@@ -2678,6 +2687,21 @@ ManagerImpl::getConferenceId(const std::string& callID)
     return "";
 }
 
+void
+ManagerImpl::saveHistory()
+{
+    if (!history_.save())
+        RING_ERR("Could not save history!");
+    else
+        emitSignal<DRing::ConfigurationSignal::AccountsChanged>();
+}
+
+void
+ManagerImpl::clearHistory()
+{
+    history_.clear();
+}
+
 void
 ManagerImpl::startAudioDriverStream()
 {
diff --git a/daemon/src/managerimpl.h b/daemon/src/managerimpl.h
index 572af9ebca812799824e3b0ddc25859b39f6a48d..6ca8eb607f7cbd2127e33fb875402bd7cab6fa24 100644
--- a/daemon/src/managerimpl.h
+++ b/daemon/src/managerimpl.h
@@ -58,6 +58,7 @@
 #include "audio/sound/tone.h"  // for Tone::TONEID declaration
 
 #include "preferences.h"
+#include "history/history.h"
 #include "noncopyable.h"
 
 namespace ring {
@@ -864,6 +865,9 @@ class ManagerImpl {
          */
         bool hasCurrentCall() const;
 
+        std::vector<std::map<std::string, std::string> > getHistory();
+        void clearHistory();
+
         /**
          * Get an account pointer, looks for both SIP and IAX
          * @param accountID account ID to get
@@ -898,6 +902,8 @@ class ManagerImpl {
          */
         void registerAccounts();
 
+        void saveHistory();
+
         /**
          * Suspends Ring's audio processing if no calls remain, allowing
          * other applications to resume audio.
@@ -964,6 +970,11 @@ class ManagerImpl {
         // Map containing conference pointers
         ConferenceMap conferenceMap_;
 
+        /**
+         * To handle the persistent history
+         * TODO: move this to ConfigurationManager
+         */
+        History history_;
         std::atomic_bool finished_ {false};
 
         AccountFactory accountFactory_;
diff --git a/daemon/src/sip/sipcall.cpp b/daemon/src/sip/sipcall.cpp
index 1de9ce876cfc921ad80a86c2f85a1309ec111619..2e06135ccc580772239cdd005682bdd1162a167a 100644
--- a/daemon/src/sip/sipcall.cpp
+++ b/daemon/src/sip/sipcall.cpp
@@ -183,6 +183,13 @@ void SIPCall::setContactHeader(pj_str_t *contact)
     pj_strcpy(&contactHeader_, contact);
 }
 
+std::map<std::string, std::string>
+SIPCall::createHistoryEntry() const
+{
+    std::map<std::string, std::string> entry(Call::createHistoryEntry());
+    return entry;
+}
+
 /**
  * Send a reINVITE inside an active dialog to modify its state
  * Local SDP session should be modified before calling this method
diff --git a/daemon/src/sip/sipcall.h b/daemon/src/sip/sipcall.h
index a3499dd243ec06e12bc194b8801631e5d00425d3..c9278e6135c2a8a95cb5ad5c6fe9b0db3a155ff1 100644
--- a/daemon/src/sip/sipcall.h
+++ b/daemon/src/sip/sipcall.h
@@ -196,6 +196,10 @@ class SIPCall : public Call
     private:
         NON_COPYABLE(SIPCall);
 
+        // override of Call::createHistoryEntry
+        std::map<std::string, std::string>
+        createHistoryEntry() const;
+
         void stopAllMedia();
 
         /**