diff --git a/Documentation/Doxyfile.in b/Documentation/Doxyfile.in
index a86ea6c1..6689ace1 100644
--- a/Documentation/Doxyfile.in
+++ b/Documentation/Doxyfile.in
@@ -68,7 +68,14 @@ EXCLUDE_SYMBOLS        = libcamera::BoundMethodArgs \
 
 EXCLUDE_SYMLINKS       = YES
 
-HTML_OUTPUT            = api-html
+INTERNAL_DOCS          = @INTERNAL_DOCS@
+
+HIDE_UNDOC_CLASSES     = @HIDE_UNDOC_CLASSES@
+HIDE_UNDOC_MEMBERS     = @HIDE_UNDOC_MEMBERS@
+
+HTML_OUTPUT            = @HTML_OUTPUT@
+
+ENABLED_SECTIONS       = @ENABLED_SECTIONS@
 
 GENERATE_LATEX         = NO
 
diff --git a/Documentation/meson.build b/Documentation/meson.build
index 7a58fec8..7d2b7e33 100644
--- a/Documentation/meson.build
+++ b/Documentation/meson.build
@@ -21,14 +21,25 @@ if doxygen.found() and dot.found()
         doxygen_predefined += '@0@=@1@'.format(key, config_h.get(key))
     endforeach
 
+    # We run doxygen twice - once to build a reduced documentation set that's
+    # more appropriate for application developers, and a second run that covers
+    # all of the library's objects for libcamera developers. To achieve this we
+    # flag as \internal the comments for objects we wish to hide, and remove the
+    # auto generated documents via HIDE_UNDOC_CLASSES and HIDE_UNDOC_MEMBERS.
+
+
     cdata.set('PREDEFINED', ' \\\n\t\t\t '.join(doxygen_predefined))
+    cdata.set('INTERNAL_DOCS', 'NO')
+    cdata.set('HIDE_UNDOC_CLASSES', 'YES')
+    cdata.set('HIDE_UNDOC_MEMBERS', 'YES')
+    cdata.set('HTML_OUTPUT', 'api-html')
+    cdata.set('ENABLED_SECTIONS', '')
 
     doxyfile = configure_file(input : 'Doxyfile.in',
                               output : 'Doxyfile',
                               configuration : cdata)
 
-    doxygen_input = [
-        doxyfile,
+    global_doxygen_input = [
         libcamera_base_headers,
         libcamera_base_sources,
         libcamera_internal_headers,
@@ -41,16 +52,44 @@ if doxygen.found() and dot.found()
     ]
 
     if is_variable('ipu3_ipa_sources')
-        doxygen_input += [ipu3_ipa_sources]
+        global_doxygen_input += [ipu3_ipa_sources]
     endif
 
+    public_doxygen_input = global_doxygen_input
+    public_doxygen_input += doxyfile
+
     custom_target('doxygen',
-                  input : doxygen_input,
+                  input : public_doxygen_input,
                   output : 'api-html',
                   command : [doxygen, doxyfile],
                   install : true,
                   install_dir : doc_install_dir,
                   install_tag : 'doc')
+
+    # This is the internal documentation, so _don't_ hide undocumented classes
+    # as we want everything to show up.
+    cdata_internal = configuration_data()
+    cdata_internal.merge_from(cdata)
+    cdata_internal.set('HTML_OUTPUT', 'internal-api-html')
+    cdata_internal.set('INTERNAL_DOCS', 'YES')
+    cdata_internal.set('HIDE_UNDOC_CLASSES', 'NO')
+    cdata_internal.set('HIDE_UNDOC_MEMBERS', 'NO')
+    cdata_internal.set('ENABLED_SECTIONS', 'internal')
+
+    doxyfile_internal = configure_file(input : 'Doxyfile.in',
+                                       output : 'Doxyfile-internal',
+                                       configuration : cdata_internal)
+
+    internal_doxygen_input = global_doxygen_input
+    internal_doxygen_input += doxyfile_internal
+
+    custom_target('doxygen-internal',
+                  input : internal_doxygen_input,
+                  output : 'internal-api-html',
+                  command : [doxygen, doxyfile_internal],
+                  install : true,
+                  install_dir : doc_install_dir,
+                  install_tag : 'doc-internal')
 endif
 
 #
diff --git a/include/libcamera/ipa/core.mojom b/include/libcamera/ipa/core.mojom
index bce79724..f4a7dc4b 100644
--- a/include/libcamera/ipa/core.mojom
+++ b/include/libcamera/ipa/core.mojom
@@ -3,6 +3,7 @@
 module libcamera;
 
 /**
+ * \internal
  * \file core_ipa_interface.h
  * \brief libcamera structs for IPAs
  */
@@ -109,6 +110,7 @@ module libcamera;
 };
 
 /**
+ * \internal
  * \struct IPACameraSensorInfo
  * \brief Report the image sensor characteristics
  *
@@ -257,6 +259,7 @@ struct IPACameraSensorInfo {
 };
 
 /**
+ * \internal
  * \struct IPABuffer
  * \brief Buffer information for the IPA interface
  *
@@ -291,6 +294,7 @@ struct IPABuffer {
 };
 
 /**
+ * \internal
  * \struct IPASettings
  * \brief IPA interface initialization settings
  *
@@ -320,6 +324,7 @@ struct IPASettings {
 };
 
 /**
+ * \internal
  * \struct IPAStream
  * \brief Stream configuration for the IPA interface
  *
diff --git a/src/ipa/ipu3/algorithms/af.cpp b/src/ipa/ipu3/algorithms/af.cpp
index 12927eec..25109451 100644
--- a/src/ipa/ipu3/algorithms/af.cpp
+++ b/src/ipa/ipu3/algorithms/af.cpp
@@ -26,6 +26,7 @@
 #include "libipa/histogram.h"
 
 /**
+ * \internal
  * \file af.h
  */
 
@@ -96,6 +97,7 @@ static struct ipu3_uapi_af_filter_config afFilterConfigDefault = {
 };
 
 /**
+ * \internal
  * \class Af
  * \brief An auto-focus algorithm based on IPU3 statistics
  *
diff --git a/src/ipa/ipu3/algorithms/agc.cpp b/src/ipa/ipu3/algorithms/agc.cpp
index 606a237a..e3cfbe57 100644
--- a/src/ipa/ipu3/algorithms/agc.cpp
+++ b/src/ipa/ipu3/algorithms/agc.cpp
@@ -20,6 +20,7 @@
 #include "libipa/histogram.h"
 
 /**
+ * \internal
  * \file agc.h
  */
 
@@ -30,6 +31,7 @@ using namespace std::literals::chrono_literals;
 namespace ipa::ipu3::algorithms {
 
 /**
+ * \internal
  * \class Agc
  * \brief A mean-based auto-exposure algorithm
  *
diff --git a/src/ipa/ipu3/algorithms/awb.cpp b/src/ipa/ipu3/algorithms/awb.cpp
index 5abd4621..11a6dfdc 100644
--- a/src/ipa/ipu3/algorithms/awb.cpp
+++ b/src/ipa/ipu3/algorithms/awb.cpp
@@ -14,6 +14,7 @@
 #include <libcamera/control_ids.h>
 
 /**
+ * \internal
  * \file awb.h
  */
 
@@ -45,6 +46,7 @@ static constexpr double kMaxCellSaturationRatio = 0.8;
 static constexpr uint32_t kMinCellsPerZoneRatio = 255 * 90 / 100;
 
 /**
+ * \internal
  * \struct Accumulator
  * \brief RGB statistics for a given zone
  *
@@ -73,6 +75,7 @@ static constexpr uint32_t kMinCellsPerZoneRatio = 255 * 90 / 100;
  */
 
 /**
+ * \internal
  * \struct Awb::AwbStatus
  * \brief AWB parameters calculated
  *
@@ -118,6 +121,7 @@ static const struct ipu3_uapi_ccm_mat_config imguCssCcmDefault = {
 };
 
 /**
+ * \internal
  * \class Awb
  * \brief A Grey world white balance correction algorithm
  *
diff --git a/src/ipa/ipu3/algorithms/blc.cpp b/src/ipa/ipu3/algorithms/blc.cpp
index e838072a..d5b2f70d 100644
--- a/src/ipa/ipu3/algorithms/blc.cpp
+++ b/src/ipa/ipu3/algorithms/blc.cpp
@@ -10,6 +10,7 @@
 #include <string.h>
 
 /**
+ * \internal
  * \file blc.h
  * \brief IPU3 Black Level Correction control
  */
@@ -19,6 +20,7 @@ namespace libcamera {
 namespace ipa::ipu3::algorithms {
 
 /**
+ * \internal
  * \class BlackLevelCorrection
  * \brief A class to handle black level correction
  *
diff --git a/src/ipa/ipu3/algorithms/tone_mapping.cpp b/src/ipa/ipu3/algorithms/tone_mapping.cpp
index a169894c..83eaa002 100644
--- a/src/ipa/ipu3/algorithms/tone_mapping.cpp
+++ b/src/ipa/ipu3/algorithms/tone_mapping.cpp
@@ -11,6 +11,7 @@
 #include <string.h>
 
 /**
+ * \internal
  * \file tone_mapping.h
  */
 
@@ -19,6 +20,7 @@ namespace libcamera {
 namespace ipa::ipu3::algorithms {
 
 /**
+ * \internal
  * \class ToneMapping
  * \brief A class to handle tone mapping based on gamma
  *
diff --git a/src/ipa/ipu3/ipa_context.cpp b/src/ipa/ipu3/ipa_context.cpp
index 959f314f..6490c0ec 100644
--- a/src/ipa/ipu3/ipa_context.cpp
+++ b/src/ipa/ipu3/ipa_context.cpp
@@ -8,6 +8,7 @@
 #include "ipa_context.h"
 
 /**
+ * \internal
  * \file ipa_context.h
  * \brief Context and state information shared between the algorithms
  */
@@ -15,6 +16,7 @@
 namespace libcamera::ipa::ipu3 {
 
 /**
+ * \internal
  * \struct IPASessionConfiguration
  * \brief Session configuration for the IPA module
  *
@@ -25,6 +27,7 @@ namespace libcamera::ipa::ipu3 {
  */
 
 /**
+ * \internal
  * \struct IPAActiveState
  * \brief The active state of the IPA algorithms
  *
@@ -36,6 +39,7 @@ namespace libcamera::ipa::ipu3 {
  */
 
 /**
+ * \internal
  * \struct IPAContext
  * \brief Global IPA context data shared between all algorithms
  *
@@ -167,6 +171,7 @@ namespace libcamera::ipa::ipu3 {
  */
 
 /**
+ * \internal
  * \struct IPAFrameContext
  * \brief IPU3-specific FrameContext
  *
diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp
index 08ee6eb3..f635f6ac 100644
--- a/src/ipa/ipu3/ipu3.cpp
+++ b/src/ipa/ipu3/ipu3.cpp
@@ -67,6 +67,7 @@ using namespace std::literals::chrono_literals;
 namespace ipa::ipu3 {
 
 /**
+ * \internal
  * \brief The IPU3 IPA implementation
  *
  * The IPU3 Pipeline defines an IPU3-specific interface for communication
diff --git a/src/ipa/libipa/algorithm.cpp b/src/ipa/libipa/algorithm.cpp
index bc1c29a6..a36e628b 100644
--- a/src/ipa/libipa/algorithm.cpp
+++ b/src/ipa/libipa/algorithm.cpp
@@ -8,6 +8,7 @@
 #include "algorithm.h"
 
 /**
+ * \internal
  * \file algorithm.h
  * \brief Algorithm common interface
  */
@@ -17,6 +18,7 @@ namespace libcamera {
 namespace ipa {
 
 /**
+ * \internal
  * \class Algorithm
  * \brief The base class for all IPA algorithms
  * \tparam Module The IPA module type for this class of algorithms
@@ -134,6 +136,7 @@ namespace ipa {
  */
 
 /**
+ * \internal
  * \class AlgorithmFactory
  * \brief Registration of Algorithm classes and creation of instances
  * \tparam _Algorithm The algorithm class type for this factory
diff --git a/src/ipa/libipa/camera_sensor_helper.cpp b/src/ipa/libipa/camera_sensor_helper.cpp
index f0ecc383..23afc954 100644
--- a/src/ipa/libipa/camera_sensor_helper.cpp
+++ b/src/ipa/libipa/camera_sensor_helper.cpp
@@ -12,6 +12,7 @@
 #include <libcamera/base/log.h>
 
 /**
+ * \internal
  * \file camera_sensor_helper.h
  * \brief Helper class that performs sensor-specific parameter computations
  *
@@ -31,6 +32,7 @@ LOG_DEFINE_CATEGORY(CameraSensorHelper)
 namespace ipa {
 
 /**
+ * \internal
  * \class CameraSensorHelper
  * \brief Base class for computing sensor tuning parameters using
  * sensor-specific constants
@@ -112,6 +114,7 @@ double CameraSensorHelper::gain(uint32_t gainCode) const
 }
 
 /**
+ * \internal
  * \enum CameraSensorHelper::AnalogueGainType
  * \brief The gain calculation modes as defined by the MIPI CCS
  *
@@ -159,6 +162,7 @@ double CameraSensorHelper::gain(uint32_t gainCode) const
  */
 
 /**
+ * \internal
  * \struct CameraSensorHelper::AnalogueGainLinearConstants
  * \brief Analogue gain constants for the linear gain model
  *
@@ -180,6 +184,7 @@ double CameraSensorHelper::gain(uint32_t gainCode) const
  */
 
 /**
+ * \internal
  * \struct CameraSensorHelper::AnalogueGainExpConstants
  * \brief Analogue gain constants for the exponential gain model
  *
@@ -191,6 +196,7 @@ double CameraSensorHelper::gain(uint32_t gainCode) const
  */
 
 /**
+ * \internal
  * \struct CameraSensorHelper::AnalogueGainConstants
  * \brief Analogue gain model constants
  *
@@ -218,6 +224,7 @@ double CameraSensorHelper::gain(uint32_t gainCode) const
  */
 
 /**
+ * \internal
  * \class CameraSensorHelperFactoryBase
  * \brief Base class for camera sensor helper factories
  *
@@ -297,6 +304,7 @@ std::vector<CameraSensorHelperFactoryBase *> &CameraSensorHelperFactoryBase::fac
 }
 
 /**
+ * \internal
  * \class CameraSensorHelperFactory
  * \brief Registration of CameraSensorHelperFactory classes and creation of instances
  * \tparam _Helper The camera sensor helper class type for this factory
diff --git a/src/ipa/libipa/fc_queue.cpp b/src/ipa/libipa/fc_queue.cpp
index e812faa5..21656405 100644
--- a/src/ipa/libipa/fc_queue.cpp
+++ b/src/ipa/libipa/fc_queue.cpp
@@ -16,11 +16,13 @@ LOG_DEFINE_CATEGORY(FCQueue)
 namespace ipa {
 
 /**
+ * \internal
  * \file fc_queue.h
  * \brief Queue of per-frame contexts
  */
 
 /**
+ * \internal
  * \struct FrameContext
  * \brief Context for a frame
  *
@@ -39,6 +41,7 @@ namespace ipa {
  */
 
 /**
+ * \internal
  * \class FCQueue
  * \brief A support class for managing FrameContext instances in IPA modules
  * \tparam FrameContext The IPA module-specific FrameContext derived class type
diff --git a/src/ipa/libipa/histogram.cpp b/src/ipa/libipa/histogram.cpp
index 6b5cde8e..0e9f6a62 100644
--- a/src/ipa/libipa/histogram.cpp
+++ b/src/ipa/libipa/histogram.cpp
@@ -11,6 +11,7 @@
 #include <libcamera/base/log.h>
 
 /**
+ * \internal
  * \file histogram.h
  * \brief Class to represent Histograms and manipulate them
  */
@@ -20,6 +21,7 @@ namespace libcamera {
 namespace ipa {
 
 /**
+ * \internal
  * \class Histogram
  * \brief The base class for creating histograms
  *
diff --git a/src/ipa/libipa/module.cpp b/src/ipa/libipa/module.cpp
index ee01f12a..9484a925 100644
--- a/src/ipa/libipa/module.cpp
+++ b/src/ipa/libipa/module.cpp
@@ -8,6 +8,7 @@
 #include "module.h"
 
 /**
+ * \internal
  * \file module.h
  * \brief IPA Module common interface
  */
@@ -26,6 +27,7 @@ LOG_DEFINE_CATEGORY(IPAModuleAlgo)
 namespace ipa {
 
 /**
+ * \internal
  * \class Module
  * \brief The base class for all IPA modules
  * \tparam Context The type of the shared IPA context
diff --git a/src/ipa/rkisp1/algorithms/agc.cpp b/src/ipa/rkisp1/algorithms/agc.cpp
index e5aeb342..70af80e0 100644
--- a/src/ipa/rkisp1/algorithms/agc.cpp
+++ b/src/ipa/rkisp1/algorithms/agc.cpp
@@ -20,6 +20,7 @@
 #include "libipa/histogram.h"
 
 /**
+ * \internal
  * \file agc.h
  */
 
@@ -30,6 +31,7 @@ using namespace std::literals::chrono_literals;
 namespace ipa::rkisp1::algorithms {
 
 /**
+ * \internal
  * \class Agc
  * \brief A mean-based auto-exposure algorithm
  */
diff --git a/src/ipa/rkisp1/algorithms/awb.cpp b/src/ipa/rkisp1/algorithms/awb.cpp
index 744f4a38..82b89ed3 100644
--- a/src/ipa/rkisp1/algorithms/awb.cpp
+++ b/src/ipa/rkisp1/algorithms/awb.cpp
@@ -17,6 +17,7 @@
 #include <libcamera/ipa/core_ipa_interface.h>
 
 /**
+ * \internal
  * \file awb.h
  */
 
@@ -25,6 +26,7 @@ namespace libcamera {
 namespace ipa::rkisp1::algorithms {
 
 /**
+ * \internal
  * \class Awb
  * \brief A Grey world white balance correction algorithm
  */
diff --git a/src/ipa/rkisp1/algorithms/blc.cpp b/src/ipa/rkisp1/algorithms/blc.cpp
index 15324fb1..278587aa 100644
--- a/src/ipa/rkisp1/algorithms/blc.cpp
+++ b/src/ipa/rkisp1/algorithms/blc.cpp
@@ -12,6 +12,7 @@
 #include "libcamera/internal/yaml_parser.h"
 
 /**
+ * \internal
  * \file blc.h
  */
 
@@ -20,6 +21,7 @@ namespace libcamera {
 namespace ipa::rkisp1::algorithms {
 
 /**
+ * \internal
  * \class BlackLevelCorrection
  * \brief RkISP1 Black Level Correction control
  *
diff --git a/src/ipa/rkisp1/algorithms/cproc.cpp b/src/ipa/rkisp1/algorithms/cproc.cpp
index eaa56c37..9f77a681 100644
--- a/src/ipa/rkisp1/algorithms/cproc.cpp
+++ b/src/ipa/rkisp1/algorithms/cproc.cpp
@@ -15,6 +15,7 @@
 #include <libcamera/control_ids.h>
 
 /**
+ * \internal
  * \file cproc.h
  */
 
@@ -23,6 +24,7 @@ namespace libcamera {
 namespace ipa::rkisp1::algorithms {
 
 /**
+ * \internal
  * \class ColorProcessing
  * \brief RkISP1 Color Processing control
  *
diff --git a/src/ipa/rkisp1/algorithms/dpcc.cpp b/src/ipa/rkisp1/algorithms/dpcc.cpp
index 80a1b734..5ae68fda 100644
--- a/src/ipa/rkisp1/algorithms/dpcc.cpp
+++ b/src/ipa/rkisp1/algorithms/dpcc.cpp
@@ -14,6 +14,7 @@
 #include "linux/rkisp1-config.h"
 
 /**
+ * \internal
  * \file dpcc.h
  */
 
@@ -22,6 +23,7 @@ namespace libcamera {
 namespace ipa::rkisp1::algorithms {
 
 /**
+ * \internal
  * \class DefectPixelClusterCorrection
  * \brief RkISP1 Defect Pixel Cluster Correction control
  *
diff --git a/src/ipa/rkisp1/algorithms/dpf.cpp b/src/ipa/rkisp1/algorithms/dpf.cpp
index 5bd7e59f..16931a6f 100644
--- a/src/ipa/rkisp1/algorithms/dpf.cpp
+++ b/src/ipa/rkisp1/algorithms/dpf.cpp
@@ -16,6 +16,7 @@
 #include "linux/rkisp1-config.h"
 
 /**
+ * \internal
  * \file dpf.h
  */
 
@@ -24,6 +25,7 @@ namespace libcamera {
 namespace ipa::rkisp1::algorithms {
 
 /**
+ * \internal
  * \class Dpf
  * \brief RkISP1 Denoise Pre-Filter control
  *
diff --git a/src/ipa/rkisp1/algorithms/filter.cpp b/src/ipa/rkisp1/algorithms/filter.cpp
index 4b89c05a..5576af3c 100644
--- a/src/ipa/rkisp1/algorithms/filter.cpp
+++ b/src/ipa/rkisp1/algorithms/filter.cpp
@@ -14,6 +14,7 @@
 #include <libcamera/control_ids.h>
 
 /**
+ * \internal
  * \file filter.h
  */
 
@@ -22,6 +23,7 @@ namespace libcamera {
 namespace ipa::rkisp1::algorithms {
 
 /**
+ * \internal
  * \class Filter
  * \brief RkISP1 Filter control
  *
diff --git a/src/ipa/rkisp1/algorithms/gsl.cpp b/src/ipa/rkisp1/algorithms/gsl.cpp
index b9f87912..cb4a595a 100644
--- a/src/ipa/rkisp1/algorithms/gsl.cpp
+++ b/src/ipa/rkisp1/algorithms/gsl.cpp
@@ -15,6 +15,7 @@
 #include "linux/rkisp1-config.h"
 
 /**
+ * \internal
  * \file gsl.h
  */
 
@@ -23,6 +24,7 @@ namespace libcamera {
 namespace ipa::rkisp1::algorithms {
 
 /**
+ * \internal
  * \class GammaSensorLinearization
  * \brief RkISP1 Gamma Sensor Linearization control
  *
diff --git a/src/ipa/rkisp1/algorithms/lsc.cpp b/src/ipa/rkisp1/algorithms/lsc.cpp
index a7ccedb1..40c3de9e 100644
--- a/src/ipa/rkisp1/algorithms/lsc.cpp
+++ b/src/ipa/rkisp1/algorithms/lsc.cpp
@@ -19,6 +19,7 @@
 #include "linux/rkisp1-config.h"
 
 /**
+ * \internal
  * \file lsc.h
  */
 
@@ -27,6 +28,7 @@ namespace libcamera {
 namespace ipa::rkisp1::algorithms {
 
 /**
+ * \internal
  * \class LensShadingCorrection
  * \brief RkISP1 Lens Shading Correction control
  *
diff --git a/src/ipa/rkisp1/ipa_context.cpp b/src/ipa/rkisp1/ipa_context.cpp
index 9bbf3684..1d2fedc9 100644
--- a/src/ipa/rkisp1/ipa_context.cpp
+++ b/src/ipa/rkisp1/ipa_context.cpp
@@ -8,6 +8,7 @@
 #include "ipa_context.h"
 
 /**
+ * \internal
  * \file ipa_context.h
  * \brief Context and state information shared between the algorithms
  */
@@ -15,6 +16,7 @@
 namespace libcamera::ipa::rkisp1 {
 
 /**
+ * \internal
  * \struct IPASessionConfiguration
  * \brief Session configuration for the IPA module
  *
@@ -95,6 +97,7 @@ namespace libcamera::ipa::rkisp1 {
  */
 
 /**
+ * \internal
  * \struct IPAActiveState
  * \brief Active state for algorithms
  *
@@ -139,9 +142,11 @@ namespace libcamera::ipa::rkisp1 {
  * \var IPAActiveState::awb
  * \brief State for the Automatic White Balance algorithm
  *
+ * \internal
  * \struct IPAActiveState::awb.gains
  * \brief White balance gains
  *
+ * \internal
  * \struct IPAActiveState::awb.gains.manual
  * \brief Manual white balance gains (set through requests)
  *
@@ -154,6 +159,7 @@ namespace libcamera::ipa::rkisp1 {
  * \var IPAActiveState::awb.gains.manual.blue
  * \brief Manual white balance gain for B channel
  *
+ * \internal
  * \struct IPAActiveState::awb.gains.automatic
  * \brief Automatic white balance gains (computed by the algorithm)
  *
@@ -177,6 +183,7 @@ namespace libcamera::ipa::rkisp1 {
  * \var IPAActiveState::cproc
  * \brief State for the Color Processing algorithm
  *
+ * \internal
  * \struct IPAActiveState::cproc.brightness
  * \brief Brightness level
  *
@@ -199,6 +206,7 @@ namespace libcamera::ipa::rkisp1 {
  * \var IPAActiveState::filter
  * \brief State for the Filter algorithm
  *
+ * \internal
  * \struct IPAActiveState::filter.denoise
  * \brief Denoising level
  *
@@ -207,6 +215,7 @@ namespace libcamera::ipa::rkisp1 {
  */
 
 /**
+ * \internal
  * \struct IPAFrameContext
  * \brief Per-frame context for algorithms
  *
@@ -258,6 +267,7 @@ namespace libcamera::ipa::rkisp1 {
  * \var IPAFrameContext::awb
  * \brief Automatic White Balance parameters for this frame
  *
+ * \internal
  * \struct IPAFrameContext::awb.gains
  * \brief White balance gains
  *
@@ -281,6 +291,7 @@ namespace libcamera::ipa::rkisp1 {
  * \var IPAFrameContext::cproc
  * \brief Color Processing parameters for this frame
  *
+ * \internal
  * \struct IPAFrameContext::cproc.brightness
  * \brief Brightness level
  *
@@ -311,6 +322,7 @@ namespace libcamera::ipa::rkisp1 {
  * \var IPAFrameContext::filter
  * \brief Filter parameters for this frame
  *
+ * \internal
  * \struct IPAFrameContext::filter.denoise
  * \brief Denoising level
  *
@@ -334,6 +346,7 @@ namespace libcamera::ipa::rkisp1 {
  */
 
 /**
+ * \internal
  * \struct IPAContext
  * \brief Global IPA context data shared between all algorithms
  *
diff --git a/src/libcamera/base/backtrace.cpp b/src/libcamera/base/backtrace.cpp
index be30589d..8c0acdfc 100644
--- a/src/libcamera/base/backtrace.cpp
+++ b/src/libcamera/base/backtrace.cpp
@@ -33,6 +33,7 @@
 #include <libcamera/base/utils.h>
 
 /**
+ * \internal
  * \file backtrace.h
  * \brief Generate call stack backtraces
  */
@@ -135,6 +136,7 @@ std::string DwflParser::stackEntry(const void *ip)
 } /* namespace */
 
 /**
+ * \internal
  * \class Backtrace
  * \brief Representation of a call stack backtrace
  *
diff --git a/src/libcamera/base/event_dispatcher.cpp b/src/libcamera/base/event_dispatcher.cpp
index 4be89e81..4829a876 100644
--- a/src/libcamera/base/event_dispatcher.cpp
+++ b/src/libcamera/base/event_dispatcher.cpp
@@ -9,6 +9,7 @@
 #include <libcamera/base/log.h>
 
 /**
+ * \internal
  * \file base/event_dispatcher.h
  */
 
@@ -17,6 +18,7 @@ namespace libcamera {
 LOG_DEFINE_CATEGORY(Event)
 
 /**
+ * \internal
  * \class EventDispatcher
  * \brief Interface to manage the libcamera events and timers
  *
diff --git a/src/libcamera/base/event_dispatcher_poll.cpp b/src/libcamera/base/event_dispatcher_poll.cpp
index 7238a316..a4efec16 100644
--- a/src/libcamera/base/event_dispatcher_poll.cpp
+++ b/src/libcamera/base/event_dispatcher_poll.cpp
@@ -23,6 +23,7 @@
 #include <libcamera/base/utils.h>
 
 /**
+ * \internal
  * \file base/event_dispatcher_poll.h
  */
 
@@ -43,6 +44,7 @@ static const char *notifierType(EventNotifier::Type type)
 }
 
 /**
+ * \internal
  * \class EventDispatcherPoll
  * \brief A poll-based event dispatcher
  */
diff --git a/src/libcamera/base/event_notifier.cpp b/src/libcamera/base/event_notifier.cpp
index fd93c087..35515b87 100644
--- a/src/libcamera/base/event_notifier.cpp
+++ b/src/libcamera/base/event_notifier.cpp
@@ -14,6 +14,7 @@
 #include <libcamera/camera_manager.h>
 
 /**
+ * \internal
  * \file event_notifier.h
  * \brief File descriptor event notifier
  */
@@ -21,6 +22,7 @@
 namespace libcamera {
 
 /**
+ * \internal
  * \class EventNotifier
  * \brief Notify of activity on a file descriptor
  *
@@ -47,6 +49,7 @@ namespace libcamera {
  */
 
 /**
+ * \internal
  * \enum EventNotifier::Type
  * Type of file descriptor event to listen for.
  * \var EventNotifier::Read
diff --git a/src/libcamera/base/file.cpp b/src/libcamera/base/file.cpp
index d1ab1aa5..55d3c074 100644
--- a/src/libcamera/base/file.cpp
+++ b/src/libcamera/base/file.cpp
@@ -18,6 +18,7 @@
 #include <libcamera/base/shared_fd.h>
 
 /**
+ * \internal
  * \file base/file.h
  * \brief File I/O operations
  */
@@ -27,6 +28,7 @@ namespace libcamera {
 LOG_DEFINE_CATEGORY(File)
 
 /**
+ * \internal
  * \class File
  * \brief Interface for I/O operations on files
  *
@@ -44,6 +46,7 @@ LOG_DEFINE_CATEGORY(File)
  */
 
 /**
+ * \internal
  * \enum File::MapFlag
  * \brief Flags for the File::map() function
  * \var File::MapFlag::NoOption
@@ -59,6 +62,7 @@ LOG_DEFINE_CATEGORY(File)
  */
 
 /**
+ * \internal
  * \enum File::OpenModeFlag
  * \brief Mode in which a file is opened
  * \var File::OpenModeFlag::NotOpen
diff --git a/src/libcamera/base/log.cpp b/src/libcamera/base/log.cpp
index c8045ef7..8f4e01c1 100644
--- a/src/libcamera/base/log.cpp
+++ b/src/libcamera/base/log.cpp
@@ -26,6 +26,7 @@
 #include <libcamera/base/utils.h>
 
 /**
+ * \internal
  * \file base/log.h
  * \brief Logging infrastructure
  *
@@ -98,6 +99,7 @@ static const char *log_severity_name(LogSeverity severity)
 }
 
 /**
+ * \internal
  * \brief Log output
  *
  * The LogOutput class models a log output destination
@@ -287,6 +289,7 @@ void LogOutput::writeStream(const std::string &str)
 }
 
 /**
+ * \internal
  * \brief Message logger
  *
  * The Logger class handles log configuration.
@@ -755,6 +758,7 @@ LogCategory *Logger::findCategory(const char *name) const
 }
 
 /**
+ * \internal
  * \enum LogSeverity
  * Log message severity
  * \var LogDebug
@@ -770,6 +774,7 @@ LogCategory *Logger::findCategory(const char *name) const
  */
 
 /**
+ * \internal
  * \class LogCategory
  * \brief A category of log message
  *
@@ -849,6 +854,7 @@ const LogCategory &LogCategory::defaultCategory()
 }
 
 /**
+ * \internal
  * \class LogMessage
  * \brief Internal log message representation.
  *
@@ -977,6 +983,7 @@ LogMessage::~LogMessage()
  */
 
 /**
+ * \internal
  * \class Loggable
  * \brief Base class to support log message extensions
  *
diff --git a/src/libcamera/base/message.cpp b/src/libcamera/base/message.cpp
index 2da2a7ed..872f57bf 100644
--- a/src/libcamera/base/message.cpp
+++ b/src/libcamera/base/message.cpp
@@ -11,6 +11,7 @@
 #include <libcamera/base/signal.h>
 
 /**
+ * \internal
  * \file base/message.h
  * \brief Message queue support
  *
@@ -35,11 +36,13 @@ LOG_DEFINE_CATEGORY(Message)
 std::atomic_uint Message::nextUserType_{ Message::UserMessage };
 
 /**
+ * \internal
  * \class Message
  * \brief A message that can be posted to a Thread
  */
 
 /**
+ * \internal
  * \enum Message::Type
  * \brief The message type
  * \var Message::None
@@ -112,6 +115,7 @@ Message::Type Message::registerMessageType()
 }
 
 /**
+ * \internal
  * \class InvokeMessage
  * \brief A message carrying a method invocation across threads
  */
diff --git a/src/libcamera/base/mutex.cpp b/src/libcamera/base/mutex.cpp
index e34e8618..d5998594 100644
--- a/src/libcamera/base/mutex.cpp
+++ b/src/libcamera/base/mutex.cpp
@@ -8,6 +8,7 @@
 #include <libcamera/base/mutex.h>
 
 /**
+ * \internal
  * \file base/mutex.h
  * \brief Mutex classes with clang thread safety annotation
  */
@@ -15,6 +16,7 @@
 namespace libcamera {
 
 /**
+ * \internal
  * \class Mutex
  * \brief std::mutex wrapper with clang thread safety annotation
  *
@@ -28,6 +30,7 @@ namespace libcamera {
  */
 
 /**
+ * \internal
  * \class MutexLocker
  * \brief std::unique_lock wrapper with clang thread safety annotation
  *
@@ -41,6 +44,7 @@ namespace libcamera {
  */
 
 /**
+ * \internal
  * \class ConditionVariable
  * \brief std::condition_variable wrapper integrating with MutexLocker
  *
diff --git a/src/libcamera/base/object.cpp b/src/libcamera/base/object.cpp
index 92cecd22..4f51e078 100644
--- a/src/libcamera/base/object.cpp
+++ b/src/libcamera/base/object.cpp
@@ -163,8 +163,11 @@ void Object::deleteLater()
  * loop gets started.
  *
  * Due to their asynchronous nature, threads do not provide any guarantee that
- * all posted messages are delivered before the thread is stopped. See
- * \ref thread-stop for additional information.
+ * all posted messages are delivered before the thread is stopped.
+ *
+ * \if internal
+ * See \ref thread-stop for additional information.
+ * \endif
  *
  * \context This function is \threadsafe.
  */
@@ -229,7 +232,11 @@ void Object::message(Message *msg)
  *
  * Due to the asynchronous nature of threads, functions invoked asynchronously
  * with the ConnectionTypeQueued type are not guaranteed to be called before
- * the thread is stopped. See \ref thread-stop for additional information.
+ * the thread is stopped.
+ *
+ * \if internal
+ * See \ref thread-stop for additional information.
+ * \endif
  *
  * \context This function is \threadsafe.
  *
diff --git a/src/libcamera/base/semaphore.cpp b/src/libcamera/base/semaphore.cpp
index 6217e386..8992288f 100644
--- a/src/libcamera/base/semaphore.cpp
+++ b/src/libcamera/base/semaphore.cpp
@@ -8,6 +8,7 @@
 #include <libcamera/base/semaphore.h>
 
 /**
+ * \internal
  * \file base/semaphore.h
  * \brief General-purpose counting semaphore
  */
@@ -15,6 +16,7 @@
 namespace libcamera {
 
 /**
+ * \internal
  * \class Semaphore
  * \brief General-purpose counting semaphore
  *
diff --git a/src/libcamera/base/thread.cpp b/src/libcamera/base/thread.cpp
index b96951ac..8780e34a 100644
--- a/src/libcamera/base/thread.cpp
+++ b/src/libcamera/base/thread.cpp
@@ -102,6 +102,7 @@
  */
 
 /**
+ * \internal
  * \file base/thread.h
  * \brief Thread support
  */
@@ -113,6 +114,7 @@ LOG_DEFINE_CATEGORY(Thread)
 class ThreadMain;
 
 /**
+ * \internal
  * \brief A queue of posted messages
  */
 class MessageQueue
@@ -134,6 +136,7 @@ public:
 };
 
 /**
+ * \internal
  * \brief Thread-local internal data
  */
 class ThreadData
@@ -166,6 +169,7 @@ private:
 };
 
 /**
+ * \internal
  * \brief Thread wrapper for the main thread
  */
 class ThreadMain : public Thread
@@ -206,6 +210,7 @@ ThreadData *ThreadData::current()
 }
 
 /**
+ * \internal
  * \class Thread
  * \brief A thread of execution
  *
diff --git a/src/libcamera/base/timer.cpp b/src/libcamera/base/timer.cpp
index 74b060af..81372728 100644
--- a/src/libcamera/base/timer.cpp
+++ b/src/libcamera/base/timer.cpp
@@ -18,6 +18,7 @@
 #include <libcamera/camera_manager.h>
 
 /**
+ * \internal
  * \file base/timer.h
  * \brief Generic timer
  */
@@ -27,6 +28,7 @@ namespace libcamera {
 LOG_DEFINE_CATEGORY(Timer)
 
 /**
+ * \internal
  * \class Timer
  * \brief Single-shot timer interface
  *
diff --git a/src/libcamera/base/utils.cpp b/src/libcamera/base/utils.cpp
index 3b73b442..5b8caa22 100644
--- a/src/libcamera/base/utils.cpp
+++ b/src/libcamera/base/utils.cpp
@@ -15,6 +15,7 @@
 #include <unistd.h>
 
 /**
+ * \internal
  * \file base/utils.h
  * \brief Miscellaneous utility functions
  */
@@ -402,6 +403,7 @@ std::string toAscii(const std::string &str)
  */
 
 /**
+ * \internal
  * \class Duration
  * \brief Helper class from std::chrono::duration that represents a time
  * duration in nanoseconds with double precision
diff --git a/src/libcamera/bayer_format.cpp b/src/libcamera/bayer_format.cpp
index 3bf15fb4..6d8d34a7 100644
--- a/src/libcamera/bayer_format.cpp
+++ b/src/libcamera/bayer_format.cpp
@@ -18,6 +18,7 @@
 #include <libcamera/transform.h>
 
 /**
+ * \internal
  * \file bayer_format.h
  * \brief Class to represent Bayer formats and manipulate them
  */
@@ -25,6 +26,7 @@
 namespace libcamera {
 
 /**
+ * \internal
  * \class BayerFormat
  * \brief Class to represent a raw image Bayer format
  *
@@ -36,6 +38,7 @@ namespace libcamera {
  */
 
 /**
+ * \internal
  * \enum BayerFormat::Order
  * \brief The order of the colour channels in the Bayer pattern
  *
@@ -52,6 +55,7 @@ namespace libcamera {
  */
 
 /**
+ * \internal
  * \enum BayerFormat::Packing
  * \brief Different types of packing that can be applied to a BayerFormat
  *
diff --git a/src/libcamera/byte_stream_buffer.cpp b/src/libcamera/byte_stream_buffer.cpp
index 881cd371..c9ec1133 100644
--- a/src/libcamera/byte_stream_buffer.cpp
+++ b/src/libcamera/byte_stream_buffer.cpp
@@ -13,6 +13,7 @@
 #include <libcamera/base/log.h>
 
 /**
+ * \internal
  * \file byte_stream_buffer.h
  * \brief Managed memory container for serialized data
  */
@@ -22,6 +23,7 @@ namespace libcamera {
 LOG_DEFINE_CATEGORY(Serialization)
 
 /**
+ * \internal
  * \class ByteStreamBuffer
  * \brief Wrap a memory buffer and provide sequential data read and write
  *
diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp
index 0ad1a4b5..f4ac06fb 100644
--- a/src/libcamera/camera.cpp
+++ b/src/libcamera/camera.cpp
@@ -560,6 +560,7 @@ CameraConfiguration::Status CameraConfiguration::validateColorSpaces(ColorSpaceF
  */
 
 /**
+ * \internal
  * \class Camera::Private
  * \brief Base class for camera private data
  *
diff --git a/src/libcamera/camera_controls.cpp b/src/libcamera/camera_controls.cpp
index cabdcf75..260303eb 100644
--- a/src/libcamera/camera_controls.cpp
+++ b/src/libcamera/camera_controls.cpp
@@ -11,6 +11,7 @@
 #include <libcamera/controls.h>
 
 /**
+ * \internal
  * \file camera_controls.h
  * \brief Controls for Camera instances
  */
@@ -18,6 +19,7 @@
 namespace libcamera {
 
 /**
+ * \internal
  * \class CameraControlValidator
  * \brief A control validator for Camera instances
  *
diff --git a/src/libcamera/camera_lens.cpp b/src/libcamera/camera_lens.cpp
index b3d48199..eda4cb5c 100644
--- a/src/libcamera/camera_lens.cpp
+++ b/src/libcamera/camera_lens.cpp
@@ -12,6 +12,7 @@
 #include "libcamera/internal/v4l2_subdevice.h"
 
 /**
+ * \internal
  * \file camera_lens.h
  * \brief A camera lens controller
  */
@@ -21,6 +22,7 @@ namespace libcamera {
 LOG_DEFINE_CATEGORY(CameraLens)
 
 /**
+ * \internal
  * \class CameraLens
  * \brief A camera lens based on V4L2 subdevices
  *
diff --git a/src/libcamera/camera_manager.cpp b/src/libcamera/camera_manager.cpp
index 355f3ada..61d45256 100644
--- a/src/libcamera/camera_manager.cpp
+++ b/src/libcamera/camera_manager.cpp
@@ -23,6 +23,7 @@
  */
 
 /**
+ * \internal
  * \file libcamera/internal/camera_manager.h
  * \brief Internal camera manager support
  */
diff --git a/src/libcamera/camera_sensor.cpp b/src/libcamera/camera_sensor.cpp
index 0ef78d9c..f84822e1 100644
--- a/src/libcamera/camera_sensor.cpp
+++ b/src/libcamera/camera_sensor.cpp
@@ -28,6 +28,7 @@
 #include "libcamera/internal/sysfs.h"
 
 /**
+ * \internal
  * \file camera_sensor.h
  * \brief A camera sensor
  */
@@ -37,6 +38,7 @@ namespace libcamera {
 LOG_DEFINE_CATEGORY(CameraSensor)
 
 /**
+ * \internal
  * \class CameraSensor
  * \brief A camera sensor based on V4L2 subdevices
  *
diff --git a/src/libcamera/camera_sensor_properties.cpp b/src/libcamera/camera_sensor_properties.cpp
index 27d6799a..83391b80 100644
--- a/src/libcamera/camera_sensor_properties.cpp
+++ b/src/libcamera/camera_sensor_properties.cpp
@@ -14,6 +14,7 @@
 #include <libcamera/control_ids.h>
 
 /**
+ * \internal
  * \file camera_sensor_properties.h
  * \brief Database of camera sensor properties
  *
@@ -31,6 +32,7 @@ namespace libcamera {
 LOG_DEFINE_CATEGORY(CameraSensorProperties)
 
 /**
+ * \internal
  * \struct CameraSensorProperties
  * \brief Database of camera sensor properties
  *
diff --git a/src/libcamera/control_serializer.cpp b/src/libcamera/control_serializer.cpp
index 0cf719bd..3c30efc5 100644
--- a/src/libcamera/control_serializer.cpp
+++ b/src/libcamera/control_serializer.cpp
@@ -23,6 +23,7 @@
 #include "libcamera/internal/byte_stream_buffer.h"
 
 /**
+ * \internal
  * \file control_serializer.h
  * \brief Serialization and deserialization helpers for controls
  */
@@ -32,6 +33,7 @@ namespace libcamera {
 LOG_DEFINE_CATEGORY(Serializer)
 
 /**
+ * \internal
  * \class ControlSerializer
  * \brief Serializer and deserializer for control-related classes
  *
@@ -86,6 +88,7 @@ LOG_DEFINE_CATEGORY(Serializer)
  */
 
 /**
+ * \internal
  * \enum ControlSerializer::Role
  * \brief Define the role of the IPC component using the control serializer
  *
diff --git a/src/libcamera/control_validator.cpp b/src/libcamera/control_validator.cpp
index cf08b34a..4c3cbd5b 100644
--- a/src/libcamera/control_validator.cpp
+++ b/src/libcamera/control_validator.cpp
@@ -8,6 +8,7 @@
 #include "libcamera/internal/control_validator.h"
 
 /**
+ * \internal
  * \file control_validator.h
  * \brief Abstract control validator
  */
@@ -15,6 +16,7 @@
 namespace libcamera {
 
 /**
+ * \internal
  * \class ControlValidator
  * \brief Interface for the control validator
  *
diff --git a/src/libcamera/converter.cpp b/src/libcamera/converter.cpp
index 9f64eb51..09792064 100644
--- a/src/libcamera/converter.cpp
+++ b/src/libcamera/converter.cpp
@@ -14,6 +14,7 @@
 #include "libcamera/internal/media_device.h"
 
 /**
+ * \internal
  * \file internal/converter.h
  * \brief Abstract converter
  */
@@ -23,6 +24,7 @@ namespace libcamera {
 LOG_DEFINE_CATEGORY(Converter)
 
 /**
+ * \internal
  * \class Converter
  * \brief Abstract Base Class for converter
  *
@@ -164,6 +166,7 @@ Converter::~Converter()
  */
 
 /**
+ * \internal
  * \class ConverterFactoryBase
  * \brief Base class for converter factories
  *
@@ -296,6 +299,7 @@ std::vector<ConverterFactoryBase *> &ConverterFactoryBase::factories()
  */
 
 /**
+ * \internal
  * \class ConverterFactory
  * \brief Registration of ConverterFactory classes and creation of instances
  * \param _Converter The converter class type for this factory
diff --git a/src/libcamera/converter/converter_v4l2_m2m.cpp b/src/libcamera/converter/converter_v4l2_m2m.cpp
index 2a4d1d99..147b5b12 100644
--- a/src/libcamera/converter/converter_v4l2_m2m.cpp
+++ b/src/libcamera/converter/converter_v4l2_m2m.cpp
@@ -23,6 +23,7 @@
 #include "libcamera/internal/v4l2_videodevice.h"
 
 /**
+ * \internal
  * \file internal/converter/converter_v4l2_m2m.h
  * \brief V4L2 M2M based converter
  */
@@ -182,6 +183,7 @@ void V4L2M2MConverter::Stream::captureBufferReady(FrameBuffer *buffer)
  */
 
 /**
+ * \internal
  * \class libcamera::V4L2M2MConverter
  * \brief The V4L2 M2M converter implements the converter interface based on
  * V4L2 M2M device.
diff --git a/src/libcamera/delayed_controls.cpp b/src/libcamera/delayed_controls.cpp
index 777441e8..496aa941 100644
--- a/src/libcamera/delayed_controls.cpp
+++ b/src/libcamera/delayed_controls.cpp
@@ -14,6 +14,7 @@
 #include "libcamera/internal/v4l2_device.h"
 
 /**
+ * \internal
  * \file delayed_controls.h
  * \brief Helper to deal with controls that take effect with a delay
  */
@@ -23,6 +24,7 @@ namespace libcamera {
 LOG_DEFINE_CATEGORY(DelayedControls)
 
 /**
+ * \internal
  * \class DelayedControls
  * \brief Helper to deal with controls that take effect with a delay
  *
@@ -39,6 +41,7 @@ LOG_DEFINE_CATEGORY(DelayedControls)
  */
 
 /**
+ * \internal
  * \struct DelayedControls::ControlParams
  * \brief Parameters associated with controls handled by the \a DelayedControls
  * helper class
diff --git a/src/libcamera/device_enumerator.cpp b/src/libcamera/device_enumerator.cpp
index f2e055de..a4aeb660 100644
--- a/src/libcamera/device_enumerator.cpp
+++ b/src/libcamera/device_enumerator.cpp
@@ -16,6 +16,7 @@
 #include "libcamera/internal/media_device.h"
 
 /**
+ * \internal
  * \file device_enumerator.h
  * \brief Enumeration and matching of media devices
  *
@@ -41,6 +42,7 @@ namespace libcamera {
 LOG_DEFINE_CATEGORY(DeviceEnumerator)
 
 /**
+ * \internal
  * \class DeviceMatch
  * \brief Description of a media device search pattern
  *
@@ -114,6 +116,7 @@ bool DeviceMatch::match(const MediaDevice *device) const
 }
 
 /**
+ * \internal
  * \class DeviceEnumerator
  * \brief Enumerate, store and search media devices
  *
diff --git a/src/libcamera/framebuffer.cpp b/src/libcamera/framebuffer.cpp
index 5a7f3c0b..b667022a 100644
--- a/src/libcamera/framebuffer.cpp
+++ b/src/libcamera/framebuffer.cpp
@@ -17,6 +17,7 @@
  * \file libcamera/framebuffer.h
  * \brief Frame buffer handling
  *
+ * \internal
  * \file libcamera/internal/framebuffer.h
  * \brief Internal frame buffer handling support
  */
@@ -105,6 +106,7 @@ LOG_DEFINE_CATEGORY(Buffer)
  */
 
 /**
+ * \internal
  * \class FrameBuffer::Private
  * \brief Base class for FrameBuffer private data
  *
diff --git a/src/libcamera/ipa_controls.cpp b/src/libcamera/ipa_controls.cpp
index 870a443b..255023a0 100644
--- a/src/libcamera/ipa_controls.cpp
+++ b/src/libcamera/ipa_controls.cpp
@@ -8,6 +8,7 @@
 #include <libcamera/ipa/ipa_controls.h>
 
 /**
+ * \internal
  * \file ipa_controls.h
  * \brief Type definitions for serialized controls
  *
@@ -166,6 +167,7 @@ namespace libcamera {
  */
 
 /**
+ * \internal
  * \struct ipa_controls_header
  * \brief Serialized control packet header
  * \var ipa_controls_header::version
@@ -190,6 +192,7 @@ static_assert(sizeof(ipa_controls_header) == 32,
 	      "Invalid ABI size change for struct ipa_control_header");
 
 /**
+ * \internal
  * \struct ipa_control_value_entry
  * \brief Description of a serialized ControlValue entry
  * \var ipa_control_value_entry::id
@@ -211,6 +214,7 @@ static_assert(sizeof(ipa_control_value_entry) == 16,
 	      "Invalid ABI size change for struct ipa_control_value_entry");
 
 /**
+ * \internal
  * \struct ipa_control_info_entry
  * \brief Description of a serialized ControlInfo entry
  * \var ipa_control_info_entry::id
diff --git a/src/libcamera/ipa_data_serializer.cpp b/src/libcamera/ipa_data_serializer.cpp
index 0a259305..022801a2 100644
--- a/src/libcamera/ipa_data_serializer.cpp
+++ b/src/libcamera/ipa_data_serializer.cpp
@@ -12,6 +12,7 @@
 #include <libcamera/base/log.h>
 
 /**
+ * \internal
  * \file ipa_data_serializer.h
  * \brief IPA Data Serializer
  */
@@ -21,6 +22,7 @@ namespace libcamera {
 LOG_DEFINE_CATEGORY(IPADataSerializer)
 
 /**
+ * \internal
  * \class IPADataSerializer
  * \brief IPA Data Serializer
  *
diff --git a/src/libcamera/ipa_interface.cpp b/src/libcamera/ipa_interface.cpp
index 8ea6cbee..45f50981 100644
--- a/src/libcamera/ipa_interface.cpp
+++ b/src/libcamera/ipa_interface.cpp
@@ -8,6 +8,7 @@
 #include <libcamera/ipa/ipa_interface.h>
 
 /**
+ * \internal
  * \file ipa_interface.h
  * \brief Image Processing Algorithm interface
  *
@@ -76,6 +77,7 @@
 namespace libcamera {
 
 /**
+ * \internal
  * \class IPAInterface
  * \brief C++ Interface for IPA implementation
  *
diff --git a/src/libcamera/ipa_manager.cpp b/src/libcamera/ipa_manager.cpp
index 7a4515d9..865fbb5a 100644
--- a/src/libcamera/ipa_manager.cpp
+++ b/src/libcamera/ipa_manager.cpp
@@ -21,6 +21,7 @@
 #include "libcamera/internal/pipeline_handler.h"
 
 /**
+ * \internal
  * \file ipa_manager.h
  * \brief Image Processing Algorithm module manager
  */
@@ -30,6 +31,7 @@ namespace libcamera {
 LOG_DEFINE_CATEGORY(IPAManager)
 
 /**
+ * \internal
  * \class IPAManager
  * \brief Manager for IPA modules
  *
diff --git a/src/libcamera/ipa_module.cpp b/src/libcamera/ipa_module.cpp
index f2dd87e5..73a415ac 100644
--- a/src/libcamera/ipa_module.cpp
+++ b/src/libcamera/ipa_module.cpp
@@ -28,11 +28,13 @@
 #include "libcamera/internal/pipeline_handler.h"
 
 /**
+ * \internal
  * \file ipa_module.h
  * \brief Image Processing Algorithm module
  */
 
 /**
+ * \internal
  * \file ipa_module_info.h
  * \brief Image Processing Algorithm module information
  */
@@ -200,6 +202,7 @@ Span<const uint8_t> elfLoadSymbol(Span<const uint8_t> elf, const char *symbol)
  */
 
 /**
+ * \internal
  * \struct IPAModuleInfo
  * \brief Information of an IPA module
  *
@@ -240,6 +243,7 @@ Span<const uint8_t> elfLoadSymbol(Span<const uint8_t> elf, const char *symbol)
  */
 
 /**
+ * \internal
  * \class IPAModule
  * \brief Wrapper around IPA module shared object
  */
diff --git a/src/libcamera/ipa_proxy.cpp b/src/libcamera/ipa_proxy.cpp
index 3f2cc6b8..7205f588 100644
--- a/src/libcamera/ipa_proxy.cpp
+++ b/src/libcamera/ipa_proxy.cpp
@@ -18,6 +18,7 @@
 #include "libcamera/internal/ipa_module.h"
 
 /**
+ * \internal
  * \file ipa_proxy.h
  * \brief IPA Proxy
  */
@@ -27,6 +28,7 @@ namespace libcamera {
 LOG_DEFINE_CATEGORY(IPAProxy)
 
 /**
+ * \internal
  * \class IPAProxy
  * \brief IPA Proxy
  *
@@ -34,6 +36,7 @@ LOG_DEFINE_CATEGORY(IPAProxy)
  */
 
 /**
+ * \internal
  * \enum IPAProxy::ProxyState
  * \brief Identifies the available operational states of the proxy
  *
diff --git a/src/libcamera/ipc_pipe.cpp b/src/libcamera/ipc_pipe.cpp
index 31a0ca09..2f36a129 100644
--- a/src/libcamera/ipc_pipe.cpp
+++ b/src/libcamera/ipc_pipe.cpp
@@ -10,6 +10,7 @@
 #include <libcamera/base/log.h>
 
 /**
+ * \internal
  * \file ipc_pipe.h
  * \brief IPC mechanism for IPA isolation
  */
@@ -19,6 +20,7 @@ namespace libcamera {
 LOG_DEFINE_CATEGORY(IPCPipe)
 
 /**
+ * \internal
  * \struct IPCMessage::Header
  * \brief Container for an IPCMessage header
  *
@@ -41,6 +43,7 @@ LOG_DEFINE_CATEGORY(IPCPipe)
  */
 
 /**
+ * \internal
  * \class IPCMessage
  * \brief IPC message to be passed through IPC message pipe
  */
@@ -149,6 +152,7 @@ IPCUnixSocket::Payload IPCMessage::payload() const
  */
 
 /**
+ * \internal
  * \class IPCPipe
  * \brief IPC message pipe for IPA isolation
  *
diff --git a/src/libcamera/ipc_unixsocket.cpp b/src/libcamera/ipc_unixsocket.cpp
index 1980d374..38365134 100644
--- a/src/libcamera/ipc_unixsocket.cpp
+++ b/src/libcamera/ipc_unixsocket.cpp
@@ -17,6 +17,7 @@
 #include <libcamera/base/log.h>
 
 /**
+ * \internal
  * \file ipc_unixsocket.h
  * \brief IPC mechanism based on Unix sockets
  */
@@ -26,6 +27,7 @@ namespace libcamera {
 LOG_DEFINE_CATEGORY(IPCUnixSocket)
 
 /**
+ * \internal
  * \struct IPCUnixSocket::Payload
  * \brief Container for an IPC payload
  *
@@ -44,6 +46,7 @@ LOG_DEFINE_CATEGORY(IPCUnixSocket)
  */
 
 /**
+ * \internal
  * \class IPCUnixSocket
  * \brief IPC mechanism based on Unix sockets
  *
diff --git a/src/libcamera/mapped_framebuffer.cpp b/src/libcamera/mapped_framebuffer.cpp
index 6860069b..c1e941b1 100644
--- a/src/libcamera/mapped_framebuffer.cpp
+++ b/src/libcamera/mapped_framebuffer.cpp
@@ -16,6 +16,7 @@
 #include <libcamera/base/log.h>
 
 /**
+ * \internal
  * \file libcamera/internal/mapped_framebuffer.h
  * \brief Frame buffer memory mapping support
  */
@@ -25,6 +26,7 @@ namespace libcamera {
 LOG_DECLARE_CATEGORY(Buffer)
 
 /**
+ * \internal
  * \class MappedBuffer
  * \brief Provide an interface to support managing memory mapped buffers
  *
@@ -148,11 +150,13 @@ MappedBuffer::~MappedBuffer()
  */
 
 /**
+ * \internal
  * \class MappedFrameBuffer
  * \brief Map a FrameBuffer using the MappedBuffer interface
  */
 
 /**
+ * \internal
  * \enum MappedFrameBuffer::MapFlag
  * \brief Specify the mapping mode for the FrameBuffer
  * \var MappedFrameBuffer::Read
diff --git a/src/libcamera/media_device.cpp b/src/libcamera/media_device.cpp
index 2949816b..ef7bdafa 100644
--- a/src/libcamera/media_device.cpp
+++ b/src/libcamera/media_device.cpp
@@ -21,6 +21,7 @@
 #include <libcamera/base/log.h>
 
 /**
+ * \internal
  * \file media_device.h
  * \brief Provide a representation of a Linux kernel Media Controller device
  * that exposes the full graph topology.
@@ -31,6 +32,7 @@ namespace libcamera {
 LOG_DEFINE_CATEGORY(MediaDevice)
 
 /**
+ * \internal
  * \class MediaDevice
  * \brief The MediaDevice represents a Media Controller device with its full
  * graph of connected objects.
diff --git a/src/libcamera/media_object.cpp b/src/libcamera/media_object.cpp
index c78f4758..7b8099a8 100644
--- a/src/libcamera/media_object.cpp
+++ b/src/libcamera/media_object.cpp
@@ -20,6 +20,7 @@
 #include "libcamera/internal/media_device.h"
 
 /**
+ * \internal
  * \file media_object.h
  * \brief Provides a class hierarchy that represents the  media objects exposed
  * by the Linux kernel Media Controller APIs.
@@ -43,6 +44,7 @@ namespace libcamera {
 LOG_DECLARE_CATEGORY(MediaDevice)
 
 /**
+ * \internal
  * \class MediaObject
  * \brief Base class for all media objects
  *
@@ -94,6 +96,7 @@ LOG_DECLARE_CATEGORY(MediaDevice)
  */
 
 /**
+ * \internal
  * \class MediaLink
  * \brief The MediaLink represents a link between two pads in the media graph.
  *
@@ -169,6 +172,7 @@ MediaLink::MediaLink(const struct media_v2_link *link, MediaPad *source,
  */
 
 /**
+ * \internal
  * \class MediaPad
  * \brief The MediaPad represents a pad of an entity in the media graph
  *
@@ -236,6 +240,7 @@ void MediaPad::addLink(MediaLink *link)
 }
 
 /**
+ * \internal
  * \class MediaEntity
  * \brief The MediaEntity represents an entity in the media graph
  *
@@ -248,6 +253,7 @@ void MediaPad::addLink(MediaLink *link)
  */
 
 /**
+ * \internal
  * \enum MediaEntity::Type
  * \brief The type of the interface exposed by the entity to userspace
  *
diff --git a/src/libcamera/pipeline/ipu3/imgu.cpp b/src/libcamera/pipeline/ipu3/imgu.cpp
index 531879f1..f8eb43dd 100644
--- a/src/libcamera/pipeline/ipu3/imgu.cpp
+++ b/src/libcamera/pipeline/ipu3/imgu.cpp
@@ -274,6 +274,7 @@ FOV calcFOV(const Size &in, const ImgUDevice::PipeConfig &pipe)
 } /* namespace */
 
 /**
+ * \internal
  * \struct PipeConfig
  * \brief The ImgU pipe configuration parameters
  *
@@ -299,6 +300,7 @@ FOV calcFOV(const Size &in, const ImgUDevice::PipeConfig &pipe)
  */
 
 /**
+ * \internal
  * \struct Pipe
  * \brief Describe the ImgU requested configuration
  *
diff --git a/src/libcamera/pipeline/rpi/common/delayed_controls.cpp b/src/libcamera/pipeline/rpi/common/delayed_controls.cpp
index 3db92e7d..f0cfcc6f 100644
--- a/src/libcamera/pipeline/rpi/common/delayed_controls.cpp
+++ b/src/libcamera/pipeline/rpi/common/delayed_controls.cpp
@@ -16,6 +16,7 @@
 #include "libcamera/internal/v4l2_device.h"
 
 /**
+ * \internal
  * \file delayed_controls.h
  * \brief Helper to deal with controls that take effect with a delay
  */
@@ -27,6 +28,7 @@ LOG_DEFINE_CATEGORY(RPiDelayedControls)
 namespace RPi {
 
 /**
+ * \internal
  * \class DelayedControls
  * \brief Helper to deal with controls that take effect with a delay
  *
@@ -43,6 +45,7 @@ namespace RPi {
  */
 
 /**
+ * \internal
  * \struct DelayedControls::ControlParams
  * \brief Parameters associated with controls handled by the \a DelayedControls
  * helper class
diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp
index 29e0c98a..c690ec98 100644
--- a/src/libcamera/pipeline_handler.cpp
+++ b/src/libcamera/pipeline_handler.cpp
@@ -28,6 +28,7 @@
 #include "libcamera/internal/tracepoints.h"
 
 /**
+ * \internal
  * \file pipeline_handler.h
  * \brief Create pipelines and cameras from a set of media devices
  *
@@ -48,6 +49,7 @@ namespace libcamera {
 LOG_DEFINE_CATEGORY(Pipeline)
 
 /**
+ * \internal
  * \class PipelineHandler
  * \brief Create and manage cameras based on a set of media devices
  *
@@ -720,6 +722,7 @@ void PipelineHandler::disconnect()
  */
 
 /**
+ * \internal
  * \class PipelineHandlerFactoryBase
  * \brief Base class for pipeline handler factories
  *
@@ -795,6 +798,7 @@ std::vector<PipelineHandlerFactoryBase *> &PipelineHandlerFactoryBase::factories
 }
 
 /**
+ * \internal
  * \class PipelineHandlerFactory
  * \brief Registration of PipelineHandler classes and creation of instances
  * \tparam _PipelineHandler The pipeline handler class type for this factory
diff --git a/src/libcamera/process.cpp b/src/libcamera/process.cpp
index 86a382fb..ca69a7fb 100644
--- a/src/libcamera/process.cpp
+++ b/src/libcamera/process.cpp
@@ -25,6 +25,7 @@
 #include <libcamera/base/utils.h>
 
 /**
+ * \internal
  * \file process.h
  * \brief Process object
  */
@@ -34,6 +35,7 @@ namespace libcamera {
 LOG_DEFINE_CATEGORY(Process)
 
 /**
+ * \internal
  * \class ProcessManager
  * \brief Manager of processes
  *
@@ -191,6 +193,7 @@ const struct sigaction &ProcessManager::oldsa() const
 
 
 /**
+ * \internal
  * \class Process
  * \brief Process object
  *
@@ -199,6 +202,7 @@ const struct sigaction &ProcessManager::oldsa() const
  */
 
 /**
+ * \internal
  * \enum Process::ExitStatus
  * \brief Exit status of process
  * \var Process::NotExited
diff --git a/src/libcamera/pub_key.cpp b/src/libcamera/pub_key.cpp
index 64dfa234..8b8624ef 100644
--- a/src/libcamera/pub_key.cpp
+++ b/src/libcamera/pub_key.cpp
@@ -17,6 +17,7 @@
 #endif
 
 /**
+ * \internal
  * \file pub_key.h
  * \brief Public key signature verification
  */
@@ -24,6 +25,7 @@
 namespace libcamera {
 
 /**
+ * \internal
  * \class PubKey
  * \brief Public key wrapper for signature verification
  *
diff --git a/src/libcamera/request.cpp b/src/libcamera/request.cpp
index 949c556f..930d8c92 100644
--- a/src/libcamera/request.cpp
+++ b/src/libcamera/request.cpp
@@ -33,6 +33,7 @@ namespace libcamera {
 LOG_DEFINE_CATEGORY(Request)
 
 /**
+ * \internal
  * \class Request::Private
  * \brief Request private data
  *
diff --git a/src/libcamera/source_paths.cpp b/src/libcamera/source_paths.cpp
index 19689585..cb29efb8 100644
--- a/src/libcamera/source_paths.cpp
+++ b/src/libcamera/source_paths.cpp
@@ -17,6 +17,7 @@
 #include <libcamera/base/utils.h>
 
 /**
+ * \internal
  * \file source_paths.h
  * \brief Identify the build and source path of a not-yet-installed library
  */
diff --git a/src/libcamera/sysfs.cpp b/src/libcamera/sysfs.cpp
index 44c3331b..e256db7c 100644
--- a/src/libcamera/sysfs.cpp
+++ b/src/libcamera/sysfs.cpp
@@ -16,6 +16,7 @@
 #include <libcamera/base/log.h>
 
 /**
+ * \internal
  * \file sysfs.h
  * \brief Miscellaneous utility functions to access sysfs
  */
diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp
index 24d208ef..4d016bda 100644
--- a/src/libcamera/v4l2_device.cpp
+++ b/src/libcamera/v4l2_device.cpp
@@ -28,6 +28,7 @@
 #include "libcamera/internal/sysfs.h"
 
 /**
+ * \internal
  * \file v4l2_device.h
  * \brief Common base for V4L2 devices and subdevices
  */
@@ -37,6 +38,7 @@ namespace libcamera {
 LOG_DEFINE_CATEGORY(V4L2)
 
 /**
+ * \internal
  * \class V4L2Device
  * \brief Base class for V4L2VideoDevice and V4L2Subdevice
  *
diff --git a/src/libcamera/v4l2_pixelformat.cpp b/src/libcamera/v4l2_pixelformat.cpp
index 5551c62e..693ec3e0 100644
--- a/src/libcamera/v4l2_pixelformat.cpp
+++ b/src/libcamera/v4l2_pixelformat.cpp
@@ -20,6 +20,7 @@
 #include "libcamera/internal/formats.h"
 
 /**
+ * \internal
  * \file v4l2_pixelformat.h
  * \brief V4L2 Pixel Format
  */
@@ -29,6 +30,7 @@ namespace libcamera {
 LOG_DECLARE_CATEGORY(V4L2)
 
 /**
+ * \internal
  * \class V4L2PixelFormat
  * \brief V4L2 pixel format FourCC wrapper
  *
@@ -212,6 +214,7 @@ const std::map<V4L2PixelFormat, V4L2PixelFormat::Info> vpf2pf{
 } /* namespace */
 
 /**
+ * \internal
  * \struct V4L2PixelFormat::Info
  * \brief Information about a V4L2 pixel format
  *
diff --git a/src/libcamera/v4l2_subdevice.cpp b/src/libcamera/v4l2_subdevice.cpp
index 15e8206a..70697868 100644
--- a/src/libcamera/v4l2_subdevice.cpp
+++ b/src/libcamera/v4l2_subdevice.cpp
@@ -28,6 +28,7 @@
 #include "libcamera/internal/media_object.h"
 
 /**
+ * \internal
  * \file v4l2_subdevice.h
  * \brief V4L2 Subdevice API
  */
@@ -39,6 +40,7 @@ LOG_DECLARE_CATEGORY(V4L2)
 namespace {
 
 /*
+ * \internal
  * \struct V4L2SubdeviceFormatInfo
  * \brief Information about media bus formats
  * \param bitsPerPixel Bits per pixel
@@ -140,6 +142,7 @@ const std::map<uint32_t, V4L2SubdeviceFormatInfo> formatInfoMap = {
 } /* namespace */
 
 /**
+ * \internal
  * \struct V4L2SubdeviceCapability
  * \brief struct v4l2_subdev_capability object wrapper and helpers
  *
@@ -164,6 +167,7 @@ const std::map<uint32_t, V4L2SubdeviceFormatInfo> formatInfoMap = {
  */
 
 /**
+ * \internal
  * \struct V4L2SubdeviceFormat
  * \brief The V4L2 sub-device image format and sizes
  *
@@ -267,6 +271,7 @@ std::ostream &operator<<(std::ostream &out, const V4L2SubdeviceFormat &f)
 }
 
 /**
+ * \internal
  * \class V4L2Subdevice
  * \brief A V4L2 subdevice as exposed by the Linux kernel
  *
@@ -286,6 +291,7 @@ std::ostream &operator<<(std::ostream &out, const V4L2SubdeviceFormat &f)
  */
 
 /**
+ * \internal
  * \enum V4L2Subdevice::Whence
  * \brief Specify the type of format for getFormat() and setFormat() operations
  * \var V4L2Subdevice::ActiveFormat
@@ -295,6 +301,7 @@ std::ostream &operator<<(std::ostream &out, const V4L2SubdeviceFormat &f)
  */
 
 /**
+ * \internal
  * \class V4L2Subdevice::Routing
  * \brief V4L2 subdevice routing table
  *
diff --git a/src/libcamera/v4l2_videodevice.cpp b/src/libcamera/v4l2_videodevice.cpp
index a72ef64d..699a4284 100644
--- a/src/libcamera/v4l2_videodevice.cpp
+++ b/src/libcamera/v4l2_videodevice.cpp
@@ -33,6 +33,7 @@
 #include "libcamera/internal/media_object.h"
 
 /**
+ * \internal
  * \file v4l2_videodevice.h
  * \brief V4L2 Video Device
  */
@@ -42,6 +43,7 @@ namespace libcamera {
 LOG_DECLARE_CATEGORY(V4L2)
 
 /**
+ * \internal
  * \struct V4L2Capability
  * \brief struct v4l2_capability object wrapper and helpers
  *
@@ -147,6 +149,7 @@ LOG_DECLARE_CATEGORY(V4L2)
  */
 
 /**
+ * \internal
  * \class V4L2BufferCache
  * \brief Hot cache of associations between V4L2 buffer indexes and FrameBuffer
  *
@@ -302,6 +305,7 @@ bool V4L2BufferCache::Entry::operator==(const FrameBuffer &buffer) const
 }
 
 /**
+ * \internal
  * \class V4L2DeviceFormat
  * \brief The V4L2 video device image format and sizes
  *
@@ -375,6 +379,7 @@ bool V4L2BufferCache::Entry::operator==(const FrameBuffer &buffer) const
  */
 
 /**
+ * \internal
  * \struct V4L2DeviceFormat::Plane
  * \brief Per-plane memory size information
  * \var V4L2DeviceFormat::Plane::size
@@ -452,6 +457,7 @@ std::ostream &operator<<(std::ostream &out, const V4L2DeviceFormat &f)
 }
 
 /**
+ * \internal
  * \class V4L2VideoDevice
  * \brief V4L2VideoDevice object and API
  *
@@ -2064,6 +2070,7 @@ V4L2PixelFormat V4L2VideoDevice::toV4L2PixelFormat(const PixelFormat &pixelForma
 }
 
 /**
+ * \internal
  * \class V4L2M2MDevice
  * \brief Memory-to-Memory video device
  *
diff --git a/src/libcamera/yaml_parser.cpp b/src/libcamera/yaml_parser.cpp
index bf21141e..f9c37e8f 100644
--- a/src/libcamera/yaml_parser.cpp
+++ b/src/libcamera/yaml_parser.cpp
@@ -18,6 +18,7 @@
 #include <yaml.h>
 
 /**
+ * \internal
  * \file libcamera/internal/yaml_parser.h
  * \brief A YAML parser helper
  */
@@ -34,6 +35,7 @@ static const YamlObject empty;
 } /* namespace */
 
 /**
+ * \internal
  * \class YamlObject
  * \brief A class representing the tree structure of the YAML content
  *
@@ -511,6 +513,7 @@ private:
 };
 
 /**
+ * \internal
  * \class YamlParserContext
  * \brief Class for YamlParser parsing and context data
  *
@@ -523,6 +526,7 @@ YamlParserContext::YamlParserContext()
 }
 
 /**
+ * \internal
  * \class YamlParserContext
  * \brief Destructor of YamlParserContext
  */
@@ -772,6 +776,7 @@ int YamlParserContext::parseNextYamlObject(YamlObject &yamlObject, EventPtr even
 #endif /* __DOXYGEN__ */
 
 /**
+ * \internal
  * \class YamlParser
  * \brief A helper class for parsing a YAML file
  *
