diff --git a/docs/source/conf.py b/docs/source/conf.py
index 40f59bcb8bef6c57a7845a3340dbd07a7e44fa74..ec4ba29e5ae345953d6af2c5228c85f2a9763585 100644
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -13,7 +13,7 @@ source_suffix = {
 }
 
 # -- Options for Markdown support --------------------------------------------
-myst_enable_extensions = ['attrs_block', 'deflist', 'replacements', 'smartquotes', 'strikethrough']
+myst_enable_extensions = ['attrs_block', 'deflist', 'replacements', 'smartquotes', 'strikethrough', 'fieldlist']
 suppress_warnings = ['myst.strikethrough']
 
 # -- Options for autodoc -----------------------------------------------------
@@ -33,7 +33,7 @@ html_logo = 'static/geant_logo_white.svg'
 
 # Both the class' and the __init__ method's docstring are concatenated and inserted.
 autoclass_content = 'both'
-autodoc_typehints = 'none'
+# autodoc_typehints = 'none'
 
 # Display todos by setting to True
 todo_include_todos = True
diff --git a/gso/services/provisioning_proxy.py b/gso/services/provisioning_proxy.py
index 479e18097578ae6a9da77ec78f26d849c8c1cd69..13d90249b50917c899ef12c05f1d15758662b30c 100644
--- a/gso/services/provisioning_proxy.py
+++ b/gso/services/provisioning_proxy.py
@@ -22,45 +22,55 @@ from gso.products.product_types.device import DeviceProvisioning
 from gso.products.product_types.iptrunk import Iptrunk, IptrunkProvisioning
 
 logger = logging.getLogger(__name__)
+"""{class}`logging.Logger` instance."""
 DEFAULT_LABEL = "Provisioning proxy is running. Please come back later for the results."
+"""The default label displayed when the provisioning proxy is running."""
 
 
 class CUDOperation(strEnum):
-    """Enumerator for different C(R)UD operations that the provisioning proxy supports.
+    """Enumerator for different CRUD operations that the provisioning proxy supports.
 
     Read isn't applicable, hence these become CUD and not CRUD operations.
     """
 
-    #: Creation is done with a POST request
     POST = "POST"
-    #: Updating is done with a PUT request
+    """Creation is done with a POST request."""
     PUT = "PUT"
-    #: Removal is done with a DELETE request
+    """Updating is done with a PUT request."""
     DELETE = "DELETE"
+    """Removal is done with a DELETE request."""
 
 
 def _send_request(endpoint: str, parameters: dict, process_id: UUIDstr, operation: CUDOperation) -> None:
     """Send a request to LSO. The callback address is derived using the process ID provided.
 
-    :param str endpoint: The LSO-specific endpoint to call, depending on the type of service object that's acted upon.
-    :param dict parameters: JSON body for the request, which will almost always at least consist of a subscription
-        object, and a boolean value to indicate a dry run.
-    :param UUIDstr process_id: The process ID that this request is a part of, used to call back to when the execution
-        of the playbook is completed.
-    :param :class:`CUDOperation` operation: The specific operation that's performed with the request.
+    :param endpoint: The LSO-specific endpoint to call, depending on the type of service object that's acted upon.
+    :type endpoint: str
+    :param parameters: JSON body for the request, which will almost always at least consist of a subscription object,
+        and a boolean value to indicate a dry run.
+    :type parameters: dict
+    :param process_id: The process ID that this request is a part of, used to call back to when the execution of the
+        playbook is completed.
+    :type process_id: UUIDstr
+    :param operation: The specific operation that's performed with the request.
+    :type operation: {class}`CUDOperation`
+    :rtype: None
     """
     oss = settings.load_oss_params()
     pp_params = oss.PROVISIONING_PROXY
     assert pp_params
 
+    # Build up a callback URL for the Provisioning Proxy to return its results to.
     callback_url = f"{settings.load_oss_params().GENERAL.public_hostname}" f"/api/processes/{process_id}/resume"
-    logger.debug("[provisioning proxy] provisioning for process %s", process_id)
+    logger.debug(f"[provisioning proxy] provisioning for process {process_id}")
+    logger.debug(f"[provisioning proxy] Callback URL set to {callback_url}")
 
     parameters.update({"callback": callback_url})
     url = f"{pp_params.scheme}://{pp_params.api_base}/api/{endpoint}"
 
     request = None
 
+    # Fire off the request, depending on the operation type.
     if operation == CUDOperation.POST:
         request = requests.post(url, json=parameters, timeout=10000)
     elif operation == CUDOperation.PUT:
@@ -76,9 +86,13 @@ def _send_request(endpoint: str, parameters: dict, process_id: UUIDstr, operatio
 def provision_device(subscription: DeviceProvisioning, process_id: UUIDstr, dry_run: bool = True) -> None:
     """Provision a new device using LSO.
 
-    :param :class:`DeviceProvisioning` subscription: The subscription object that's to be provisioned.
-    :param UUIDstr process_id: The related process ID, used for callback.
-    :param bool dry_run: A boolean indicating whether this should be a dry run or not, defaults to ``True``.
+    :param subscription: The subscription object that's to be provisioned.
+    :type subscription: {class}`DeviceProvisioning`
+    :param process_id: The related process ID, used for callback.
+    :type process_id: UUIDstr
+    :param dry_run: A boolean indicating whether this should be a dry run or not, defaults to `True`.
+    :type dry_run: bool
+    :rtype: None
     """
     parameters = {"dry_run": dry_run, "subscription": json.loads(json_dumps(subscription))}
 
@@ -90,10 +104,15 @@ def provision_ip_trunk(
 ) -> None:
     """Provision an IP trunk service using LSO.
 
-    :param :class:`IptrunkProvisioning` subscription: The subscription object that's to be provisioned.
-    :param UUIDstr process_id: The related process ID, used for callback.
-    :param str config_object: The type of object that's deployed
-    :param bool dry_run: A boolean indicating whether this should be a dry run or not, defaults to ``True``.
+    :param subscription: The subscription object that's to be provisioned.
+    :type subscription: {class}`IptrunkProvisioning`
+    :param process_id: The related process ID, used for callback.
+    :type process_id: UUIDstr
+    :param config_object: The type of object that's deployed.
+    :type config_object: str
+    :param dry_run: A boolean indicating whether this should be a dry run or not, defaults to `True`.
+    :type dry_run: bool
+    :rtype: None
     """
     parameters = {
         "subscription": json.loads(json_dumps(subscription)),
@@ -105,37 +124,16 @@ def provision_ip_trunk(
     _send_request("ip_trunk", parameters, process_id, CUDOperation.POST)
 
 
-# def modify_ip_trunk(old_subscription: Iptrunk,
-#                    new_subscription: Iptrunk,
-#                    process_id: UUIDstr,
-#                    dry_run: bool = True):
-#    """
-#    Function that modifies an existing IP trunk subscription using LSO.
-#
-#    :param :class:`Iptrunk` old_subscription: The subscription object, before
-#        its modification.
-#    :param :class:`Iptrunk` new_subscription: The subscription object, after
-#        modifications have been made to it.
-#    :param UUIDstr process_id: The related process ID, used for callback.
-#    :param bool dry_run: A boolean indicating whether this should be a dry ryn
-#        or not, defaults to ``True``.
-#    """
-#    parameters = {
-#        'dry_run': dry_run,
-#        'old_subscription': old_subscription,
-#        'subscription': new_subscription
-#        # ... missing parameters
-#    }
-#
-#    _send_request('ip_trunk', parameters, process_id, CUDOperation.PUT)
-
-
 def deprovision_ip_trunk(subscription: Iptrunk, process_id: UUIDstr, dry_run: bool = True) -> None:
     """Deprovision an IP trunk service using LSO.
 
-    :param :class:`IptrunkProvisioning` subscription: The subscription object that's to be provisioned.
-    :param UUIDstr process_id: The related process ID, used for callback.
-    :param bool dry_run: A boolean indicating whether this should be a dry run or not, defaults to ``True``.
+    :param subscription: The subscription object that's to be provisioned.
+    :type subscription: {class}`IptrunkProvisioning`
+    :param process_id: The related process ID, used for callback.
+    :type process_id: UUIDstr
+    :param dry_run: A boolean indicating whether this should be a dry run or not, defaults to `True`.
+    :type dry_run: bool
+    :rtype: None
     """
     parameters = {"subscription": json.loads(json_dumps(subscription)), "dry_run": dry_run, "verb": "terminate"}
 
@@ -143,7 +141,24 @@ def deprovision_ip_trunk(subscription: Iptrunk, process_id: UUIDstr, dry_run: bo
 
 
 @inputstep("Await provisioning proxy results", assignee=Assignee("SYSTEM"))
-def await_pp_results(subscription: SubscriptionModel, label_text: str = DEFAULT_LABEL) -> FormGenerator:
+def _await_pp_results(subscription: SubscriptionModel, label_text: str = DEFAULT_LABEL) -> FormGenerator:
+    """Input step that forces the workflow to go into a `SUSPENDED` state.
+
+    When the workflow is `SUSPENDED`, it will wait for user input to be presented before it continues running the next
+    steps of the workflow. User input is mimicked by the provisioning proxy, as it makes a `PUT` request to the callback
+    URL that it was given in `_send_request()`. This input is fabricated in such a way that it will advance the workflow
+    to the next step. This next step should always be `confirm_pp_results()`, where the operator is presented with the
+    output of the provisioning proxy.
+
+    :param subscription: The current subscription that the provisioning proxy is acting on.
+    :type subscription: {class}`orchestrator.domain.SubscriptionModel`
+    :param label_text: A label that is displayed to the operator when the provisioning proxy has not returned its
+        results yet. Defaults to `DEFAULT_LABEL`.
+    :type label_text: str
+    :return: The input that is given by the provisioning proxy, that should contain run results, and a `confirm`
+        boolean set to `True`.
+    :rtype: {class}`orchestrator.types.FormGenerator`
+    """
     class ProvisioningResultPage(FormPage):
         class Config:
             title = f"Deploying {subscription.product.name}..."
@@ -165,11 +180,27 @@ def await_pp_results(subscription: SubscriptionModel, label_text: str = DEFAULT_
 
 @step("Reset Provisioning Proxy state")
 def reset_pp_success_state() -> State:
+    """Reset the boolean that indicates a successful provisioning proxy result in the state of a running workflow.
+
+    :return: A new state of the workflow, where the key `pp_did_succeed` has been (re)set to false.
+    :rtype: {class}`orchestrator.types.State`
+    """
     return {"pp_did_succeed": False}
 
 
 @inputstep("Confirm provisioning proxy results", assignee=Assignee("SYSTEM"))
-def confirm_pp_results(state: State) -> FormGenerator:
+def _confirm_pp_results(state: State) -> FormGenerator:
+    """Input step where a human has to confirm the result from calling provisioning proxy.
+
+    The results of a call to the provisioning proxy are displayed, together with the fact whether this execution was
+    a success or not. If unsuccessful, an extra label is displayed that warns the user about the fact that this
+    execution will be retried. This will happen up to two times, after which the workflow will fail.
+
+    :param state: The current state of the workflow.
+    :type state: {class}`orchestrator.types.State`
+    :return: Confirmation from the user, when presented with the run results.
+    :rtype: {class}`orchestrator.types.FormGenerator`
+    """
     successful_run = state["pp_run_results"]["return_code"] == 0
 
     class ConfirmRunPage(FormPage):
@@ -194,10 +225,26 @@ def confirm_pp_results(state: State) -> FormGenerator:
 
 
 def pp_interaction(provisioning_step: Step) -> StepList:
+    """Wrapper function for an interaction with the provisioning proxy
+
+    This method returns the three steps that make up an interaction with the provisioning proxy:
+        - The provisioning step itself, given by the user as input.
+        - The input step that suspends the workflow, and will wait for results from the provisioning proxy.
+        - An input step that presents the user with the results, where they must be confirmed.
+
+    All these steps are wrapped in a {class}`orchestrator.workflow.conditional`. This ensures that when provisioning was
+    already successful, these steps are skipped. This mechanism is quite a dirty hack, and it is planned to be addressed
+    in a later release.
+
+    :param provisioning_step: The step that executes an interaction with the provisioning proxy.
+    :type provisioning_step: {class}`orchestrator.workflow.Step`
+    :return: A list of three steps that form one interaction with the provisioning proxy.
+    :rtype: {class}`orchestrator.workflow.StepList`
+    """
     should_retry_pp_steps = conditional(lambda state: not state.get("pp_did_succeed"))
 
     return (
         should_retry_pp_steps(provisioning_step)
-        >> should_retry_pp_steps(await_pp_results)
-        >> should_retry_pp_steps(confirm_pp_results)
+        >> should_retry_pp_steps(_await_pp_results)
+        >> should_retry_pp_steps(_confirm_pp_results)
     )