Repository: CrowdStrike/falconpy (language: python)

Issue:
[ BUG ] FirewallPolicy.performFirewallPoliciesAction returns 500 error with 'add-rule-group'.
**Describe the bug**
DocString shows 'add-rule-group' and 'remove-rule-group' as available options. However, in '_allowed_actions' var within the relevant function, these actions are absent. So the function returns a 500 error instead. If I manually add in the actions, it instead returns a 400 error. 

**To Reproduce**
`from falconpy import FirewallPolicies`
`client = FirewallPolicies()`
`rg = "target FW rule group"`
`pol = "target FW policy"`
`response = client.perform_policies_action(action_name = 'add-rule-group', ids = pol, group_id = rg)`
response output:
`{'status_code': 500, 'headers': {}, 'body': {'errors': [{'message': 'Invalid value specified for action_name parameter.'}], 'resources': []}}`

Again, above error is result of action not being in '_allowed_actions' var. Manually adding these actions does not fix the issue, just instead returns 400 error from server.

**Expected behavior**
See below output for what happens when following the same steps, but instead trying to use the 'add-host-group' action. This is about what I'd expect to see from the 'add-rule-group' action:
`from falconpy import FirewallPolicies`
`client = FirewallPolicies()`
`hg = "target host group"`
`pol = "target FW policy"`
`response = client.perform_policies_action(action_name = 'add-host-group', ids = pol, group_id = hg)`
Reponse output:
`'{'status_code': 200, 'headers': {'Server': 'nginx', 'Date': 'Fri, 27 Oct 2023 15:24:17 GMT', 'Content-Type': 'application/json', 'Content-Length': '915', 'Connection': 'keep-alive', 'Content-Encoding': 'gzip', 'Strict-Transport-Security': 'max-age=15724800; includeSubDomains, max-age=31536000; includeSubDomains', 'X-Cs-Region': 'us-2', 'X-Cs-Traceid': '...', 'X-Ratelimit-Limit': '6000', 'X-Ratelimit-Remaining': '5999'}, 'body': {'meta': {'query_time': 0.087387752, 'trace_id': '...'}, 'resources': [{...}]'`

**Environment (please complete the following information):**
 - OS: MacOS Ventura 13.6
 - Python: 3.11.5
 - FalconPy: 1.3.2




Discussion / hints:

Fix patch:
diff --git a/.github/wordlist.txt b/.github/wordlist.txt
index 5e4c4216d..8093703bb 100644
--- a/.github/wordlist.txt
+++ b/.github/wordlist.txt
@@ -876,4 +876,27 @@ GetCombinedImages
 AggregateAlerts
 QueryAlertIdsByFilter
 URLEncoded
-aboese
\ No newline at end of file
+aboese
+ListObjects
+SearchObjects
+GetObject
+PutObject
+DeleteObject
+GetObjectMetadata
+WorkflowExecute
+WorkflowExecutionsAction
+WorkflowExecutionResults
+WorkflowSystemsDefinitionsDeProvision
+WorkflowSystemsDefinitionsPromote
+WorkflowSystemsDefinitionsProvision
+RTRAuditSessions
+LogScale
+ListReposV
+ListViewV
+IngestDataV
+CreateSavedSearchesDynamicExecuteV
+GetSavedSearchesExecuteV
+CreateSavedSearchesExecuteV
+CreateSavedSearchesIngestV
+GetSavedSearchesJobResultsDownloadV
+clobberer
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e84e691bc..35ebf3bdf 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,88 @@
+# Version 1.3.3
+## Added features and functionality
++ Added: Deprecation warnings for deprecated classes and operations. Closes #1055.
+    - `_endpoint/__init__.py`
+    - `_endpoint/deprecated/__init__.py`
+    - `_endpoint/deprecated/_mapping.py`
+    - `_error/__init__.py`
+    - `_error/_warnings.py`
+    - `_service_class/_service_class.py`
+    - `_util/__init__.py`
+    - `_util/_functions.py`
++ Added: New Custom Storage service collection.
+    - `__init__.py`
+    - `_endpoint/__init__.py`
+    - `_endpoint/_custom_storage.py`
+    - `_util/_functions.py`
+    - `custom_storage.py`
+    > Expanded unit testing to complete code coverage.
+    - `tests/test_custom_storage.py`
+    > The following new operations are provided by this service collection:
+    + _ListObjects_
+    + _SearchObjects_
+    + _GetObject_
+    + _PutObject_
+    + _DeleteObject_
+    + _GetObjectMetadata_
++ Added: New Workflows service collection.
+    - `__init__.py`
+    - `_endpoint/__init__.py`
+    - `_endpoint/_workflows.py`
+    - `_endpoint/_workflows.py`
+    - `_payload/__init__.py`
+    - `_payload/_generic.py`
+    - `_payload/_workflows.py`
+    - `workflows.py`
+    > Expanded unit testing to complete code coverage.
+    - `tests/test_workflows.py`
+    > The following new operations are provided by this service collection:
+    + _WorkflowExecute_
+    + _WorkflowExecutionsAction_
+    + _WorkflowExecutionResults_
+    + _WorkflowSystemsDefinitionsDeProvision_
+    + _WorkflowSystemsDefinitionsPromote_
+    + _WorkflowSystemsDefinitionsProvision_
++ Added: New Real Time Response Audit service collection.
+    - `__init__.py`
+    - `_endpoint/__init__.py`
+    - `_endpoint/_real_time_response_audit.py`
+    - `real_time_response_audit.py`
+    > Expanded unit testing to complete code coverage.
+    - `tests/test_real_time_response_audit.py`
+    > The following new operations are provided by this service collection:
+    + _RTRAuditSessions_
++ Added: New Foundry LogScale service collection.
+    - `__init__.py`
+    - `_endpoint/__init__.py`
+    - `_endpoint/_foundry_logscale.py`
+    - `_payload/__init__.py`
+    - `_payload/_foundry.py`
+    - `foundry_logscale.py`
+    > Expanded unit testing to complete code coverage.
+    - `tests/test_foundry_logscale.py`
+    > The following new operations are provided by this service collection:
+    + _ListReposV1_
+    + _ListViewV1_
+    + _IngestDataV1_
+    + _CreateSavedSearchesDynamicExecuteV1_
+    + _GetSavedSearchesExecuteV1_
+    + _CreateSavedSearchesExecuteV1_
+    + _CreateSavedSearchesIngestV1_
+    + _GetSavedSearchesJobResultsDownloadV1_
+
+## Issues resolved
++ Fixed: Error when trying to directly import falconpy module (no package installation). Closes #1056.
+    - `_auth_object/_falcon_interface.py`
+    - `_util/_functions.py`
+    - Thanks go out to @tsullivan06 for identifying and reporting this issue. 🙇
++ Fixed: Legacy Uber Class is not logging Operation ID in debug logs. Closes #1057.
+    - `api_complete/_legacy.py`
++ Fixed: Can not use `add-rule-group` and `remove-rule-group` actions with the __`performFirewallPoliciesAction`__ operation. Closes #1059.
+    - `firewall_policies.py`
+    - Thanks go out to @api-clobberer for identifying and reporting this issue. 🙇
+
+---
+
 # Version 1.3.2
 > This release resolves a breaking change introduced in Version 1.3.0. This issue presents itself when developers attempt to call the `authenticated` method directly from the `OAuth2` Service Class. Review issue #1043 for more detail.
 
diff --git a/README.md b/README.md
index 521baa60b..c0c37f062 100644
--- a/README.md
+++ b/README.md
@@ -81,7 +81,7 @@ For each CrowdStrike Falcon API service collection, a matching Service Class is
 | Device Control | [device_control_policies.py](https://github.com/CrowdStrike/falconpy/blob/main/src/falconpy/device_control_policies.py) | [DeviceControlPolicies](https://www.falconpy.io/Service-Collections/Device-Control-Policies.html) |
 | Custom Indicators of Attack (IOAs) | [custom_ioa.py](https://github.com/CrowdStrike/falconpy/blob/main/src/falconpy/custom_ioa.py) <br/> [ioa_exclusions.py](https://github.com/CrowdStrike/falconpy/blob/main/src/falconpy/ioa_exclusions.py)| [CustomIOA](https://www.falconpy.io/Service-Collections/Custom-IOA.html)<BR/>[IOAExclusions](https://www.falconpy.io/Service-Collections/IOA-Exclusions.html) |
 | Detections | [detects.py](https://github.com/CrowdStrike/falconpy/blob/main/src/falconpy/detects.py) | [Detects](https://www.falconpy.io/Service-Collections/Detects.html) |
-| Falcon Discover | [cloud_connect_aws.py](https://github.com/CrowdStrike/falconpy/blob/main/src/falconpy/cloud_connect_aws.py)<BR/>[d4c_registration.py](https://github.com/CrowdStrike/falconpy/blob/main/src/falconpy/d4c_registration.py)<BR/>[discover.py](https://github.com/CrowdStrike/falconpy/blob/main/src/falconpy/discover.py) | [CloudConnectAWS](https://www.falconpy.io/Service-Collections/Cloud-Connect-AWS.html)<BR/>[D4CRegistration](https://www.falconpy.io/Service-Collections/D4C-Registration.html)<BR/>[Discover](https://www.falconpy.io/Service-Collections/Discover.html) |
+| Falcon Discover | [cloud_connect_aws.py](https://github.com/CrowdStrike/falconpy/blob/main/src/falconpy/cloud_connect_aws.py) <small>(*Deprecated*)</small><BR/>[d4c_registration.py](https://github.com/CrowdStrike/falconpy/blob/main/src/falconpy/d4c_registration.py) <small>(*Deprecated*)</small><BR/>[discover.py](https://github.com/CrowdStrike/falconpy/blob/main/src/falconpy/discover.py) | [CloudConnectAWS](https://www.falconpy.io/Service-Collections/Cloud-Connect-AWS.html)<BR/>[D4CRegistration](https://www.falconpy.io/Service-Collections/D4C-Registration.html)<BR/>[Discover](https://www.falconpy.io/Service-Collections/Discover.html) |
 | Event Streams | [event_streams.py](https://github.com/CrowdStrike/falconpy/blob/main/src/falconpy/event_streams.py) | [EventStreams](https://www.falconpy.io/Service-Collections/Event-Streams.html) |
 | Falcon Container | [falcon_container.py](https://github.com/CrowdStrike/falconpy/blob/main/src/falconpy/falcon_container.py) | [FalconContainer](https://www.falconpy.io/Service-Collections/Falcon-Container.html) |
 | Falcon Horizon | [cspm_registration.py](https://github.com/CrowdStrike/falconpy/blob/main/src/falconpy/cspm_registration.py) | [CSPMRegistration](https://www.falconpy.io/Service-Collections/CSPM-Registration.html) |
@@ -112,7 +112,7 @@ For each CrowdStrike Falcon API service collection, a matching Service Class is
 | Sensor Visibility Exclusions | [sensor_visibility_exclusions.py](https://github.com/CrowdStrike/falconpy/blob/main/src/falconpy/sensor_visibility_exclusions.py) | [SensorVisibilityExclusions](https://www.falconpy.io/Service-Collections/Sensor-Visibility-Exclusions.html) |
 | Sensor Update Policy Management | [sensor_update_policy.py](https://github.com/CrowdStrike/falconpy/blob/main/src/falconpy/sensor_update_policy.py) | [SensorUpdatePolicy](https://www.falconpy.io/Service-Collections/Sensor-Update-Policy.html) |
 | Spotlight | [spotlight_evaluation_logic.py](https://github.com/CrowdStrike/falconpy/blob/main/src/falconpy/spotlight_evaluation_logic.py)<BR/>[spotlight_vulnerabilities.py](https://github.com/CrowdStrike/falconpy/blob/main/src/falconpy/spotlight_vulnerabilities.py) | [SpotlightEvaluationLogic](https://www.falconpy.io/Service-Collections/Spotlight-Evaluation-Logic.html)<BR/>[SpotlightVulnerabilities](https://www.falconpy.io/Service-Collections/Spotlight-Vulnerabilities.html) |
-| __Falcon Intelligence__<BR/>Intel<BR/>IOC<BR/>IOCS<BR/>MalQuery<BR/>ODS (On Demand Scan)<BR/>Quick Scan<BR/>Recon<BR/>Sample Uploads<BR/>Sandbox | <BR/>[intel.py](https://github.com/CrowdStrike/falconpy/blob/main/src/falconpy/intel.py)<br/>[ioc.py](https://github.com/CrowdStrike/falconpy/blob/main/src/falconpy/ioc.py) <BR/> [iocs.py](https://github.com/CrowdStrike/falconpy/blob/main/src/falconpy/iocs.py) <small>*Deprecated*</small><BR/>[malquery.py](https://github.com/CrowdStrike/falconpy/blob/main/src/falconpy/malquery.py)<BR/>[ods.py](https://github.com/CrowdStrike/falconpy/blob/main/src/falconpy/ods.py)<BR/>[quick_scan.py](https://github.com/CrowdStrike/falconpy/blob/main/src/falconpy/quick_scan.py)<BR/>[recon.py](https://github.com/CrowdStrike/falconpy/blob/main/src/falconpy/recon.py)<BR/>[sample_uploads.py](https://github.com/CrowdStrike/falconpy/blob/main/src/falconpy/sample_uploads.py) <BR/> [falconx_sandbox.py](https://github.com/CrowdStrike/falconpy/blob/main/src/falconpy/falconx_sandbox.py)| <BR/>[Intel](https://www.falconpy.io/Service-Collections/Intel.html)<BR/>[IOC](https://www.falconpy.io/Service-Collections/IOC.html)<BR/>[Iocs](https://www.falconpy.io/Service-Collections/IOCs.html)<BR/>[MalQuery](https://www.falconpy.io/Service-Collections/MalQuery.html)<BR/>[ODS](https://www.falconpy.io/Service-Collections/ODS.html)<BR/>[QuickScan](https://www.falconpy.io/Service-Collections/Quick-Scan.html)<BR/><a href="https://www.falconpy.io/Service-Collections/Recon.html" target="_blank">Recon</a><BR/>[SampleUploads](https://www.falconpy.io/Service-Collections/Sample-Uploads.html)<BR/>[FalconXSandbox](https://www.falconpy.io/Service-Collections/Falconx-Sandbox.html) |
+| __Falcon Intelligence__<BR/>Intel<BR/>IOC<BR/>IOCS<BR/>MalQuery<BR/>ODS (On Demand Scan)<BR/>Quick Scan<BR/>Recon<BR/>Sample Uploads<BR/>Sandbox | <BR/>[intel.py](https://github.com/CrowdStrike/falconpy/blob/main/src/falconpy/intel.py)<br/>[ioc.py](https://github.com/CrowdStrike/falconpy/blob/main/src/falconpy/ioc.py) <BR/> [iocs.py](https://github.com/CrowdStrike/falconpy/blob/main/src/falconpy/iocs.py) <small>(*Deprecated*)</small><BR/>[malquery.py](https://github.com/CrowdStrike/falconpy/blob/main/src/falconpy/malquery.py)<BR/>[ods.py](https://github.com/CrowdStrike/falconpy/blob/main/src/falconpy/ods.py)<BR/>[quick_scan.py](https://github.com/CrowdStrike/falconpy/blob/main/src/falconpy/quick_scan.py)<BR/>[recon.py](https://github.com/CrowdStrike/falconpy/blob/main/src/falconpy/recon.py)<BR/>[sample_uploads.py](https://github.com/CrowdStrike/falconpy/blob/main/src/falconpy/sample_uploads.py) <BR/> [falconx_sandbox.py](https://github.com/CrowdStrike/falconpy/blob/main/src/falconpy/falconx_sandbox.py)| <BR/>[Intel](https://www.falconpy.io/Service-Collections/Intel.html)<BR/>[IOC](https://www.falconpy.io/Service-Collections/IOC.html)<BR/>[Iocs](https://www.falconpy.io/Service-Collections/IOCs.html)<BR/>[MalQuery](https://www.falconpy.io/Service-Collections/MalQuery.html)<BR/>[ODS](https://www.falconpy.io/Service-Collections/ODS.html)<BR/>[QuickScan](https://www.falconpy.io/Service-Collections/Quick-Scan.html)<BR/><a href="https://www.falconpy.io/Service-Collections/Recon.html" target="_blank">Recon</a><BR/>[SampleUploads](https://www.falconpy.io/Service-Collections/Sample-Uploads.html)<BR/>[FalconXSandbox](https://www.falconpy.io/Service-Collections/Falconx-Sandbox.html) |
 | User and Roles | [user_management.py](https://github.com/CrowdStrike/falconpy/blob/main/src/falconpy/user_management.py) | [UserManagement](https://www.falconpy.io/Service-Collections/User-Management.html) |
 | Falcon Zero Trust Assessment | [zero_trust_assessment.py](https://github.com/CrowdStrike/falconpy/blob/main/src/falconpy/zero_trust_assessment.py) | [ZeroTrustAssessment](https://www.falconpy.io/Service-Collections/Zero-Trust-Assessment.html) |
 
diff --git a/src/falconpy/__init__.py b/src/falconpy/__init__.py
index d43429d7d..af0c177ce 100644
--- a/src/falconpy/__init__.py
+++ b/src/falconpy/__init__.py
@@ -61,7 +61,10 @@
     NoAuthenticationMechanism,
     InvalidIndex,
     InvalidCredentialFormat,
-    UnnecessaryEncodingUsed
+    UnnecessaryEncodingUsed,
+    DeprecatedClass,
+    DeprecatedOperation,
+    SDKDeprecationWarning
     )
 from ._result import (
     Result,
@@ -90,6 +93,7 @@
 from .cloud_connect_aws import CloudConnectAWS
 from .cspm_registration import CSPMRegistration
 from .custom_ioa import CustomIOA
+from .custom_storage import CustomStorage
 from .d4c_registration import D4CRegistration
 from .detects import Detects
 from .device_control_policies import DeviceControlPolicies
@@ -102,6 +106,7 @@
 from .filevantage import FileVantage
 from .firewall_management import FirewallManagement
 from .firewall_policies import FirewallPolicies
+from .foundry_logscale import FoundryLogScale
 from .host_group import HostGroup
 from .hosts import Hosts
 from .identity_protection import IdentityProtection
@@ -124,6 +129,7 @@
 from .quarantine import Quarantine
 from .quick_scan import QuickScan
 from .real_time_response_admin import RealTimeResponseAdmin
+from .real_time_response_audit import RealTimeResponseAudit
 from .real_time_response import RealTimeResponse
 from .recon import Recon
 from .report_executions import ReportExecutions
@@ -137,6 +143,7 @@
 from .spotlight_evaluation_logic import SpotlightEvaluationLogic
 from .tailored_intelligence import TailoredIntelligence
 from .user_management import UserManagement
+from .workflows import Workflows
 from .zero_trust_assessment import ZeroTrustAssessment
 
 __version__ = _VERSION
@@ -173,7 +180,9 @@
     "RequestPayloads", "RequestValidator", "PayloadValidationError", "MIN_TOKEN_RENEW_WINDOW",
     "MAX_TOKEN_RENEW_WINDOW", "GLOBAL_API_MAX_RETURN", "MOCK_OPERATIONS", "CloudSnapshots",
     "NoAuthenticationMechanism", "InvalidIndex", "version", "InvalidCredentialFormat",
-    "UnnecessaryEncodingUsed", "APIHarnessV2"
+    "UnnecessaryEncodingUsed", "APIHarnessV2", "CustomStorage", "FoundryLogScale",
+    "RealTimeResponseAudit", "Workflows", "DeprecatedClass", "DeprecatedOperation",
+    "SDKDeprecationWarning"
     ]
 """
 This is free and unencumbered software released into the public domain.
diff --git a/src/falconpy/_auth_object/_falcon_interface.py b/src/falconpy/_auth_object/_falcon_interface.py
index 943e5581c..f71cf2e3a 100644
--- a/src/falconpy/_auth_object/_falcon_interface.py
+++ b/src/falconpy/_auth_object/_falcon_interface.py
@@ -44,7 +44,7 @@
 from json import loads
 try:
     from simplejson import JSONDecodeError
-except ImportError:
+except (ImportError, ModuleNotFoundError):  # Support import as a module
     from json.decoder import JSONDecodeError
 from logging import Logger, getLogger
 from typing import Dict, Optional, Union
diff --git a/src/falconpy/_constant/__init__.py b/src/falconpy/_constant/__init__.py
index a8bf1e5cb..c9d44ffde 100644
--- a/src/falconpy/_constant/__init__.py
+++ b/src/falconpy/_constant/__init__.py
@@ -45,7 +45,8 @@
 PREFER_IDS_IN_BODY: List[str] = [
     "GetDeviceDetails", "PostDeviceDetailsV2", "GetVulnerabilities", "GetIntelIndicatorEntities",
     "getChildrenV2", "cancel-scans", "GetDetectSummaries", "UpdateQuarantinedDetectsByIds",
-    "GetQuarantineFiles", "PostEntitiesAlertsV1"
+    "GetQuarantineFiles", "PostEntitiesAlertsV1", "CreateSavedSearchesDeployV1",
+    "WorkflowExecutionsAction"
 ]
 MOCK_OPERATIONS: List[str] = [
     "GetImageAssessmentReport", "DeleteImageDetails", "ImageMatchesPolicy"
diff --git a/src/falconpy/_endpoint/__init__.py b/src/falconpy/_endpoint/__init__.py
index 46d2c7619..be3400177 100644
--- a/src/falconpy/_endpoint/__init__.py
+++ b/src/falconpy/_endpoint/__init__.py
@@ -36,12 +36,15 @@
 from .deprecated import _report_executions_deprecated
 from .deprecated import _scheduled_reports_deprecated
 from .deprecated import _zero_trust_assessment_deprecated
+from .deprecated import _deprecated_operation_mapping
+from .deprecated import _deprecated_class_mapping
 
 from ._alerts import _alerts_endpoints
 from ._cloud_connect_aws import _cloud_connect_aws_endpoints
 from ._cloud_snapshots import _cloud_snapshot_endpoints
 from ._cspm_registration import _cspm_registration_endpoints
 from ._custom_ioa import _custom_ioa_endpoints
+from ._custom_storage import _custom_storage_endpoints
 from ._d4c_registration import _d4c_registration_endpoints
 from ._detects import _detects_endpoints
 from ._device_control_policies import _device_control_policies_endpoints
@@ -53,6 +56,7 @@
 from ._filevantage import _filevantage_endpoints
 from ._firewall_management import _firewall_management_endpoints
 from ._firewall_policies import _firewall_policies_endpoints
+from ._foundry_logscale import _foundry_logscale_endpoints
 from ._host_group import _host_group_endpoints
 from ._hosts import _hosts_endpoints
 from ._identity_protection import _identity_protection_endpoints
@@ -76,6 +80,7 @@
 from ._quick_scan import _quick_scan_endpoints
 from ._real_time_response import _real_time_response_endpoints
 from ._real_time_response_admin import _real_time_response_admin_endpoints
+from ._real_time_response_audit import _real_time_response_audit_endpoints
 from ._recon import _recon_endpoints
 from ._report_executions import _report_executions_endpoints
 from ._response_policies import _response_policies_endpoints
@@ -88,6 +93,7 @@
 from ._spotlight_vulnerabilities import _spotlight_vulnerabilities_endpoints
 from ._tailored_intelligence import _tailored_intelligence_endpoints
 from ._user_management import _user_management_endpoints
+from ._workflows import _workflows_endpoints
 from ._zero_trust_assessment import _zero_trust_assessment_endpoints
 
 api_endpoints: List[Any] = []
@@ -96,6 +102,7 @@
 api_endpoints.extend(_cloud_snapshot_endpoints)
 api_endpoints.extend(_cspm_registration_endpoints)
 api_endpoints.extend(_custom_ioa_endpoints)
+api_endpoints.extend(_custom_storage_endpoints)
 api_endpoints.extend(_d4c_registration_endpoints)
 api_endpoints.extend(_detects_endpoints)
 api_endpoints.extend(_device_control_policies_endpoints)
@@ -107,6 +114,7 @@
 api_endpoints.extend(_filevantage_endpoints)
 api_endpoints.extend(_firewall_management_endpoints)
 api_endpoints.extend(_firewall_policies_endpoints)
+api_endpoints.extend(_foundry_logscale_endpoints)
 api_endpoints.extend(_host_group_endpoints)
 api_endpoints.extend(_hosts_endpoints)
 api_endpoints.extend(_identity_protection_endpoints)
@@ -130,6 +138,7 @@
 api_endpoints.extend(_quick_scan_endpoints)
 api_endpoints.extend(_real_time_response_endpoints)
 api_endpoints.extend(_real_time_response_admin_endpoints)
+api_endpoints.extend(_real_time_response_audit_endpoints)
 api_endpoints.extend(_recon_endpoints)
 api_endpoints.extend(_report_executions_endpoints)
 api_endpoints.extend(_response_policies_endpoints)
@@ -142,6 +151,7 @@
 api_endpoints.extend(_spotlight_vulnerabilities_endpoints)
 api_endpoints.extend(_tailored_intelligence_endpoints)
 api_endpoints.extend(_user_management_endpoints)
+api_endpoints.extend(_workflows_endpoints)
 api_endpoints.extend(_zero_trust_assessment_endpoints)
 
 # Deprecated endpoints
@@ -163,5 +173,9 @@
 deprecated_endpoints.extend(_scheduled_reports_deprecated)
 deprecated_endpoints.extend(_zero_trust_assessment_deprecated)
 
+# Mapping of manually deprecated endpoints
+operation_deprecation_mapping = _deprecated_operation_mapping
+class_deprecation_mapping = _deprecated_class_mapping
+
 # api_endpoints contains all endpoints, production and deprecated
 api_endpoints.extend(deprecated_endpoints)
diff --git a/src/falconpy/_endpoint/_custom_storage.py b/src/falconpy/_endpoint/_custom_storage.py
new file mode 100644
index 000000000..d950ca61a
--- /dev/null
+++ b/src/falconpy/_endpoint/_custom_storage.py
@@ -0,0 +1,374 @@
+"""Internal API endpoint constant library.
+
+ _______                        __ _______ __        __ __
+|   _   .----.-----.--.--.--.--|  |   _   |  |_.----|__|  |--.-----.
+|.  1___|   _|  _  |  |  |  |  _  |   1___|   _|   _|  |    <|  -__|
+|.  |___|__| |_____|________|_____|____   |____|__| |__|__|__|_____|
+|:  1   |                         |:  1   |
+|::.. . |   CROWDSTRIKE FALCON    |::.. . |    FalconPy
+`-------'                         `-------'
+
+OAuth2 API - Customer SDK
+
+This is free and unencumbered software released into the public domain.
+
+Anyone is free to copy, modify, publish, use, compile, sell, or
+distribute this software, either in source code form or as a compiled
+binary, for any purpose, commercial or non-commercial, and by any
+means.
+
+In jurisdictions that recognize copyright laws, the author or authors
+of this software dedicate any and all copyright interest in the
+software to the public domain. We make this dedication for the benefit
+of the public at large and to the detriment of our heirs and
+successors. We intend this dedication to be an overt act of
+relinquishment in perpetuity of all present and future rights to this
+software under copyright law.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+For more information, please refer to <https://unlicense.org>
+"""
+
+_custom_storage_endpoints = [
+  [
+    "ListObjects",
+    "GET",
+    "/customobjects/v1/collections/{collection_name}/objects",
+    "List the object keys in the specified collection in alphabetical order",
+    "custom_storage",
+    [
+      {
+        "maxLength": 32,
+        "minLength": 32,
+        "type": "string",
+        "description": "The id of the app the collection belongs to. "
+        "This will map to the namespace of the collection",
+        "name": "X-CS-APP-ID",
+        "in": "header"
+      },
+      {
+        "maxLength": 255,
+        "minLength": 1,
+        "type": "string",
+        "description": "The name of the collection",
+        "name": "collection_name",
+        "in": "path",
+        "required": True
+      },
+      {
+        "maxLength": 1000,
+        "minLength": 1,
+        "type": "string",
+        "description": "The end key to end listing to",
+        "name": "end",
+        "in": "query",
+        "allowEmptyValue": True
+      },
+      {
+        "type": "integer",
+        "description": "The limit of results to return",
+        "name": "limit",
+        "in": "query",
+        "allowEmptyValue": True
+      },
+      {
+        "maxLength": 255,
+        "minLength": 1,
+        "type": "string",
+        "description": "The name of the namespace the collection belongs to",
+        "name": "X-CS-ADB-NAMESPACE",
+        "in": "header",
+        "required": True
+      },
+      {
+        "maxLength": 1000,
+        "minLength": 1,
+        "type": "string",
+        "description": "The start key to start listing from",
+        "name": "start",
+        "in": "query",
+        "allowEmptyValue": True
+      }
+    ]
+  ],
+  [
+    "SearchObjects",
+    "POST",
+    "/customobjects/v1/collections/{collection_name}/objects",
+    "Search for objects that match the specified filter criteria (returns metadata, not actual objects)",
+    "custom_storage",
+    [
+      {
+        "maxLength": 32,
+        "minLength": 32,
+        "type": "string",
+        "description": "The id of the app the collection belongs to. This will map to the namespace of the collection",
+        "name": "X-CS-APP-ID",
+        "in": "header"
+      },
+      {
+        "maxLength": 255,
+        "minLength": 1,
+        "type": "string",
+        "description": "The name of the collection",
+        "name": "collection_name",
+        "in": "path",
+        "required": True
+      },
+      {
+        "maxLength": 255,
+        "minLength": 1,
+        "type": "string",
+        "description": "The filter to limit the returned results.",
+        "name": "filter",
+        "in": "query",
+        "required": True
+      },
+      {
+        "type": "integer",
+        "description": "The limit of results to return",
+        "name": "limit",
+        "in": "query",
+        "allowEmptyValue": True
+      },
+      {
+        "maxLength": 255,
+        "minLength": 1,
+        "type": "string",
+        "description": "The name of the namespace the collection belongs to",
+        "name": "X-CS-ADB-NAMESPACE",
+        "in": "header",
+        "required": True
+      },
+      {
+        "type": "integer",
+        "description": "The offset of results to return",
+        "name": "offset",
+        "in": "query",
+        "allowEmptyValue": True
+      },
+      {
+        "maxLength": 255,
+        "minLength": 1,
+        "type": "string",
+        "description": "The sort order for the returned results.",
+        "name": "sort",
+        "in": "query"
+      }
+    ]
+  ],
+  [
+    "GetObject",
+    "GET",
+    "/customobjects/v1/collections/{collection_name}/objects/{object_key}",
+    "Get the bytes for the specified object",
+    "custom_storage",
+    [
+      {
+        "maxLength": 32,
+        "minLength": 32,
+        "type": "string",
+        "description": "The id of the app the collection belongs to. This will map to the namespace of the collection",
+        "name": "X-CS-APP-ID",
+        "in": "header"
+      },
+      {
+        "maxLength": 255,
+        "minLength": 1,
+        "type": "string",
+        "description": "The name of the collection",
+        "name": "collection_name",
+        "in": "path",
+        "required": True
+      },
+      {
+        "maxLength": 255,
+        "minLength": 1,
+        "type": "string",
+        "description": "The name of the namespace the collection belongs to",
+        "name": "X-CS-ADB-NAMESPACE",
+        "in": "header",
+        "required": True
+      },
+      {
+        "maxLength": 1000,
+        "minLength": 1,
+        "type": "string",
+        "description": "The object key",
+        "name": "object_key",
+        "in": "path",
+        "required": True
+      }
+    ]
+  ],
+  [
+    "PutObject",
+    "PUT",
+    "/customobjects/v1/collections/{collection_name}/objects/{object_key}",
+    "Put the specified new object at the given key or overwrite an existing object at the given key",
+    "custom_storage",
+    [
+      {
+        "name": "body",
+        "in": "body",
+        "required": True
+      },
+      {
+        "maxLength": 32,
+        "minLength": 32,
+        "type": "string",
+        "description": "The id of the app the collection belongs to. This will map to the namespace of the collection",
+        "name": "X-CS-APP-ID",
+        "in": "header"
+      },
+      {
+        "maxLength": 255,
+        "minLength": 1,
+        "type": "string",
+        "description": "The name of the collection",
+        "name": "collection_name",
+        "in": "path",
+        "required": True
+      },
+      {
+        "type": "boolean",
+        "description": "If false, run the operation as normal.  "
+        "If true, validate that the request *would* succeed, but don't execute it.",
+        "name": "dry_run",
+        "in": "query",
+        "allowEmptyValue": True
+      },
+      {
+        "maxLength": 255,
+        "minLength": 1,
+        "type": "string",
+        "description": "The name of the namespace the collection belongs to",
+        "name": "X-CS-ADB-NAMESPACE",
+        "in": "header",
+        "required": True
+      },
+      {
+        "maxLength": 1000,
+        "minLength": 1,
+        "type": "string",
+        "description": "The object key",
+        "name": "object_key",
+        "in": "path",
+        "required": True
+      },
+      {
+        "minLength": 1,
+        "type": "string",
+        "description": "The version of the collection schema",
+        "name": "schema_version",
+        "in": "query",
+        "required": True
+      }
+    ]
+  ],
+  [
+    "DeleteObject",
+    "DELETE",
+    "/customobjects/v1/collections/{collection_name}/objects/{object_key}",
+    "Delete the specified object",
+    "custom_storage",
+    [
+      {
+        "maxLength": 32,
+        "minLength": 32,
+        "type": "string",
+        "description": "The id of the app the collection belongs to. "
+        "This will map to the namespace of the collection",
+        "name": "X-CS-APP-ID",
+        "in": "header"
+      },
+      {
+        "maxLength": 255,
+        "minLength": 1,
+        "type": "string",
+        "description": "The name of the collection",
+        "name": "collection_name",
+        "in": "path",
+        "required": True
+      },
+      {
+        "type": "boolean",
+        "description": "If false, run the operation as normal.  "
+        "If true, validate that the request *would* succeed, but don't execute it.",
+        "name": "dry_run",
+        "in": "query",
+        "allowEmptyValue": True
+      },
+      {
+        "maxLength": 255,
+        "minLength": 1,
+        "type": "string",
+        "description": "The name of the namespace the collection belongs to",
+        "name": "X-CS-ADB-NAMESPACE",
+        "in": "header",
+        "required": True
+      },
+      {
+        "maxLength": 1000,
+        "minLength": 1,
+        "type": "string",
+        "description": "The object key",
+        "name": "object_key",
+        "in": "path",
+        "required": True
+      }
+    ]
+  ],
+  [
+    "GetObjectMetadata",
+    "GET",
+    "/customobjects/v1/collections/{collection_name}/objects/{object_key}/metadata",
+    "Get the metadata for the specified object",
+    "custom_storage",
+    [
+      {
+        "maxLength": 32,
+        "minLength": 32,
+        "type": "string",
+        "description": "The id of the app the collection belongs to. "
+        "This will map to the namespace of the collection",
+        "name": "X-CS-APP-ID",
+        "in": "header"
+      },
+      {
+        "maxLength": 255,
+        "minLength": 1,
+        "type": "string",
+        "description": "The name of the collection",
+        "name": "collection_name",
+        "in": "path",
+        "required": True
+      },
+      {
+        "maxLength": 255,
+        "minLength": 1,
+        "type": "string",
+        "description": "The name of the namespace the collection belongs to",
+        "name": "X-CS-ADB-NAMESPACE",
+        "in": "header",
+        "required": True
+      },
+      {
+        "maxLength": 1000,
+        "minLength": 1,
+        "type": "string",
+        "description": "The object key",
+        "name": "object_key",
+        "in": "path",
+        "required": True
+      }
+    ]
+  ]
+]
diff --git a/src/falconpy/_endpoint/_foundry_logscale.py b/src/falconpy/_endpoint/_foundry_logscale.py
new file mode 100644
index 000000000..9baaea7c4
--- /dev/null
+++ b/src/falconpy/_endpoint/_foundry_logscale.py
@@ -0,0 +1,273 @@
+"""Internal API endpoint constant library.
+
+ _______                        __ _______ __        __ __
+|   _   .----.-----.--.--.--.--|  |   _   |  |_.----|__|  |--.-----.
+|.  1___|   _|  _  |  |  |  |  _  |   1___|   _|   _|  |    <|  -__|
+|.  |___|__| |_____|________|_____|____   |____|__| |__|__|__|_____|
+|:  1   |                         |:  1   |
+|::.. . |   CROWDSTRIKE FALCON    |::.. . |    FalconPy
+`-------'                         `-------'
+
+OAuth2 API - Customer SDK
+
+This is free and unencumbered software released into the public domain.
+
+Anyone is free to copy, modify, publish, use, compile, sell, or
+distribute this software, either in source code form or as a compiled
+binary, for any purpose, commercial or non-commercial, and by any
+means.
+
+In jurisdictions that recognize copyright laws, the author or authors
+of this software dedicate any and all copyright interest in the
+software to the public domain. We make this dedication for the benefit
+of the public at large and to the detriment of our heirs and
+successors. We intend this dedication to be an overt act of
+relinquishment in perpetuity of all present and future rights to this
+software under copyright law.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+For more information, please refer to <https://unlicense.org>
+"""
+
+_foundry_logscale_endpoints = [
+  [
+    "ListReposV1",
+    "GET",
+    "/loggingapi/combined/repos/v1",
+    "Lists available repositories and views",
+    "foundry_logscale",
+    []
+  ],
+  [
+    "IngestDataV1",
+    "POST",
+    "/loggingapi/entities/data-ingestion/ingest/v1",
+    "Ingest data into the application repository",
+    "foundry_logscale",
+    [
+      {
+        "type": "file",
+        "description": "Data file to ingest",
+        "name": "data_file",
+        "in": "formData",
+        "required": True
+      },
+      {
+        "type": "array",
+        "items": {
+          "type": "string"
+        },
+        "description": "Custom tag for ingested data in the form tag:value",
+        "name": "tag",
+        "in": "formData"
+      },
+      {
+        "type": "string",
+        "description": "Tag the data with the specified source",
+        "name": "tag_source",
+        "in": "formData"
+      },
+      {
+        "type": "boolean",
+        "default": False,
+        "description": "Tag the data with test-ingest",
+        "name": "test_data",
+        "in": "formData"
+      }
+    ]
+  ],
+  [
+    "CreateSavedSearchesDynamicExecuteV1",
+    "POST",
+    "/loggingapi/entities/saved-searches/execute-dynamic/v1",
+    "Execute a dynamic saved search",
+    "foundry_logscale",
+    [
+      {
+        "type": "boolean",
+        "default": False,
+        "description": "Include generated schemas in the response",
+        "name": "include_schema_generation",
+        "in": "query"
+      },
+      {
+        "type": "boolean",
+        "default": False,
+        "description": "Include test data when executing searches",
+        "name": "include_test_data",
+        "in": "query"
+      },
+      {
+        "type": "boolean",
+        "default": False,
+        "description": "Whether to include metadata in the response",
+        "name": "metadata",
+        "in": "query"
+      },
+      {
+        "enum": [
+          "sync",
+          "async"
+        ],
+        "type": "string",
+        "description": "Mode to execute the query under.",
+        "name": "mode",
+        "in": "query"
+      },
+      {
+        "name": "body",
+        "in": "body",
+        "required": True
+      }
+    ]
+  ],
+  [
+    "GetSavedSearchesExecuteV1",
+    "GET",
+    "/loggingapi/entities/saved-searches/execute/v1",
+    "Get the results of a saved search",
+    "foundry_logscale",
+    [
+      {
+        "type": "string",
+        "description": "Job ID for a previously executed async query",
+        "name": "job_id",
+        "in": "query",
+        "required": True
+      },
+      {
+        "minimum": 0,
+        "type": "string",
+        "description": "Maximum number of records to return.",
+        "name": "limit",
+        "in": "query"
+      },
+      {
+        "type": "boolean",
+        "default": False,
+        "description": "Whether to include metadata in the response",
+        "name": "metadata",
+        "in": "query"
+      },
+      {
+        "minimum": 0,
+        "type": "string",
+        "description": "Starting pagination offset of records to return.",
+        "name": "offset",
+        "in": "query"
+      },
+      {
+        "pattern": "v?([0-9]+)(\\.[0-9]+)?(\\.[0-9]+)?(-([0-9A-Za-z\\-]+"
+        "(\\.[0-9A-Za-z\\-]+)*))?(\\+([0-9A-Za-z\\-]+(\\.[0-9A-Za-z\\-]+)*))?",
+        "type": "string",
+        "description": "Version of resource being created",
+        "name": "version",
+        "in": "query"
+      }
+    ]
+  ],
+  [
+    "CreateSavedSearchesExecuteV1",
+    "POST",
+    "/loggingapi/entities/saved-searches/execute/v1",
+    "Execute a saved search",
+    "foundry_logscale",
+    [
+      {
+        "type": "boolean",
+        "default": False,
+        "description": "Whether to include search field details",
+        "name": "detailed",
+        "in": "query"
+      },
+      {
+        "type": "boolean",
+        "default": False,
+        "description": "Include test data when executing searches",
+        "name": "include_test_data",
+        "in": "query"
+      },
+      {
+        "type": "boolean",
+        "default": False,
+        "description": "Whether to include metadata in the response",
+        "name": "metadata",
+        "in": "query"
+      },
+      {
+        "enum": [
+          "sync",
+          "async",
+          "async_offload"
+        ],
+        "type": "string",
+        "description": "Mode to execute the query under.  "
+        "If provided, takes precedence over the mode provided in the body.",
+        "name": "mode",
+        "in": "query"
+      },
+      {
+        "pattern": "v?([0-9]+)(\\.[0-9]+)?(\\.[0-9]+)?(-([0-9A-Za-z\\-]+"
+        "(\\.[0-9A-Za-z\\-]+)*))?(\\+([0-9A-Za-z\\-]+(\\.[0-9A-Za-z\\-]+)*))?",
+        "type": "string",
+        "description": "Version of resource being created",
+        "name": "version",
+        "in": "query"
+      },
+      {
+        "name": "body",
+        "in": "body",
+        "required": True
+      }
+    ]
+  ],
+  [
+    "CreateSavedSearchesIngestV1",
+    "POST",
+    "/loggingapi/entities/saved-searches/ingest/v1",
+    "Populate a saved search",
+    "foundry_logscale",
+    []
+  ],
+  [
+    "GetSavedSearchesJobResultsDownloadV1",
+    "GET",
+    "/loggingapi/entities/saved-searches/job-results-download/v1",
+    "Get the results of a saved search as a file",
+    "foundry_logscale",
+    [
+      {
+        "type": "string",
+        "description": "Job ID for a previously executed async query",
+        "name": "job_id",
+        "in": "query",
+        "required": True
+      },
+      {
+        "enum": [
+          "json",
+          "csv"
+        ],
+        "type": "string",
+        "description": "Result Format",
+        "name": "result_format",
+        "in": "query"
+      }
+    ]
+  ],
+  [
+    "ListViewV1",
+    "GET",
+    "/loggingapi/entities/views/v1",
+    "List views",
+    "foundry_logscale",
+    []
+  ]
+]
diff --git a/src/falconpy/_endpoint/_real_time_response_audit.py b/src/falconpy/_endpoint/_real_time_response_audit.py
new file mode 100644
index 000000000..5f073d6e0
--- /dev/null
+++ b/src/falconpy/_endpoint/_real_time_response_audit.py
@@ -0,0 +1,91 @@
+"""Internal API endpoint constant library.
+
+ _______                        __ _______ __        __ __
+|   _   .----.-----.--.--.--.--|  |   _   |  |_.----|__|  |--.-----.
+|.  1___|   _|  _  |  |  |  |  _  |   1___|   _|   _|  |    <|  -__|
+|.  |___|__| |_____|________|_____|____   |____|__| |__|__|__|_____|
+|:  1   |                         |:  1   |
+|::.. . |   CROWDSTRIKE FALCON    |::.. . |    FalconPy
+`-------'                         `-------'
+
+OAuth2 API - Customer SDK
+
+This is free and unencumbered software released into the public domain.
+
+Anyone is free to copy, modify, publish, use, compile, sell, or
+distribute this software, either in source code form or as a compiled
+binary, for any purpose, commercial or non-commercial, and by any
+means.
+
+In jurisdictions that recognize copyright laws, the author or authors
+of this software dedicate any and all copyright interest in the
+software to the public domain. We make this dedication for the benefit
+of the public at large and to the detriment of our heirs and
+successors. We intend this dedication to be an overt act of
+relinquishment in perpetuity of all present and future rights to this
+software under copyright law.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+For more information, please refer to <https://unlicense.org>
+"""
+
+_real_time_response_audit_endpoints = [
+  [
+    "RTRAuditSessions",
+    "GET",
+    "/real-time-response-audit/combined/sessions/v1",
+    "Get all the RTR sessions created for a customer in a specified duration",
+    "real_time_response_audit",
+    [
+      {
+        "type": "string",
+        "description": "Optional filter criteria in the form of an FQL query. "
+        "For more information about FQL queries, see our [FQL documentation in Falcon]"
+        "(https://falcon.crowdstrike.com/support/documentation/45/falcon-query-language-feature-guide).",
+        "name": "filter",
+        "in": "query"
+      },
+      {
+        "enum": [
+          "created_at",
+          "updated_at",
+          "deleted_at"
+        ],
+        "type": "string",
+        "description": "how to sort the session IDs. e.g. sort=created_at|desc "
+        "will sort the results based on createdAt in descending order",
+        "name": "sort",
+        "in": "query"
+      },
+      {
+        "maximum": 1000,
+        "minimum": 1,
+        "type": "string",
+        "description": "number of sessions to be returned",
+        "name": "limit",
+        "in": "query"
+      },
+      {
+        "type": "string",
+        "description": "offset value to be used for paginated results",
+        "name": "offset",
+        "in": "query"
+      },
+      {
+        "type": "boolean",
+        "default": False,
+        "description": "get sessions with command info included; by default sessions "
+        "are returned without command info which include cloud_request_ids and logs fields",
+        "name": "with_command_info",
+        "in": "query"
+      }
+    ]
+  ]
+]
diff --git a/src/falconpy/_endpoint/_workflows.py b/src/falconpy/_endpoint/_workflows.py
new file mode 100644
index 000000000..aaa8c5d44
--- /dev/null
+++ b/src/falconpy/_endpoint/_workflows.py
@@ -0,0 +1,175 @@
+"""Internal API endpoint constant library.
+
+ _______                        __ _______ __        __ __
+|   _   .----.-----.--.--.--.--|  |   _   |  |_.----|__|  |--.-----.
+|.  1___|   _|  _  |  |  |  |  _  |   1___|   _|   _|  |    <|  -__|
+|.  |___|__| |_____|________|_____|____   |____|__| |__|__|__|_____|
+|:  1   |                         |:  1   |
+|::.. . |   CROWDSTRIKE FALCON    |::.. . |    FalconPy
+`-------'                         `-------'
+
+OAuth2 API - Customer SDK
+
+This is free and unencumbered software released into the public domain.
+
+Anyone is free to copy, modify, publish, use, compile, sell, or
+distribute this software, either in source code form or as a compiled
+binary, for any purpose, commercial or non-commercial, and by any
+means.
+
+In jurisdictions that recognize copyright laws, the author or authors
+of this software dedicate any and all copyright interest in the
+software to the public domain. We make this dedication for the benefit
+of the public at large and to the detriment of our heirs and
+successors. We intend this dedication to be an overt act of
+relinquishment in perpetuity of all present and future rights to this
+software under copyright law.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+For more information, please refer to <https://unlicense.org>
+"""
+
+_workflows_endpoints = [
+  [
+    "WorkflowExecute",
+    "POST",
+    "/workflows/entities/execute/v1",
+    "Executes an on-demand Workflow, the body is JSON used to trigger the execution, the response the execution ID(s)",
+    "workflows",
+    [
+      {
+        "type": "array",
+        "items": {
+          "type": "string"
+        },
+        "collectionFormat": "csv",
+        "description": "Definition ID to execute, either a name or an ID can be specified.",
+        "name": "definition_id",
+        "in": "query"
+      },
+      {
+        "type": "string",
+        "description": "Workflow name to execute, either a name or an ID can be specified.",
+        "name": "name",
+        "in": "query"
+      },
+      {
+        "type": "string",
+        "description": "Key used to help deduplicate executions, if unset a new UUID is used",
+        "name": "key",
+        "in": "query"
+      },
+      {
+        "type": "integer",
+        "description": "Used to record the execution depth to help limit execution "
+        "loops when a workflow triggers another. The maximum depth is 4.",
+        "name": "depth",
+        "in": "query"
+      },
+      {
+        "name": "body",
+        "in": "body",
+        "required": True
+      }
+    ]
+  ],
+  [
+    "WorkflowExecutionsAction",
+    "POST",
+    "/workflows/entities/execution-actions/v1",
+    "Allows a user to resume/retry a failed workflow execution.",
+    "workflows",
+    [
+      {
+        "enum": [
+          "resume"
+        ],
+        "type": "string",
+        "description": "Specify one of these actions:\n\n- `resume`: resume/retry the workflow execution(s) specified in ids",
+        "name": "action_name",
+        "in": "query",
+        "required": True
+      },
+      {
+        "name": "body",
+        "in": "body",
+        "required": True
+      }
+    ]
+  ],
+  [
+    "WorkflowExecutionResults",
+    "GET",
+    "/workflows/entities/execution-results/v1",
+    "Get execution result of a given execution",
+    "workflows",
+    [
+      {
+        "maxItems": 500,
+        "minItems": 1,
+        "type": "array",
+        "items": {
+          "type": "string"
+        },
+        "collectionFormat": "csv",
+        "description": "workflow execution id to return results for.",
+        "name": "ids",
+        "in": "query",
+        "required": True
+      }
+    ]
+  ],
+  [
+    "WorkflowSystemDefinitionsDeProvision",
+    "POST",
+    "/workflows/system-definitions/deprovision/v1",
+    "Deprovisions a system definition that was previously provisioned on the target CID",
+    "workflows",
+    [
+      {
+        "name": "body",
+        "in": "body",
+        "required": True
+      }
+    ]
+  ],
+  [
+    "WorkflowSystemDefinitionsPromote",
+    "POST",
+    "/workflows/system-definitions/promote/v1",
+    "Promotes a version of a system definition on a customer. "
+    "The customer must already have been provisioned. This allows the callerto apply an "
+    "updated template version to a specific cid and expects all parameters to be supplied. "
+    "If the template supports multi-instancethe customer scope definition ID must be supplied "
+    "to determine which customer workflow should be updated.",
+    "workflows",
+    [
+      {
+        "name": "body",
+        "in": "body",
+        "required": True
+      }
+    ]
+  ],
+  [
+    "WorkflowSystemDefinitionsProvision",
+    "POST",
+    "/workflows/system-definitions/provision/v1",
+    "Provisions a system definition onto the target CID by using the template and provided parameters",
+    "workflows",
+    [
+      {
+        "name": "body",
+        "in": "body",
+        "required": True
+      }
+    ]
+  ]
+]
diff --git a/src/falconpy/_endpoint/deprecated/__init__.py b/src/falconpy/_endpoint/deprecated/__init__.py
index f397e956a..0c86c921a 100644
--- a/src/falconpy/_endpoint/deprecated/__init__.py
+++ b/src/falconpy/_endpoint/deprecated/__init__.py
@@ -47,6 +47,7 @@
 from ._report_executions import _report_executions_endpoints
 from ._scheduled_reports import _scheduled_reports_endpoints
 from ._zero_trust_assessment import _zero_trust_assessment_endpoints
+from ._mapping import _deprecated_op_mapping, _deprecated_cls_mapping
 
 _custom_ioa_deprecated = _custom_ioa_endpoints
 _d4c_registration_deprecated = _d4c_registration_endpoints
@@ -64,3 +65,5 @@
 _report_executions_deprecated = _report_executions_endpoints
 _scheduled_reports_deprecated = _scheduled_reports_endpoints
 _zero_trust_assessment_deprecated = _zero_trust_assessment_endpoints
+_deprecated_operation_mapping = _deprecated_op_mapping
+_deprecated_class_mapping = _deprecated_cls_mapping
diff --git a/src/falconpy/_endpoint/deprecated/_mapping.py b/src/falconpy/_endpoint/deprecated/_mapping.py
new file mode 100644
index 000000000..3de024413
--- /dev/null
+++ b/src/falconpy/_endpoint/deprecated/_mapping.py
@@ -0,0 +1,69 @@
+"""Internal API endpoint constant library.
+
+ _______                        __ _______ __        __ __
+|   _   .----.-----.--.--.--.--|  |   _   |  |_.----|__|  |--.-----.
+|.  1___|   _|  _  |  |  |  |  _  |   1___|   _|   _|  |    <|  -__|
+|.  |___|__| |_____|________|_____|____   |____|__| |__|__|__|_____|
+|:  1   |                         |:  1   |
+|::.. . |   CROWDSTRIKE FALCON    |::.. . |    FalconPy
+`-------'                         `-------'
+
+OAuth2 API - Customer SDK
+
+This is free and unencumbered software released into the public domain.
+
+Anyone is free to copy, modify, publish, use, compile, sell, or
+distribute this software, either in source code form or as a compiled
+binary, for any purpose, commercial or non-commercial, and by any
+means.
+
+In jurisdictions that recognize copyright laws, the author or authors
+of this software dedicate any and all copyright interest in the
+software to the public domain. We make this dedication for the benefit
+of the public at large and to the detriment of our heirs and
+successors. We intend this dedication to be an overt act of
+relinquishment in perpetuity of all present and future rights to this
+software under copyright law.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+For more information, please refer to <https://unlicense.org>
+"""
+
+_deprecated_op_mapping = {
+    "QueryAWSAccounts": "GetCSPMAwsAccount",
+    "GetAWSSettings": "",
+    "GetAWSAccounts": "GetCSPMAwsAccount",
+    "ProvisionAWSAccounts": "CreateCSPMAwsAccount",
+    "DeleteAWSAccounts": "DeleteCSPMAwsAccount",
+    "UpdateAWSAccounts": "PatchCSPMAwsAccount",
+    "CreateOrUpdateAWSSettings": "",
+    "VerifyAWSAccountAccess": "",
+    "GetD4CAwsAccount": "GetCSPMAwsAccount",
+    "CreateD4CAwsAccount": "CreateCSPMAwsAccount",
+    "DeleteD4CAwsAccount": "DeleteCSPMAwsAccount",
+    "GetD4CAwsConsoleSetupURLs": "GetCSPMAwsConsoleSetupURLs",
+    "GetD4CAWSAccountScriptsAttachment": "GetCSPMAwsAccountScriptsAttachment",
+    "GetDiscoverCloudAzureAccount": "GetCSPMAzureAccount",
+    "CreateDiscoverCloudAzureAccount": "CreateCSPMAzureAccount",
+    "UpdateDiscoverCloudAzureAccountClientID": "UpdateCSPMAzureAccountClientID",
+    "GetDiscoverCloudAzureUserScriptsAttachment": "GetCSPMAzureUserScriptsAttachment",
+    "GetDiscoverCloudCGPAccount": "",
+    "CreateDiscoverCloudGCPAccount": "",
+    "DiscoverCloudAzureDownloadCertificate": "AzureDownloadCertificate",
+    "GetDiscoverCloudAzureTenantIDs": "",
+    "GetDiscoverCloudGCPUserScripts": "",
+    "GetHorizonD4CScripts": ""
+}
+
+_deprecated_cls_mapping = {
+    "CloudConnectAWS": "CSPMRegistration",
+    "D4CRegistration": "CSPMRegistration",
+    "Iocs": "IOC"
+}
diff --git a/src/falconpy/_error/__init__.py b/src/falconpy/_error/__init__.py
index bcbf1fc8e..cba137d50 100644
--- a/src/falconpy/_error/__init__.py
+++ b/src/falconpy/_error/__init__.py
@@ -57,7 +57,10 @@
     SSLDisabledWarning,
     NoContentWarning,
     NoAuthenticationMechanism,
-    UnnecessaryEncodingUsed
+    UnnecessaryEncodingUsed,
+    SDKDeprecationWarning,
+    DeprecatedOperation,
+    DeprecatedClass
 )
 
 
@@ -66,5 +69,6 @@
            "InvalidCredentials", "APIError", "NoContentWarning", "CannotRevokeToken",
            "FunctionalityNotImplemented", "InvalidBaseURL", "PayloadValidationError",
            "NoAuthenticationMechanism", "FeatureNotSupportedByPythonVersion",
-           "InvalidIndex", "InvalidCredentialFormat", "UnnecessaryEncodingUsed"
+           "InvalidIndex", "InvalidCredentialFormat", "UnnecessaryEncodingUsed",
+           "SDKDeprecationWarning", "DeprecatedOperation", "DeprecatedClass"
            ]
diff --git a/src/falconpy/_error/_warnings.py b/src/falconpy/_error/_warnings.py
index e8cdac492..14b4b0b59 100644
--- a/src/falconpy/_error/_warnings.py
+++ b/src/falconpy/_error/_warnings.py
@@ -102,3 +102,72 @@ class UnnecessaryEncodingUsed(SDKWarning):
 
     _code = 400
     _message = "A provided argument utilizes unnecessary encoding."
+
+
+class SDKDeprecationWarning(FutureWarning):
+    """SDK specific deprecation warning."""
+
+    _code = 299
+    _message = "This method has been deprecated."
+    warning: bool = True
+
+    def __init__(self,
+                 code: int = None,
+                 message: str = None
+                 ):
+        """Construct an instance of the class."""
+        self.code = self._code
+        self.message = self._message
+
+        if isinstance(code, int):
+            self.code = code
+        if message:
+            self.message = message
+
+        super().__init__(self.message)
+
+
+class DeprecatedOperation(SDKDeprecationWarning):
+    """This API operation has been deprecated."""
+
+    _message = "This operation has been deprecated."
+
+    def __init__(self,
+                 code: int = None,
+                 operation: str = None,
+                 new_operation: str = None
+                 ):
+        """Construct an instance of the class."""
+        if code:
+            self._code = code
+        self.code = self._code
+        if operation:
+            self._message = f"The {operation} operation has been deprecated."
+        if new_operation:
+            self._message = f"{self._message} " \
+                            f"Update code to leverage the {new_operation} operation instead."
+        self.message = self._message
+        super().__init__(self.message)
+
+
+class DeprecatedClass(SDKDeprecationWarning):
+    """This Service Class has been deprecated."""
+
+    _message = "This service class has been deprecated."
+
+    def __init__(self,
+                 code: int = None,
+                 class_name: str = None,
+                 new_class_name: str = None
+                 ):
+        """Construct an instance of the class."""
+        if code:
+            self._code = code
+        self.code = self._code
+        if class_name:
+            self._message = f"The {class_name} service class has been deprecated."
+        if new_class_name:
+            self._message = f"{self._message} " \
+                            f"Update code to leverage the {new_class_name} service class instead."
+        self.message = self._message
+        super().__init__(self.message)
diff --git a/src/falconpy/_payload/__init__.py b/src/falconpy/_payload/__init__.py
index eb9814fdd..531f0e3ff 100644
--- a/src/falconpy/_payload/__init__.py
+++ b/src/falconpy/_payload/__init__.py
@@ -78,7 +78,8 @@
 from ._sample_uploads import extraction_payload
 from ._ods import scheduled_scan_payload
 from ._cloud_snapshots import snapshot_inventory_payload, snapshot_registration_payload
-
+from ._workflows import workflow_deprovision_payload, workflow_template_payload
+from ._foundry import foundry_dynamic_search_payload, foundry_execute_search_payload
 
 __all__ = [
     "generic_payload_list", "aggregate_payload", "recon_action_payload", "recon_rules_payload",
@@ -100,5 +101,6 @@
     "recon_export_job_payload", "default_device_policy_config_payload", "registry_payload",
     "gcp_registration_payload", "filevantage_rule_group_payload", "filevantage_rule_payload",
     "filevantage_policy_payload", "filevantage_scheduled_exclusion_payload",
-    "snapshot_inventory_payload", "snapshot_registration_payload"
+    "snapshot_inventory_payload", "snapshot_registration_payload", "workflow_deprovision_payload",
+    "workflow_template_payload", "foundry_execute_search_payload", "foundry_dynamic_search_payload"
 ]
diff --git a/src/falconpy/_payload/_foundry.py b/src/falconpy/_payload/_foundry.py
new file mode 100644
index 000000000..e67644569
--- /dev/null
+++ b/src/falconpy/_payload/_foundry.py
@@ -0,0 +1,113 @@
+"""Internal payload handling library - Foundry Payloads.
+
+ _______                        __ _______ __        __ __
+|   _   .----.-----.--.--.--.--|  |   _   |  |_.----|__|  |--.-----.
+|.  1___|   _|  _  |  |  |  |  _  |   1___|   _|   _|  |    <|  -__|
+|.  |___|__| |_____|________|_____|____   |____|__| |__|__|__|_____|
+|:  1   |                         |:  1   |
+|::.. . |   CROWDSTRIKE FALCON    |::.. . |    FalconPy
+`-------'                         `-------'
+
+OAuth2 API - Customer SDK
+
+This is free and unencumbered software released into the public domain.
+
+Anyone is free to copy, modify, publish, use, compile, sell, or
+distribute this software, either in source code form or as a compiled
+binary, for any purpose, commercial or non-commercial, and by any
+means.
+
+In jurisdictions that recognize copyright laws, the author or authors
+of this software dedicate any and all copyright interest in the
+software to the public domain. We make this dedication for the benefit
+of the public at large and to the detriment of our heirs and
+successors. We intend this dedication to be an overt act of
+relinquishment in perpetuity of all present and future rights to this
+software under copyright law.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+For more information, please refer to <https://unlicense.org>
+"""
+
+
+def foundry_dynamic_search_payload(passed_keywords: dict):
+    """Create a properly formatted dynamic execute search payload.
+
+    {
+        "end": "string",
+        "repo_or_view": "string",
+        "search_query": "string",
+        "search_query_args": {},
+        "start": "string"
+    }
+    """
+    returned_payload = {}
+    keys = ["end", "repo_or_view", "search_query", "search_query_args", "start"]
+    for key in keys:
+        if passed_keywords.get(key, None):
+            returned_payload[key] = passed_keywords.get(key)
+
+    return returned_payload
+
+
+def foundry_execute_search_payload(passed_keywords: dict):
+    """Create a properly formatted saved search execute payload.
+
+    {
+        "end": "string",
+        "id": "string",
+        "mode": "string",
+        "name": "string",
+        "parameters": {},
+        "start": "string",
+        "version": "string",
+        "with_in": {
+            "field": "string",
+            "values": [
+                "string"
+            ]
+        },
+        "with_limit": {
+            "from": "string",
+            "limit": 0
+        },
+        "with_renames": [
+            {
+                "as": "string",
+                "field": "string"
+            }
+        ],
+        "with_sort": {
+            "fields": [
+                "string"
+            ],
+            "limit": 0,
+            "order": [
+                "string"
+            ],
+            "reverse": true,
+            "type": [
+                "string"
+            ]
+        }
+    }
+    """
+    returned_payload = {}
+    keys = ["end", "id", "mode", "name", "search_parameters", "start", "version"
+            "with_in", "with_limit", "with_renames", "with_sort"
+            ]
+    for key in keys:
+        if passed_keywords.get(key, None):
+            if key == "search_parameters":
+                returned_payload["parameters"] = passed_keywords.get(key)
+            else:
+                returned_payload[key] = passed_keywords.get(key)
+
+    return returned_payload
diff --git a/src/falconpy/_payload/_generic.py b/src/falconpy/_payload/_generic.py
index ea69c3856..e0aa83c64 100644
--- a/src/falconpy/_payload/_generic.py
+++ b/src/falconpy/_payload/_generic.py
@@ -176,7 +176,7 @@ def installation_token_payload(passed_keywords: dict) -> dict:
     return returned_payload
 
 
-def simple_action_parameter(passed_keywords: dict) -> dict:
+def simple_action_parameter(passed_keywords: dict, existing_payload: dict = None) -> dict:
     """Create a properly formatted action parameter body payload.
 
     {
@@ -189,6 +189,8 @@ def simple_action_parameter(passed_keywords: dict) -> dict:
     }
     """
     returned_payload = {}
+    if existing_payload:
+        returned_payload = existing_payload
     returned_payload["action_parameters"] = []
     _single = {}
     for key in ["name", "value"]:
diff --git a/src/falconpy/_payload/_workflows.py b/src/falconpy/_payload/_workflows.py
new file mode 100644
index 000000000..203f2f56f
--- /dev/null
+++ b/src/falconpy/_payload/_workflows.py
@@ -0,0 +1,133 @@
+"""Internal payload handling library - Generic Payloads.
+
+ _______                        __ _______ __        __ __
+|   _   .----.-----.--.--.--.--|  |   _   |  |_.----|__|  |--.-----.
+|.  1___|   _|  _  |  |  |  |  _  |   1___|   _|   _|  |    <|  -__|
+|.  |___|__| |_____|________|_____|____   |____|__| |__|__|__|_____|
+|:  1   |                         |:  1   |
+|::.. . |   CROWDSTRIKE FALCON    |::.. . |    FalconPy
+`-------'                         `-------'
+
+OAuth2 API - Customer SDK
+
+This is free and unencumbered software released into the public domain.
+
+Anyone is free to copy, modify, publish, use, compile, sell, or
+distribute this software, either in source code form or as a compiled
+binary, for any purpose, commercial or non-commercial, and by any
+means.
+
+In jurisdictions that recognize copyright laws, the author or authors
+of this software dedicate any and all copyright interest in the
+software to the public domain. We make this dedication for the benefit
+of the public at large and to the detriment of our heirs and
+successors. We intend this dedication to be an overt act of
+relinquishment in perpetuity of all present and future rights to this
+software under copyright law.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+For more information, please refer to <https://unlicense.org>
+"""
+
+
+def workflow_deprovision_payload(passed_keywords: dict):
+    """Create a valid workflow deprovisioning payload from provided keywords.
+
+    {
+        "definition_id": "string",
+        "deprovision_all": boolean,
+        "template_id": "string",
+        "template_name": "string"
+    }
+    """
+    returned_payload = {}
+    keys = ["definition_id", "template_id", "deprovision_all", "template_name"]
+    for key in keys:
+        if passed_keywords.get(key, None) is not None:
+            returned_payload[key] = passed_keywords.get(key)
+
+    return returned_payload
+
+
+def workflow_template_payload(passed_keywords: dict):
+    """Create a properly formatted workflow template payload.
+
+    {
+        "customer_definition_id": "string",
+        "name": "string",
+        "parameters": {
+            "activities": {
+                "configuration": [
+                    {
+                        "node_id": "string",
+                        "properties": {}
+                    }
+                ],
+                "selection": [
+                    {
+                        "id": "string",
+                        "properties": {},
+                        "source": "string"
+                    }
+                ]
+            },
+            "conditions": [
+                {
+                    "fields": [
+                        {
+                            "name": "string",
+                            "operator": "string"
+                        }
+                    ],
+                    "node_id": "string"
+                }
+            ],
+            "trigger": {
+                "fields": {
+                    "additionalProp1": {
+                        "properties": {},
+                        "required": true
+                    },
+                    "additionalProp2": {
+                        "properties": {},
+                        "required": true
+                    },
+                    "additionalProp3": {
+                        "properties": {},
+                        "required": true
+                    }
+                },
+                "node_id": "string"
+            }
+        },
+        "template_id": "string",
+        "template_name": "string",
+        "template_version": "string"
+    }
+    """
+    returned_payload = {}
+    keys = ["customer_definition_id", "name", "parameters",
+            "template_id", "template_name", "template_version"
+            ]
+
+    for key in keys:
+        if passed_keywords.get(key, None) is not None:
+            returned_payload[key] = passed_keywords.get(key)
+
+    # Providing a parameters dictionary will override the activities, conditions & trigger branches
+    if "parameters" not in returned_payload:
+        param_branch = {}
+        for key in ["activities", "conditions", "trigger"]:
+            if passed_keywords.get(key, None) is not None:
+                param_branch[key] = passed_keywords.get(key)
+        if param_branch:
+            returned_payload["parameters"] = param_branch
+
+    return returned_payload
diff --git a/src/falconpy/_service_class/_service_class.py b/src/falconpy/_service_class/_service_class.py
index 6f53619f1..a11a4df5b 100644
--- a/src/falconpy/_service_class/_service_class.py
+++ b/src/falconpy/_service_class/_service_class.py
@@ -38,9 +38,10 @@
 from typing import Dict, Type, Optional, Union
 from ._base_service_class import BaseServiceClass
 from .._auth_object import FalconInterface
-from .._util import log_class_startup, perform_request, service_override_payload
+from .._util import log_class_startup, perform_request, service_override_payload, deprecated_class
 from ..oauth2 import OAuth2
 from .._result import Result
+from .._endpoint import class_deprecation_mapping
 
 
 class ServiceClass(BaseServiceClass):
@@ -136,6 +137,14 @@ def __init__(self: "ServiceClass",
                          **kwargs
                          )
 
+        # Issue a warning if the developer is using a deprecated class.
+        if self.__class__.__name__ in class_deprecation_mapping:
+            deprecated_class(self.pythonic,
+                             self.log,
+                             self.__class__.__name__,
+                             class_deprecation_mapping[self.__class__.__name__]
+                             )
+
         # Extended headers that can be set on a Service Class and provided
         # with every request to the CrowdStrike API. These do not override
         # authorization headers.
diff --git a/src/falconpy/_util/__init__.py b/src/falconpy/_util/__init__.py
index c1c2688ae..f895b653a 100644
--- a/src/falconpy/_util/__init__.py
+++ b/src/falconpy/_util/__init__.py
@@ -56,6 +56,8 @@
     sanitize_dictionary,
     calc_content_return,
     log_class_startup,
+    deprecated_operation,
+    deprecated_class,
     _ALLOWED_METHODS
 )
 from ._service import service_override_payload
@@ -74,5 +76,6 @@
            "get_default", "args_to_params", "process_service_request", "confirm_base_url",
            "confirm_base_region", "return_preferred_default", "base_url_regions",
            "_ALLOWED_METHODS", "login_payloads", "logout_payloads", "sanitize_dictionary",
-           "calc_content_return", "log_class_startup", "service_override_payload"
+           "calc_content_return", "log_class_startup", "service_override_payload",
+           "deprecated_operation", "deprecated_class"
            ]
diff --git a/src/falconpy/_util/_functions.py b/src/falconpy/_util/_functions.py
index 977314b97..43016515e 100644
--- a/src/falconpy/_util/_functions.py
+++ b/src/falconpy/_util/_functions.py
@@ -41,7 +41,7 @@
 from json import loads
 try:
     from simplejson import JSONDecodeError
-except ImportError:
+except (ImportError, ModuleNotFoundError):  # Support import as a module
     from json.decoder import JSONDecodeError
 from typing import Dict, Any, Union, Optional, List
 from copy import deepcopy
@@ -50,6 +50,7 @@
 import urllib3
 from urllib3.exceptions import InsecureRequestWarning
 from .._api_request import APIRequest
+from .._endpoint import operation_deprecation_mapping
 from .._enum import BaseURL, ContainerBaseURL
 from .._constant import (
     PREFER_NONETYPE,
@@ -69,7 +70,9 @@
     PayloadValidationError,
     InvalidBaseURL,
     SSLDisabledWarning,
-    UnnecessaryEncodingUsed
+    UnnecessaryEncodingUsed,
+    DeprecatedOperation,
+    DeprecatedClass
     )
 from .._result import Result
 urllib3.disable_warnings(InsecureRequestWarning)
@@ -558,6 +561,8 @@ def args_to_params(payload: dict,
     """
     returned_payload = {}
     if epname != "Manual":  # pylint: disable=R1702
+        if epname in operation_deprecation_mapping:
+            deprecated_operation(pyth, log_utl, epname, operation_deprecation_mapping[epname])
         for arg in passed_arguments:
             eps = [ep[5] for ep in endpoints if epname == ep[0]][0]
             try:
@@ -617,13 +622,15 @@ def process_service_request(calling_object,  # pylint: disable=R0914 # (19/15)
     body -- Dictionary representing the body payload passed to the service class function.
     data -- Dictionary representing the data payload passed to the service class function.
     files -- List of files to be uploaded.
-    partition -- ID of the partition to open (Event Streams API)
-    distinct_field -- Field name to retrieve distinct values for (Sensor Update Policies API)
-    image_id -- Image ID to be deleted (Falcon Container API)
+    partition -- ID of the partition to open [PATH] (Event Streams API)
+    distinct_field -- Field name to retrieve distinct values for [PATH] (Sensor Update Policies API)
+    image_id -- Image ID to be deleted [PATH] (Falcon Container API)
     body_validator -- Dictionary containing details regarding body payload validation
     body_required -- List of required body payload parameters
     expand_result -- Request expanded results output
     pythonic -- Pythonic responses
+    collection_name -- Repository collection name [PATH] (Custom Objects API)
+    object_key -- Object Key [PATH] (Custom Objects API)
     """
     # Log the operation ID if we have logging enabled.
     if calling_object.log:
@@ -639,38 +646,30 @@ def process_service_request(calling_object,  # pylint: disable=R0914 # (19/15)
     target_endpoint = [ep for ep in endpoints if operation_id == ep[0]][0]
     base_url = calling_object.base_url
     container = False
+    # Check if this operation requires the custom container base URL.
     if operation_id in MOCK_OPERATIONS:
         for base in [burl for burl in dir(BaseURL) if "__" not in burl]:
             if BaseURL[base].value == calling_object.base_url.replace("https://", ""):
                 base_url = f"https://{ContainerBaseURL[base].value}"
                 container = True
-    target_url = f"{base_url}{target_endpoint[2]}"
-    target_method = target_endpoint[1]
-    passed_partition = kwargs.get("partition", None)
-    if passed_partition or isinstance(passed_partition, int):
-        target_url = target_url.format(str(passed_partition))
-    passed_distinct_field = kwargs.get("distinct_field", None)
-    if passed_distinct_field:
-        target_url = target_url.format(str(passed_distinct_field))
-    passed_image_id = kwargs.get("image_id", None)
-    if passed_image_id:
-        target_url = target_url.format(str(passed_image_id))
+    # Handle any provided PATH variables, should happen before query string argument abstraction.
+    target_url = handle_path_variables(passed=kwargs, route_url=f"{base_url}{target_endpoint[2]}")
     # Retrieve our keyword arguments
-    passed_keywords = kwargs.get("keywords", None)
+    passed_keywords = kwargs.get("keywords", {})  # Changed from None in v1.3.3
     passed_params = kwargs.get("params", None)
-    parameter_payload = None
-    if passed_keywords or passed_params:
-        parameter_payload = args_to_params(passed_params,
-                                           passed_keywords,
-                                           endpoints,
-                                           operation_id,
-                                           calling_object.log,
-                                           calling_object.pythonic
-                                           )
+    # Starting in v1.3.3, Service Classes will pass an empty parameters dictionary
+    # instead of a NoneType when no query string arguments are specified.
+    parameter_payload = args_to_params(passed_params,
+                                       passed_keywords,
+                                       endpoints,
+                                       operation_id,
+                                       calling_object.log,
+                                       calling_object.pythonic
+                                       )
     expand_result = passed_keywords.get("expand_result", False) if passed_keywords else kwargs.get("expand_result", False)
     new_keywords = {
         "caller": calling_object,
-        "method": target_method,
+        "method": target_endpoint[1],
         "endpoint": target_url,
         "verify": calling_object.ssl_verify,
         "headers": joined_headers,
@@ -689,6 +688,28 @@ def process_service_request(calling_object,  # pylint: disable=R0914 # (19/15)
     return service_request(**new_keywords)
 
 
+def handle_path_variables(passed: dict, route_url: str):
+    """Review passed arguments and perform any necessary replacements to our operation route."""
+    passed_partition = passed.get("partition", None)
+    if passed_partition or isinstance(passed_partition, int):
+        route_url = route_url.format(str(passed_partition))
+    passed_distinct_field = passed.get("distinct_field", None)
+    if passed_distinct_field:
+        route_url = route_url.format(str(passed_distinct_field))
+    passed_image_id = passed.get("image_id", None)
+    if passed_image_id:
+        route_url = route_url.format(str(passed_image_id))
+    passed_collection_name = passed.get("collection_name", None)
+    if passed_collection_name:
+        collect_args = {"collection_name": str(passed_collection_name)}
+        passed_object_key = passed.get("object_key", None)
+        if passed_object_key:
+            collect_args["object_key"] = str(passed_object_key)
+        route_url = route_url.format(**collect_args)
+
+    return route_url
+
+
 def confirm_base_url(provided_base: Optional[str] = "https://api.crowdstrike.com") -> str:
     """Confirm the passed base_url value matches URL syntax.
 
@@ -809,3 +830,21 @@ def log_class_startup(interface, log_device: Logger):
     log_device.debug(
         "CONFIG: Pythonic responses are %s", "enabled" if interface.pythonic else "disabled"
         )
+
+
+def deprecated_operation(pythonic: bool, log: Logger, old: str, new: str):
+    """Provide a warning that the requested operation has been deprecated."""
+    if pythonic:
+        warn(DeprecatedOperation(operation=old, new_operation=new), FutureWarning)
+    else:
+        if log:
+            log.warning(DeprecatedOperation(operation=old, new_operation=new))
+
+
+def deprecated_class(pythonic: bool, log: Logger, old: str, new: str):
+    """Provide a warning that the constructed class has been deprecated."""
+    if pythonic:
+        warn(DeprecatedClass(class_name=old, new_class_name=new), FutureWarning)
+    else:
+        if log:
+            log.warning(DeprecatedClass(class_name=old, new_class_name=new))
diff --git a/src/falconpy/_util/_uber.py b/src/falconpy/_util/_uber.py
index 0a2c0fbbb..6ce666d10 100644
--- a/src/falconpy/_util/_uber.py
+++ b/src/falconpy/_util/_uber.py
@@ -81,13 +81,33 @@ def handle_body_payload_ids(kwa: dict) -> dict:
 def scrub_target(oper: str, scrubbed: str, kwas: dict) -> str:
     """Scrubs the endpoint target by performing any outstanding string replacements."""
     field_mapping = {
-        "image_id": "DeleteImageDetails",
-        "partition": "refreshActiveStreamSession",
-        "distinct_field": "querySensorUpdateKernelsDistinct"
+        "DeleteImageDetails": "image_id",
+        "refreshActiveStreamSession": "partition",
+        "querySensorUpdateKernelsDistinct": "distinct_field",
+        "ListObjects": "collection_name",
+        "SearchObjects": "collection_name",
+        "GetObject": "collection_name~object_key",
+        "PutObject": "collection_name~object_key",
+        "DeleteObject": "collection_name~object_key",
+        "GetObjectMetadata": "collection_name~object_key"
     }
-    for field_name, field_value in field_mapping.items():
+    for field_value, field_name in field_mapping.items():
         if oper == field_value:  # Only perform replacements on mapped operation IDs.
-            scrubbed = handle_field(scrubbed, kwas, field_name)
+            field_names = field_name.split("~")
+            if len(field_names) == 1:
+                scrubbed = handle_field(scrubbed, kwas, field_names[0])
+            else:
+                # Handle replacements for multiple PATH variables.
+                fnames = {
+                    fna: kwas[fna]
+                    for fna in field_names
+                }
+                scrubbed = scrubbed.format(**fnames)
+
+            for fna in field_names:
+                # Remove these arguments from the list of
+                # potential query string parameters.
+                kwas.pop(fna)
 
     return scrubbed
 
diff --git a/src/falconpy/_version.py b/src/falconpy/_version.py
index 1436ef769..6542247cd 100644
--- a/src/falconpy/_version.py
+++ b/src/falconpy/_version.py
@@ -35,7 +35,7 @@
 
 For more information, please refer to <https://unlicense.org>
 """
-_VERSION = '1.3.2'
+_VERSION = '1.3.3'
 _MAINTAINER = 'Joshua Hiller'
 _AUTHOR = 'CrowdStrike'
 _AUTHOR_EMAIL = 'falconpy@crowdstrike.com'
diff --git a/src/falconpy/api_complete/_legacy.py b/src/falconpy/api_complete/_legacy.py
index e6d58d884..8cbb4ee40 100644
--- a/src/falconpy/api_complete/_legacy.py
+++ b/src/falconpy/api_complete/_legacy.py
@@ -372,6 +372,9 @@ def command(self: object, *args, **kwargs) -> dict or bytes:
                 # Which HTTP method to execute
                 selected_method = uber_command[0][1].upper()
                 selected_operation = uber_command[0][0]
+                # Log the operation we're performing if enabled.
+                if self.log:
+                    self.log.debug("OPERATION: %s", selected_operation)
                 # Only accept allowed HTTP methods
                 if selected_method in _ALLOWED_METHODS:
                     returned = perform_request(method=selected_method,
@@ -381,7 +384,9 @@ def command(self: object, *args, **kwargs) -> dict or bytes:
                                                params=args_to_params(kwargs.get("parameters", {}),
                                                                      kwargs,
                                                                      self.commands,
-                                                                     selected_operation
+                                                                     selected_operation,
+                                                                     self.log,
+                                                                     self.pythonic
                                                                      ),
                                                headers=self._create_header_payload(kwargs),
                                                files=kwargs.get("files",
diff --git a/src/falconpy/custom_storage.py b/src/falconpy/custom_storage.py
new file mode 100644
index 000000000..57c4bec90
--- /dev/null
+++ b/src/falconpy/custom_storage.py
@@ -0,0 +1,361 @@
+"""Falcon Custom Storage API Interface Class.
+
+ _______                        __ _______ __        __ __
+|   _   .----.-----.--.--.--.--|  |   _   |  |_.----|__|  |--.-----.
+|.  1___|   _|  _  |  |  |  |  _  |   1___|   _|   _|  |    <|  -__|
+|.  |___|__| |_____|________|_____|____   |____|__| |__|__|__|_____|
+|:  1   |                         |:  1   |
+|::.. . |   CROWDSTRIKE FALCON    |::.. . |    FalconPy
+`-------'                         `-------'
+
+OAuth2 API - Customer SDK
+
+This is free and unencumbered software released into the public domain.
+
+Anyone is free to copy, modify, publish, use, compile, sell, or
+distribute this software, either in source code form or as a compiled
+binary, for any purpose, commercial or non-commercial, and by any
+means.
+
+In jurisdictions that recognize copyright laws, the author or authors
+of this software dedicate any and all copyright interest in the
+software to the public domain. We make this dedication for the benefit
+of the public at large and to the detriment of our heirs and
+successors. We intend this dedication to be an overt act of
+relinquishment in perpetuity of all present and future rights to this
+software under copyright law.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+For more information, please refer to <https://unlicense.org>
+"""
+import json
+from typing import Dict, Union
+from ._util import process_service_request, force_default, generate_error_result
+from ._service_class import ServiceClass
+from ._endpoint._custom_storage import _custom_storage_endpoints as Endpoints
+
+
+class CustomStorage(ServiceClass):
+    """The only requirement to instantiate an instance of this class is one of the following.
+
+    - a valid client_id and client_secret provided as keywords.
+    - a credential dictionary with client_id and client_secret containing valid API credentials
+      {
+          "client_id": "CLIENT_ID_HERE",
+          "client_secret": "CLIENT_SECRET_HERE"
+      }
+    - a previously-authenticated instance of the authentication service class (oauth2.py)
+    - a valid token provided by the authentication service class (oauth2.py)
+    """
+
+    @force_default(defaults=["parameters"], default_types=["dict"])
+    def list(self, parameters: dict = None, **kwargs) -> Dict[str, Union[int, dict]]:
+        """List the object keys in the specified collection in alphabetical order.
+
+        HTTP Method: GET
+
+        Swagger URL
+        ----
+        https://assets.falcon.crowdstrike.com/support/api/swagger.html#/custom-storage/ListObjects
+
+        Keyword arguments
+        ----
+        collection_name : string (required)
+            The name of the collection to list objects for.
+        end : string
+            The ending key to use for the end of the listing.
+        limit : integer
+            The maximum number of results to return.
+        parameters : dict
+            Full parameters payload. Not required if using other keywords.
+        start : string
+            The starting key to begin listing from.
+
+        This method only supports keywords for providing arguments.
+
+        Returns
+        ----
+        dict
+            Dictionary object containing API response.
+        """
+        collection_name = kwargs.get("collection_name", None)
+        if collection_name:
+            # Pop the path variable from the keywords dictionary
+            # before processing query string arguments.
+            kwargs.pop("collection_name")
+            returned = process_service_request(calling_object=self,
+                                               endpoints=Endpoints,
+                                               operation_id="ListObjects",
+                                               keywords=kwargs,
+                                               params=parameters,
+                                               collection_name=collection_name
+                                               )
+        else:
+            returned = generate_error_result("You must provide a collection_name "
+                                             "argument in order to use this operation."
+                                             )
+        return returned
+
+    @force_default(defaults=["parameters"], default_types=["dict"])
+    def search(self, parameters: dict = None, **kwargs) -> Dict[str, Union[int, dict]]:
+        """Search for objects that match the specified filter creteria.
+
+        Object metadata is returned, not actual objects.
+
+        HTTP Method: POST
+
+        Swagger URL
+        ----
+        https://assets.falcon.crowdstrike.com/support/api/swagger.html#/custom-storage/SearchObjects
+
+        Keyword arguments
+        ----
+        collection_name : string (required)
+            The name of the collection to search.
+        filter : string (required)
+            The FQL formatted filter to use to limit returned results.
+        limit : integer
+            The maximum number of results to return.
+        offset : integer
+            The pagination offset to use for returned results.
+        parameters : dict
+            Full parameters payload. Not required if using other keywords.
+        sort : string
+            Sort order for returned results in FQL format.
+
+        This method only supports keywords for providing arguments.
+
+        Returns
+        ----
+        dict
+            Dictionary object containing API response.
+        """
+        collection_name = kwargs.get("collection_name", None)
+        if collection_name:
+            # Pop the path variable from the keywords dictionary
+            # before processing query string arguments.
+            kwargs.pop("collection_name")
+            returned = process_service_request(calling_object=self,
+                                               endpoints=Endpoints,
+                                               operation_id="SearchObjects",
+                                               keywords=kwargs,
+                                               params=parameters,
+                                               collection_name=collection_name
+                                               )
+        else:
+            returned = generate_error_result("You must provide a collection_name "
+                                             "argument in order to use this operation."
+                                             )
+        return returned
+
+    def get(self, **kwargs) -> Union[bytes, Dict[str, Union[int, dict]]]:
+        """Retrieve an object in binary format.
+
+        HTTP Method: GET
+
+        Swagger URL
+        ----
+        https://assets.falcon.crowdstrike.com/support/api/swagger.html#/custom-storage/GetObject
+
+        Keyword arguments
+        ----
+        collection_name : string (required)
+            The name of the collection where the object resides.
+        object_key : string (required)
+            The key of the object to be retrieved.
+
+        This method only supports keywords for providing arguments.
+
+        Returns
+        ----
+        bytes or dict
+            Binary (success) or Dictionary (failure) object containing API response.
+        """
+        collection_name = kwargs.get("collection_name", None)
+        object_key = kwargs.get("object_key", None)
+        if collection_name and object_key:
+            # Pop the path variables from the keywords dictionary
+            # before processing query string arguments.
+            kwargs.pop("collection_name")
+            kwargs.pop("object_key")
+            returned = process_service_request(calling_object=self,
+                                               endpoints=Endpoints,
+                                               operation_id="GetObject",
+                                               keywords=kwargs,
+                                               collection_name=collection_name,
+                                               object_key=object_key
+                                               )
+        else:
+            returned = generate_error_result("You must provide a collection_name and an "
+                                             "object_key argument in order to use this operation."
+                                             )
+        return returned
+
+    @force_default(defaults=["body", "parameters"], default_types=["dict", "dict"])
+    def upload(self, body: dict = None, parameters: dict = None, **kwargs) -> Dict[str, Union[int, dict]]:
+        """Upload a new or overwrite an existing object at the given key.
+
+        HTTP Method: PUT
+
+        Swagger URL
+        ----
+        https://assets.falcon.crowdstrike.com/support/api/swagger.html#/custom-storage/PutObject
+
+        Keyword arguments
+        ----
+        body : binary [application/octet-stream] (required)
+            The object to be uploaded.
+        collection_name : string (required)
+            The name of the collection to upload to.
+        dry_run : boolean
+            Boolean flag indicating if this is a dry run. If set to True, the
+            request is validated if it would succeed, but not actually executed.
+        object_key : string (required)
+            The key of the object to be uploaded.
+        parameters : dict
+            Full parameters payload. Not required if using other keywords.
+        schema_version : string
+            The version of the collection schema.
+
+        This method only supports keywords for providing arguments.
+
+        Returns
+        ----
+        dict
+            Dictionary object containing API response.
+        """
+        collection_name = kwargs.get("collection_name", None)
+        object_key = kwargs.get("object_key", None)
+        if collection_name and object_key:
+            # Pop the path variables from the keywords dictionary
+            # before processing query string arguments.
+            kwargs.pop("collection_name")
+            kwargs.pop("object_key")
+            # Create a copy of our default header dictionary
+            header_payload = json.loads(json.dumps(self.headers))
+            # Set our content-type header
+            header_payload["Content-Type"] = "application/octet-stream"
+            returned = process_service_request(calling_object=self,
+                                               endpoints=Endpoints,
+                                               operation_id="PutObject",
+                                               keywords=kwargs,
+                                               body=body,
+                                               params=parameters,
+                                               collection_name=collection_name,
+                                               object_key=object_key
+                                               )
+        else:
+            returned = generate_error_result("You must provide a collection_name and an "
+                                             "object_key argument in order to use this operation."
+                                             )
+        return returned
+
+    @force_default(defaults=["parameters"], default_types=["dict"])
+    def delete(self, parameters: dict = None, **kwargs) -> Dict[str, Union[int, dict]]:
+        """Delete an existing object at the given key.
+
+        HTTP Method: DELETE
+
+        Swagger URL
+        ----
+        https://assets.falcon.crowdstrike.com/support/api/swagger.html#/custom-storage/DeleteObject
+
+        Keyword arguments
+        ----
+        collection_name : string (required)
+            The name of the collection to upload to.
+        dry_run : boolean
+            Boolean flag indicating if this is a dry run. If set to True, the
+            request is validated if it would succeed, but not actually executed.
+        object_key : string (required)
+            The key of the object to be uploaded.
+        parameters : dict
+            Full parameters payload. Not required if using other keywords.
+
+        This method only supports keywords for providing arguments.
+
+        Returns
+        ----
+        dict
+            Dictionary object containing API response.
+        """
+        collection_name = kwargs.get("collection_name", None)
+        object_key = kwargs.get("object_key", None)
+        if collection_name and object_key:
+            # Pop the path variables from the keywords dictionary
+            # before processing query string arguments.
+            kwargs.pop("collection_name")
+            kwargs.pop("object_key")
+            returned = process_service_request(calling_object=self,
+                                               endpoints=Endpoints,
+                                               operation_id="DeleteObject",
+                                               keywords=kwargs,
+                                               params=parameters,
+                                               collection_name=collection_name,
+                                               object_key=object_key
+                                               )
+        else:
+            returned = generate_error_result("You must provide a collection_name and an "
+                                             "object_key argument in order to use this operation."
+                                             )
+        return returned
+
+    def metadata(self, **kwargs) -> Dict[str, Union[int, dict]]:
+        """Retrieve the metadata for a specified object.
+
+        HTTP Method: GET
+
+        Swagger URL
+        ----
+        https://assets.falcon.crowdstrike.com/support/api/swagger.html#/custom-storage/GetObjectMetadata
+
+        Keyword arguments
+        ----
+        collection_name : string (required)
+            The name of the collection where the object resides.
+        object_key : string (required)
+            The key of the object to be retrieved.
+
+        This method only supports keywords for providing arguments.
+
+        Returns
+        ----
+        dict
+            Dictionary object containing API response.
+        """
+        collection_name = kwargs.get("collection_name", None)
+        object_key = kwargs.get("object_key", None)
+        if collection_name and object_key:
+            # Pop the path variables from the keywords dictionary
+            # before processing query string arguments.
+            kwargs.pop("collection_name")
+            kwargs.pop("object_key")
+            returned = process_service_request(calling_object=self,
+                                               endpoints=Endpoints,
+                                               operation_id="GetObjectMetadata",
+                                               keywords=kwargs,
+                                               collection_name=collection_name,
+                                               object_key=object_key
+                                               )
+        else:
+            returned = generate_error_result("You must provide a collection_name and an "
+                                             "object_key argument in order to use this operation."
+                                             )
+        return returned
+
+    # These method names align to the operation IDs in the API but
+    # do not conform to snake_case / PEP8 and are defined here for
+    # backwards compatibility / ease of use purposes.
+    ListObjects = list
+    SearchObjects = search
+    GetObject = get
+    PutObject = upload
+    DeleteObject = delete
+    GetObjectMetadata = metadata
diff --git a/src/falconpy/falcon_container.py b/src/falconpy/falcon_container.py
index c3745cf99..30c0539af 100644
--- a/src/falconpy/falcon_container.py
+++ b/src/falconpy/falcon_container.py
@@ -84,7 +84,7 @@ def get_credentials(self: object) -> Dict[str, Union[int, dict]]:
             )
 
     @force_default(defaults=["parameters"], default_types=["dict"])
-    def get_combined_images(self: object, parameters: dict = None, **kwargs) -> dict:
+    def get_combined_images(self: object, parameters: dict = None, **kwargs) -> Dict[str, Union[int, dict]]:
         """Retrieve registry entities identified by the customer ID.
 
         HTTP Method: GET
@@ -309,7 +309,7 @@ def image_matches_policy(self: object, parameters: dict = None, **kwargs) -> Dic
             )
 
     @force_default(defaults=["parameters"], default_types=["dict"])
-    def read_registry_entities(self: object, parameters: dict = None, **kwargs) -> dict:
+    def read_registry_entities(self: object, parameters: dict = None, **kwargs) -> Dict[str, Union[int, dict]]:
         """Retrieve registry entities identified by the customer ID.
 
         HTTP Method: GET
@@ -351,7 +351,7 @@ def read_registry_entities_by_uuid(self: object,
                                        *args,
                                        parameters: dict = None,
                                        **kwargs
-                                       ) -> dict:
+                                       ) -> Dict[str, Union[int, dict]]:
         """Retrieve registry entities identified by the customer UUID.
 
         HTTP Method: GET
@@ -386,7 +386,7 @@ def read_registry_entities_by_uuid(self: object,
             )
 
     @force_default(defaults=["parameters"], default_types=["dict"])
-    def delete_registry_entities(self: object, *args, parameters: dict = None, **kwargs) -> dict:
+    def delete_registry_entities(self: object, *args, parameters: dict = None, **kwargs) -> Dict[str, Union[int, dict]]:
         """Delete the registry entity identified by the entity UUID.
 
         HTTP Method: DELETE
@@ -421,7 +421,7 @@ def delete_registry_entities(self: object, *args, parameters: dict = None, **kwa
             )
 
     @force_default(defaults=["body"], default_types=["dict"])
-    def create_registry_entities(self: object, body: dict = None, **kwargs) -> dict:
+    def create_registry_entities(self: object, body: dict = None, **kwargs) -> Dict[str, Union[int, dict]]:
         """Create a registry entity using the provided details.
 
         HTTP Method: POST
@@ -462,7 +462,7 @@ def create_registry_entities(self: object, body: dict = None, **kwargs) -> dict:
             )
 
     @force_default(defaults=["body"], default_types=["dict"])
-    def update_registry_entities(self: object, body: dict = None, **kwargs) -> dict:
+    def update_registry_entities(self: object, body: dict = None, **kwargs) -> Dict[str, Union[int, dict]]:
         """Update the registry entity, as identified by the entity UUID, using the provided details.
 
         HTTP Method: PATCH
diff --git a/src/falconpy/firewall_policies.py b/src/falconpy/firewall_policies.py
index 4047609e8..7f11da473 100644
--- a/src/falconpy/firewall_policies.py
+++ b/src/falconpy/firewall_policies.py
@@ -164,7 +164,9 @@ def perform_action(self: object, body: dict = None, parameters: dict = None, **k
         Swagger URL
         https://assets.falcon.crowdstrike.com/support/api/swagger.html#/firewall-policies/performFirewallPoliciesAction
         """
-        _allowed_actions = ['add-host-group', 'disable', 'enable', 'remove-host-group']
+        _allowed_actions = ['add-host-group', 'disable', 'enable',
+                            'remove-host-group', 'add-rule-group', 'remove-rule-group'
+                            ]
         operation_id = "performFirewallPoliciesAction"
         parameter_payload = args_to_params(parameters, kwargs, Endpoints, operation_id)
         action_name = parameter_payload.get("action_name", "Not Specified")
diff --git a/src/falconpy/foundry_logscale.py b/src/falconpy/foundry_logscale.py
new file mode 100644
index 000000000..8e7ff3bb7
--- /dev/null
+++ b/src/falconpy/foundry_logscale.py
@@ -0,0 +1,362 @@
+"""CrowdStrike Falcon Foundry LogScale API interface class.
+
+ _______                        __ _______ __        __ __
+|   _   .----.-----.--.--.--.--|  |   _   |  |_.----|__|  |--.-----.
+|.  1___|   _|  _  |  |  |  |  _  |   1___|   _|   _|  |    <|  -__|
+|.  |___|__| |_____|________|_____|____   |____|__| |__|__|__|_____|
+|:  1   |                         |:  1   |
+|::.. . |   CROWDSTRIKE FALCON    |::.. . |    FalconPy
+`-------'                         `-------'
+
+OAuth2 API - Customer SDK
+
+This is free and unencumbered software released into the public domain.
+
+Anyone is free to copy, modify, publish, use, compile, sell, or
+distribute this software, either in source code form or as a compiled
+binary, for any purpose, commercial or non-commercial, and by any
+means.
+
+In jurisdictions that recognize copyright laws, the author or authors
+of this software dedicate any and all copyright interest in the
+software to the public domain. We make this dedication for the benefit
+of the public at large and to the detriment of our heirs and
+successors. We intend this dedication to be an overt act of
+relinquishment in perpetuity of all present and future rights to this
+software under copyright law.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+For more information, please refer to <https://unlicense.org>
+"""
+from typing import Dict, Union
+from ._util import force_default, process_service_request
+from ._payload import foundry_execute_search_payload, foundry_dynamic_search_payload
+from ._service_class import ServiceClass
+from ._endpoint._foundry_logscale import _foundry_logscale_endpoints as Endpoints
+
+
+class FoundryLogScale(ServiceClass):
+    """The only requirement to instantiate an instance of this class is one of the following.
+
+    - a valid client_id and client_secret provided as keywords.
+    - a credential dictionary with client_id and client_secret containing valid API credentials
+      {
+          "client_id": "CLIENT_ID_HERE",
+          "client_secret": "CLIENT_SECRET_HERE"
+      }
+    - a previously-authenticated instance of the authentication service class (oauth2.py)
+    - a valid token provided by the authentication service class (oauth2.py)
+    """
+
+    def list_repos(self: object) -> Dict[str, Union[int, dict]]:
+        """List available repositories and views.
+
+        Keyword arguments:
+        This method does not accept keyword arguments.
+
+        This method does not accept arguments.
+
+        Returns: dict object containing API response.
+
+        HTTP Method: GET
+
+        Swagger URL
+        https://assets.falcon.crowdstrike.com/support/api/swagger.html#/foundry-logscale/ListReposV1
+        """
+        return process_service_request(
+            calling_object=self,
+            endpoints=Endpoints,
+            operation_id="ListReposV1"
+            )
+
+    @force_default(defaults=["parameters", "body"], default_types=["dict", "dict"])
+    def ingest_data(self: object,
+                    data_file: dict = None,
+                    body: dict = None,
+                    parameters: dict = None,
+                    **kwargs
+                    ) -> dict:
+        """Ingest data into the application repository.
+
+        Keyword arguments:
+        data_file -- Content of the uploaded archive in binary format.
+                     'file' is also accepted as this parameter.
+        parameters -- full parameters payload, not required if using other keywords.
+        tag -- Custom tag for ingested data in the form 'tag:value'. String.
+        tag_source -- Tag the data with the specified source. String.
+        test_data -- Tag the data with 'test-ingest'. Defaults to False. Boolean.
+
+        This method only supports keywords for providing arguments.
+
+        Returns: dict object containing API response.
+
+        HTTP Method: POST
+
+        Swagger URL
+        https://assets.falcon.crowdstrike.com/support/api/swagger.html#/foundry-logscale/IngestDataV1
+        """
+        # Try to find the binary object they provided us
+        if not data_file:
+            data_file = kwargs.get("file", None)
+
+        # Create a multipart form payload for our upload file
+        file_tuple = [("file", ("data-upload", data_file, "application/json"))]
+        return process_service_request(
+            calling_object=self,
+            endpoints=Endpoints,
+            operation_id="IngestDataV1",
+            body=body,  # Not sure we need to provide a body
+            files=file_tuple,
+            keywords=kwargs,
+            params=parameters
+            )
+
+    @force_default(defaults=["body", "parameters"], default_types=["dict", "dict"])
+    def execute_dynamic(self: object,
+                        body: dict = None,
+                        parameters: dict = None,
+                        **kwargs
+                        ) -> Dict[str, Union[int, dict]]:
+        """Deploy a saved search.
+
+        Keyword arguments:
+        body -- full body payload, not required if using other keywords.
+                {
+                    "end": "string",
+                    "repo_or_view": "string",
+                    "search_query": "string",
+                    "search_query_args": {},
+                    "start": "string"
+                }
+        end -- Ending position. String.
+        include_schema_generation -- Include generated schemas in the response. Boolean.
+        incude_test_data -- Include test data when executing searches. Boolean.
+        metadata -- Include metadata in the response. Boolean.
+        mode -- Mode to execute the query under (async or sync). String.
+        repo_or_view -- Name of the repo or view to perform the search. String.
+        search_query -- Query for the search. String.
+        search_query_args -- Argumetns provided to the search. Dictionary.
+        start -- Starting position. String.
+
+        This method only supports keywords for providing arguments.
+
+        Returns: dict object containing API response.
+
+        HTTP Method: POST
+
+        Swagger URL
+        https://assets.falcon.crowdstrike.com/support/api/swagger.html#/foundry-logscale/CreateSavedSearchesDynamicExecuteV1
+        """
+        if not body:
+            body = foundry_dynamic_search_payload(passed_keywords=kwargs)
+
+        return process_service_request(
+            calling_object=self,
+            endpoints=Endpoints,
+            operation_id="CreateSavedSearchesDynamicExecuteV1",
+            keywords=kwargs,
+            body=body,
+            params=parameters
+            )
+
+    @force_default(defaults=["parameters"], default_types=["dict"])
+    def get_search_results(self: object, parameters: dict = None, **kwargs) -> Dict[str, Union[int, dict]]:
+        """Get the results of a saved search.
+
+        Keyword arguments:
+        job_id -- Job ID for a previously executed asynchronous query. String.
+        limit -- The maximum number of records to return in this response. Integer.
+                 Use with the offset parameter to manage pagination of results.
+        metadata -- Flag indicating if metadata should be included in the results. Boolean.
+        offset -- The offset to start retrieving records from. String.
+                  Use with the limit parameter to manage pagination of results.
+        parameters - full parameters payload, not required if using other keywords.
+        version -- Version of the resource. String.
+
+        This method only supports keywords for providing arguments.
+
+        Returns: dict object containing API response.
+
+        HTTP Method: GET
+
+        Swagger URL
+        https://assets.falcon.crowdstrike.com/support/api/swagger.html#/foundry-logscale/GetSavedSearchesExecuteV1
+        """
+        return process_service_request(
+            calling_object=self,
+            endpoints=Endpoints,
+            operation_id="GetSavedSearchesExecuteV1",
+            keywords=kwargs,
+            params=parameters
+            )
+
+    @force_default(defaults=["body", "parameters"], default_types=["dict", "dict"])
+    def execute(self: object,
+                body: dict = None,
+                parameters: dict = None,
+                **kwargs
+                ) -> Dict[str, Union[int, dict]]:
+        """Deploy a saved search.
+
+        Keyword arguments:
+        body -- full body payload, not required if using other keywords.
+                {
+                    "end": "string",
+                    "id": "string",
+                    "mode": "string",
+                    "name": "string",
+                    "parameters": {},
+                    "start": "string",
+                    "version": "string",
+                    "with_in": {
+                        "field": "string",
+                        "values": [
+                        "string"
+                        ]
+                    },
+                    "with_limit": {
+                        "from": "string",
+                        "limit": 0
+                    },
+                    "with_renames": [
+                        {
+                        "as": "string",
+                        "field": "string"
+                        }
+                    ],
+                    "with_sort": {
+                        "fields": [
+                        "string"
+                        ],
+                        "limit": 0,
+                        "order": [
+                        "string"
+                        ],
+                        "reverse": true,
+                        "type": [
+                        "string"
+                        ]
+                    }
+                }
+        detailed -- Flag indicating if search field details should be included. Boolean.
+        end -- Ending position. String.
+        id -- Saved search ID. String.
+        include_test_data -- Include test data when executing searches. Boolean.
+        metadata -- Include metadata in the response. Boolean.
+        mode -- Mode to execute the query under (async, async_offload or sync). String.
+        name -- Saved search name. String.
+        search_parameters -- Search specific parameters. Dictionary.
+                             NOT to be confused with the default parameters dictionary.
+        start -- Starting position. String.
+        version -- Version of the search. String.
+        with_in -- With in. Dictionary.
+        with_limit -- With limit. Dictionary.
+        with_renames -- With renames. Dictionary.
+        with_sort -- With sort. Dictionary.
+
+        This method only supports keywords for providing arguments.
+
+        Returns: dict object containing API response.
+
+        HTTP Method: POST
+
+        Swagger URL
+        https://assets.falcon.crowdstrike.com/support/api/swagger.html#/foundry-logscale/CreateSavedSearchesExecuteV1
+        """
+        if not body:
+            body = foundry_execute_search_payload(passed_keywords=kwargs)
+
+        return process_service_request(
+            calling_object=self,
+            endpoints=Endpoints,
+            operation_id="CreateSavedSearchesExecuteV1",
+            keywords=kwargs,
+            body=body,
+            params=parameters
+            )
+
+    def populate(self: object) -> Dict[str, Union[int, dict]]:
+        """Populate a saved search.
+
+        Keyword arguments:
+        This method does not accept keyword arguments.
+
+        This method does not accept arguments.
+
+        Returns: dict object containing API response.
+
+        HTTP Method: POST
+
+        Swagger URL
+        https://assets.falcon.crowdstrike.com/support/api/swagger.html#/foundry-logscale/CreateSavedSearchesIngestV1
+        """
+        return process_service_request(
+            calling_object=self,
+            endpoints=Endpoints,
+            operation_id="CreateSavedSearchesIngestV1"
+            )
+
+    @force_default(defaults=["parameters"], default_types=["dict"])
+    def download_results(self: object, parameters: dict = None, **kwargs) -> Dict[str, Union[int, dict]]:
+        """Get the results of a saved search as a file.
+
+        Keyword arguments:
+        job_id -- Job ID for a previously executed asynchronous query. String.
+        parameters - full parameters payload, not required if using other keywords.
+        result_format -- Result file format. Allowed values: 'json' or 'csv'. String.
+
+        This method only supports keywords for providing arguments.
+
+        Returns: binary object (success) or dict object (failure) containing API response.
+
+        HTTP Method: GET
+
+        Swagger URL
+        https://assets.falcon.crowdstrike.com/support/api/swagger.html#/foundry-logscale/GetSavedSearchesJobResultsDownloadV1
+        """
+        return process_service_request(
+            calling_object=self,
+            endpoints=Endpoints,
+            operation_id="GetSavedSearchesJobResultsDownloadV1",
+            keywords=kwargs,
+            params=parameters
+            )
+
+    def list_views(self: object) -> Dict[str, Union[int, dict]]:
+        """List views.
+
+        Keyword arguments: This method does not accept keyword arguments.
+
+        Arguments: This method does not accept arguments.
+
+        Returns: dict object containing API response.
+
+        HTTP Method: GET
+
+        Swagger URL
+        https://assets.falcon.crowdstrike.com/support/api/swagger.html#/foundry-logscale/ListViewV1
+        """
+        return process_service_request(
+            calling_object=self,
+            endpoints=Endpoints,
+            operation_id="ListViewV1"
+            )
+
+    # These method names align to the operation IDs in the API but
+    # do not conform to snake_case / PEP8 and are defined here for
+    # backwards compatibility / ease of use purposes
+    ListReposV1 = list_repos
+    ListViewV1 = list_views
+    IngestDataV1 = ingest_data
+    CreateSavedSearchesDynamicExecuteV1 = execute_dynamic
+    GetSavedSearchesExecuteV1 = get_search_results
+    CreateSavedSearchesExecuteV1 = execute
+    CreateSavedSearchesIngestV1 = populate
+    GetSavedSearchesJobResultsDownloadV1 = download_results
diff --git a/src/falconpy/real_time_response_audit.py b/src/falconpy/real_time_response_audit.py
new file mode 100644
index 000000000..a1e771799
--- /dev/null
+++ b/src/falconpy/real_time_response_audit.py
@@ -0,0 +1,99 @@
+"""CrowdStrike Falcon Real Time Response Audit API interface class.
+
+ _______                        __ _______ __        __ __
+|   _   .----.-----.--.--.--.--|  |   _   |  |_.----|__|  |--.-----.
+|.  1___|   _|  _  |  |  |  |  _  |   1___|   _|   _|  |    <|  -__|
+|.  |___|__| |_____|________|_____|____   |____|__| |__|__|__|_____|
+|:  1   |                         |:  1   |
+|::.. . |   CROWDSTRIKE FALCON    |::.. . |    FalconPy
+`-------'                         `-------'
+
+OAuth2 API - Customer SDK
+
+This is free and unencumbered software released into the public domain.
+
+Anyone is free to copy, modify, publish, use, compile, sell, or
+distribute this software, either in source code form or as a compiled
+binary, for any purpose, commercial or non-commercial, and by any
+means.
+
+In jurisdictions that recognize copyright laws, the author or authors
+of this software dedicate any and all copyright interest in the
+software to the public domain. We make this dedication for the benefit
+of the public at large and to the detriment of our heirs and
+successors. We intend this dedication to be an overt act of
+relinquishment in perpetuity of all present and future rights to this
+software under copyright law.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+For more information, please refer to <https://unlicense.org>
+"""
+from typing import Dict, Union
+from ._util import force_default, process_service_request
+from ._service_class import ServiceClass
+from ._endpoint._real_time_response_audit import _real_time_response_audit_endpoints as Endpoints
+
+
+class RealTimeResponseAudit(ServiceClass):
+    """The only requirement to instantiate an instance of this class is one of the following.
+
+    - a valid client_id and client_secret provided as keywords.
+    - a credential dictionary with client_id and client_secret containing valid API credentials
+      {
+          "client_id": "CLIENT_ID_HERE",
+          "client_secret": "CLIENT_SECRET_HERE"
+      }
+    - a previously-authenticated instance of the authentication service class (oauth2.py)
+    - a valid token provided by the authentication service class (oauth2.py)
+    """
+
+    @force_default(defaults=["parameters"], default_types=["dict"])
+    def audit_sessions(self: object, parameters: dict = None, **kwargs) -> Dict[str, Union[int, dict]]:
+        """Get all the RTR sessions created for a customer during a specified time period.
+
+        Keyword arguments:
+        filter -- The filter expression that should be used to limit the results. FQL syntax.
+        limit -- The maximum number of sessions to return in this response. Integer.
+                 Use with the offset parameter to manage pagination of results.
+        offset -- Starting index of overall result set from which to return ids.
+                  Use with the limit parameter to manage pagination of results.
+        parameters - full parameters payload, not required if using other keywords.
+        sort -- The property to sort by. FQL syntax (e.g. date_created|asc).
+                Available sort fields: created_at, updated_at, deleted_at
+        with_command_info -- Retrieve sessions with command information included. By default
+                             sessions are returned without command information which includes
+                             cloud request IDs and log fields.
+
+        This method only supports keywords for providing arguments.
+
+        Returns: dict object containing API response.
+
+        HTTP Method: GET
+
+        Swagger URL
+        https://assets.falcon.crowdstrike.com/support/api/swagger.html#/real-time-response-audit/RTRAuditSessions
+        """
+        return process_service_request(
+            calling_object=self,
+            endpoints=Endpoints,
+            operation_id="RTRAuditSessions",
+            keywords=kwargs,
+            params=parameters
+            )
+
+    # These method names align to the operation IDs in the API but
+    # do not conform to snake_case / PEP8 and are defined here for
+    # backwards compatibility / ease of use purposes
+    RTRAuditSessions = audit_sessions
+
+
+# The legacy name for this class does not conform to PascalCase / PEP8
+# It is defined here for backwards compatibility purposes only.
+Real_Time_Response_Audit = RealTimeResponseAudit  # pylint: disable=C0103
diff --git a/src/falconpy/workflows.py b/src/falconpy/workflows.py
new file mode 100644
index 000000000..bc3014a08
--- /dev/null
+++ b/src/falconpy/workflows.py
@@ -0,0 +1,381 @@
+"""Falcon Workflows API Interface Class.
+
+ _______                        __ _______ __        __ __
+|   _   .----.-----.--.--.--.--|  |   _   |  |_.----|__|  |--.-----.
+|.  1___|   _|  _  |  |  |  |  _  |   1___|   _|   _|  |    <|  -__|
+|.  |___|__| |_____|________|_____|____   |____|__| |__|__|__|_____|
+|:  1   |                         |:  1   |
+|::.. . |   CROWDSTRIKE FALCON    |::.. . |    FalconPy
+`-------'                         `-------'
+
+OAuth2 API - Customer SDK
+
+This is free and unencumbered software released into the public domain.
+
+Anyone is free to copy, modify, publish, use, compile, sell, or
+distribute this software, either in source code form or as a compiled
+binary, for any purpose, commercial or non-commercial, and by any
+means.
+
+In jurisdictions that recognize copyright laws, the author or authors
+of this software dedicate any and all copyright interest in the
+software to the public domain. We make this dedication for the benefit
+of the public at large and to the detriment of our heirs and
+successors. We intend this dedication to be an overt act of
+relinquishment in perpetuity of all present and future rights to this
+software under copyright law.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+For more information, please refer to <https://unlicense.org>
+"""
+from typing import Dict, Union
+from ._util import force_default, process_service_request, handle_single_argument
+from ._payload import (
+    simple_action_parameter,
+    generic_payload_list,
+    workflow_deprovision_payload,
+    workflow_template_payload
+    )
+from ._service_class import ServiceClass
+from ._endpoint._workflows import _workflows_endpoints as Endpoints
+
+
+class Workflows(ServiceClass):
+    """The only requirement to instantiate an instance of this class is one of the following.
+
+    - a valid client_id and client_secret provided as keywords.
+    - a credential dictionary with client_id and client_secret containing valid API credentials
+      {
+          "client_id": "CLIENT_ID_HERE",
+          "client_secret": "CLIENT_SECRET_HERE"
+      }
+    - a previously-authenticated instance of the authentication service class (oauth2.py)
+    - a valid token provided by the authentication service class (oauth2.py)
+    """
+
+    @force_default(defaults=["body", "parameters"], default_types=["dict", "dict"])
+    def execute(self: object, body: dict = None, parameters: dict = None, **kwargs) -> Dict[str, Union[int, dict]]:
+        """Execute an on-demand workflow. Response will contain the execution ID.
+
+        Keyword arguments:
+        body -- full body payload, not required if using other keywords.
+                {
+                    Workflow schema
+                }
+        definition_id -- Definition ID to execute. Either a name or ID can be specified.
+                         String or List of Strings.
+        name -- Workflow name to execute. Either a name or ID can be specified. String.
+        parameters -- Full parameters payload in dictionary (JSON) format. Not required
+                      if you are using other keywords. Dictionary.
+        key -- Key used to help deduplicate executions. If unset a new UUID is used. String.
+        depth -- Used to record the execution depth to help limit execution loops when a workflow
+                 triggers another. The maximum depth is 4. Integer.
+        source_event_url -- Used to record a URL to the source that led to trigger the workflow.
+                            String.
+
+        This method only supports keywords for providing arguments.
+
+        Returns: dict object containing API response.
+
+        HTTP Method: POST
+
+        Swagger URL
+        https://assets.falcon.crowdstrike.com/support/api/swagger.html#/workflows/WorkflowExecute
+        """
+        return process_service_request(
+            calling_object=self,
+            endpoints=Endpoints,
+            operation_id="WorkflowExecute",
+            keywords=kwargs,
+            params=parameters,
+            body=body
+            )
+
+    @force_default(defaults=["body", "parameters"], default_types=["dict", "dict"])
+    def execution_action(self: object, body: dict = None, parameters: dict = None, **kwargs) -> Dict[str, Union[int, dict]]:
+        """Allow a user to resume/retry a failed workflow execution.
+
+        Keyword arguments:
+        action_name -- Action to perform. String.
+                       Allowed values: resume
+        action_parameters -- List of actions to perform. List of dictionaries.
+        body -- full body payload, not required if using other keywords.
+                {
+                    "action_parameters": [
+                        {
+                            "name": "string",
+                            "value": "string"
+                        }
+                    ],
+                    "ids": [
+                        "string"
+                    ]
+                }
+        ids -- Execution IDs. String or List of Strings.
+        name -- For single action parameter actions. Specifies the action parameter name. String.
+        value -- For single action parameter actions. Specifies the action parameter value. String.
+
+        This method only supports keywords for providing arguments.
+
+        Returns: dict object containing API response.
+
+        HTTP Method: POST
+
+        Swagger URL
+        https://assets.falcon.crowdstrike.com/support/api/swagger.html#/workflows/WorkflowExecutionsAction
+        """
+        if not body:
+            body = simple_action_parameter(kwargs,
+                                           generic_payload_list(submitted_keywords=kwargs,
+                                                                payload_value="ids"
+                                                                )
+                                           )
+
+        return process_service_request(
+            calling_object=self,
+            endpoints=Endpoints,
+            operation_id="WorkflowExecutionsAction",
+            keywords=kwargs,
+            body=body,
+            params=parameters
+            )
+
+    @force_default(defaults=["parameters"], default_types=["dict"])
+    def execution_results(self: object, *args, parameters: dict = None, **kwargs) -> Dict[str, Union[int, dict]]:
+        """Retrieve results for a specified execution.
+
+        Keyword arguments:
+        ids -- Workflow execution ID to retrieve results for. String or List of Strings.
+        parameters - full parameters payload, not required if ids is provided as a keyword.
+
+        Arguments: When not specified, the first argument to this method is assumed to be 'ids'.
+                   All others are ignored.
+
+        Returns: dict object containing API response.
+
+        HTTP Method: GET
+
+        Swagger URL
+        https://assets.falcon.crowdstrike.com/support/api/swagger.html#/workflows/WorkflowExecutionResults
+        """
+        return process_service_request(
+            calling_object=self,
+            endpoints=Endpoints,
+            operation_id="WorkflowExecutionResults",
+            keywords=kwargs,
+            params=handle_single_argument(args, parameters, "ids")
+            )
+
+    @force_default(defaults=["body"], default_types=["dict"])
+    def deprovision(self: object, body: dict = None, **kwargs) -> Dict[str, Union[int, dict]]:
+        """Deprovision a system definition that was previously provisioned on a target CID.
+
+        Keyword arguments:
+        body -- full body payload, not required if using other keywords.
+                {
+                    "definition_id": "string",
+                    "deprovision_all": boolean,
+                    "template_id": "string",
+                    "template_name": "string"
+                }
+        definition_id -- String.
+        deprovision_all -- Boolean.
+        template_id -- String.
+        template_name -- String.
+
+        This method only supports keywords for providing arguments.
+
+        Returns: dict object containing API response.
+
+        HTTP Method: POST
+
+        Swagger URL
+        https://assets.falcon.crowdstrike.com/support/api/swagger.html#/workflows/WorkflowSystemDefinitionsDeProvision
+        """
+        if not body:
+            body = workflow_deprovision_payload(passed_keywords=kwargs)
+
+        return process_service_request(
+            calling_object=self,
+            endpoints=Endpoints,
+            operation_id="WorkflowSystemDefinitionsDeProvision",
+            keywords=kwargs,
+            body=body
+            )
+
+    @force_default(defaults=["body"], default_types=["dict"])
+    def promote(self: object, body: dict = None, **kwargs) -> Dict[str, Union[int, dict]]:
+        """Promote a version of a system definition.
+
+        Tenant must be already provisioned. This allows the caller to apply an updated template
+        version on a CID and expects all parameters to be supplied. If the template supports
+        multi-instance, the customer scope definition ID must be supplied to determine which
+        customer workflow should be update.
+
+        Keyword arguments:
+        activities -- Dictionary.
+        body -- Template to use for update. Not required if using other keywords. Dictionary.
+                {
+                    "customer_definition_id": "string",
+                    "name": "string",
+                    "parameters": {
+                        "activities": {
+                            "configuration": [
+                                {
+                                    "node_id": "string",
+                                    "properties": {}
+                                }
+                            ],
+                            "selection": [
+                                {
+                                    "id": "string",
+                                    "properties": {},
+                                    "source": "string"
+                                }
+                            ]
+                        },
+                        "conditions": [
+                            {
+                                "fields": [
+                                    {
+                                        "name": "string",
+                                        "operator": "string"
+                                    }
+                                ],
+                                "node_id": "string"
+                            }
+                        ],
+                        "trigger": {
+                            "fields": {},
+                            "node_id": "string"
+                        }
+                    },
+                    "template_id": "string",
+                    "template_name": "string",
+                    "template_version": "string"
+                }
+        conditions -- List of dictionaries.
+        customer_definition_id -- String.
+        name -- String.
+        parameters -- Dictionary. Overrides specified activities, conditions and trigger keywords.
+        template_id -- String.
+        template_name -- String.
+        template_version -- String.
+        trigger -- Dictionary.
+
+        This method only supports keywords for providing arguments.
+
+        Returns: dict object containing API response.
+
+        HTTP Method: POST
+
+        Swagger URL
+        https://assets.falcon.crowdstrike.com/support/api/swagger.html#/workflows/WorkflowSystemDefinitionsPromote
+        """
+        if not body:
+            body = workflow_template_payload(passed_keywords=kwargs)
+
+        return process_service_request(
+            calling_object=self,
+            endpoints=Endpoints,
+            operation_id="WorkflowSystemDefinitionsPromote",
+            keywords=kwargs,
+            body=body
+            )
+
+    @force_default(defaults=["body"], default_types=["dict"])
+    def provision(self: object, body: dict = None, **kwargs) -> Dict[str, Union[int, dict]]:
+        """Promote a version of a system definition.
+
+        Tenant must be already provisioned. This allows the caller to apply an updated template
+        version on a CID and expects all parameters to be supplied. If the template supports
+        multi-instance, the customer scope definition ID must be supplied to determine which
+        customer workflow should be update.
+
+        Keyword arguments:
+        activities -- Dictionary.
+        body -- Template to use for update. Not required if using other keywords. Dictionary.
+                {
+                    "customer_definition_id": "string",
+                    "name": "string",
+                    "parameters": {
+                        "activities": {
+                            "configuration": [
+                                {
+                                    "node_id": "string",
+                                    "properties": {}
+                                }
+                            ],
+                            "selection": [
+                                {
+                                    "id": "string",
+                                    "properties": {},
+                                    "source": "string"
+                                }
+                            ]
+                        },
+                        "conditions": [
+                            {
+                                "fields": [
+                                    {
+                                        "name": "string",
+                                        "operator": "string"
+                                    }
+                                ],
+                                "node_id": "string"
+                            }
+                        ],
+                        "trigger": {
+                            "fields": {},
+                            "node_id": "string"
+                        }
+                    },
+                    "template_id": "string",
+                    "template_name": "string",
+                    "template_version": "string"
+                }
+        conditions -- List of dictionaries.
+        customer_definition_id -- String.
+        name -- String.
+        parameters -- Dictionary. Overrides specified activities, conditions and trigger keywords.
+        template_id -- String.
+        template_name -- String.
+        template_version -- String.
+        trigger -- Dictionary.
+
+        This method only supports keywords for providing arguments.
+
+        Returns: dict object containing API response.
+
+        HTTP Method: POST
+
+        Swagger URL
+        https://assets.falcon.crowdstrike.com/support/api/swagger.html#/workflows/WorkflowSystemDefinitionsProvision
+        """
+        if not body:
+            body = workflow_template_payload(passed_keywords=kwargs)
+
+        return process_service_request(
+            calling_object=self,
+            endpoints=Endpoints,
+            operation_id="WorkflowSystemDefinitionsProvision",
+            keywords=kwargs,
+            body=body
+            )
+
+    # These method names align to the operation IDs in the API but
+    # do not conform to snake_case / PEP8 and are defined here for
+    # backwards compatibility / ease of use purposes
+    WorkflowExecute = execute
+    WorkflowExecutionsAction = execution_action
+    WorkflowExecutionResults = execution_results
+    WorkflowSystemDefinitionsDeProvision = deprovision
+    WorkflowSystemDefinitionsPromote = promote
+    WorkflowSystemDefinitionsProvision = provision


Test patch:
diff --git a/tests/test_cloud_snapshots.py b/tests/test_cloud_snapshots.py
index ee474f39e..669131d7f 100644
--- a/tests/test_cloud_snapshots.py
+++ b/tests/test_cloud_snapshots.py
@@ -38,10 +38,16 @@ def run_tests(self):
 
         return error_checks
 
+    @pytest.mark.skipif(config.base_url == "https://api.laggar.gcw.crowdstrike.com",
+                        reason="Unit testing unavailable on US-GOV-1"
+                        )
     def test_get_credentials(self):
         """Pytest harness hook"""
         assert bool(falcon.get_credentials()["status_code"] in AllowedResponses) is True
 
+    @pytest.mark.skipif(config.base_url == "https://api.laggar.gcw.crowdstrike.com",
+                        reason="Unit testing unavailable on US-GOV-1"
+                        )
     def test_remaining_code_paths(self):
         """Pytest harness hook"""
         assert self.run_tests() is True
diff --git a/tests/test_custom_storage.py b/tests/test_custom_storage.py
new file mode 100644
index 000000000..f4b982c30
--- /dev/null
+++ b/tests/test_custom_storage.py
@@ -0,0 +1,54 @@
+"""
+test_custom_storage.py - This class tests the Custom Storage service class
+"""
+import os
+import sys
+import pytest
+
+# Authentication via the test_authorization.py
+from tests import test_authorization as Authorization
+# Import our sibling src folder into the path
+sys.path.append(os.path.abspath('src'))
+# Classes to test - manually imported from sibling folder
+from falconpy import CustomStorage, APIHarnessV2
+
+auth = Authorization.TestAuthorization()
+config = auth.getConfigObject()
+uber = APIHarnessV2(creds=config.creds)
+falcon = CustomStorage(auth_object=config)
+AllowedResponses = [200, 201, 400, 403, 404, 429]  # Temp allow 403
+
+
+class TestCustomStorage:
+    def run_all_tests(self):
+        error_checks = True
+        tests = {
+            "ListObjects" : falcon.list(collection_name="Whatever"),
+            "SearchObjects" : falcon.search(collection_name="whatever"),
+            "GetObject" : falcon.get(collection_name="whatever", object_key="whatever_else"),
+            "PutObject" : falcon.upload(collection_name="whatever", object_key="whatever_else"),
+            "DeleteObject" : falcon.delete(collection_name="whatever", object_key="whatever_else"),
+            "FailBecauseMissingCollectionNameListObjects" : falcon.list(),
+            "FailBecauseMissingCollectionNameSearchObjects" : falcon.search(),
+            "GetObjectMetadata" : falcon.metadata(collection_name="whatever", object_key="whatever_else"),
+            "UberStyleGetObjectMetadata" : uber.command("GetObjectMetadata", collection_name="whatever", object_key="whatever_else"),
+            "FailBecauseMissingObjectKeyMetadata" : falcon.metadata(collection_name="no_object_key"),
+            "FailBecauseMissingObjectKeyDeleteObject" : falcon.delete(collection_name="no_object_key"),
+            "FailBecauseMissingObjectKeyPutObject" : falcon.upload(collection_name="no_object_key"),
+            "FailBecauseMissingObjectKeyGetObject" : falcon.get(collection_name="no_object_key")
+        }
+        for key in tests:
+            if tests[key]["status_code"] not in AllowedResponses:
+                error_checks = False
+                if "FailBecauseMissing" in key and tests[key]["status_code"] == 500:
+                    error_checks = True
+                # if not error_checks:
+                #     print(tests[key])
+
+        return error_checks
+
+    @pytest.mark.skipif(config.base_url == "https://api.laggar.gcw.crowdstrike.com",
+                        reason="Unit testing unavailable on US-GOV-1"
+                        )
+    def test_all_functionality(self):
+        assert self.run_all_tests() is True
diff --git a/tests/test_foundry_logscale.py b/tests/test_foundry_logscale.py
new file mode 100644
index 000000000..3d6e12d04
--- /dev/null
+++ b/tests/test_foundry_logscale.py
@@ -0,0 +1,47 @@
+"""
+test_foundry_logscale.py - This class tests the FoundryLogScale service class
+"""
+import os
+import sys
+import pytest
+
+# Authentication via the test_authorization.py
+from tests import test_authorization as Authorization
+# Import our sibling src folder into the path
+sys.path.append(os.path.abspath('src'))
+# Classes to test - manually imported from sibling folder
+from falconpy import FoundryLogScale
+
+auth = Authorization.TestAuthorization()
+config = auth.getConfigObject()
+falcon = FoundryLogScale(auth_object=config)
+AllowedResponses = [200, 201, 400, 404, 429, 406, 500, 501, 502, 503]
+
+
+class TestFoundryLogScale:
+    def run_all_tests(self):
+        error_checks = True
+        tests = {
+            "ListReposV1" : falcon.list_repos(),
+            "ListViewV1" : falcon.list_views(),
+            "IngestDataV1" : falcon.ingest_data(data_file="testfile.png", tag="file_tag"),
+            "IngestDataV1also" : falcon.ingest_data(file="testfile.png", tag="file_tag"),
+            "CreateSavedSearchesDynamicExecuteV1" : falcon.execute_dynamic(end="10", start="1"),
+            "GetSavedSearchesExecuteV1" : falcon.get_search_results(job_id="12345"),
+            "CreateSavedSearchesExecuteV1" : falcon.execute(search_parameters={"something": "somethingElse"}, end="10", start="1"),
+            "CreateSavedSearchesIngestV1" : falcon.populate(),
+            "GetSavedSearchesJobResultsDownloadV1" : falcon.download_results(job_id="12345", result_format="json"),
+        }
+        for key in tests:
+            if tests[key]["status_code"] not in AllowedResponses:
+                error_checks = False
+                # print(f"\n{key}\n")
+                # print(tests[key])
+
+        return error_checks
+
+    @pytest.mark.skipif(config.base_url == "https://api.laggar.gcw.crowdstrike.com",
+                        reason="Unit testing unavailable on US-GOV-1"
+                        )
+    def test_all_functionality(self):
+        assert self.run_all_tests() is True
diff --git a/tests/test_real_time_response_audit.py b/tests/test_real_time_response_audit.py
new file mode 100644
index 000000000..aeac29e36
--- /dev/null
+++ b/tests/test_real_time_response_audit.py
@@ -0,0 +1,38 @@
+"""
+test_real_time_response_audit.py - This class tests the RealTimeResponseAudit service class
+"""
+import os
+import sys
+import pytest
+
+# Authentication via the test_authorization.py
+from tests import test_authorization as Authorization
+# Import our sibling src folder into the path
+sys.path.append(os.path.abspath('src'))
+# Classes to test - manually imported from sibling folder
+from falconpy import RealTimeResponseAudit
+
+auth = Authorization.TestAuthorization()
+config = auth.getConfigObject()
+falcon = RealTimeResponseAudit(auth_object=config)
+AllowedResponses = [200, 201, 400, 404, 429]
+
+
+class TestRealTimeResponseAudit:
+    def run_all_tests(self):
+        error_checks = True
+        tests = {
+            "RTRAuditSessions" : falcon.audit_sessions()
+        }
+        for key in tests:
+            if tests[key]["status_code"] not in AllowedResponses:
+                error_checks = False
+            #     print(tests[key])
+
+        return error_checks
+
+    @pytest.mark.skipif(config.base_url == "https://api.laggar.gcw.crowdstrike.com",
+                        reason="Unit testing unavailable on US-GOV-1"
+                        )
+    def test_all_functionality(self):
+        assert self.run_all_tests() is True
diff --git a/tests/test_result_object.py b/tests/test_result_object.py
index 3cf2cbd9a..dc93cf780 100644
--- a/tests/test_result_object.py
+++ b/tests/test_result_object.py
@@ -15,6 +15,7 @@
 # We'll use Hosts to retrieve data to test results with
 from falconpy import (
     Hosts,
+    CloudConnectAWS,
     Result,
     APIError,
     RegionSelectError,
@@ -26,7 +27,10 @@
     Errors,
     SampleUploads,
     CSPMRegistration,
-    UnnecessaryEncodingUsed
+    UnnecessaryEncodingUsed,
+    DeprecatedOperation,
+    DeprecatedClass,
+    SDKDeprecationWarning
     )
 from falconpy._result._base_dictionary import UnsupportedPythonVersion
 
@@ -743,4 +747,30 @@ def test_unnecessary_encoding_used_warning(self):
                 _success = True
             hosts = Hosts(auth_object=hosts, pythonic=False)
             hosts.query_devices_by_filter_scroll(filter="hostname%3A%27falconpy%27")
-            assert _success
\ No newline at end of file
+            assert _success
+
+    @pytest.mark.skipif(config.base_url == "https://api.laggar.gcw.crowdstrike.com",
+                        reason="Unit testing unavailable on US-GOV-1"
+                        )
+    @not_supported
+    def test_pythonic_deprecation_warnings(self):
+        _success = False
+        with pytest.warns(SDKDeprecationWarning):
+            warnings.warn(SDKDeprecationWarning(message="This is a generic deprecation warning", code=187))
+        with pytest.warns(DeprecatedClass):
+            warnings.warn(DeprecatedClass(code=187))
+        with pytest.warns(DeprecatedOperation):
+            warnings.warn(DeprecatedOperation(code=187))
+        with pytest.warns(DeprecatedClass):
+            try:
+                old_discover = CloudConnectAWS(auth_object=config, pythonic=True)
+            except APIError:
+                pass
+
+        with pytest.warns(DeprecatedOperation):
+            try:
+                old_discover.get_aws_settings()
+                _success = True
+            except:
+                pass
+        assert _success
\ No newline at end of file
diff --git a/tests/test_workflows.py b/tests/test_workflows.py
new file mode 100644
index 000000000..a82534013
--- /dev/null
+++ b/tests/test_workflows.py
@@ -0,0 +1,44 @@
+"""
+test_workflows.py - This class tests the Workflows service class
+"""
+import os
+import sys
+import pytest
+
+# Authentication via the test_authorization.py
+from tests import test_authorization as Authorization
+# Import our sibling src folder into the path
+sys.path.append(os.path.abspath('src'))
+# Classes to test - manually imported from sibling folder
+from falconpy import Workflows
+
+auth = Authorization.TestAuthorization()
+config = auth.getConfigObject()
+falcon = Workflows(auth_object=config)
+AllowedResponses = [200, 201, 400, 403, 404, 429]  # Temp allow 403
+
+
+class TestWorkflows:
+    def run_all_tests(self):
+        error_checks = True
+        tests = {
+            "WorkflowExecute" : falcon.execute(body={}),
+            "WorkflowExecutionsAction" : falcon.execution_action(action_name="resume", ids="12345678"),
+            "WorkflowExecutionResults" : falcon.execution_results(ids="12345678"),
+            "WorkflowSystemDefinitionsDeProvision" : falcon.deprovision(definition_id="12345", deprovision_all=True),
+            "WorkflowSystemDefinitionsPromote" : falcon.promote(customer_definition_id="12345", activities={}),
+            "WorkflowSystemDefinitionsProvision" : falcon.provision(name="FalconPyTesting", configuration=[{}]),
+
+        }
+        for key in tests:
+            if tests[key]["status_code"] not in AllowedResponses:
+                error_checks = False
+            #     print(tests[key])
+
+        return error_checks
+
+    @pytest.mark.skipif(config.base_url == "https://api.laggar.gcw.crowdstrike.com",
+                        reason="Unit testing unavailable on US-GOV-1"
+                        )
+    def test_all_functionality(self):
+        assert self.run_all_tests() is True
diff --git a/util/run-tests.sh b/util/run-tests.sh
index bd0a64f58..659e9e8d2 100755
--- a/util/run-tests.sh
+++ b/util/run-tests.sh
@@ -1,6 +1,8 @@
 #!/bin/bash
 #
 
+function splat() ( echo "--------------------------------------------------------"; )
+
 DO_MANUAL="--ignore-glob=**/manual/*"
 if ! [ -z "$1" ]
 then
@@ -17,3 +19,12 @@ fi
 coverage run --rcfile=util/coverage.config -m pytest -s -v $DO_MANUAL $DO_DEBUG
 coverage report
 bandit -r src
+echo -e "\nFormatting"
+splat
+flake8 src/falconpy --count --statistics
+echo -e "\nCode style and syntax"
+splat
+pylint src/falconpy
+echo "Docstring style and syntax"
+splat
+pydocstyle src/falconpy
\ No newline at end of file