diff --git a/CMakeLists.txt b/CMakeLists.txt
index cd1ad493b089048f6ea3e6dd527a445bbe084b34..ea93c5502f4d8054bd99700084a3b45651b37dfa 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -534,7 +534,7 @@ ENDIF()
 
 if (ENABLE_SHARED)
     message(STATUS "Configuring as shared lib")
-    add_library(ringclient SHARED ${libringclient_LIB_SRCS} ${LIB_HEADER_MOC} )
+    add_library(ringclient SHARED ${libringclient_LIB_SRCS} ${libringclient_api_LIB_HDRS} ${LIB_HEADER_MOC} )
     target_link_libraries(ringclient Qt5::Core Qt5::Gui)
 endif()
 
@@ -780,4 +780,4 @@ ENDIF()
 
 IF (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
     SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /U_MBCS /DUNICODE")
-ENDIF()
\ No newline at end of file
+ENDIF()
diff --git a/src/api/account.h b/src/api/account.h
index 481d501c08641e0185aaef77973e08e7924dd4a5..bc4636f728e91347613e3a9237e21b995596caf6 100644
--- a/src/api/account.h
+++ b/src/api/account.h
@@ -213,7 +213,7 @@ struct ConfProperties_t {
 // Possible account export status
 enum class ExportOnRingStatus {
     SUCCESS = 0,
-    WRONG_PASSWORD = 1 ,
+    WRONG_PASSWORD = 1,
     NETWORK_ERROR = 2,
     INVALID
 };
@@ -256,7 +256,7 @@ struct Info
     std::unique_ptr<lrc::api::NewDeviceModel> deviceModel;
     std::unique_ptr<lrc::api::NewCodecModel> codecModel;
     std::unique_ptr<lrc::api::PeerDiscoveryModel> peerDiscoveryModel;
-    NewAccountModel* accountModel {nullptr};
+    NewAccountModel* accountModel{ nullptr };
 
     // daemon config
     QString                 id;
diff --git a/src/api/avmodel.h b/src/api/avmodel.h
index 8bce2730741422bf8302baa5f9d0d2937ad01255..e46c166d85a343e73968c1dddb71bdb8c1f6bc62 100644
--- a/src/api/avmodel.h
+++ b/src/api/avmodel.h
@@ -18,7 +18,7 @@
  ***************************************************************************/
 #pragma once
 
-// std
+ // std
 #include <memory>
 #include <string>
 #include <vector>
@@ -49,222 +49,215 @@ public:
      * Get if hardware decoding is enabled
      * @return hardware decoding enabled
      */
-    bool getDecodingAccelerated() const;
+    Q_INVOKABLE bool getDecodingAccelerated() const;
     /**
      * Enable/disable hardware decoding
      * @param if hardware decoding enabled
      */
-    void setDecodingAccelerated(bool accelerate);
-
+    Q_INVOKABLE void setDecodingAccelerated(bool accelerate);
     /**
      * Get if hardware encoding is enabled
      * @return hardware encoding enabled
      */
-    bool getEncodingAccelerated() const;
+    Q_INVOKABLE bool getEncodingAccelerated() const;
     /**
      * Enable/disable hardware encoding
      * @param if hardware encoding enabled
      */
-    void setEncodingAccelerated(bool accelerate);
-
+    Q_INVOKABLE void setEncodingAccelerated(bool accelerate);
     /**
      * Get if hardware acceleration is enabled
      * @return hardware acceleration enabled
      */
-    bool getHardwareAcceleration() const;
+    Q_INVOKABLE bool getHardwareAcceleration() const;
     /**
      * Enable/disable hardware acceleration
      * @param if hardware acceleration enabled
      */
-    void setHardwareAcceleration(bool accelerate);
-
+    Q_INVOKABLE void setHardwareAcceleration(bool accelerate);
     /**
      * Get video devices
      * @return list of devices
      */
-    VectorString getDevices() const;
+    Q_INVOKABLE QVector<QString> getDevices() const;
     /**
      * Retrieve current default video device
      * @return current default video device id
      */
-    QString getDefaultDevice() const;
+    Q_INVOKABLE QString getDefaultDevice() const;
     /**
      * Set new default video device
      * @param id of the device
      */
-    void setDefaultDevice(const QString& deviceId);
+    Q_INVOKABLE void setDefaultDevice(const QString& deviceId);
     /**
      * Retrieve current framerate/resolution/etc of a device
      * @param id of the device
      * @return settings of the device
      */
-    video::Settings getDeviceSettings(const QString& deviceId) const;
+    Q_INVOKABLE video::Settings getDeviceSettings(const QString& deviceId) const;
     /**
      * Set device settings
      * @param video::Settings
      */
-    void setDeviceSettings(video::Settings& settings);
+    Q_INVOKABLE void setDeviceSettings(video::Settings& settings);
     /**
      * Retrieve all framerate/resolution/etc possibilities of a device
      * @param id of the device
      * @return possibilities of the device
      */
-    video::Capabilities getDeviceCapabilities(const QString& deviceId) const;
+    Q_INVOKABLE video::Capabilities getDeviceCapabilities(const QString& deviceId) const;
     /**
      * Get the deviceId corresponding to a given device friendly name
      * @return deviceId
      */
-    QString getDeviceIdFromName(const QString& deviceName) const;
-
+    Q_INVOKABLE QString getDeviceIdFromName(const QString& deviceName) const;
     /**
      * Get supported audio managers
      * @return supported audio managers
      */
-    VectorString getSupportedAudioManagers() const;
+    Q_INVOKABLE VectorString getSupportedAudioManagers() const;
     /**
      * Get current audio manager
      * @return current audio manager
      */
-    QString getAudioManager() const;
+    Q_INVOKABLE QString getAudioManager() const;
     /**
      * Get current audio outputs
      * @return audio outputs
      */
-    VectorString getAudioOutputDevices() const;
+    Q_INVOKABLE QVector<QString> getAudioOutputDevices() const;
     /**
      * Get current audio inputs
      * @return audio inputs
      */
-    VectorString getAudioInputDevices() const;
+    Q_INVOKABLE QVector<QString> getAudioInputDevices() const;
     /**
      * Get current ringtone device
      * @return current ringtone device
      */
-    QString getRingtoneDevice() const;
+    Q_INVOKABLE QString getRingtoneDevice() const;
     /**
      * Get current output device
      * @return current output device
      */
-    QString getOutputDevice() const;
+    Q_INVOKABLE QString getOutputDevice() const;
     /**
      * Get current input device
      * @return current input device
      */
-    QString getInputDevice() const;
+    Q_INVOKABLE QString getInputDevice() const;
     /**
      * Get current state of the audio meter
      * @return current state of the audio meter
      */
-    bool isAudioMeterActive(const QString& id="") const;
+    Q_INVOKABLE bool isAudioMeterActive(const QString& id = "") const;
     /**
      * Turn on/off the audio metering feature
      * @param the new state of the meter
      */
-    void setAudioMeterState(bool active, const QString& id="") const;
+    Q_INVOKABLE void setAudioMeterState(bool active, const QString& id = "") const;
     /**
      * Starts audio device. Should only be invoked when outside of a call.
      */
-    void startAudioDevice() const;
+    Q_INVOKABLE void startAudioDevice() const;
     /**
      * Stops audio device. Should only be invoked when outside of a call.
      */
-    void stopAudioDevice() const;
+    Q_INVOKABLE void stopAudioDevice() const;
     /**
      * Set current audio manager
      * @param name of the new audio manager
      * @return if the operation is successful
      */
-    bool setAudioManager(const QString& name);
+    Q_INVOKABLE bool setAudioManager(const QString& name);
     /**
      * Set current ringtone device
      * @param name of the new ringtone device
      */
-    void setRingtoneDevice(const QString& name);
+    Q_INVOKABLE void setRingtoneDevice(const QString& name);
     /**
      * Set current output device
      * @param name of the new output device
      */
-    void setOutputDevice(const QString& name);
+    Q_INVOKABLE void setOutputDevice(const QString& name);
     /**
      * Set current input device
      * @param name of the new input device
      */
-    void setInputDevice(const QString& name);
-
+    Q_INVOKABLE void setInputDevice(const QString& name);
     /**
      * Stop local record at given path
      * @param path
      */
-    void stopLocalRecorder(const QString& path) const;
+    Q_INVOKABLE void stopLocalRecorder(const QString& path) const;
     /**
      * Start a local recorder and return it path.
      * @param audioOnly
      */
-    QString startLocalRecorder(const bool& audioOnly) const;
+    Q_INVOKABLE QString startLocalRecorder(const bool& audioOnly) const;
     /**
      * Get the current recording path
      * @return recording path
      */
-    QString getRecordPath() const;
+    Q_INVOKABLE QString getRecordPath() const;
     /**
      * Sets the recording path
      * @param path recording path
      */
-    void setRecordPath(const QString& path) const;
+    Q_INVOKABLE void setRecordPath(const QString& path) const;
     /**
      * Whether or not to record every call
      * @return always recording
      */
-    bool getAlwaysRecord() const;
+    Q_INVOKABLE bool getAlwaysRecord() const;
     /**
      * Sets whether or not to record every call
      * @param rec always recording
      */
-    void setAlwaysRecord(const bool& rec) const;
+    Q_INVOKABLE void setAlwaysRecord(const bool& rec) const;
     /**
      * Whether or not local video is recorded
      * @return recording preview
      */
-    bool getRecordPreview() const;
+    Q_INVOKABLE bool getRecordPreview() const;
     /**
      * Sets whether or not to record local video
      * @param rec recording preview
      */
-    void setRecordPreview(const bool& rec) const;
+    Q_INVOKABLE void setRecordPreview(const bool& rec) const;
     /**
      * Gets the quality used while recording
      * @return recording quality
      */
-    int getRecordQuality() const;
+    Q_INVOKABLE int getRecordQuality() const;
     /**
      * Sets the recording quality
      * @param quality recording quality
      */
-    void setRecordQuality(const int& quality) const;
-
+    Q_INVOKABLE void setRecordQuality(const int& quality) const;
     /**
      * Start preview renderer. This will start the camera
      */
-    void startPreview();
+    Q_INVOKABLE void startPreview();
     /**
      * Stop preview renderer and the camera.
      */
-    void stopPreview();
+    Q_INVOKABLE void stopPreview();
     /**
      * Get a renderer from a call
      * @param id the callid or "local"
      * @return the linked renderer
      * @throw std::out_of_range if not found
      */
-    const video::Renderer& getRenderer(const QString& id) const;
-
+    Q_INVOKABLE const video::Renderer& getRenderer(const QString& id) const;
     /**
      * Render a file to the call id specified
      * @param uri the path of the file
      * @param callId
      * @note callId can be omitted to switch the input of the local recorder
      */
-    void setInputFile(const QString& uri, const QString& callId = {});
+    Q_INVOKABLE void setInputFile(const QString& uri, const QString& callId = {});
     /**
      * Change the current device rendered for the call id specified
      * @param id of the camera
@@ -272,7 +265,7 @@ public:
      * @note renders a black frame if device not found or empty
      * @note callId can be omitted to switch the input of the local recorder
      */
-    void switchInputTo(const QString& id, const QString& callId = {});
+    Q_INVOKABLE void switchInputTo(const QString& id, const QString& callId = {});
     /**
      * Render the current display to the call id specified
      * @param idx of the display
@@ -283,35 +276,31 @@ public:
      * @param callId
      * @note callId can be omitted to switch the input of the local recorder
      */
-    void setDisplay(int idx, int x, int y, int w, int h, const QString& callId = {});
+    Q_INVOKABLE void setDisplay(int idx, int x, int y, int w, int h, const QString& callId = {});
     /**
      * Get informations on the rendered device
      * @param call_id linked call to the renderer
      * @return the device rendered
      */
-    video::RenderedDevice getCurrentRenderedDevice(const QString& call_id) const;
-
+    Q_INVOKABLE video::RenderedDevice getCurrentRenderedDevice(const QString& call_id) const;
     /**
      * set to true to receive AVFrames from render
      */
-    void useAVFrame(bool useAVFrame);
-
-     /**
-     * set current using device
-     * @ param device name
-     */
-    void setCurrentVideoCaptureDevice(QString &currentVideoCaptureDevice);
-
-     /**
-     * set current using device
-     * @ return current using device name
-     */
-    QString getCurrentVideoCaptureDevice() const;
-
-     /**
-     * clear current using device
-     */
-    void clearCurrentVideoCaptureDevice();
+    Q_INVOKABLE void useAVFrame(bool useAVFrame);
+    /**
+    * set current using device
+    * @ param device name
+    */
+    Q_INVOKABLE void setCurrentVideoCaptureDevice(const QString& currentVideoCaptureDevice);
+    /**
+    * set current using device
+    * @ return current using device name
+    */
+    Q_INVOKABLE QString getCurrentVideoCaptureDevice() const;
+    /**
+    * clear current using device
+    */
+    Q_INVOKABLE void clearCurrentVideoCaptureDevice();
 
 Q_SIGNALS:
     /**
@@ -348,6 +337,8 @@ Q_SIGNALS:
 private:
     std::unique_ptr<AVModelPimpl> pimpl_;
 };
-
 } // namespace api
 } // namespace lrc
+#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
+Q_DECLARE_METATYPE(lrc::api::AVModel*)
+#endif
diff --git a/src/api/behaviorcontroller.h b/src/api/behaviorcontroller.h
index 9b2195fa2b7b0f9677eea9e32e06854c95a6fa4d..c02ae90c7ae38da9b9c418bebcbd0e81464866f7 100644
--- a/src/api/behaviorcontroller.h
+++ b/src/api/behaviorcontroller.h
@@ -35,12 +35,12 @@ class Lrc;
 
 namespace conversation
 {
-    struct Info;
+struct Info;
 }
 
 namespace interaction
 {
-    struct Info;
+struct Info;
 }
 
 /**
@@ -87,17 +87,19 @@ Q_SIGNALS:
     /**
      * Emitted when the unread interaction is now read
      */
-     void newReadInteraction(const QString& accountId, const QString& conversation, uint64_t interactionId) const;
-     /**
-     * Emitted debugMessageReceived
-     */
-     void debugMessageReceived(const QString& message);
-     /**
-     * Emitted audioMeter
-     */
-     void audioMeter(const QString& id, float level);
+    void newReadInteraction(const QString& accountId, const QString& conversation, uint64_t interactionId) const;
+    /**
+    * Emitted debugMessageReceived
+    */
+    void debugMessageReceived(const QString& message);
+    /**
+    * Emitted audioMeter
+    */
+    void audioMeter(const QString& id, float level);
 
 };
-
 } // namespace api
 } // namespace lrc
+#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
+Q_DECLARE_METATYPE(lrc::api::BehaviorController*)
+#endif
diff --git a/src/api/contactmodel.h b/src/api/contactmodel.h
index ef0134fe82574513c6fde0b57a7ba2d20ec3c8c3..6f54378301845beaf1856a0cced686ba35a9189b 100644
--- a/src/api/contactmodel.h
+++ b/src/api/contactmodel.h
@@ -52,9 +52,9 @@ public:
     const account::Info& owner;
 
     ContactModel(const account::Info& owner,
-                 Database& db,
-                 const CallbacksHandler& callbacksHandler,
-                 const BehaviorController& behaviorController);
+        Database& db,
+        const CallbacksHandler& callbacksHandler,
+        const BehaviorController& behaviorController);
     ~ContactModel();
 
     /**
@@ -67,7 +67,7 @@ public:
      * @param contactUri
      * @param banned
      */
-    void removeContact(const QString& contactUri, bool banned=false);
+    void removeContact(const QString& contactUri, bool banned = false);
     /**
      * get contact information.
      * @param  contactUri
@@ -79,7 +79,7 @@ public:
      * get list of banned contacts.
      * @return list of banned contacts uris as string
      */
-    const QList<QString>& getBannedContacts() const;
+    Q_INVOKABLE const QList<QString>& getBannedContacts() const;
     /**
      * @return all contacts for this account.
      */
@@ -109,7 +109,7 @@ Q_SIGNALS:
     /**
      * Connect this signal to know when this model was updated.
      */
-    void modelUpdated(const QString& uri, bool needsSorted=true) const;
+    void modelUpdated(const QString& uri, bool needsSorted = true) const;
     /**
      * Connect this signal to know when a contact was added.
      * @param contactUri
@@ -139,9 +139,9 @@ Q_SIGNALS:
      * @param payloads content of the message
      */
     void newAccountMessage(const QString& accountId,
-                           const QString& msgId,
-                           const QString& from,
-                           const MapStringString& payloads) const;
+        const QString& msgId,
+        const QString& from,
+        const MapStringString& payloads) const;
     /**
      * Connect this signal to know when a file transfer interaction is incoming
      * @param dringId Daemon's ID for incoming transfer
@@ -158,6 +158,8 @@ Q_SIGNALS:
 private:
     std::unique_ptr<ContactModelPimpl> pimpl_;
 };
-
 } // namespace api
 } // namespace lrc
+#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
+Q_DECLARE_METATYPE(lrc::api::ContactModel*)
+#endif
diff --git a/src/api/conversationmodel.h b/src/api/conversationmodel.h
index 6aee13f819e52e720dd10d07a689459ecd927c52..0b36314a3f05d5fa8081770a6206429300f4ce0d 100644
--- a/src/api/conversationmodel.h
+++ b/src/api/conversationmodel.h
@@ -85,164 +85,164 @@ public:
     const account::Info& owner;
 
     ConversationModel(const account::Info& owner,
-                      Lrc& lrc,
-                      Database& db,
-                      const CallbacksHandler& callbacksHandler,
-                      const api::BehaviorController& behaviorController);
+        Lrc& lrc,
+        Database& db,
+        const CallbacksHandler& callbacksHandler,
+        const api::BehaviorController& behaviorController);
     ~ConversationModel();
 
     /**
      * Get conversations which should be shown client side
      * @return conversations filtered with the current filter
      */
-    const ConversationQueue& allFilteredConversations() const;
-
+    Q_INVOKABLE const ConversationQueue& allFilteredConversations() const;
     /**
      * Get conversation for a given identifier
      * @param  conversation id
      * @return conversations with given id
      */
-    conversation::Info getConversationForUID(const QString& uid) const;
-
+    Q_INVOKABLE conversation::Info getConversationForUID(const QString& uid) const;
     /**
      * Get conversations that could be added to conference
      * @param  current conversation id
      * @param  search name filter
      * @return filtered conversations
      */
-    QMap<ConferenceableItem, ConferenceableValue> getConferenceableConversations(const QString& convId, const QString& filter = {}) const;
+    Q_INVOKABLE QMap<ConferenceableItem, ConferenceableValue> getConferenceableConversations(const QString& convId, const QString& filter = {}) const;
     /**
      * Get a custom filtered set of conversations
      * @return conversations filtered
      */
-    const ConversationQueue& getFilteredConversations(const profile::Type& filter = profile::Type::INVALID, bool forceUpdate = false, const bool includeBanned = false) const;
+    Q_INVOKABLE const ConversationQueue& getFilteredConversations(const profile::Type& filter = profile::Type::INVALID,
+        bool forceUpdate = false,
+        const bool includeBanned = false) const;
     /**
      * Get the conversation at row in the filtered conversations
      * @param  row
      * @return a copy of the conversation
      */
-    conversation::Info filteredConversation(unsigned int row) const;
+    Q_INVOKABLE conversation::Info filteredConversation(unsigned int row) const;
     /**
      * Emit a filterChanged signal to force the client to refresh the filter. For instance
      * this is required when a contact was banned or un-banned.
      */
-    void refreshFilter();
+    Q_INVOKABLE void refreshFilter();
     /**
      * Make permanent a temporary contact or a pending request.
      * Ensure that given conversation is stored permanently into the system.
      * @param uid of the conversation to change.
      * @exception std::out_of_range if uid doesn't correspond to an existing conversation
      */
-    void makePermanent(const QString& uid);
+    Q_INVOKABLE void makePermanent(const QString& uid);
     /**
      * Remove a conversation and the contact if it's a dialog
      * @param uid of the conversation
      * @param banned if we want to ban the contact.
      */
-    void removeConversation(const QString& uid, bool banned=false);
+    Q_INVOKABLE void removeConversation(const QString& uid, bool banned = false);
     /**
      * Get the action wanted by the user when they click on the conversation
      * @param uid of the conversation
      */
-    void selectConversation(const QString& uid) const;
+    Q_INVOKABLE void selectConversation(const QString& uid) const;
     /**
      * Call contacts linked to this conversation
      * @param uid of the conversation
      */
-    void placeCall(const QString& uid);
+    Q_INVOKABLE void placeCall(const QString& uid);
     /**
      * Perform an audio call with contacts linked to this conversation
      * @param uid of the conversation
      */
-    void placeAudioOnlyCall(const QString& uid);
+    Q_INVOKABLE void placeAudioOnlyCall(const QString& uid);
     /**
      * Send a message to the conversation
      * @param uid of the conversation
      * @param body of the message
      */
-    void sendMessage(const QString& uid, const QString& body);
+    Q_INVOKABLE void sendMessage(const QString& uid, const QString& body);
     /**
      * Modify the current filter (will change the result of getFilteredConversations)
      * @param filter the new filter
      */
-    void setFilter(const QString& filter);
+    Q_INVOKABLE void setFilter(const QString& filter);
     /**
      * Modify the current filter (will change the result of getFilteredConversations)
      * @param filter the new filter (example: PENDING, RING)
      */
-    void setFilter(const profile::Type& filter = profile::Type::INVALID);
+    Q_INVOKABLE void setFilter(const profile::Type& filter = profile::Type::INVALID);
     /**
      * Join participants from A to B and vice-versa.
      * @note conversations must be in a call.
      * @param uidA uid of the conversation A
      * @param uidB uid of the conversation B
      */
-    void joinConversations(const QString& uidA, const QString& uidB);
+    Q_INVOKABLE void joinConversations(const QString& uidA, const QString& uidB);
     /**
      * Clear the history of a conversation
      * @param uid of the conversation
      */
-    void clearHistory(const QString& uid);
+    Q_INVOKABLE void clearHistory(const QString& uid);
     /**
      * change the status of the interaction from UNREAD to READ
      * @param convId, id of the conversation
      * @param msgId, id of the interaction
      */
-    void setInteractionRead(const QString& convId, const uint64_t& msgId);
+    Q_INVOKABLE void setInteractionRead(const QString& convId, const uint64_t& msgId);
     /**
      * Clears the unread text messages of a conversation
      * @param convId, uid of the conversation
      */
-    void clearUnreadInteractions(const QString& convId);
+    Q_INVOKABLE void clearUnreadInteractions(const QString& convId);
     /**
      * clear all history
      */
-    void clearAllHistory();
+    Q_INVOKABLE void clearAllHistory();
     /**
      * Clear one interaction from the history
      * @param convId
      * @param interactionId
      */
-    void clearInteractionFromConversation(const QString& convId, const uint64_t& interactionId);
+    Q_INVOKABLE void clearInteractionFromConversation(const QString& convId, const uint64_t& interactionId);
     /**
      * Retry to send a message. In fact, will delete the previous interaction and resend a new one.
      * @param convId
      * @param interactionId
      */
-    void retryInteraction(const QString& convId, const uint64_t& interactionId);
+    Q_INVOKABLE void retryInteraction(const QString& convId, const uint64_t& interactionId);
     /**
      * @param convId
      * @param interactionId
      * @param participant uri
      * @return whether the interaction is last displayed for the conversation
      */
-    bool isLastDisplayed(const QString& convId, const uint64_t& interactionId, const QString participant);
+    Q_INVOKABLE bool isLastDisplayed(const QString& convId, const uint64_t& interactionId, const QString participant);
     /**
      * delete obsolete history from the database
      * @param days, number of days from today. Below this date, interactions will be deleted
      */
-    void deleteObsoleteHistory(int date);
+    Q_INVOKABLE void deleteObsoleteHistory(int date);
 
-    void sendFile(const QString& convUid, const QString& path, const QString& filename);
+    Q_INVOKABLE void sendFile(const QString& convUid, const QString& path, const QString& filename);
 
-    void acceptTransfer(const QString & convUid, uint64_t interactionId);
+    Q_INVOKABLE void acceptTransfer(const QString& convUid, uint64_t interactionId);
 
-    void acceptTransfer(const QString& convUid, uint64_t interactionId, const QString& path);
+    Q_INVOKABLE void acceptTransfer(const QString& convUid, uint64_t interactionId, const QString& path);
 
-    void cancelTransfer(const QString& convUid, uint64_t interactionId);
+    Q_INVOKABLE void cancelTransfer(const QString& convUid, uint64_t interactionId);
 
-    void getTransferInfo(uint64_t interactionId, api::datatransfer::Info& info);
+    Q_INVOKABLE void getTransferInfo(uint64_t interactionId, api::datatransfer::Info& info);
     /**
      * @param convUid, uid of the conversation
      * @return the number of unread messages for the conversation
      */
-    int getNumberOfUnreadMessagesFor(const QString& convUid);
+    Q_INVOKABLE int getNumberOfUnreadMessagesFor(const QString& convUid);
     /**
      * Send a composing status
      * @param uid           conversation's id
      * @param isComposing   if is composing
      */
-    void setIsComposing(const QString& uid, bool isComposing);
+    Q_INVOKABLE void setIsComposing(const QString& uid, bool isComposing);
 
 Q_SIGNALS:
     /**
@@ -259,15 +259,15 @@ Q_SIGNALS:
      * @param msg
      */
     void interactionStatusUpdated(const QString& convUid,
-                                  uint64_t interactionId,
-                                  const api::interaction::Info& msg) const;
+        uint64_t interactionId,
+        const api::interaction::Info& msg) const;
     /**
      * Emitted when an interaction got removed from the conversation
      * @param convUid conversation which owns the interaction
      * @param interactionId
      */
     void interactionRemoved(const QString& convUid,
-                            uint64_t interactionId) const;
+        uint64_t interactionId) const;
     /**
      * Emitted when user clear the history of a conversation
      * @param uid
@@ -322,11 +322,13 @@ Q_SIGNALS:
      * @param newdUid uid of a new displayed interaction
      */
     void displayedInteractionChanged(const QString& uid, const QString& participantURI,
-                                     const uint64_t previousUid, const uint64_t newdUid) const;
+        const uint64_t previousUid, const uint64_t newdUid) const;
 
 private:
     std::unique_ptr<ConversationModelPimpl> pimpl_;
 };
-
 } // namespace api
 } // namespace lrc
+#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
+Q_DECLARE_METATYPE(lrc::api::ConversationModel*)
+#endif
diff --git a/src/api/datatransfermodel.h b/src/api/datatransfermodel.h
index f98650ab0883ba5741faf2f4a0ff2828c150b63b..690fa682eede295969e78e22ad1ab4c4a3dda6b5 100644
--- a/src/api/datatransfermodel.h
+++ b/src/api/datatransfermodel.h
@@ -46,27 +46,27 @@ class Info;
  */
 class LIB_EXPORT DataTransferModel : public QObject {
     Q_OBJECT
-
+    Q_PROPERTY(QString downloadDirectory_qml MEMBER downloadDirectory)
 public:
     DataTransferModel();
     ~DataTransferModel();
 
-    void sendFile(const QString& account_id, const QString& peer_uri,
-                  const QString& file_path, const QString& display_name);
+    Q_INVOKABLE void sendFile(const QString& account_id, const QString& peer_uri,
+        const QString& file_path, const QString& display_name);
 
-    void transferInfo(long long ringId, datatransfer::Info& lrc_info);
+    Q_INVOKABLE void transferInfo(long long ringId, datatransfer::Info& lrc_info);
 
-    void bytesProgress(int interactionId, int64_t& total, int64_t& progress);
+    Q_INVOKABLE void bytesProgress(int interactionId, int64_t& total, int64_t& progress);
 
-    QString accept(int interactionId, const QString& file_path, std::size_t offset);
+    Q_INVOKABLE QString accept(int interactionId, const QString& file_path, std::size_t offset);
 
-    void cancel(int interactionId);
+    Q_INVOKABLE void cancel(int interactionId);
 
-    void registerTransferId(long long dringId, int interactionId);
+    Q_INVOKABLE void registerTransferId(long long dringId, int interactionId);
 
-    int getInteractionIdFromDringId(long long dringId);
+    Q_INVOKABLE int getInteractionIdFromDringId(long long dringId);
 
-    long long getDringIdFromInteractionId(int interactionId);
+    Q_INVOKABLE long long getDringIdFromInteractionId(int interactionId);
 
     /**
      * Used when images < 20 Mb are automatically accepted and downloaded
@@ -77,22 +77,22 @@ public:
     /**
      *  Creates APPDATA/received and return the path
      */
-    static QString createDefaultDirectory();
+    Q_INVOKABLE static QString createDefaultDirectory();
 
     /**
      * Accept transfer from untrusted contacts
      */
-    bool acceptFromUnstrusted {false};
+    bool acceptFromUnstrusted{ false };
 
     /**
      * Accept transfer from trusted contacts
      */
-    bool automaticAcceptTransfer {true};
+    bool automaticAcceptTransfer{ true };
 
     /**
      * Automatically accept transfer under
      */
-    unsigned acceptBehindMb {20} /* Mb */;
+    unsigned acceptBehindMb{ 20 } /* Mb */;
 
 Q_SIGNALS:
     /**
@@ -111,5 +111,8 @@ private:
     class Impl;
     std::unique_ptr<Impl> pimpl_;
 };
-
-}} // namespace lrc::api
+}
+} // namespace lrc::api
+#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
+Q_DECLARE_METATYPE(lrc::api::DataTransferModel*)
+#endif
diff --git a/src/api/newaccountmodel.h b/src/api/newaccountmodel.h
index 1e36eaa80cd94978224ee0f8af8500547c438210..19602bc66852cf57177629ea6bd48b2f896380c3 100644
--- a/src/api/newaccountmodel.h
+++ b/src/api/newaccountmodel.h
@@ -51,49 +51,45 @@ class LIB_EXPORT NewAccountModel : public QObject {
     Q_OBJECT
 public:
     NewAccountModel(Lrc& lrc,
-                    const CallbacksHandler& callbackHandler,
-                    const api::BehaviorController& behaviorController,
-                    MigrationCb& willMigrateCb,
-                    MigrationCb& didMigrateCb);
+        const CallbacksHandler& callbackHandler,
+        const api::BehaviorController& behaviorController,
+        MigrationCb& willMigrateCb,
+        MigrationCb& didMigrateCb);
 
     ~NewAccountModel();
     /**
      * @return a list of all acountId.
      */
-    QStringList getAccountList() const;
-
+    Q_INVOKABLE QStringList getAccountList() const;
     /**
      * get account informations associated to an accountId.
      * @param accountId.
      * @return a const account::Info& structure.
      */
-    const account::Info& getAccountInfo(const QString& accountId) const;
-
+    Q_INVOKABLE const account::Info& getAccountInfo(const QString& accountId) const;
     /**
      * flag account corresponding to passed id as freeable.
      */
-    void flagFreeable(const QString& accountId) const;
-
-     /**
-     * set account enable/disable, save config and do unregister for account
-     * @param accountId.
-     * @param enabled.
-     */
-    void setAccountEnabled(const QString& accountID, bool enabled) const;
-
+    Q_INVOKABLE void flagFreeable(const QString& accountId) const;
+    /**
+    * set account enable/disable, save config and do unregister for account
+    * @param accountId.
+    * @param enabled.
+    */
+    Q_INVOKABLE void setAccountEnabled(const QString& accountID, bool enabled) const;
     /**
      * saves account config to .yml
      * @param accountId.
      * @param reference to the confProperties
      */
-    void setAccountConfig(const QString& accountID,
-                          const account::ConfProperties_t& confProperties) const;
+    Q_INVOKABLE void setAccountConfig(const QString& accountID,
+        const account::ConfProperties_t& confProperties) const;
     /**
      * gets a copy of the accounts config
      * @param accountId.
      * @return an account::Info::ConfProperties_t structure.
      */
-    account::ConfProperties_t getAccountConfig(const QString& accountId) const;
+    Q_INVOKABLE account::ConfProperties_t getAccountConfig(const QString& accountId) const;
     /**
      * Call exportToFile from the daemon
      * @param accountId
@@ -101,20 +97,20 @@ public:
      * @param password
      * @return if the file is exported with success
      */
-    bool exportToFile(const QString& accountId, const QString& path, const QString& password = {}) const;
+    Q_INVOKABLE bool exportToFile(const QString& accountId, const QString& path, const QString& password = {}) const;
     /**
      * Call exportOnRing from the daemon
      * @param accountId
      * @param password
      * @return if the export is initialized
      */
-    bool exportOnRing(const QString& accountId, const QString& password) const;
+    Q_INVOKABLE bool exportOnRing(const QString& accountId, const QString& password) const;
     /**
      * Call removeAccount from the daemon
      * @param accountId to remove
      * @note will emit accountRemoved
      */
-    void removeAccount(const QString& accountId) const;
+    Q_INVOKABLE void removeAccount(const QString& accountId) const;
     /**
      * Call changeAccountPassword from the daemon
      * @param accountId
@@ -122,23 +118,23 @@ public:
      * @param newPassword
      * @return if the password has been changed
      */
-    bool changeAccountPassword(const QString& accountId,
-                               const QString& currentPassword,
-                               const QString& newPassword) const;
+    Q_INVOKABLE bool changeAccountPassword(const QString& accountId,
+        const QString& currentPassword,
+        const QString& newPassword) const;
     /**
      * Change the avatar of an account
      * @param accountId
      * @param avatar
      * @throws out_of_range exception if account is not found
      */
-    void setAvatar(const QString& accountId, const QString& avatar);
+    Q_INVOKABLE void setAvatar(const QString& accountId, const QString& avatar);
     /**
      * Change the alias of an account
      * @param accountId
      * @param alias
      * @throws out_of_range exception if account is not found
      */
-    void setAlias(const QString& accountId, const QString& alias);
+    Q_INVOKABLE void setAlias(const QString& accountId, const QString& alias);
     /**
      * Try to register a name
      * @param accountId
@@ -146,8 +142,7 @@ public:
      * @param username
      * @return if operation started
      */
-    bool registerName(const QString& accountId, const QString& password, const QString& username);
-
+    Q_INVOKABLE bool registerName(const QString& accountId, const QString& password, const QString& username);
     /**
      * Connect to JAMS to retrieve the account
      * @param username
@@ -156,11 +151,10 @@ public:
      * @param config
      * @return the account id
      */
-    static QString connectToAccountManager(const QString& username,
-                                           const QString& password,
-                                           const QString& serverUri,
-                                           const MapStringString& config = MapStringString());
-
+    Q_INVOKABLE static QString connectToAccountManager(const QString& username,
+        const QString& password,
+        const QString& serverUri,
+        const MapStringString& config = MapStringString());
     /**
      * Create a new Ring or SIP account
      * @param type determine if the new account will be a Ring account or a SIP one
@@ -173,25 +167,23 @@ public:
      * @param config
      * @return the created account
      */
-    static QString createNewAccount(profile::Type type,
-                                    const QString& displayName = "",
-                                    const QString& archivePath = "",
-                                    const QString& password = "",
-                                    const QString& pin = "",
-                                    const QString& uri = "",
-                                    const MapStringString& config = MapStringString());
-
+    Q_INVOKABLE static QString createNewAccount(profile::Type type,
+        const QString& displayName = "",
+        const QString& archivePath = "",
+        const QString& password = "",
+        const QString& pin = "",
+        const QString& uri = "",
+        const MapStringString& config = MapStringString());
     /**
      * Set an account to the first position
      */
-    void setTopAccount(const QString& accountId);
-
+    Q_INVOKABLE void setTopAccount(const QString& accountId);
     /**
      * Get the vCard for an account
      * @param id
      * @return vcard of the account
      */
-    QString accountVCard(const QString& accountId, bool compressImage = true) const;
+    Q_INVOKABLE QString accountVCard(const QString& accountId, bool compressImage = true) const;
 
 Q_SIGNALS:
     /**
@@ -254,6 +246,8 @@ Q_SIGNALS:
 private:
     std::unique_ptr<NewAccountModelPimpl> pimpl_;
 };
-
 } // namespace api
 } // namespace lrc
+#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
+Q_DECLARE_METATYPE(lrc::api::NewAccountModel*)
+#endif
diff --git a/src/api/newcallmodel.h b/src/api/newcallmodel.h
index 86e1ddf0403796a7bd4e3616dc304da09e734df1..1dc36acbe4291203de03fe316a70d87b1d31aa40 100644
--- a/src/api/newcallmodel.h
+++ b/src/api/newcallmodel.h
@@ -70,7 +70,7 @@ public:
      * @param  isAudioOnly, set to false by default
      * @return the call uid created. Empty string is returned if call couldn't be created.
      */
-    QString createCall(const QString& uri, bool isAudioOnly = false);
+    Q_INVOKABLE QString createCall(const QString& uri, bool isAudioOnly = false);
 
     /**
      * Get the call from its call id
@@ -78,7 +78,7 @@ public:
      * @return the callInfo
      * @throw out_of_range exception if not found
      */
-    const call::Info& getCall(const QString& uid) const;
+    Q_INVOKABLE const call::Info& getCall(const QString& uid) const;
 
     /**
      * Get the call from the peer uri
@@ -87,7 +87,7 @@ public:
      * @return the callInfo
      * @throw out_of_range exception if not found
      */
-    const call::Info& getCallFromURI(const QString& uri, bool notOver = false) const;
+    Q_INVOKABLE const call::Info& getCallFromURI(const QString& uri, bool notOver = false) const;
 
     /**
      * Get conference from a peer uri
@@ -95,91 +95,91 @@ public:
      * @return the callInfo
      * @throw out_of_range exception if not found
      */
-    const call::Info& getConferenceFromURI(const QString& uri) const;
+    Q_INVOKABLE const call::Info& getConferenceFromURI(const QString& uri) const;
 
     /**
      * @param  callId to test
      * @return true if callId is presend else false.
      */
-    bool hasCall(const QString& callId) const;
+    Q_INVOKABLE bool hasCall(const QString& callId) const;
 
     /**
      * Send a text message to a SIP call
      * @param callId
      * @param body of the message
      */
-    void sendSipMessage(const QString& callId, const QString& body) const;
+    Q_INVOKABLE void sendSipMessage(const QString& callId, const QString& body) const;
 
     /**
      * Accept a call
      * @param callId
      */
-    void accept(const QString& callId) const;
+    Q_INVOKABLE void accept(const QString& callId) const;
 
     /**
      * Hang up a call
      * @param callId
      */
-    void hangUp(const QString& callId) const;
+    Q_INVOKABLE void hangUp(const QString& callId) const;
 
     /**
      * Refuse a call
      * @param callId
      */
-    void refuse(const QString& callId) const;
+    Q_INVOKABLE void refuse(const QString& callId) const;
 
     /**
      * Toggle audio record on a call
      * @param callId
      */
-    void toggleAudioRecord(const QString& callId) const;
+    Q_INVOKABLE void toggleAudioRecord(const QString& callId) const;
 
     /**
      * Play DTMF in a call
      * @param callId
      * @param value to play
      */
-    void playDTMF(const QString& callId, const QString& value) const;
+    Q_INVOKABLE void playDTMF(const QString& callId, const QString& value) const;
 
     /**
      * Toggle pause on a call.
      * @warn only use this function for SIP calls
      * @param callId
      */
-    void togglePause(const QString& callId) const;
+    Q_INVOKABLE void togglePause(const QString& callId) const;
 
     /**
      * Toggle a media on a call
      * @param callId
      * @param media {AUDIO, VIDEO}
      */
-    void toggleMedia(const QString& callId, const NewCallModel::Media media) const;
+    Q_INVOKABLE void toggleMedia(const QString& callId, const NewCallModel::Media media) const;
 
     /**
      * Not implemented yet
      */
-    void setQuality(const QString& callId, const double quality) const;
+    Q_INVOKABLE void setQuality(const QString& callId, const double quality) const;
 
     /**
      * Blind transfer. Directly transfer a call to a sip number
      * @param callId: the call to transfer
      * @param to: the sip number (for example: "sip:1412")
      */
-    void transfer(const QString& callId, const QString& to) const;
+    Q_INVOKABLE void transfer(const QString& callId, const QString& to) const;
 
     /**
      * Perform an attended. Transfer a call to another call
      * @param callIdSrc: the call to transfer
      * @param callIdDest: the destination's call
      */
-    void transferToCall(const QString& callIdSrc, const QString& callIdDest) const;
+    Q_INVOKABLE void transferToCall(const QString& callIdSrc, const QString& callIdDest) const;
 
     /**
      * Create a conference from 2 calls.
      * @param callIdA uid of the call A
      * @param callIdB uid of the call B
      */
-    void joinCalls(const QString& callIdA, const QString& callIdB) const;
+    Q_INVOKABLE void joinCalls(const QString& callIdA, const QString& callIdB) const;
 
     /**
      * Call a participant and add it to a call
@@ -188,42 +188,42 @@ public:
      * @param audioOnly If the call is audio only
      * @return id for a new call
      */
-    QString callAndAddParticipant(const QString uri, const QString& callId, bool audioOnly);
+    Q_INVOKABLE QString callAndAddParticipant(const QString uri, const QString& callId, bool audioOnly);
 
     /**
      * Not implemented yet
      */
-    void removeParticipant(const QString& callId, const QString& participant) const;
+    Q_INVOKABLE void removeParticipant(const QString& callId, const QString& participant) const;
 
     /**
      * @param  callId
      * @return a human readable call duration (M:ss)
      */
-    QString getFormattedCallDuration(const QString& callId) const;
+    Q_INVOKABLE QString getFormattedCallDuration(const QString& callId) const;
 
     /**
      * Get if a call is recording
      * @param callId
      * @return true if the call is recording else false
      */
-    bool isRecording(const QString& callId) const;
+    Q_INVOKABLE bool isRecording(const QString& callId) const;
 
     /**
      * Close all active calls and conferences
      */
-    static void hangupCallsAndConferences();
+    Q_INVOKABLE static void hangupCallsAndConferences();
 
     /**
      * Extract Status Message From Status Map
      * @param statusCode
      * @return status message
      */
-    static QString getSIPCallStatusString(const short& statusCode);
+    Q_INVOKABLE static QString getSIPCallStatusString(const short& statusCode);
 
     /**
      * Set a call as the current call (hold other calls)
      */
-    void setCurrentCall(const QString& callId) const;
+    Q_INVOKABLE void setCurrentCall(const QString& callId) const;
 
     /**
      * Change the conference layout
@@ -282,6 +282,8 @@ Q_SIGNALS:
 private:
     std::unique_ptr<NewCallModelPimpl> pimpl_;
 };
-
 } // namespace api
 } // namespace lrc
+#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
+Q_DECLARE_METATYPE(lrc::api::NewCallModel*)
+#endif
diff --git a/src/api/newcodecmodel.h b/src/api/newcodecmodel.h
index 02d325a8de1b0114dd978c40745c0948a4955474..d1eb4af24c53691e0e79d1474b5bfad5af258aba 100644
--- a/src/api/newcodecmodel.h
+++ b/src/api/newcodecmodel.h
@@ -116,6 +116,8 @@ public:
 private:
     std::unique_ptr<NewCodecModelPimpl> pimpl_;
 };
-
 } // namespace api
 } // namespace lrc
+#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
+Q_DECLARE_METATYPE(lrc::api::NewCodecModel*)
+#endif
diff --git a/src/api/newdevicemodel.h b/src/api/newdevicemodel.h
index feb05232214515a7ba62177297d7af87d1bcf1b5..07fea0ab09e40a6c080e06c8159d2970c807b98a 100644
--- a/src/api/newdevicemodel.h
+++ b/src/api/newdevicemodel.h
@@ -83,7 +83,7 @@ public:
      * @param password of the account's archive
      * @note will emit deviceRevoked when finished
      */
-    void revokeDevice(const QString& id, const QString& password);
+    Q_INVOKABLE void revokeDevice(const QString& id, const QString& password);
 
     /**
      * Change the name of the current device
@@ -91,7 +91,7 @@ public:
      * @note will emit deviceUpdated when finished
      * @note ring can't change the name of another device
      */
-    void setCurrentDeviceName(const QString& newName);
+    Q_INVOKABLE void setCurrentDeviceName(const QString& newName);
 
 Q_SIGNALS:
     /**
@@ -114,6 +114,8 @@ Q_SIGNALS:
 private:
     std::unique_ptr<NewDeviceModelPimpl> pimpl_;
 };
-
 } // namespace api
 } // namespace lrc
+#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
+Q_DECLARE_METATYPE(lrc::api::NewDeviceModel*)
+#endif
diff --git a/src/api/newvideo.h b/src/api/newvideo.h
index c5163ede873efced7d653bf4321b682fd15dffc1..fc873bb1a2b4a66d02414974050ea433142e4193 100644
--- a/src/api/newvideo.h
+++ b/src/api/newvideo.h
@@ -17,7 +17,7 @@
  ***************************************************************************/
 #pragma once
 
-// Std
+ // Std
 #include <map>
 #include <memory>
 #include <string>
@@ -67,12 +67,12 @@ using Capabilities = QMap<Channel, ResRateList>;
  * If shared data is carried, only "ptr" and "size" are set.
  */
 struct Frame {
-   uint8_t*             ptr     { nullptr };
-   std::size_t          size    { 0       };
-   std::vector<uint8_t> storage {         };
-   // Next variables are currently used with DirectRenderer only
-   unsigned int         height  { 0       };
-   unsigned int         width   { 0       };
+    uint8_t* ptr{ nullptr };
+    std::size_t          size{ 0 };
+    std::vector<uint8_t> storage{         };
+    // Next variables are currently used with DirectRenderer only
+    unsigned int         height{ 0 };
+    unsigned int         width{ 0 };
 };
 
 enum class DeviceType
@@ -89,7 +89,7 @@ Q_ENUM_NS(DeviceType)
 /**
  * This class describes the current rendered device
  */
-struct RenderedDevice
+    struct RenderedDevice
 {
     QString name;
     DeviceType type = DeviceType::INVALID;
diff --git a/src/api/peerdiscoverymodel.h b/src/api/peerdiscoverymodel.h
index 38cf150c88adb5c4d5983ac5084c471ed6ba887b..be2779495db2ed3c8470d293167909b56c703dc8 100644
--- a/src/api/peerdiscoverymodel.h
+++ b/src/api/peerdiscoverymodel.h
@@ -18,7 +18,7 @@
 
 #pragma once
 
-// Lrc
+ // Lrc
 #include "typedefs.h"
 
 // Qt
@@ -74,6 +74,8 @@ Q_SIGNALS:
 private:
     std::unique_ptr<PeerDiscoveryModelPimpl> pimpl_;
 };
-
 } // namespace api
 } // namespace lrc
+#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
+Q_DECLARE_METATYPE(lrc::api::PeerDiscoveryModel*)
+#endif
diff --git a/src/api/profile.h b/src/api/profile.h
index d08acf75ca9b953e82a3645b27e642d17cfa2b29..0c910cac0bf77ee72c59fc74b419238ee64a7d00 100644
--- a/src/api/profile.h
+++ b/src/api/profile.h
@@ -49,7 +49,7 @@ Q_ENUM_NS(Type)
 static inline const QString
 to_string(const Type& type)
 {
-    switch(type) {
+    switch (type) {
     case Type::RING:
         return "RING";
     case Type::SIP:
diff --git a/src/avmodel.cpp b/src/avmodel.cpp
index ba5f34548b0a3b408f0914e58286714ffa075e66..48423ae4d3b0fba2d082b06a83598bf251d11d10 100644
--- a/src/avmodel.cpp
+++ b/src/avmodel.cpp
@@ -18,7 +18,7 @@
  ***************************************************************************/
 #include "api/avmodel.h"
 
-// Std
+ // Std
 #include <algorithm>    // std::sort
 #include <chrono>
 #include <csignal>
@@ -50,7 +50,7 @@ namespace lrc
 
 using namespace api;
 
-class AVModelPimpl: public QObject
+class AVModelPimpl : public QObject
 {
     Q_OBJECT
 public:
@@ -66,7 +66,7 @@ public:
     // store if a renderers is for a finished call
     std::map<QString, bool> finishedRenderers_;
     bool useAVFrame_ = false;
-    QString currentVideoCaptureDevice_ {};
+    QString currentVideoCaptureDevice_{};
 
 #ifndef ENABLE_LIBWRAP
     // TODO: Init Video Renderers from daemon (see: https://git.jami.net/savoirfairelinux/ring-daemon/issues/59)
@@ -102,7 +102,7 @@ public Q_SLOTS:
      * @param state the new state
      * @param code unused
      */
-    void slotCallStateChanged(const QString& id, const QString &state, int code);
+    void slotCallStateChanged(const QString& id, const QString& state, int code);
     /**
      * Detect when the current frame is updated
      * @param id
@@ -132,8 +132,8 @@ uint32_t AVModelPimpl::SIZE_RENDERER = 0;
 #endif
 
 AVModel::AVModel(const CallbacksHandler& callbacksHandler)
-: QObject()
-, pimpl_(std::make_unique<AVModelPimpl>(*this, callbacksHandler))
+    : QObject(nullptr)
+    , pimpl_(std::make_unique<AVModelPimpl>(*this, callbacksHandler))
 {
 #ifndef ENABLE_LIBWRAP
     // Because the client uses DBUS, if a crash occurs, the daemon will not
@@ -190,7 +190,7 @@ AVModel::setHardwareAcceleration(bool accelerate)
     setEncodingAccelerated(accelerate);
 }
 
-VectorString
+QVector<QString>
 AVModel::getDevices() const
 {
     QStringList devices = VideoManager::instance()
@@ -199,7 +199,7 @@ AVModel::getDevices() const
     for (const auto& device : devices) {
         result.push_back(device);
     }
-    return result;
+    return (QVector<QString>)result;
 }
 
 QString
@@ -255,10 +255,10 @@ AVModel::getDeviceCapabilities(const QString& deviceId) const
         // sort by resolution widths
         std::sort(channelCapabilities.begin(), channelCapabilities.end(),
             [](const QPair<video::Resolution, video::FrameratesList>& lhs,
-               const QPair<video::Resolution, video::FrameratesList>& rhs) {
-                auto lhsWidth = lhs.first.left(lhs.first.indexOf("x")).toLongLong();
-                auto rhsWidth = rhs.first.left(rhs.first.indexOf("x")).toLongLong();
-                return lhsWidth > rhsWidth;
+                const QPair<video::Resolution, video::FrameratesList>& rhs) {
+                    auto lhsWidth = lhs.first.left(lhs.first.indexOf("x")).toLongLong();
+                    auto rhsWidth = rhs.first.left(rhs.first.indexOf("x")).toLongLong();
+                    return lhsWidth > rhsWidth;
             });
         result.insert(channel.first, channelCapabilities);
     }
@@ -323,7 +323,7 @@ AVModel::getAudioManager() const
     return ConfigurationManager::instance().getAudioManager();
 }
 
-VectorString
+QVector<QString>
 AVModel::getAudioOutputDevices() const
 {
     QStringList devices = ConfigurationManager::instance()
@@ -341,10 +341,10 @@ AVModel::getAudioOutputDevices() const
     for (const auto& device : devices) {
         result.push_back(device);
     }
-    return result;
+    return (QVector<QString>)result;
 }
 
-VectorString
+QVector<QString>
 AVModel::getAudioInputDevices() const
 {
     QStringList devices = ConfigurationManager::instance()
@@ -362,7 +362,7 @@ AVModel::getAudioInputDevices() const
     for (const auto& device : devices) {
         result.push_back(device);
     }
-    return result;
+    return (QVector<QString>)result;
 }
 
 QString
@@ -440,20 +440,20 @@ AVModel::setInputDevice(const QString& name)
 void
 AVModel::stopLocalRecorder(const QString& path) const
 {
-   if (path.isEmpty()) {
-      qWarning("stopLocalRecorder: can't stop non existing recording");
-      return;
-   }
+    if (path.isEmpty()) {
+        qWarning("stopLocalRecorder: can't stop non existing recording");
+        return;
+    }
 
-   VideoManager::instance().stopLocalRecorder(path);
+    VideoManager::instance().stopLocalRecorder(path);
 }
 
 QString
 AVModel::startLocalRecorder(const bool& audioOnly) const
 {
-   const QString path = pimpl_->getRecordingPath();
-   const QString finalPath = VideoManager::instance().startLocalRecorder(audioOnly, path);
-   return finalPath;
+    const QString path = pimpl_->getRecordingPath();
+    const QString finalPath = VideoManager::instance().startLocalRecorder(audioOnly, path);
+    return finalPath;
 }
 
 QString
@@ -563,7 +563,7 @@ AVModel::getRenderer(const QString& id) const
 
 void
 AVModel::setInputFile(const QString& uri,
-                      const QString& callId)
+    const QString& callId)
 {
     QString sep = DRing::Media::VideoProtocolPrefix::SEPARATOR;
     auto resource = !uri.isEmpty() ? QString("%1%2%3")
@@ -573,7 +573,8 @@ AVModel::setInputFile(const QString& uri,
         : DRing::Media::VideoProtocolPrefix::NONE;
     if (callId.isEmpty()) {
         VideoManager::instance().switchInput(resource);
-    } else {
+    }
+    else {
         CallManager::instance()
             .switchInput(callId, resource);
     }
@@ -581,7 +582,7 @@ AVModel::setInputFile(const QString& uri,
 
 void
 AVModel::setDisplay(int idx, int x, int y, int w, int h,
-                    const QString& callId)
+    const QString& callId)
 {
     QString sep = DRing::Media::VideoProtocolPrefix::SEPARATOR;
     auto resource = QString("%1%2:%3+%4,%5 %6x%7")
@@ -594,7 +595,8 @@ AVModel::setDisplay(int idx, int x, int y, int w, int h,
         .arg(h);
     if (callId.isEmpty()) {
         VideoManager::instance().switchInput(resource);
-    } else {
+    }
+    else {
         CallManager::instance()
             .switchInput(callId, resource);
     }
@@ -603,7 +605,7 @@ AVModel::setDisplay(int idx, int x, int y, int w, int h,
 
 void
 AVModel::switchInputTo(const QString& id,
-                       const QString& callId)
+    const QString& callId)
 {
     QString resource;
     auto devices = getDevices();
@@ -615,12 +617,14 @@ AVModel::switchInputTo(const QString& id,
             .arg(DRing::Media::VideoProtocolPrefix::CAMERA)
             .arg(sep)
             .arg(id);
-    } else {
+    }
+    else {
         resource = QString(DRing::Media::VideoProtocolPrefix::NONE);
     }
     if (callId.isEmpty()) {
         VideoManager::instance().switchInput(resource);
-    } else {
+    }
+    else {
         CallManager::instance()
             .switchInput(callId, resource);
     }
@@ -634,7 +638,8 @@ AVModel::getCurrentRenderedDevice(const QString& call_id) const
     QStringList conferences = CallManager::instance().getConferenceList();
     if (conferences.indexOf(call_id) != -1) {
         callDetails = CallManager::instance().getConferenceDetails(call_id);
-    } else {
+    }
+    else {
         callDetails = CallManager::instance().getCallDetails(call_id);
     }
     if (!callDetails.contains("VIDEO_SOURCE")) {
@@ -646,11 +651,13 @@ AVModel::getCurrentRenderedDevice(const QString& call_id) const
         result.type = video::DeviceType::CAMERA;
         result.name = source
             .right(sourceSize - QString("camera://").size());
-    } else if (source.startsWith("file://")) {
+    }
+    else if (source.startsWith("file://")) {
         result.type = video::DeviceType::FILE;
         result.name = source
-            .right(sourceSize -QString("file://").size());
-    } else if (source.startsWith("display://")) {
+            .right(sourceSize - QString("file://").size());
+    }
+    else if (source.startsWith("display://")) {
         result.type = video::DeviceType::DISPLAY;
         result.name = source
             .right(sourceSize - QString("display://").size());
@@ -659,7 +666,7 @@ AVModel::getCurrentRenderedDevice(const QString& call_id) const
 }
 
 void
-AVModel::setCurrentVideoCaptureDevice(QString &currentVideoCaptureDevice)
+AVModel::setCurrentVideoCaptureDevice(const QString& currentVideoCaptureDevice)
 {
     pimpl_->currentVideoCaptureDevice_ = currentVideoCaptureDevice;
 }
@@ -677,37 +684,38 @@ AVModel::clearCurrentVideoCaptureDevice()
 }
 
 AVModelPimpl::AVModelPimpl(AVModel& linked, const CallbacksHandler& callbacksHandler)
-: linked_(linked)
-, callbacksHandler(callbacksHandler)
+    : linked_(linked)
+    , callbacksHandler(callbacksHandler)
 {
     std::srand(std::time(nullptr));
     // add preview renderer
     try {
         renderers_.insert(std::make_pair(video::PREVIEW_RENDERER_ID,
-                                         std::make_unique<video::Renderer>(video::PREVIEW_RENDERER_ID,
-                                                                           linked_.getDeviceSettings(linked_.getDefaultDevice()),
-                                                                           "",
-                                                                           useAVFrame_)));
-    } catch (const std::out_of_range& e) {
+            std::make_unique<video::Renderer>(video::PREVIEW_RENDERER_ID,
+                linked_.getDeviceSettings(linked_.getDefaultDevice()),
+                "",
+                useAVFrame_)));
+    }
+    catch (const std::out_of_range& e) {
         qWarning() << "Couldn't setup video input renderer: " << e.what();
     }
 #ifndef ENABLE_LIBWRAP
     SIZE_RENDERER = renderers_.size();
 #endif
     connect(&callbacksHandler, &CallbacksHandler::deviceEvent,
-            this, &AVModelPimpl::slotDeviceEvent);
+        this, &AVModelPimpl::slotDeviceEvent);
     connect(&callbacksHandler, &CallbacksHandler::audioMeter,
-            this, &AVModelPimpl::slotAudioMeter);
+        this, &AVModelPimpl::slotAudioMeter);
     connect(&callbacksHandler, &CallbacksHandler::startedDecoding,
-            this, &AVModelPimpl::startedDecoding);
+        this, &AVModelPimpl::startedDecoding);
     connect(&callbacksHandler, &CallbacksHandler::stoppedDecoding,
-            this, &AVModelPimpl::stoppedDecoding);
+        this, &AVModelPimpl::stoppedDecoding);
     connect(&callbacksHandler, &CallbacksHandler::callStateChanged,
-            this, &AVModelPimpl::slotCallStateChanged);
+        this, &AVModelPimpl::slotCallStateChanged);
     connect(&*renderers_[video::PREVIEW_RENDERER_ID], &api::video::Renderer::frameUpdated,
-            this, &AVModelPimpl::slotFrameUpdated);
+        this, &AVModelPimpl::slotFrameUpdated);
     connect(&callbacksHandler, &CallbacksHandler::recordPlaybackStopped,
-            this, &AVModelPimpl::slotRecordPlaybackStopped);
+        this, &AVModelPimpl::slotRecordPlaybackStopped);
 
     auto startedPreview = false;
     auto restartRenderers = [&](const QStringList& callList) {
@@ -727,7 +735,7 @@ AVModelPimpl::AVModelPimpl(AVModel& linked, const CallbacksHandler& callbacksHan
     restartRenderers(CallManager::instance().getCallList());
     restartRenderers(CallManager::instance().getConferenceList());
     if (startedPreview)
-        restartRenderers({"local"});
+        restartRenderers({ "local" });
 }
 
 QString
@@ -777,7 +785,8 @@ AVModelPimpl::startedDecoding(const QString& id, const QString& shmPath, int wid
             renderers_.at(id)->initThread();
             connect(&*renderers_[id], &api::video::Renderer::frameUpdated,
                 this, &AVModelPimpl::slotFrameUpdated);
-        } else {
+        }
+        else {
             (*search).second->update(res, shmPath);
         }
         renderers_.at(id)->startRendering();
@@ -821,11 +830,11 @@ AVModelPimpl::stoppedDecoding(const QString& id, const QString& shmPath)
 }
 
 void
-AVModelPimpl::slotCallStateChanged(const QString& id, const QString &state, int code)
+AVModelPimpl::slotCallStateChanged(const QString& id, const QString& state, int code)
 {
     Q_UNUSED(code)
-    if (call::to_status(state) != call::Status::ENDED)
-        return;
+        if (call::to_status(state) != call::Status::ENDED)
+            return;
     std::lock_guard<std::mutex> lk(renderers_mtx_);
     auto search = renderers_.find(id);
     auto searchFinished = finishedRenderers_.find(id);
@@ -842,7 +851,8 @@ AVModelPimpl::slotCallStateChanged(const QString& id, const QString &state, int
         SIZE_RENDERER = renderers_.size();
 #endif
         finishedRenderers_.erase(id);
-    } else {
+    }
+    else {
         finishedRenderers_.at(id) = true;
     }
 }
@@ -871,15 +881,15 @@ AVModelPimpl::getDevice(int type) const
     QString result = "";
     VectorString devices;
     switch (type) {
-        case 1: // INPUT
-            devices = linked_.getAudioInputDevices();
-            break;
-        case 0: // OUTPUT
-        case 2: // RINGTONE
-            devices = linked_.getAudioOutputDevices();
-            break;
-        default:
-            break;
+    case 1: // INPUT
+        devices = linked_.getAudioInputDevices();
+        break;
+    case 0: // OUTPUT
+    case 2: // RINGTONE
+        devices = linked_.getAudioOutputDevices();
+        break;
+    default:
+        break;
     }
     QStringList currentDevicesIdx = ConfigurationManager::instance()
         .getCurrentAudioDevicesIndex();
@@ -907,7 +917,8 @@ AVModelPimpl::getDevice(int type) const
             }
         }
         return "";
-    } catch (std::bad_alloc& ba) {
+    }
+    catch (std::bad_alloc& ba) {
         qWarning() << "bad_alloc caught: " << ba.what();
         return "";
     }
@@ -933,7 +944,7 @@ AVModelPimpl::slotAudioMeter(const QString& id, float level)
 }
 
 void
-AVModelPimpl::slotRecordPlaybackStopped(const QString &filePath)
+AVModelPimpl::slotRecordPlaybackStopped(const QString& filePath)
 {
     emit linked_.recordPlaybackStopped(filePath);
 }
diff --git a/src/behaviorcontroller.cpp b/src/behaviorcontroller.cpp
index 3da29ea533593fd36fb3ee5110aded59277fad73..d091324d83bbe20e4d4c7dc42c01bfe21d9b92cc 100644
--- a/src/behaviorcontroller.cpp
+++ b/src/behaviorcontroller.cpp
@@ -27,7 +27,7 @@ namespace lrc
 using namespace api;
 
 BehaviorController::BehaviorController()
-: QObject()
+: QObject(nullptr)
 {
 }
 
diff --git a/src/conversationmodel.cpp b/src/conversationmodel.cpp
index e7dac7fe2e34d2f59f2e27e1d375ec9db637b240..fcb1135a261988121c7faee401dbf5ce2ccd8dfb 100644
--- a/src/conversationmodel.cpp
+++ b/src/conversationmodel.cpp
@@ -271,7 +271,7 @@ ConversationModel::ConversationModel(const account::Info& owner,
                                      Database& db,
                                      const CallbacksHandler& callbacksHandler,
                                      const BehaviorController& behaviorController)
-: QObject()
+: QObject(nullptr)
 , pimpl_(std::make_unique<ConversationModelPimpl>(*this, lrc, db, callbacksHandler, behaviorController))
 , owner(owner)
 {
diff --git a/src/datatransfermodel.cpp b/src/datatransfermodel.cpp
index 8fad0d863c4d784ea74fdbb8f3e816c8ab976e8b..93039c3ecc2132d28c49137359a5d4b79382573c 100644
--- a/src/datatransfermodel.cpp
+++ b/src/datatransfermodel.cpp
@@ -109,7 +109,7 @@ DataTransferModel::registerTransferId(long long dringId, int interactionId)
 }
 
 DataTransferModel::DataTransferModel()
-    : QObject()
+    : QObject(nullptr)
     , pimpl_ { std::make_unique<Impl>(*this) }
 {}
 
diff --git a/src/namedirectory.cpp b/src/namedirectory.cpp
index 811baf5269647324cac0cad951d9359c20b452a3..f74f3cb1e75c355f0a40b974084b32511c36abd5 100644
--- a/src/namedirectory.cpp
+++ b/src/namedirectory.cpp
@@ -27,9 +27,11 @@ NameDirectoryPrivate::NameDirectoryPrivate(NameDirectory* q) : q_ptr(q)
     ConfigurationManagerInterface& configurationManager = ConfigurationManager::instance();
 
     connect(&configurationManager, &ConfigurationManagerInterface::nameRegistrationEnded, this,
-            &NameDirectoryPrivate::slotNameRegistrationEnded, Qt::QueuedConnection);
+        &NameDirectoryPrivate::slotNameRegistrationEnded, Qt::QueuedConnection);
     connect(&configurationManager, &ConfigurationManagerInterface::registeredNameFound, this,
-            &NameDirectoryPrivate::slotRegisteredNameFound, Qt::QueuedConnection);
+        &NameDirectoryPrivate::slotRegisteredNameFound, Qt::QueuedConnection);
+    connect(&configurationManager, &ConfigurationManagerInterface::exportOnRingEnded, this,
+        &NameDirectoryPrivate::slotExportOnRingEnded, Qt::QueuedConnection);
 }
 
 NameDirectory::NameDirectory() : QObject(QCoreApplication::instance()), d_ptr(new NameDirectoryPrivate(this))
@@ -48,7 +50,7 @@ void NameDirectoryPrivate::slotNameRegistrationEnded(const QString& accountId, i
 {
     qDebug() << "Name registration ended. Account:" << accountId << "status:" << status << "name:" << name;
 
-   emit q_ptr->nameRegistrationEnded(static_cast<NameDirectory::RegisterNameStatus>(status), name);
+    emit q_ptr->nameRegistrationEnded(static_cast<NameDirectory::RegisterNameStatus>(status), name);
 }
 
 //Registered Name found
@@ -68,7 +70,14 @@ void NameDirectoryPrivate::slotRegisteredNameFound(const QString& accountId, int
             break;
     }
 
-    emit q_ptr->registeredNameFound( static_cast<NameDirectory::LookupStatus>(status), address, name);
+    emit q_ptr->registeredNameFound(static_cast<NameDirectory::LookupStatus>(status), address, name);
+}
+
+//Export account has ended with pin generated
+void NameDirectoryPrivate::slotExportOnRingEnded(const QString& accountId, int status, const QString& pin) {
+    qDebug() << "Export on ring ended for account: " << accountId << "status: " << status << "PIN: " << pin;
+
+    emit q_ptr->exportOnRingEnded(static_cast<NameDirectory::ExportOnRingStatus>(status), pin);
 }
 
 //Lookup a name
diff --git a/src/namedirectory.h b/src/namedirectory.h
index c8af402c4aeb226fa30f4b467f267184990e2d46..af93810723c786f9471defb7c7367ad6d0ed2aac 100644
--- a/src/namedirectory.h
+++ b/src/namedirectory.h
@@ -26,42 +26,60 @@ class Account;
 class LIB_EXPORT NameDirectory : public QObject
 {
     Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
+    Q_CLASSINFO("RegisterEnumClassesUnscoped", "false")
+#endif
 public:
+//Register name status
+enum class RegisterNameStatus {
+    SUCCESS = 0,
+    WRONG_PASSWORD = 1,
+    INVALID_NAME = 2,
+    ALREADY_TAKEN = 3,
+    NETWORK_ERROR = 4
+};
+#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
+Q_ENUM(RegisterNameStatus)
+#endif
 
-    //Register name status
-    enum class RegisterNameStatus {
-        SUCCESS = 0,
-        WRONG_PASSWORD = 1,
-        INVALID_NAME = 2,
-        ALREADY_TAKEN = 3,
-        NETWORK_ERROR = 4
-    };
-    Q_ENUMS(RegisterNameStatus)
+//Lookup name status
+enum class LookupStatus {
+    SUCCESS = 0,
+    INVALID_NAME = 1,
+    NOT_FOUND = 2,
+    ERROR = 3
+};
+#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
+Q_ENUM(LookupStatus)
+#endif
 
-    //Lookup name status
-    enum class LookupStatus {
-        SUCCESS = 0,
-        INVALID_NAME = 1,
-        NOT_FOUND = 2,
-        ERROR = 3
-    };
-    Q_ENUMS(LookupStatus)
+enum class ExportOnRingStatus {
+    SUCCESS = 0,
+    WRONG_PASSWORD = 1,
+    NETWORK_ERROR = 2,
+    INVALID
+};
+#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
+    Q_ENUM(ExportOnRingStatus)
+#endif
 
     //Singleton
     static NameDirectory& instance();
 
     //Lookup
-    Q_INVOKABLE bool lookupName    (const QString& nameServiceURL, const QString& name    ) const;
-    Q_INVOKABLE bool lookupAddress (const QString& nameServiceURL, const QString& address ) const;
+    Q_INVOKABLE bool lookupName(const QString& nameServiceURL, const QString& name) const;
+    Q_INVOKABLE bool lookupAddress(const QString& nameServiceURL, const QString& address) const;
 
 private:
     //Constructors & Destructors
-    explicit NameDirectory ();
+    explicit NameDirectory();
     virtual  ~NameDirectory();
 
     NameDirectoryPrivate* d_ptr;
+#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
     Q_DECLARE_PRIVATE(NameDirectory)
     Q_DISABLE_COPY(NameDirectory)
+#endif
 
 Q_SIGNALS:
     ///RegisterName has ended
@@ -69,8 +87,10 @@ Q_SIGNALS:
 
     ///Name or address lookup has completed
     void registeredNameFound(NameDirectory::LookupStatus status, const QString& address, const QString& name);
-};
 
+    // Export account has ended with pin generated
+    void exportOnRingEnded(NameDirectory::ExportOnRingStatus status, const QString& pin);
+};
+#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
 Q_DECLARE_METATYPE(NameDirectory*)
-Q_DECLARE_METATYPE(NameDirectory::RegisterNameStatus)
-Q_DECLARE_METATYPE(NameDirectory::LookupStatus)
+#endif
diff --git a/src/newaccountmodel.cpp b/src/newaccountmodel.cpp
index 053b6f6fc8ac90427103e5e6f942ee161f4fa12b..c4e4fc69563f1a72f4735ca0f16163fa9e04d113 100644
--- a/src/newaccountmodel.cpp
+++ b/src/newaccountmodel.cpp
@@ -176,7 +176,7 @@ NewAccountModel::NewAccountModel(Lrc& lrc,
                                  const BehaviorController& behaviorController,
                                  MigrationCb& willMigrateCb,
                                  MigrationCb& didMigrateCb)
-: QObject()
+: QObject(nullptr)
 , pimpl_(std::make_unique<NewAccountModelPimpl>(*this, lrc, callbacksHandler, behaviorController,
                                                 willMigrateCb, didMigrateCb))
 {
diff --git a/src/newcallmodel.cpp b/src/newcallmodel.cpp
index 13fb5a370ad0c71c0b236f160827d1377fac83bb..837c725166fa0d2507a25cdb328b2a550dc95cba 100644
--- a/src/newcallmodel.cpp
+++ b/src/newcallmodel.cpp
@@ -193,7 +193,8 @@ public Q_SLOTS:
 };
 
 NewCallModel::NewCallModel(const account::Info& owner, const CallbacksHandler& callbacksHandler)
-: owner(owner)
+: QObject(nullptr)
+, owner(owner)
 , pimpl_(std::make_unique<NewCallModelPimpl>(*this, callbacksHandler))
 {
 }
diff --git a/src/private/namedirectory_p.h b/src/private/namedirectory_p.h
index bd5ce235aa667ed0da127873c62e811892747e6a..db3ddefa1a0d37ca30e6724185d672036b15a56f 100644
--- a/src/private/namedirectory_p.h
+++ b/src/private/namedirectory_p.h
@@ -19,9 +19,9 @@
 
 #include "namedirectory.h"
 
-typedef void (NameDirectoryPrivate::*NameDirectoryPrivateFct)();
+typedef void (NameDirectoryPrivate::* NameDirectoryPrivateFct)();
 
-class NameDirectoryPrivate: public QObject
+class NameDirectoryPrivate : public QObject
 {
     Q_OBJECT
 
@@ -34,5 +34,5 @@ public:
 public Q_SLOTS:
     void slotNameRegistrationEnded(const QString& accountId, int status, const QString& name);
     void slotRegisteredNameFound(const QString& accountId, int status, const QString& address, const QString& name);
-
+    void slotExportOnRingEnded(const QString& accountId, int status, const QString& pin);
 };