diff --git a/src/cal_tools/calcat_interface2.py b/src/cal_tools/calcat_interface2.py
index 4bddc2b7f753ca47ce857291635b8f8956d5778c..53b01f8436c7f596f2a3090b94b477925041c581 100644
--- a/src/cal_tools/calcat_interface2.py
+++ b/src/cal_tools/calcat_interface2.py
@@ -30,34 +30,6 @@ class ModuleNameError(KeyError):
 class CalCatAPIError(requests.HTTPError):
     """Used when the response includes error details as JSON"""
 
-
-class InjectAPIError(CalCatAPIError):
-    ...
-
-
-class CCVAlreadyInjectedError(InjectAPIError):
-    ...
-
-
-CALIBRATION_CONSTANT_VERSIONS = "calibration_constant_versions"
-
-def _failed_response(resp):
-    # TODO: Add more errors if needed
-    if CALIBRATION_CONSTANT_VERSIONS in resp.url.lstrip("/"):
-        if resp.status_code == 422:
-            raise CCVAlreadyInjectedError
-    elif resp.status_code >= 400:
-        try:
-            d = json.loads(resp.content.decode("utf-8"))
-        except Exception:
-            resp.raise_for_status()
-        else:
-            raise InjectAPIError(
-                f"Error {resp.status_code} from API: "
-                f"{d.get('info', 'missing details')}"
-            )
-
-
 class CalCatAPIClient:
     def __init__(self, base_api_url, oauth_client=None, user_email=""):
         if oauth_client is not None:
@@ -106,17 +78,6 @@ class CalCatAPIClient:
             _headers.update(headers)
         return self.session.get(url, params=params, headers=_headers, **kwargs)
 
-    def post_request(self, relative_url, data=None, headers=None, **kwargs):
-        """Make a POST request, return the HTTP response object"""
-        # Base URL may include e.g. '/api/'. This is a prefix for all URLs;
-        # even if they look like an absolute path.
-        url = urljoin(self.base_api_url, relative_url.lstrip("/"))
-        _headers = self.default_headers()
-        if headers:
-            _headers.update(headers)
-        return self.session.post(
-            url, data=json.dumps(data), headers=_headers, **kwargs)
-
     @staticmethod
     def _parse_response(resp: requests.Response):
         if resp.status_code >= 400:
@@ -135,27 +96,11 @@ class CalCatAPIClient:
         else:
             return json.loads(resp.content.decode("utf-8"))
 
-    @staticmethod
-    def _parse_post_response(resp: requests.Response):
-
-        if resp.status_code >= 400:
-            _failed_response(resp)
-
-        if resp.content == b"":
-            return None
-        else:
-            return json.loads(resp.content.decode("utf-8"))
-
     def get(self, relative_url, params=None, **kwargs):
         """Make a GET request, return response content from JSON"""
         resp = self.get_request(relative_url, params, **kwargs)
         return self._parse_response(resp)
 
-    def post(self, relative_url, params=None, **kwargs):
-        """Make a POST request, return response content from JSON"""
-        resp = self.post_request(relative_url, params, **kwargs)
-        return self._parse_post_response(resp)
-
     _pagination_headers = (
         "X-Total-Pages",
         "X-Count-Per-Page",
@@ -230,20 +175,6 @@ class CalCatAPIClient:
         return self.get_by_name(
             "physical_detector_units", name, name_key="physical_name")
 
-    # Posting APIs
-    def set_expected_condition(self, conditions: dict):
-        return self.post("conditions/set_expected_condition", conditions)
-
-    def create_calibration_constant(self, calibration_constant: dict):
-        return self.post("calibration_constants", calibration_constant)
-
-    def get_or_create_report(self, report: dict):
-        # Based on create or get API
-        return self.post("reports/set", report)
-
-    def create_calibration_constant_version(self, ccv: dict):
-        return self.post(CALIBRATION_CONSTANT_VERSIONS, ccv)
-
 
 global_client = None
 
diff --git a/src/cal_tools/constants.py b/src/cal_tools/constants.py
index 98bc70a1505795f0fbe6be3565d0c65d082c7979..b7d4f8fc9b87112cd604a39c6c4957eb18d9e594 100644
--- a/src/cal_tools/constants.py
+++ b/src/cal_tools/constants.py
@@ -1,4 +1,5 @@
 import binascii
+import json
 import time
 from dataclasses import asdict, dataclass
 
@@ -8,11 +9,14 @@ from pathlib import Path
 from shutil import copyfile
 from struct import pack, unpack
 from typing import List, Tuple, Union
+from urllib.parse import urljoin
 
 import h5py
 import numpy as np
+import requests
 
 from cal_tools.calcat_interface2 import (
+    CalCatAPIClient,
     CalCatAPIError,
     get_default_caldb_root,
 )
@@ -20,6 +24,79 @@ from cal_tools.calcat_interface2 import (
 CONDITION_NAME_MAX_LENGTH = 60
 
 
+class InjectAPIError(CalCatAPIError):
+    ...
+
+
+class CCVAlreadyInjectedError(InjectAPIError):
+    ...
+
+
+def _failed_response(resp):
+    # TODO: Add more errors if needed
+    if "calibration_constant_versions" in resp.url.lstrip("/"):
+        if resp.status_code == 422:
+            raise CCVAlreadyInjectedError
+    elif resp.status_code >= 400:
+        try:
+            d = json.loads(resp.content.decode("utf-8"))
+        except Exception:
+            resp.raise_for_status()
+        else:
+            raise InjectAPIError(
+                f"Error {resp.status_code} from API: "
+                f"{d.get('info', 'missing details')}"
+            )
+
+
+class InjectAPI(CalCatAPIClient):
+    def __init__(self, base_api_url, oauth_client=None, user_email=""):
+        # Call the parent class initializer
+        super().__init__(base_api_url, oauth_client, user_email)
+        self.base_api_url = base_api_url
+
+    def post_request(self, relative_url, data=None, headers=None, **kwargs):
+        """Make a POST request, return the HTTP response object"""
+        # Base URL may include e.g. '/api/'. This is a prefix for all URLs;
+        # even if they look like an absolute path.
+        url = urljoin(self.base_api_url, relative_url.lstrip("/"))
+        _headers = self.default_headers()
+        if headers:
+            _headers.update(headers)
+        return self.session.post(
+            url, data=json.dumps(data), headers=_headers, **kwargs)
+
+    @staticmethod
+    def _parse_post_response(resp: requests.Response):
+
+        if resp.status_code >= 400:
+            _failed_response(resp)
+
+        if resp.content == b"":
+            return None
+        else:
+            return json.loads(resp.content.decode("utf-8"))
+
+    def post(self, relative_url, params=None, **kwargs):
+        """Make a POST request, return response content from JSON"""
+        resp = self.post_request(relative_url, params, **kwargs)
+        return self._parse_post_response(resp)
+
+    # Posting APIs
+    def set_expected_condition(self, conditions: dict):
+        return self.post("conditions/set_expected_condition", conditions)
+
+    def create_calibration_constant(self, calibration_constant: dict):
+        return self.post("calibration_constants", calibration_constant)
+
+    def get_or_create_report(self, report: dict):
+        # Based on create or get API
+        return self.post("reports/set", report)
+
+    def create_calibration_constant_version(self, ccv: dict):
+        return self.post("calibration_constant_versions", ccv)
+
+
 @dataclass
 class ParameterConditionAttribute:
     value: str
@@ -55,14 +132,6 @@ def create_unique_cc_name(det_type, calibration, condition_name):
     return f'{cc_name_1[:40]}_{condition_name}'
 
 
-class InjectAPIError(CalCatAPIError):
-    ...
-
-
-class CCVAlreadyInjectedError(InjectAPIError):
-    ...
-
-
 def create_unique_ccv_name(start_idx):
     # Generate unique name if it doesn't exist
     datetime_str = datetime_str = datetime.now(