diff --git a/include/opendht/dht_proxy_server.h b/include/opendht/dht_proxy_server.h
index 63d527c2d7b103b24447dda913b5820a06c5b151..0c00493850445467849d4823d0f59fece8a778ed 100644
--- a/include/opendht/dht_proxy_server.h
+++ b/include/opendht/dht_proxy_server.h
@@ -392,7 +392,7 @@ private:
         template <typename Packer>
         void msgpack_pack(Packer& p) const
         {
-            p.pack_map(2 + (sessionCtx ? 1 : 0) + (clientId.empty() ? 0 : 1) + (type == PushType::None ? 0 : 2));
+            p.pack_map(2 + (sessionCtx ? 1 : 0) + (clientId.empty() ? 0 : 1) + (type == PushType::None ? 0 : 2) + (topic.empty() ? 0 : 1));
             p.pack("value"); p.pack(value);
             p.pack("exp"); p.pack(to_time_t(expiration));
             if (not clientId.empty()) {
@@ -406,6 +406,9 @@ private:
                 p.pack("t"); p.pack(type);
                 p.pack("token"); p.pack(pushToken);
             }
+            if (not topic.empty()) {
+                p.pack("top"); p.pack(topic);
+            }
         }
 
         void msgpack_unpack(const msgpack::object& o);
@@ -437,7 +440,7 @@ private:
         template <typename Packer>
         void msgpack_pack(Packer& p) const
         {
-            p.pack_map(sessionCtx ? 4 : 3);
+            p.pack_map(3 + (sessionCtx ? 1 : 0) + (topic.empty() ? 0 : 1));
             p.pack("cid"); p.pack(clientId);
             p.pack("exp"); p.pack(to_time_t(expiration));
             if (sessionCtx) {
@@ -445,6 +448,9 @@ private:
                 p.pack("sid"); p.pack(sessionCtx->sessionId);
             }
             p.pack("t"); p.pack(type);
+            if (!topic.empty()) {
+                p.pack("top"); p.pack(topic);
+            }
         }
 
         void msgpack_unpack(const msgpack::object& o);
diff --git a/src/dht_proxy_server.cpp b/src/dht_proxy_server.cpp
index 515b72c95702e500a4c3dc8544ab01c720759f95..0ea70d4d2938d01789dd7b27039cf49a9763d06c 100644
--- a/src/dht_proxy_server.cpp
+++ b/src/dht_proxy_server.cpp
@@ -173,6 +173,9 @@ DhtProxyServer::PermanentPut::msgpack_unpack(const msgpack::object& o)
     if (auto val = findMapValue(o, "value"sv)) {
         value = std::make_shared<dht::Value>(*val);
     }
+    if (auto top = findMapValue(o, "top"sv)) {
+        topic = top->as<std::string>();
+    }
 }
 
 #ifdef OPENDHT_PUSH_NOTIFICATIONS
@@ -194,6 +197,9 @@ DhtProxyServer::Listener::msgpack_unpack(const msgpack::object& o)
     if (auto t = findMapValue(o, "t"sv)) {
         type = t->as<PushType>();
     }
+    if (auto top = findMapValue(o, "top"sv)) {
+        topic = top->as<std::string>();
+    }
 }
 #endif