diff --git a/gso/services/netbox_client.py b/gso/services/netbox_client.py
index f13fe47741111c9be68c31abe5e6005349499ce4..d5e31fdf14a430dd2049afdece2ba29ef4d93a69 100644
--- a/gso/services/netbox_client.py
+++ b/gso/services/netbox_client.py
@@ -67,7 +67,9 @@ class NetBoxClient:
             self.netbox.dcim.interfaces.filter(device_id=device.id, enabled=False, mark_connected=False, speed=speed)
         )
 
-    def create_interface(self, iface_name: str, type: str, speed: str, device_name: str) -> Interfaces:
+    def create_interface(
+        self, iface_name: str, type: str, device_name: str, description: str | None = None, enabled: bool = False
+    ) -> Interfaces:
         """Create new interface on a device, where device is defined by name.
 
         The type parameter can be 1000base-t, 10gbase-t, lag, etc.
@@ -76,7 +78,12 @@ class NetBoxClient:
         """
         device = self.get_device_by_name(device_name)
         return self.netbox.dcim.interfaces.create(
-            name=iface_name, type=type, speed=speed, enabled=False, mark_connected=False, device=device.id
+            name=iface_name,
+            type=type,
+            enabled=enabled,
+            mark_connected=False,
+            device=device.id,
+            description=description,
         )
 
     def create_device_type(self, manufacturer: str, model: str, slug: str) -> DeviceTypes:
@@ -110,7 +117,7 @@ class NetBoxClient:
         device_role = self.netbox.dcim.device_roles.get(name="router")
 
         # Get site id
-        device_site = self.netbox.dcim.sites.get(name="Amsterdam")
+        device_site = self.netbox.dcim.sites.get(name="GEANT")
 
         # Create new device
         device = self.netbox.dcim.devices.create(
@@ -118,40 +125,59 @@ class NetBoxClient:
         )
         module_bays = list(self.netbox.dcim.module_bays.filter(device_id=device.id))
         card_type = self.netbox.dcim.module_types.get(model=tier_info.module_type)
+        # TODo: Use the module_bays_slots to create the modules
         for module_bay in module_bays:
             self.netbox.dcim.modules.create(
                 device=device.id,
                 module_bay=module_bay.id,
                 module_type=card_type.id,
                 status="active",
+                enabled=False,
                 comments="Installed via pynetbox",
             )
 
+        for interface in self.netbox.dcim.interfaces.filter(device_id=device.id):
+            speed = None
+            type_parts = interface.type.value.split("-")
+            if "gbase" in type_parts[0]:
+                # Extract the numeric part and convert to bits per second
+                speed = int("".join(filter(str.isdigit, type_parts[0]))) * 1000000
+            interface.speed = speed
+            interface.enabled = False
+            interface.save()
+
         return device
 
     def delete_device(self, router_name: str) -> None:
         self.netbox.dcim.devices.get(name=router_name).delete()
         return
 
-    def attach_interface_to_lag(self, device_name: str, lag_name: str, iface_name: str) -> Interfaces:
-        """Assign a given interface to a lag.
+    def attach_interface_to_lag(
+        self, device_name: str, lag_name: str, iface_name: str, description: str | None = None
+    ) -> Interfaces:
+        """Assign a given interface to a LAG.
 
-        Returns the lag object with the assignend interfaces
+        Returns the interface object after assignment.
         """
         # Get device id
         device = self.get_device_by_name(device_name)
 
-        # Now get interface for device
+        # Get interface for device
         iface = self.netbox.dcim.interfaces.get(name=iface_name, device_id=device.id)
 
-        # Get lag
+        # Get LAG
         lag = self.netbox.dcim.interfaces.get(name=lag_name, device_id=device.id)
 
-        # Assign interface to lag
+        # Assign interface to LAG
         iface.lag = lag.id
 
-        # Update interface
-        return self.netbox.dcim.interfaces.update(iface)
+        # Set description if provided
+        if description:
+            iface.description = description
+
+        iface.save()
+
+        return iface
 
     def reserve_interface(self, device_name: str, iface_name: str) -> Interfaces:
         """Reserve an interface by enabling it."""
@@ -210,3 +236,10 @@ class NetBoxClient:
 
         # Return available lags not assigned to the device
         return [lag for lag in all_feasible_lags if lag not in lag_interface_names]
+
+    def get_available_interfaces(self, router_id: UUID, speed: str) -> Interfaces:
+        router = Router.from_subscription(router_id).router.router_fqdn
+        device = self.get_device_by_name(router)
+        return self.netbox.dcim.interfaces.filter(
+            device=device.name, enabled=False, mark_connected=False, speed=int(speed.split("G")[0]) * 1000000
+        )
diff --git a/gso/utils/device_info.py b/gso/utils/device_info.py
index 1c193557f8c21515103b210517f4c1e5ab58a597..219e4950a204062b012499e98400c31239e0c296 100644
--- a/gso/utils/device_info.py
+++ b/gso/utils/device_info.py
@@ -12,16 +12,16 @@ class ModuleInfo(BaseModel):
 class TierInfo:
     def __init__(self) -> None:
         self.Tier1 = ModuleInfo(
-            device_type="7750-SR7s",
+            device_type="7750 SR-7s",
             module_bays_slots=[1, 2],
-            module_type="XCM2s-XMA2s-36p-800g",
+            module_type="XMA2-s-36p-400g",
             breakout_interfaces_per_slot=[36, 35, 34, 33],
             total_10g_interfaces=80,
         )
         self.Tier2 = ModuleInfo(
             device_type="7750-SR7s",
             module_bays_slots=[1, 2],
-            module_type="XCM2s-XMA2s-36p-400g",
+            module_type="XMA2-s-36p-400g",
             breakout_interfaces_per_slot=[36, 35, 34, 33],
             total_10g_interfaces=60,
         )
@@ -30,4 +30,5 @@ class TierInfo:
         return getattr(self, name)
 
 
-FEASIBLE_IP_TRUNK_LAG_RANGE = range(1, 10)
+# The range includes values from 1 to 10 (11 is not included)
+FEASIBLE_IP_TRUNK_LAG_RANGE = range(1, 11)
diff --git a/gso/workflows/iptrunk/create_iptrunk.py b/gso/workflows/iptrunk/create_iptrunk.py
index ae2c8cf9301e1e634d3695c8b5078c834705970d..b96b9d8818d3636c58d42148cc58c59f2c2a7943 100644
--- a/gso/workflows/iptrunk/create_iptrunk.py
+++ b/gso/workflows/iptrunk/create_iptrunk.py
@@ -1,18 +1,29 @@
+from typing import NoReturn
+
 from orchestrator.forms import FormPage
-from orchestrator.forms.validators import Choice, UniqueConstrainedList
+from orchestrator.forms.validators import Choice, ChoiceList, UniqueConstrainedList
 from orchestrator.targets import Target
 from orchestrator.types import FormGenerator, State, SubscriptionLifecycle, UUIDstr
 from orchestrator.workflow import StepList, done, init, step, workflow
 from orchestrator.workflows.steps import resync, set_status, store_process_subscription
 from orchestrator.workflows.utils import wrap_create_initial_input_form
+from pydantic import validator
+from pynetbox.models.dcim import Interfaces
 
 from gso.products.product_blocks import PhyPortCapacity
 from gso.products.product_blocks.iptrunk import IptrunkType
+from gso.products.product_blocks.router import RouterVendor
 from gso.products.product_types.iptrunk import IptrunkInactive, IptrunkProvisioning
 from gso.products.product_types.router import Router
 from gso.services import infoblox, provisioning_proxy, subscriptions
+from gso.services.netbox_client import NetBoxClient
 from gso.services.provisioning_proxy import pp_interaction
-from gso.workflows.utils import customer_selector
+from gso.workflows.utils import (
+    available_interfaces_choices,
+    available_lags_choices,
+    customer_selector,
+    get_router_vendor,
+)
 
 
 def initial_input_form_generator(product_name: str) -> FormGenerator:
@@ -39,28 +50,83 @@ def initial_input_form_generator(product_name: str) -> FormGenerator:
 
     initial_user_input = yield CreateIptrunkForm
 
-    class AeMembersListA(UniqueConstrainedList[str]):
+    router_enum_a = Choice("Select a router", zip(routers.keys(), routers.items()))  # type: ignore
+
+    class SelectRouterSideA(FormPage):
+        class Config:
+            title = "Select a router for side A of the trunk."
+
+        iptrunk_sideA_node_id: router_enum_a  # type: ignore[valid-type]
+
+        @validator("iptrunk_sideA_node_id", allow_reuse=True)
+        def validate_device_exists_in_netbox(cls, iptrunk_sideA_node_id: UUIDstr) -> str | NoReturn:
+            router = Router.from_subscription(iptrunk_sideA_node_id).router
+            if router.router_vendor == RouterVendor.NOKIA:
+                device = NetBoxClient().get_device_by_name(router.router_fqdn)
+                if not device:
+                    raise ValueError("The selected router does not exist in Netbox.")
+            return iptrunk_sideA_node_id
+
+    user_input_router_side_a = yield SelectRouterSideA
+    router_a = user_input_router_side_a.iptrunk_sideA_node_id.name
+    side_a_ae_iface = available_lags_choices(router_a) or str
+
+    class AeMembersListA(ChoiceList):
         min_items = initial_user_input.iptrunk_minimum_links
+        item_type = available_interfaces_choices(router_a, initial_user_input.iptrunk_speed)  # type: ignore
+        unique_items = True
 
-    RouterEnumA = Choice("Select a router", zip(routers.keys(), routers.items()))  # type: ignore[arg-type]
+    class JuniperAeMembers(UniqueConstrainedList[str]):
+        min_items = initial_user_input.iptrunk_minimum_links
+        unique_items = True
+
+    ae_members_side_a = AeMembersListA if get_router_vendor(router_a) == RouterVendor.NOKIA else JuniperAeMembers
+
+    class AeMembersDescriptionListA(UniqueConstrainedList[str]):
+        min_items = initial_user_input.iptrunk_minimum_links
 
     class CreateIptrunkSideAForm(FormPage):
         class Config:
             title = "Provide subscription details for side A of the trunk."
 
-        iptrunk_sideA_node_id: RouterEnumA  # type: ignore[valid-type]
-        iptrunk_sideA_ae_iface: str
+        iptrunk_sideA_ae_iface: side_a_ae_iface  # type: ignore[valid-type]
         iptrunk_sideA_ae_geant_a_sid: str
-        iptrunk_sideA_ae_members: AeMembersListA
-        iptrunk_sideA_ae_members_descriptions: AeMembersListA
+        iptrunk_sideA_ae_members: ae_members_side_a  # type: ignore[valid-type]
+        iptrunk_sideA_ae_members_descriptions: AeMembersDescriptionListA
 
     user_input_side_a = yield CreateIptrunkSideAForm
-
     # Remove the selected router for side A, to prevent any loops
-    routers.pop(str(user_input_side_a.iptrunk_sideA_node_id.name))
-    RouterEnumB = Choice("Select a router", zip(routers.keys(), routers.items()))  # type: ignore[arg-type]
+    routers.pop(str(user_input_router_side_a.iptrunk_sideA_node_id.name))
+    router_enum_b = Choice("Select a router", zip(routers.keys(), routers.items()))  # type: ignore
+
+    class SelectRouterSideB(FormPage):
+        class Config:
+            title = "Select a router for side B of the trunk."
+
+        iptrunk_sideB_node_id: router_enum_b  # type: ignore[valid-type]
+
+        @validator("iptrunk_sideB_node_id", allow_reuse=True)
+        def validate_device_exists_in_netbox(cls, iptrunk_sideB_node_id: UUIDstr) -> str | NoReturn:
+            router = Router.from_subscription(iptrunk_sideB_node_id).router
+            if router.router_vendor == RouterVendor.NOKIA:
+                device = NetBoxClient().get_device_by_name(router.router_fqdn)
+                if not device:
+                    raise ValueError("The selected router does not exist in Netbox.")
+            return iptrunk_sideB_node_id
 
-    class AeMembersListB(UniqueConstrainedList[str]):
+    user_input_router_side_b = yield SelectRouterSideB
+    router_b = user_input_router_side_b.iptrunk_sideB_node_id.name
+    side_b_ae_iface = available_lags_choices(router_b) or str
+
+    class AeMembersListB(ChoiceList):
+        min_items = len(user_input_side_a.iptrunk_sideA_ae_members)
+        max_items = len(user_input_side_a.iptrunk_sideA_ae_members)
+        item_type = available_interfaces_choices(router_b, initial_user_input.iptrunk_speed)  # type: ignore
+        unique_items = True
+
+    ae_members_side_b = AeMembersListB if get_router_vendor(router_b) == RouterVendor.NOKIA else JuniperAeMembers
+
+    class AeMembersDescriptionListB(UniqueConstrainedList[str]):
         min_items = len(user_input_side_a.iptrunk_sideA_ae_members)
         max_items = len(user_input_side_a.iptrunk_sideA_ae_members)
 
@@ -68,15 +134,20 @@ def initial_input_form_generator(product_name: str) -> FormGenerator:
         class Config:
             title = "Provide subscription details for side B of the trunk."
 
-        iptrunk_sideB_node_id: RouterEnumB  # type: ignore[valid-type]
-        iptrunk_sideB_ae_iface: str
+        iptrunk_sideB_ae_iface: side_b_ae_iface  # type: ignore[valid-type]
         iptrunk_sideB_ae_geant_a_sid: str
-        iptrunk_sideB_ae_members: AeMembersListB
-        iptrunk_sideB_ae_members_descriptions: AeMembersListB
+        iptrunk_sideB_ae_members: ae_members_side_b  # type: ignore[valid-type]
+        iptrunk_sideB_ae_members_descriptions: AeMembersDescriptionListB
 
     user_input_side_b = yield CreateIptrunkSideBForm
 
-    return initial_user_input.dict() | user_input_side_a.dict() | user_input_side_b.dict()
+    return (
+        initial_user_input.dict()
+        | user_input_side_a.dict()
+        | user_input_side_b.dict()
+        | user_input_router_side_a.dict()
+        | user_input_router_side_b.dict()
+    )
 
 
 @step("Create subscription")
@@ -161,7 +232,7 @@ def provision_ip_trunk_iface_real(subscription: IptrunkProvisioning, process_id:
 
     return {
         "subscription": subscription,
-        "label_text": "[COMMIT] Provisioning a trunk interface, please refresh to get the results of the playbook.",
+        "label_text": "Provisioning a trunk interface, please refresh to get the results of the playbook.",
     }
 
 
@@ -205,6 +276,57 @@ def check_ip_trunk_isis(subscription: IptrunkProvisioning, process_id: UUIDstr,
     }
 
 
+@step("NextBox integration")
+def reserve_interfaces_in_netbox(subscription: IptrunkProvisioning) -> State:
+    """Create the LAG interfaces in NetBox and attach the lag interfaces to the physical interfaces."""
+
+    nbclient = NetBoxClient()
+    for side in range(0, 2):
+        if subscription.iptrunk.iptrunk_sides[side].iptrunk_side_node.router_vendor == RouterVendor.NOKIA:
+            # Create LAG interfaces
+            lag_interface: Interfaces = nbclient.create_interface(
+                iface_name=subscription.iptrunk.iptrunk_sides[side].iptrunk_side_ae_iface,
+                type="lag",
+                device_name=subscription.iptrunk.iptrunk_sides[side].iptrunk_side_node.router_fqdn,
+                description=str(subscription.subscription_id),
+                enabled=True,
+            )
+            # Attach physical interfaces to LAG
+            # Update interface description to subscription ID
+            # Reserve interfaces
+            for interface in subscription.iptrunk.iptrunk_sides[side].iptrunk_side_ae_members:
+                nbclient.attach_interface_to_lag(
+                    device_name=subscription.iptrunk.iptrunk_sides[side].iptrunk_side_node.router_fqdn,
+                    lag_name=lag_interface.name,
+                    iface_name=interface,
+                    description=str(subscription.subscription_id),
+                )
+                nbclient.reserve_interface(
+                    device_name=subscription.iptrunk.iptrunk_sides[side].iptrunk_side_node.router_fqdn,
+                    iface_name=interface,
+                )
+    return {
+        "subscription": subscription,
+        "label_text": "NextBox integration: Reserved interfaces.",
+    }
+
+
+@step("Allocate interfaces in Netbox")
+def allocate_interfaces_in_netbox(subscription: IptrunkProvisioning) -> State:
+    """Allocate the LAG interfaces in NetBox and attach the lag interfaces to the physical interfaces."""
+    for side in range(0, 2):
+        if subscription.iptrunk.iptrunk_sides[side].iptrunk_side_node.router_vendor == RouterVendor.NOKIA:
+            for interface in subscription.iptrunk.iptrunk_sides[side].iptrunk_side_ae_members:
+                NetBoxClient().allocate_interface(
+                    device_name=subscription.iptrunk.iptrunk_sides[side].iptrunk_side_node.router_fqdn,
+                    iface_name=interface,
+                )
+    return {
+        "subscription": subscription,
+        "label_text": "NextBox integration: Allocated interfaces.",
+    }
+
+
 @workflow(
     "Create IP trunk",
     initial_input_form=wrap_create_initial_input_form(initial_input_form_generator),
@@ -217,12 +339,14 @@ def create_iptrunk() -> StepList:
         >> store_process_subscription(Target.CREATE)
         >> initialize_subscription
         >> get_info_from_ipam
+        >> reserve_interfaces_in_netbox
         >> pp_interaction(provision_ip_trunk_iface_dry, 3)
         >> pp_interaction(provision_ip_trunk_iface_real, 3)
         >> pp_interaction(check_ip_trunk_connectivity, 2, False)
         >> pp_interaction(provision_ip_trunk_isis_iface_dry, 3)
         >> pp_interaction(provision_ip_trunk_isis_iface_real, 3)
         >> pp_interaction(check_ip_trunk_isis, 2, False)
+        >> allocate_interfaces_in_netbox
         >> set_status(SubscriptionLifecycle.ACTIVE)
         >> resync
         >> done
diff --git a/gso/workflows/router/create_router.py b/gso/workflows/router/create_router.py
index 2d28c06e64879a28f3a2d031a42e7a3771705675..74d59ad357f23afbefa114d4e1328e0910518b87 100644
--- a/gso/workflows/router/create_router.py
+++ b/gso/workflows/router/create_router.py
@@ -157,9 +157,10 @@ def provision_router_real(subscription: RouterProvisioning, process_id: UUIDstr,
 
 @step("Create NetBox Device")
 def create_netbox_device(subscription: RouterProvisioning) -> State:
-    NetBoxClient().create_device(
-        subscription.router.router_fqdn, subscription.router.router_site.site_tier  # type: ignore
-    )
+    if subscription.router.router_vendor == RouterVendor.NOKIA:
+        NetBoxClient().create_device(
+            subscription.router.router_fqdn, subscription.router.router_site.site_tier  # type: ignore
+        )
 
     return {"subscription": subscription}
 
diff --git a/gso/workflows/router/terminate_router.py b/gso/workflows/router/terminate_router.py
index b02f90cae1f328e148440ffc3f146d29cb1aa198..6c036392da27aa04538e31c1860212a385a7391e 100644
--- a/gso/workflows/router/terminate_router.py
+++ b/gso/workflows/router/terminate_router.py
@@ -9,6 +9,7 @@ from orchestrator.workflow import StepList, conditional, done, init, step, workf
 from orchestrator.workflows.steps import resync, set_status, store_process_subscription, unsync
 from orchestrator.workflows.utils import wrap_modify_initial_input_form
 
+from gso.products.product_blocks.router import RouterVendor
 from gso.products.product_types.router import Router
 from gso.services import infoblox
 from gso.services.netbox_client import NetBoxClient
@@ -61,7 +62,8 @@ def remove_config_from_router() -> None:
 
 @step("Remove Device from NetBox")
 def remove_device_from_netbox(subscription: Router) -> dict[str, Router]:
-    NetBoxClient().delete_device(subscription.router.router_fqdn)
+    if subscription.router.router_vendor == RouterVendor.NOKIA:
+        NetBoxClient().delete_device(subscription.router.router_fqdn)
     return {"subscription": subscription}
 
 
diff --git a/gso/workflows/utils.py b/gso/workflows/utils.py
index 13e637ad6494bbcb74ba79ffaad4eea63d6228ee..3bfa516349d4fe1cf0764c2bf615eacc9734d10f 100644
--- a/gso/workflows/utils.py
+++ b/gso/workflows/utils.py
@@ -1,9 +1,13 @@
 import re
 from ipaddress import IPv4Address
+from uuid import UUID
 
 from orchestrator.forms.validators import Choice
 
+from gso.products.product_blocks.router import RouterVendor
+from gso.products.product_types.router import Router
 from gso.services.crm import all_customers
+from gso.services.netbox_client import NetBoxClient
 
 
 def customer_selector() -> Choice:
@@ -14,6 +18,48 @@ def customer_selector() -> Choice:
     return Choice("Select a customer", zip(customers.keys(), customers.items()))  # type: ignore[arg-type]
 
 
+def available_interfaces_choices(router_id: UUID, speed: str) -> Choice | None:
+    """Return a list of available interfaces for a given router and speed.
+
+    For Nokia routers, return a list of available interfaces.
+    For Juniper routers, return a string.
+    """
+    if Router.from_subscription(router_id).router.router_vendor != RouterVendor.NOKIA:
+        return None
+    interfaces = {
+        interface["name"]: f"{interface['name']} - {interface['module']['display']} - {interface['description']}"
+        for interface in NetBoxClient().get_available_interfaces(router_id, speed)
+    }
+    return Choice("ae member", zip(interfaces.keys(), interfaces.items()))  # type: ignore[arg-type]
+
+
+def available_lags_choices(router_id: UUID) -> Choice | None:
+    """Return a list of available lags for a given router.
+
+    For Nokia routers, return a list of available lags.
+    For Juniper routers, return a string.
+    """
+
+    if Router.from_subscription(router_id).router.router_vendor != RouterVendor.NOKIA:
+        return None
+    side_a_ae_iface_list = NetBoxClient().get_available_lags(router_id)
+    return Choice("ae iface", zip(side_a_ae_iface_list, side_a_ae_iface_list))  # type: ignore[arg-type]
+
+
+def get_router_vendor(router_id: UUID) -> str:
+    """Retrieve the vendor of a router.
+
+    Args:
+    ----
+    router_id (UUID): The {term}`UUID` of the router.
+
+    Returns:
+    -------
+    str: The vendor of the router.
+    """
+    return Router.from_subscription(router_id).router.router_vendor
+
+
 def iso_from_ipv4(ipv4_address: IPv4Address) -> str:
     """Calculate an :term:`ISO` address, based on an IPv4 address.