diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h
index de338c616641c074..f6991a50900e6956 100644
--- a/include/libcamera/camera.h
+++ b/include/libcamera/camera.h
@@ -16,7 +16,9 @@
 namespace libcamera {
 
 class Buffer;
+class BufferPool;
 class PipelineHandler;
+class Request;
 class Stream;
 class StreamConfiguration;
 
@@ -42,6 +44,10 @@ public:
 	streamConfiguration(std::vector<Stream *> &streams);
 	int configureStreams(std::map<Stream *, StreamConfiguration> &config);
 
+	BufferPool *bufferPool(Stream *);
+	Request *createRequest(std::map<Stream *, Buffer *> &resources);
+	int queueRequest(Request *request);
+
 	int start();
 	int stop();
 
@@ -55,6 +61,7 @@ private:
 	std::shared_ptr<PipelineHandler> pipe_;
 	std::string name_;
 	std::vector<Stream *> streams_;
+	std::map<Stream *, BufferPool *> bufferPools_;
 
 	bool acquired_;
 	bool disconnected_;
diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp
index bf09acfdb9cd0007..de78536993601ee3 100644
--- a/src/libcamera/camera.cpp
+++ b/src/libcamera/camera.cpp
@@ -246,7 +246,107 @@ int Camera::configureStreams(std::map<Stream *, StreamConfiguration> &config)
 	if (!config.size())
 		return -EINVAL;
 
-	return pipe_->configureStreams(this, config);
+	int ret = pipe_->configureStreams(this, config);
+	if (ret)
+		return ret;
+
+	bufferPools_ = pipe_->allocateBuffers(this, config);
+	if (!bufferPools_.size())
+		return -EINVAL;
+
+	return 0;
+}
+
+/**
+ * \brief Retrieve the buffer pool for a stream
+ * \param[in] stream Stream to retrieve buffer pool from
+ *
+ * Retrieve the buffer pool for a specific stream, if one exists. To be able to
+ * queue request to the camera the application needs to create requests and
+ * attache buffers to the request. To get hold of buffers to associate with the
+ * request the streams buffer pool needs to be retrieved. This interface allows
+ * the application to get hold of the streams buffer pool.
+ *
+ * The buffer pools are created when the application configures the camera,
+ * prior to configuration of the camera no buffer pools exists this calling
+ * this function at that time will return a nullptr.
+ *
+ * \return pointer to the buffer pool, nullptr on error
+ */
+BufferPool *Camera::bufferPool(Stream *stream)
+{
+	if (disconnected_)
+		return nullptr;
+
+	if (!acquired_)
+		return nullptr;
+
+	if (bufferPools_.find(stream) == bufferPools_.end())
+		return nullptr;
+
+	return bufferPools_[stream];
+}
+
+/**
+ * \brief Create a request object for the camera
+ * \param[in] resources Array of streams and buffer to create a request from
+ *
+ * Before an application can queue a request to the camera it needs to be
+ * created, this interface allows the application to create such requests. The
+ * application needs to supply a map of streams and buffers that the request
+ * should process once it's queued to the camera.
+ *
+ * Once a request object have been created the application can set controls
+ * that are to be used to capture the particular frame before queuing it to
+ * the camera.
+ *
+ * \return pointer to the buffer pool, nullptr on error
+ */
+Request *Camera::createRequest(std::map<Stream *, Buffer *> &resources)
+{
+	if (disconnected_)
+		return nullptr;
+
+	if (!acquired_)
+		return nullptr;
+
+	if (resources.size() == 0)
+		return nullptr;
+
+	return new Request(resources);
+}
+
+/**
+ * \brief Queue a request to the camera
+ * \param[in] request The request to queue to the camera
+ *
+ * The application can once its got hold of a request queue it to a running
+ * camera at any point. The application get hold of a request by either creating
+ * it or reusing a old request once it's been completed and the application have
+ * no further use of the buffers it contained.
+ *
+ * Once a request have been queued to the camera it will be notified once the
+ * request is complete and the associated buffers can be consumed.
+ *
+ * \return 0 on success or a negative error code on error.
+ * \retval -ENODEV The camera is not connected to any hardware
+ * \retval -EACCES The user has not acquired exclusive access to the camera
+ */
+int Camera::queueRequest(Request *request)
+{
+	if (disconnected_)
+		return -ENODEV;
+
+	if (!acquired_)
+		return -EACCES;
+
+	int ret = request->prepare();
+	if (ret) {
+		LOG(Camera, Error) << "Failed to connect request resources";
+		return ret;
+	}
+
+	return pipe_->queueRequest(this, request);
 }
 
 /**
