diff --git a/CMakeLists.txt b/CMakeLists.txt
index bcc8f9897f45aeb0ef2b2ebbb720f82ec45cde4f..94bf5d85acf9716dc37d2e407748fc7de0aa9998 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -232,6 +232,7 @@ set(${PROJECT_NAME}_HEADERS
     include/eigenpy/eigen-to-python.hpp
     include/eigenpy/eigen-from-python.hpp
     include/eigenpy/eigen-typedef.hpp
+    include/eigenpy/id.hpp
     include/eigenpy/numpy-map.hpp
     include/eigenpy/geometry.hpp
     include/eigenpy/geometry-conversion.hpp
diff --git a/include/eigenpy/fwd.hpp b/include/eigenpy/fwd.hpp
index c511b569097978a51e659340a5fb13ddacfdac44..acc8edc1100f8d34496eb2426c4590b48452cc25 100644
--- a/include/eigenpy/fwd.hpp
+++ b/include/eigenpy/fwd.hpp
@@ -200,5 +200,6 @@ struct has_operator_equal : internal::has_operator_equal_impl<T1, T2>::type {};
 }  // namespace eigenpy
 
 #include "eigenpy/alignment.hpp"
+#include "eigenpy/id.hpp"
 
 #endif  // ifndef __eigenpy_fwd_hpp__
diff --git a/include/eigenpy/id.hpp b/include/eigenpy/id.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..af56d79f1ee2daf2c02cebf79bd8afb71eb016a9
--- /dev/null
+++ b/include/eigenpy/id.hpp
@@ -0,0 +1,33 @@
+//
+// Copyright (c) 2024 INRIA
+//
+
+#ifndef __eigenpy_id_hpp__
+#define __eigenpy_id_hpp__
+
+#include <boost/python.hpp>
+#include <boost/cstdint.hpp>
+
+namespace eigenpy {
+
+///
+/// \brief Add the Python method id to retrieving a unique id for a given object
+/// exposed with Boost.Python
+///
+template <class C>
+struct IdVisitor : public bp::def_visitor<IdVisitor<C> > {
+  template <class PyClass>
+  void visit(PyClass& cl) const {
+    cl.def("id", &id, bp::arg("self"),
+           "Returns the unique identity of an object.\n"
+           "For object held in C++, it corresponds to its memory address.");
+  }
+
+ private:
+  static boost::int64_t id(const C& self) {
+    return boost::int64_t(reinterpret_cast<const void*>(&self));
+  }
+};
+}  // namespace eigenpy
+
+#endif  // ifndef __eigenpy_id_hpp__