diff --git a/notebooks/LPD/LPD_Correct_Fast.ipynb b/notebooks/LPD/LPD_Correct_Fast.ipynb
index cf6bac5aaf10d37fb8e763ace7026b2627f1d437..04d35400aafeaa9197d79ff6a11439d697c84df0 100644
--- a/notebooks/LPD/LPD_Correct_Fast.ipynb
+++ b/notebooks/LPD/LPD_Correct_Fast.ipynb
@@ -21,13 +21,13 @@
    "outputs": [],
    "source": [
     "# Input parameters\n",
-    "in_folder = \"/gpfs/exfel/exp/FXE/202201/p003073/raw/\"  # the folder to read data from, required\n",
-    "out_folder = \"/gpfs/exfel/data/scratch/schmidtp/random/LPD_test\"  # the folder to output to, required\n",
+    "in_folder = \"/gpfs/exfel/exp/FXE/202401/p005436/raw/\"  # the folder to read data from, required\n",
+    "out_folder = \"/gpfs/exfel/data/scratch/kluyvert/lpd-corr-p5436-r167\"  # the folder to output to, required\n",
     "metadata_folder = ''  # Directory containing calibration_metadata.yml when run by xfel-calibrate.\n",
     "sequences = [-1]  # Sequences to correct, use [-1] for all\n",
     "modules = [-1]  # Modules indices to correct, use [-1] for all, only used when karabo_da is empty\n",
     "karabo_da = ['']  # Data aggregators names to correct, use [''] for all\n",
-    "run = 10  # run to process, required\n",
+    "run = 167  # run to process, required\n",
     "\n",
     "# Source parameters\n",
     "karabo_id = 'FXE_DET_LPD1M-1'  # Karabo domain for detector.\n",
@@ -104,14 +104,13 @@
     "import pasha as psh\n",
     "from extra_data.components import LPD1M\n",
     "\n",
+    "from cal_tools.calcat_interface2 import CalibrationData, LPDConditions\n",
     "import cal_tools.restful_config as rest_cfg\n",
-    "from cal_tools.calcat_interface import CalCatError, LPD_CalibrationData\n",
     "from cal_tools.lpdalgs import correct_lpd_frames\n",
     "from cal_tools.lpdlib import get_mem_cell_pattern, make_cell_order_condition\n",
     "from cal_tools.tools import (\n",
-    "    CalibrationMetadata,\n",
     "    calcat_creation_time,\n",
-    "    write_constants_fragment,\n",
+    "    write_constants_fragment_extracal,\n",
     ")\n",
     "from cal_tools.files import DataFile"
    ]
@@ -238,6 +237,7 @@
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
+    "scrolled": false,
     "tags": []
    },
    "outputs": [],
@@ -253,30 +253,39 @@
     "    )\n",
     "print(\"Memory cells order:\", cell_ids_pattern_s)\n",
     "\n",
-    "lpd_cal = LPD_CalibrationData(\n",
-    "    detector_name=karabo_id,\n",
-    "    modules=karabo_da,\n",
+    "conditions = LPDConditions(\n",
     "    sensor_bias_voltage=bias_voltage,\n",
     "    memory_cells=mem_cells,\n",
     "    feedback_capacitor=capacitor,\n",
     "    source_energy=photon_energy,\n",
     "    memory_cell_order=cell_ids_pattern_s,\n",
     "    category=category,\n",
-    "    event_at=creation_time,\n",
-    "    client=rest_cfg.calibration_client(),\n",
-    "    caldb_root=Path(cal_db_root),\n",
     ")\n",
     "\n",
-    "lpd_metadata = lpd_cal.metadata([\"Offset\", \"BadPixelsDark\"])\n",
-    "try:\n",
-    "    illum_metadata = lpd_cal.metadata(lpd_cal.illuminated_calibrations)\n",
-    "    for key, value in illum_metadata.items():\n",
-    "        lpd_metadata.setdefault(key, {}).update(value)\n",
-    "except CalCatError as e:  # TODO: replace when API errors are improved.\n",
-    "    warning(f\"CalCatError: {e}\")\n",
+    "expected_constants = {'Offset', 'BadPixelsDark'}\n",
+    "if rel_gain:\n",
+    "    expected_constants.add('RelativeGain')\n",
+    "if ff_map:\n",
+    "    expected_constants.update(['FFMap', 'BadPixelsFF'])\n",
+    "if gain_amp_map:\n",
+    "    expected_constants.add('GainAmpMap')\n",
+    "\n",
+    "lpd_consts = CalibrationData.from_condition(\n",
+    "    conditions,\n",
+    "    calibrations=expected_constants,\n",
+    "    detector_name=karabo_id,\n",
+    "    event_at=creation_time,\n",
+    "    client=rest_cfg.extra_calibration_client(),\n",
+    ").select_modules(\n",
+    "    aggregator_names=karabo_da\n",
+    ").require_calibrations(\n",
+    "    ['Offset']\n",
+    ")\n",
     "\n",
     "total_time = perf_counter() - start\n",
-    "print(f'Looking up constants {total_time:.1f}s')"
+    "print(f'Looking up constants {total_time:.1f}s')\n",
+    "\n",
+    "lpd_consts.summary_table()"
    ]
   },
   {
@@ -286,18 +295,18 @@
    "outputs": [],
    "source": [
     "# Validate the constants availability and raise/warn accordingly.\n",
-    "for mod, calibrations in lpd_metadata.items():\n",
-    "    missing_offset = {\"Offset\"} - set(calibrations)\n",
-    "    warn_missing_constants = {\n",
-    "        \"BadPixelsDark\", \"BadPixelsFF\", \"GainAmpMap\",\n",
-    "        \"FFMap\", \"RelativeGain\"} - set(calibrations)\n",
-    "    if missing_offset:\n",
+    "if not lpd_consts.aggregator_names:  # Offset was required above\n",
+    "    raise Exception(\"Could not find offset constants for any modules, will not correct data.\")\n",
+    "    \n",
+    "for mod in karabo_da.copy():\n",
+    "    if mod not in lpd_consts[\"Offset\"].aggregator_names:\n",
     "        warning(f\"Offset constant is not available to correct {mod}.\")\n",
     "        karabo_da.remove(mod)\n",
-    "    if warn_missing_constants:\n",
-    "        warning(f\"Constants {warn_missing_constants} were not retrieved for {mod}.\")\n",
-    "if not karabo_da:  # Offsets are missing for all modules.\n",
-    "    raise Exception(\"Could not find offset constants for any modules, will not correct data.\")\n",
+    "    \n",
+    "    missing_constants = {c for c in expected_constants\n",
+    "                        if (c not in lpd_consts) or (mod not in lpd_consts[c].aggregator_names)}\n",
+    "    if missing_constants:\n",
+    "        warning(f\"Constants {sorted(missing_constants)} were not retrieved for {mod}.\")\n",
     "\n",
     "# Remove skipped correction modules from data_to_process\n",
     "data_to_process = [(mod, in_f, out_f) for mod, in_f, out_f in data_to_process if mod in karabo_da]"
@@ -310,14 +319,22 @@
    "outputs": [],
    "source": [
     "# write constants metadata to fragment YAML\n",
-    "write_constants_fragment(\n",
+    "write_constants_fragment_extracal(\n",
     "    out_folder=(metadata_folder or out_folder),\n",
-    "    det_metadata=lpd_metadata,\n",
-    "    caldb_root=lpd_cal.caldb_root,\n",
+    "    calib_data=lpd_consts,\n",
+    "    caldb_root=cal_db_root,\n",
     ")\n",
     "\n",
     "# Load constants data for all constants\n",
-    "const_data = lpd_cal.ndarray_map(metadata=lpd_metadata)"
+    "start = perf_counter()\n",
+    "const_data = {kda: {} for kda in lpd_consts.aggregator_names}\n",
+    "for cname, multimodconst in lpd_consts.items():\n",
+    "    arr = multimodconst.ndarray(cal_db_root, parallel=8)\n",
+    "    for i, kda in enumerate(multimodconst.aggregator_names):\n",
+    "        const_data[kda][cname] = arr[i]\n",
+    "\n",
+    "total_time = perf_counter() - start\n",
+    "print(f'Loading constants {total_time:.1f}s')"
    ]
   },
   {
@@ -367,17 +384,17 @@
     "    else:\n",
     "        ccv_masks[aggregator] = np.zeros(ccv_shape, dtype=np.uint32)\n",
     "    \n",
-    "    if rel_gain and 'RelativeGain' in consts:\n",
+    "    if 'RelativeGain' in consts:\n",
     "        ccv_gains[aggregator] *= _prepare_data('RelativeGain', np.float32)\n",
     "        \n",
-    "    if ff_map and 'FFMap' in consts:\n",
+    "    if 'FFMap' in consts:\n",
     "        ccv_gains[aggregator] *= _prepare_data('FFMap', np.float32)\n",
     "        \n",
     "        if 'BadPixelsFF' in consts:\n",
     "            np.bitwise_or(ccv_masks[aggregator], _prepare_data('BadPixelsFF', np.uint32),\n",
     "                          out=ccv_masks[aggregator])\n",
     "        \n",
-    "    if gain_amp_map and 'GainAmpMap' in consts:\n",
+    "    if 'GainAmpMap' in consts:\n",
     "        ccv_gains[aggregator] *= _prepare_data('GainAmpMap', np.float32)\n",
     "        \n",
     "    print('.', end='', flush=True)\n",
@@ -652,9 +669,9 @@
  ],
  "metadata": {
   "kernelspec": {
-   "display_name": "pycal",
+   "display_name": "Offline Cal",
    "language": "python",
-   "name": "pycal"
+   "name": "offline-cal"
   },
   "language_info": {
    "codemirror_mode": {
@@ -666,7 +683,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.8.11"
+   "version": "3.11.8"
   }
  },
  "nbformat": 4,
diff --git a/src/cal_tools/calcat_interface2.py b/src/cal_tools/calcat_interface2.py
index e5e1bc26711cd58f06c8654abfcd60ec6ab6b3a6..464ff85c576b69ef4a7a7435f9a9cfe48b76fc95 100644
--- a/src/cal_tools/calcat_interface2.py
+++ b/src/cal_tools/calcat_interface2.py
@@ -756,7 +756,7 @@ class CalibrationData(Mapping):
             modules = self.qm_names
         else:
             raise ValueError(
-                f"{module_naming=} (must be 'aggregator', 'modnum' or 'qm'"
+                f"{module_naming=} (must be 'aggregator', 'modnum' or 'qm')"
             )
 
         cal_groups = [
@@ -766,7 +766,7 @@ class CalibrationData(Mapping):
         tables = []
         # Loop over groups of calibrations.
         for cal_group in cal_groups:
-            table = ["Modules"] + cal_group
+            table = [["Modules"] + cal_group]
 
             # Loop over calibrations and modules to form the next rows.
             for mod in modules:
@@ -790,7 +790,7 @@ class CalibrationData(Mapping):
                         except KeyError:
                             mod_consts.append(f"{c_time} ({singleconst.ccv_id})")
 
-                table.append([mod] + mod_consts)
+                table.append([str(mod)] + mod_consts)
 
             tables.append(table)
 
diff --git a/src/cal_tools/tools.py b/src/cal_tools/tools.py
index 0161fb8922db89a638ac1c8e70ca27e88da2882d..48c780dd43dc7c4c783dd0b6646218686a522faa 100644
--- a/src/cal_tools/tools.py
+++ b/src/cal_tools/tools.py
@@ -970,6 +970,8 @@ def write_constants_fragment(
 ):
     """Record calibration constants metadata to a fragment file.
 
+    This variant works with the calcat_interface module in this package.
+
     Args:
         out_folder (Path): The output folder to store the fragment file.
         det_metadata (dict): A dictionary with the desired detector metadata.
@@ -993,6 +995,40 @@ def write_constants_fragment(
     CalibrationMetadata(out_folder).add_fragment(metadata)
 
 
+def write_constants_fragment_extracal(
+        out_folder: Path,
+        calib_data: 'extra.calibration.CalibrationData',
+        caldb_root: Path,
+):
+    """Record calibration constants metadata to a fragment file.
+
+    This variant works with the extra.calibration API for found constants.
+
+    Args:
+        out_folder (Path): The output folder to store the fragment file.
+        calib_data (extra.calibration.CalibrationData): Retrieved constant details
+        caldb_root (Path): The calibration database root path for constant files.
+    """
+    retrieved_consts = {}
+    for kda, pdu in zip(calib_data.aggregator_names, calib_data.pdu_names):
+        retrieved_consts[kda] = {
+            "physical-name": pdu,
+            "constants": {},
+        }
+
+    for cname, multimodconst in calib_data.items():
+        for kda in multimodconst.aggregator_names:
+            const = multimodconst[kda]
+            retrieved_consts[kda]["constants"][cname] = {
+                "path": str(caldb_root / const.path),
+                "dataset": const.dataset,
+                "creation-time": const.metadata("begin_validity_at"),
+                "ccv_id": const.ccv_id
+            }
+
+    CalibrationMetadata(out_folder).add_fragment({"retrieved-constants": retrieved_consts})
+
+
 def write_compressed_frames(
         arr: np.ndarray,
         ofile: h5py.File,