diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h
index 94cee7bd86bb..20d51c191ecd 100644
--- a/include/libcamera/camera.h
+++ b/include/libcamera/camera.h
@@ -13,6 +13,7 @@
 #include <set>
 #include <stdint.h>
 #include <string>
+#include <unordered_set>
 
 #include <libcamera/base/class.h>
 #include <libcamera/base/flags.h>
@@ -122,6 +123,7 @@ public:
 
 	const std::string &id() const;
 
+	Signal<Request *, std::unordered_set<const ControlId *>> metadataAvailable;
 	Signal<Request *, FrameBuffer *> bufferCompleted;
 	Signal<Request *> requestCompleted;
 	Signal<> disconnected;
diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp
index 4c865a46af53..63e78b24e271 100644
--- a/src/libcamera/camera.cpp
+++ b/src/libcamera/camera.cpp
@@ -886,6 +886,48 @@ const std::string &Camera::id() const
 	return _d()->id_;
 }
 
+/**
+ * \var Camera::metadataAvailable
+ * \brief Signal emitted when metadata for a request are available
+ *
+ * The metadataAvailable signal notifies applications about the availability
+ * of metadata for a request before the request completes.
+ *
+ * As metadata results could be large in size, the signal transports the ids
+ * of the metadata that have just been made available, but the actual control
+ * values are stored in the Camera::metadata() list.
+ *
+ * Applications can access the value of the newly available metadata results
+ * with:
+ *
+ * \code
+
+	void metadataAvailableHandler(Request *request,
+				      std::unordered_set<const ControlId *> ids)
+	{
+		const ControlList &metadata = request->metadata();
+
+		for (const auto id : ids) {
+			ControlValue &value = metadata.get(id->id());
+
+			....
+		}
+	}
+   \endcode
+ *
+ * This signal is emitted multiple times for the same request, it is in facts
+ * emitted by the framework every time a new metadata list is made available
+ * by the Camera to the application.
+ *
+ * The sum of all metadata lists reported through this signal is equal to
+ * Request::metadata() list when the Request completes.
+ *
+ * Application can opt-in to handle this signal to receive fast notifications
+ * of metadata availability or can equally access the full metadata list
+ * at Request complete time through Request::metadata() if they have no interest
+ * in early metadata notification.
+ */
+
 /**
  * \var Camera::bufferCompleted
  * \brief Signal emitted when a buffer for a request queued to the camera has
