diff --git a/src/qTbot/src/public/qTbot/httpexception.cpp b/src/qTbot/src/public/qTbot/httpexception.cpp
new file mode 100644
index 0000000..9818efa
--- /dev/null
+++ b/src/qTbot/src/public/qTbot/httpexception.cpp
@@ -0,0 +1,33 @@
+//#
+//# Copyright (C) 2023-2024 QuasarApp.
+//# Distributed under the GPLv3 software license, see the accompanying
+//# Everyone is permitted to copy and distribute verbatim copies
+//# of this license document, but changing it is not allowed.
+//#
+
+#include "httpexception.h"
+
+HttpException::HttpException(QNetworkReply::NetworkError code,
+                             const QByteArray &erroString) {
+
+    if (erroString.size()) {
+        _errText = erroString;
+    } else {
+
+        _errText = QByteArray("Http request fonoshed with code: ").
+                   append(QString::number(code).toLatin1());
+    }
+}
+
+const char *HttpException::what() const noexcept {
+    return _errText.constData();
+}
+
+void HttpException::raise() const {
+    throw *this;
+}
+
+QException *HttpException::clone() const {
+    return new HttpException(QNetworkReply::NetworkError(0),
+                             _errText);
+}
diff --git a/src/qTbot/src/public/qTbot/httpexception.h b/src/qTbot/src/public/qTbot/httpexception.h
new file mode 100644
index 0000000..e8c1799
--- /dev/null
+++ b/src/qTbot/src/public/qTbot/httpexception.h
@@ -0,0 +1,36 @@
+//#
+//# Copyright (C) 2023-2024 QuasarApp.
+//# Distributed under the GPLv3 software license, see the accompanying
+//# Everyone is permitted to copy and distribute verbatim copies
+//# of this license document, but changing it is not allowed.
+//#
+
+#include <QException>
+#include <QNetworkReply>
+
+
+#ifndef HTTPEXCEPTION_H
+#define HTTPEXCEPTION_H
+
+/**
+ * @brief The HttpException class is base exaption that will raise on all errors of the HTTP protocol,
+ */
+class HttpException: public QException
+{
+public:
+    HttpException(QNetworkReply::NetworkError code, const QByteArray& erroString = {});
+
+    // exception interface
+public:
+    const char *what() const noexcept;
+
+    // QException interface
+public:
+    void raise() const;
+    QException *clone() const;
+
+private:
+    QByteArray _errText;
+};
+
+#endif // HTTPEXCEPTION_H
diff --git a/src/qTbot/src/public/qTbot/ibot.cpp b/src/qTbot/src/public/qTbot/ibot.cpp
index a1b72f2..8855ac7 100644
--- a/src/qTbot/src/public/qTbot/ibot.cpp
+++ b/src/qTbot/src/public/qTbot/ibot.cpp
@@ -5,16 +5,18 @@
 //# of this license document, but changing it is not allowed.
 //#
 
+#include "httpexception.h"
 #include "ibot.h"
 #include "qstandardpaths.h"
 
 #include <QNetworkReply>
+#include <QPromise>
 
 namespace qTbot {
 
 IBot::IBot() {
     _manager = new QNetworkAccessManager();
-    _manager->setAutoDeleteReplies(false);
+    _manager->setAutoDeleteReplies(true);
 }
 
 IBot::~IBot() {
@@ -48,12 +50,11 @@ void IBot::incomeNewUpdate(const QSharedPointer<iUpdate> &message) {
     }
 }
 
-QSharedPointer<QNetworkReply>
+QFuture<QByteArray>
 IBot::sendRequest(const QSharedPointer<iRequest> &rquest) {
-    if (!rquest)
-        return nullptr;
 
-    doRemoveFinishedRequests();
+    if (!rquest)
+        return {};
 
     auto && url = makeUrl(rquest);
 
@@ -61,17 +62,13 @@ IBot::sendRequest(const QSharedPointer<iRequest> &rquest) {
     qDebug() << url;
 #endif
 
-    QSharedPointer<QNetworkReply> networkReplay;
+    QNetworkReply* networkReplay = nullptr;
     QSharedPointer<QHttpMultiPart> httpData;
 
     switch (rquest->method()) {
     case iRequest::Get: {
-        auto reply = _manager->get(QNetworkRequest(url));
+        networkReplay = _manager->get(QNetworkRequest(url));
 
-        // we control replay object wia shared pointers.
-        reply->setParent(nullptr);
-
-        networkReplay.reset(reply);
         break;
     }
 
@@ -85,38 +82,43 @@ IBot::sendRequest(const QSharedPointer<iRequest> &rquest) {
 
         httpData = rquest->argsToMultipartFormData();
         if (httpData) {
-            auto reply = _manager->post(netRequest, httpData.data());
+            networkReplay = _manager->post(netRequest, httpData.data());
 
-            // we control replay object wia shared pointers.
-            reply->setParent(nullptr);
-
-            networkReplay.reset(reply);
         } else {
-            return nullptr;
+            return {};
         }
 
         break;
     }
 
-    size_t address = reinterpret_cast<size_t>(networkReplay.get());
-    _replayStorage[address] = networkReplay;
+    if (!networkReplay) {
+        return {};
+    }
 
-    connect(networkReplay.get(), &QNetworkReply::finished, this,
-            [this, address, httpData]() {
-                _toRemove.push_back(address);
-            });
+    auto&& promise = QSharedPointer<QPromise<QByteArray>>::create();
 
-    connect(networkReplay.get(), &QNetworkReply::errorOccurred, this,
-            [this, address](QNetworkReply::NetworkError err){
-                qWarning() << "The reqeust " << address << " finished with error code : " << err;
-                if (auto&& replay = _replayStorage.value(address)) {
-                    qWarning() << replay->errorString();
-                }
+    networkReplay->connect(networkReplay, &QNetworkReply::finished, [networkReplay, promise](){
+        promise->addResult(networkReplay->readAll());
+        promise->finish();
+    });
 
-                _toRemove.push_back(address);
-            });
+    networkReplay->connect(networkReplay, &QNetworkReply::errorOccurred, [networkReplay, promise](QNetworkReply::NetworkError ){
+        promise->setException(HttpException(networkReplay->error(), networkReplay->errorString().toLatin1()));
+        promise->finish();
+    });
 
-    return networkReplay;
+    auto && setProggress = [promise](qint64 bytesCurrent, qint64 bytesTotal){
+
+        if (promise->future().progressMaximum() != bytesTotal)
+            promise->setProgressRange(0, bytesTotal);
+
+        promise->setProgressValue(bytesCurrent);
+    };
+
+    networkReplay->connect(networkReplay, &QNetworkReply::downloadProgress, setProggress);
+    networkReplay->connect(networkReplay, &QNetworkReply::uploadProgress, setProggress);
+
+    return promise->future();
 }
 
 void IBot::markUpdateAsProcessed(const QSharedPointer<iUpdate> &message) {
@@ -139,14 +141,6 @@ void IBot::handleIncomeNewUpdate(const QSharedPointer<iUpdate> & message) {
     emit sigReceiveUpdate(message);
 }
 
-void IBot::doRemoveFinishedRequests() {
-    for (auto address: std::as_const(_toRemove)) {
-        _replayStorage.remove(address);
-    }
-
-    _toRemove.clear();
-}
-
 QSet<unsigned long long> IBot::processed() const {
     return _processed;
 }
diff --git a/src/qTbot/src/public/qTbot/ibot.h b/src/qTbot/src/public/qTbot/ibot.h
index e89d900..56530ab 100644
--- a/src/qTbot/src/public/qTbot/ibot.h
+++ b/src/qTbot/src/public/qTbot/ibot.h
@@ -23,6 +23,7 @@
 #include <QNetworkReply>
 #include <QObject>
 #include <QSharedPointer>
+#include <qfuture.h>
 
 namespace qTbot {
 
@@ -177,7 +178,7 @@ protected:
      * @return shared pointer to the request replay.
      * @note The raplay will be removed from local storage only after error or finishing, If you want to save replay just make local copy of the shared pointer.
      */
-    QSharedPointer<QNetworkReply>
+    QFuture<QByteArray>
     sendRequest(const QSharedPointer<iRequest>& rquest);
 
     /**
@@ -234,7 +235,6 @@ signals:
     void sigStopRequire();
 
 private:
-    void doRemoveFinishedRequests();
 
     QByteArray _token;
     QString _name;
@@ -242,8 +242,6 @@ private:
     QSet<unsigned long long> _processed;
     QNetworkAccessManager *_manager = nullptr;
 
-    QMap<size_t,QSharedPointer<QNetworkReply>> _replayStorage;
-    QList<size_t> _toRemove;
 
 };