diff --git a/lib/wp/private.h b/lib/wp/private.h
index dfbfc29c24f28b75dc7d5207bdcc0ea01a16d69b..60c8bf173a43b1e47da7bc4f09326453c2e2fc29 100644
--- a/lib/wp/private.h
+++ b/lib/wp/private.h
@@ -179,6 +179,10 @@ WpSpaPod * wp_spa_props_build_props (WpSpaProps * self);
 GPtrArray * wp_spa_props_build_propinfo (WpSpaProps * self);
 GPtrArray * wp_spa_props_build_all_pods (WpSpaProps * self);
 
+/* session item */
+
+void wp_session_item_set_parent (WpSessionItem *self, WpSessionItem *parent);
+
 /* impl endpoint */
 
 #define WP_TYPE_IMPL_ENDPOINT (wp_impl_endpoint_get_type ())
diff --git a/lib/wp/session-bin.c b/lib/wp/session-bin.c
index 524c7d48c84931abf58b90f4588f1597b0fc8471..4ddfb33b3d56bd697eeaf2517a111264a82f05fc 100644
--- a/lib/wp/session-bin.c
+++ b/lib/wp/session-bin.c
@@ -96,6 +96,7 @@ wp_session_bin_add (WpSessionBin *self, WpSessionItem *item)
     return FALSE;
 
   g_ptr_array_add (priv->items, item);
+  wp_session_item_set_parent (item, WP_SESSION_ITEM (self));
   return TRUE;
 }
 
@@ -112,6 +113,7 @@ gboolean
 wp_session_bin_remove (WpSessionBin *self, WpSessionItem *item)
 {
   WpSessionBinPrivate *priv = wp_session_bin_get_instance_private (self);
+  wp_session_item_set_parent (item, NULL);
   return g_ptr_array_remove_fast (priv->items, item);
 }
 
diff --git a/lib/wp/session-item.c b/lib/wp/session-item.c
index ea8e699026f2bde31b3afddc3148103fb0db2761..f2c901321980e8e66e253ecf97ddd01adf783fc2 100644
--- a/lib/wp/session-item.c
+++ b/lib/wp/session-item.c
@@ -78,6 +78,7 @@ struct _WpSessionItemPrivate
 {
   GWeakRef session;
   guint32 flags;
+  GWeakRef parent;
 
   union {
     WpProxy *impl_proxy;
@@ -106,6 +107,7 @@ wp_session_item_init (WpSessionItem * self)
       wp_session_item_get_instance_private (self);
 
   g_weak_ref_init (&priv->session, NULL);
+  g_weak_ref_init (&priv->parent, NULL);
 }
 
 static void
@@ -125,6 +127,7 @@ wp_session_item_finalize (GObject * object)
   WpSessionItemPrivate *priv = wp_session_item_get_instance_private (self);
 
   g_weak_ref_clear (&priv->session);
+  g_weak_ref_clear (&priv->parent);
 
   G_OBJECT_CLASS (wp_session_item_parent_class)->finalize (object);
 }
@@ -359,6 +362,45 @@ wp_session_item_reset (WpSessionItem * self)
   WP_SESSION_ITEM_GET_CLASS (self)->reset (self);
 }
 
+/**
+ * wp_session_item_get_parent:
+ * @self: the session item
+ *
+ * Gets the item's parent, which is the #WpSessionBin this item has been added
+ * to, or NULL if the item does not belong to a session bin.
+ *
+ * Returns: (nullable) (transfer full): the item's parent.
+ */
+WpSessionItem *
+wp_session_item_get_parent (WpSessionItem * self)
+{
+  g_return_val_if_fail (WP_IS_SESSION_ITEM (self), NULL);
+
+  WpSessionItemPrivate *priv =
+      wp_session_item_get_instance_private (self);
+  return g_weak_ref_get (&priv->parent);
+}
+
+/**
+ * wp_session_item_set_parent:
+ * @self: the session item
+ *
+ * Gets the item's parent, which is the #WpSessionBin this item has been added
+ * to, or NULL if the item does not belong to a session bin.
+ *
+ * Returns: (nullable) (transfer full): the item's parent.
+ */
+void
+wp_session_item_set_parent (WpSessionItem *self, WpSessionItem *parent)
+{
+  g_return_if_fail (WP_IS_SESSION_ITEM (self));
+
+  WpSessionItemPrivate *priv =
+      wp_session_item_get_instance_private (self);
+
+  g_weak_ref_set (&priv->parent, parent);
+}
+
 /**
  * wp_session_item_get_flags:
  * @self: the session item
diff --git a/lib/wp/session-item.h b/lib/wp/session-item.h
index 0f8f45dd7c5224bb78949b485cd2b4db08665a13..ed78549afc36516b2303292ba03ed41dd3726693 100644
--- a/lib/wp/session-item.h
+++ b/lib/wp/session-item.h
@@ -120,6 +120,9 @@ struct _WpSessionItemClass
 WP_API
 void wp_session_item_reset (WpSessionItem * self);
 
+WP_API
+WpSessionItem * wp_session_item_get_parent (WpSessionItem * self);
+
 /* flags */
 
 WP_API