diff --git a/docs/source/apidocs/gso/gso.api.md b/docs/source/apidocs/gso/gso.api.md
new file mode 100644
index 0000000000000000000000000000000000000000..5ca54030c8a8e55846d167b5703bc3a9142a49b6
--- /dev/null
+++ b/docs/source/apidocs/gso/gso.api.md
@@ -0,0 +1,12 @@
+---
+orphan: true
+---
+
+# {py:mod}`gso.api`
+
+```{py:module} gso.api
+```
+
+```{autodoc2-docstring} gso.api
+:allowtitles:
+```
diff --git a/docs/source/apidocs/gso/gso.api.v1.imports.md b/docs/source/apidocs/gso/gso.api.v1.imports.md
new file mode 100644
index 0000000000000000000000000000000000000000..743d9464dedb26296f0ecaa52ffd8a09c2354108
--- /dev/null
+++ b/docs/source/apidocs/gso/gso.api.v1.imports.md
@@ -0,0 +1,68 @@
+---
+orphan: true
+---
+
+# {py:mod}`gso.api.v1.imports`
+
+```{py:module} gso.api.v1.imports
+```
+
+```{autodoc2-docstring} gso.api.v1.imports
+:allowtitles:
+```
+
+## Module Contents
+
+### Functions
+
+````{list-table}
+:class: autosummary longtable
+:align: left
+
+* - {py:obj}`_start_process <gso.api.v1.imports._start_process>`
+  - ```{autodoc2-docstring} gso.api.v1.imports._start_process
+    :summary:
+    ```
+* - {py:obj}`import_site <gso.api.v1.imports.import_site>`
+  - ```{autodoc2-docstring} gso.api.v1.imports.import_site
+    :summary:
+    ```
+* - {py:obj}`import_router <gso.api.v1.imports.import_router>`
+  - ```{autodoc2-docstring} gso.api.v1.imports.import_router
+    :summary:
+    ```
+* - {py:obj}`import_iptrunk <gso.api.v1.imports.import_iptrunk>`
+  - ```{autodoc2-docstring} gso.api.v1.imports.import_iptrunk
+    :summary:
+    ```
+````
+
+### API
+
+````{py:function} _start_process(process_name: str, data: dict) -> uuid.UUID
+:canonical: gso.api.v1.imports._start_process
+
+```{autodoc2-docstring} gso.api.v1.imports._start_process
+```
+````
+
+````{py:function} import_site(site: gso.schemas.imports.SiteImportModel) -> typing.Dict[str, typing.Any]
+:canonical: gso.api.v1.imports.import_site
+
+```{autodoc2-docstring} gso.api.v1.imports.import_site
+```
+````
+
+````{py:function} import_router(router_data: gso.schemas.imports.RouterImportModel) -> typing.Dict[str, typing.Any]
+:canonical: gso.api.v1.imports.import_router
+
+```{autodoc2-docstring} gso.api.v1.imports.import_router
+```
+````
+
+````{py:function} import_iptrunk(iptrunk_data: gso.schemas.imports.IptrunkImportModel) -> typing.Dict[str, typing.Any]
+:canonical: gso.api.v1.imports.import_iptrunk
+
+```{autodoc2-docstring} gso.api.v1.imports.import_iptrunk
+```
+````
diff --git a/docs/source/apidocs/gso/gso.api.v1.md b/docs/source/apidocs/gso/gso.api.v1.md
new file mode 100644
index 0000000000000000000000000000000000000000..675b9709d0ebc6ebfe96681778dc9552b144827a
--- /dev/null
+++ b/docs/source/apidocs/gso/gso.api.v1.md
@@ -0,0 +1,12 @@
+---
+orphan: true
+---
+
+# {py:mod}`gso.api.v1`
+
+```{py:module} gso.api.v1
+```
+
+```{autodoc2-docstring} gso.api.v1
+:allowtitles:
+```
diff --git a/docs/source/apidocs/gso/gso.cli.import_sites.md b/docs/source/apidocs/gso/gso.cli.import_sites.md
new file mode 100644
index 0000000000000000000000000000000000000000..a0aa4b5ac193273a9a27bf3517dfb60857300d61
--- /dev/null
+++ b/docs/source/apidocs/gso/gso.cli.import_sites.md
@@ -0,0 +1,35 @@
+---
+orphan: true
+---
+
+# {py:mod}`gso.cli.import_sites`
+
+```{py:module} gso.cli.import_sites
+```
+
+```{autodoc2-docstring} gso.cli.import_sites
+:allowtitles:
+```
+
+## Module Contents
+
+### Functions
+
+````{list-table}
+:class: autosummary longtable
+:align: left
+
+* - {py:obj}`import_sites <gso.cli.import_sites.import_sites>`
+  - ```{autodoc2-docstring} gso.cli.import_sites.import_sites
+    :summary:
+    ```
+````
+
+### API
+
+````{py:function} import_sites() -> None
+:canonical: gso.cli.import_sites.import_sites
+
+```{autodoc2-docstring} gso.cli.import_sites.import_sites
+```
+````
diff --git a/docs/source/apidocs/gso/gso.cli.md b/docs/source/apidocs/gso/gso.cli.md
new file mode 100644
index 0000000000000000000000000000000000000000..e05c5c32c79f8451276953c849255b31d616b3ed
--- /dev/null
+++ b/docs/source/apidocs/gso/gso.cli.md
@@ -0,0 +1,12 @@
+---
+orphan: true
+---
+
+# {py:mod}`gso.cli`
+
+```{py:module} gso.cli
+```
+
+```{autodoc2-docstring} gso.cli
+:allowtitles:
+```
diff --git a/docs/source/apidocs/gso/gso.main.md b/docs/source/apidocs/gso/gso.main.md
new file mode 100644
index 0000000000000000000000000000000000000000..7fd1617cf93dd73325bd7afc8e60371ef17d9c87
--- /dev/null
+++ b/docs/source/apidocs/gso/gso.main.md
@@ -0,0 +1,8 @@
+# {py:mod}`gso.main`
+
+```{py:module} gso.main
+```
+
+```{autodoc2-docstring} gso.main
+:allowtitles:
+```
diff --git a/docs/source/apidocs/gso/gso.md b/docs/source/apidocs/gso/gso.md
new file mode 100644
index 0000000000000000000000000000000000000000..adf1cf087206747c83e9229a0795e7077a878118
--- /dev/null
+++ b/docs/source/apidocs/gso/gso.md
@@ -0,0 +1,33 @@
+---
+orphan: true
+---
+
+# {py:mod}`gso`
+
+```{py:module} gso
+```
+
+```{autodoc2-docstring} gso
+:allowtitles:
+```
+
+## Subpackages
+
+```{toctree}
+:titlesonly:
+:maxdepth: 3
+
+gso.products
+gso.workflows
+gso.services
+```
+
+## Submodules
+
+```{toctree}
+:titlesonly:
+:maxdepth: 1
+
+gso.settings
+gso.main
+```
diff --git a/docs/source/apidocs/gso/gso.products.md b/docs/source/apidocs/gso/gso.products.md
new file mode 100644
index 0000000000000000000000000000000000000000..1a78dfebaf6dc87519484bb96e6a69e2894520fe
--- /dev/null
+++ b/docs/source/apidocs/gso/gso.products.md
@@ -0,0 +1,18 @@
+# {py:mod}`gso.products`
+
+```{py:module} gso.products
+```
+
+```{autodoc2-docstring} gso.products
+:allowtitles:
+```
+
+## Subpackages
+
+```{toctree}
+:titlesonly:
+:maxdepth: 3
+
+gso.products.product_blocks
+gso.products.product_types
+```
diff --git a/docs/source/apidocs/gso/gso.products.product_blocks.iptrunk.md b/docs/source/apidocs/gso/gso.products.product_blocks.iptrunk.md
new file mode 100644
index 0000000000000000000000000000000000000000..f09ab7218a5da26c277982dfabb0a08208dba5b9
--- /dev/null
+++ b/docs/source/apidocs/gso/gso.products.product_blocks.iptrunk.md
@@ -0,0 +1,195 @@
+# {py:mod}`gso.products.product_blocks.iptrunk`
+
+```{py:module} gso.products.product_blocks.iptrunk
+```
+
+```{autodoc2-docstring} gso.products.product_blocks.iptrunk
+:allowtitles:
+```
+
+## Module Contents
+
+### Classes
+
+````{list-table}
+:class: autosummary longtable
+:align: left
+
+* - {py:obj}`IptrunkType <gso.products.product_blocks.iptrunk.IptrunkType>`
+  -
+* - {py:obj}`IptrunkSides <gso.products.product_blocks.iptrunk.IptrunkSides>`
+  -
+* - {py:obj}`IptrunkSideBlockInactive <gso.products.product_blocks.iptrunk.IptrunkSideBlockInactive>`
+  -
+* - {py:obj}`IptrunkSideBlockProvisioning <gso.products.product_blocks.iptrunk.IptrunkSideBlockProvisioning>`
+  -
+* - {py:obj}`IptrunkSideBlock <gso.products.product_blocks.iptrunk.IptrunkSideBlock>`
+  -
+* - {py:obj}`IptrunkBlockInactive <gso.products.product_blocks.iptrunk.IptrunkBlockInactive>`
+  - ```{autodoc2-docstring} gso.products.product_blocks.iptrunk.IptrunkBlockInactive
+    :summary:
+    ```
+* - {py:obj}`IptrunkBlockProvisioning <gso.products.product_blocks.iptrunk.IptrunkBlockProvisioning>`
+  - ```{autodoc2-docstring} gso.products.product_blocks.iptrunk.IptrunkBlockProvisioning
+    :summary:
+    ```
+* - {py:obj}`IptrunkBlock <gso.products.product_blocks.iptrunk.IptrunkBlock>`
+  - ```{autodoc2-docstring} gso.products.product_blocks.iptrunk.IptrunkBlock
+    :summary:
+    ```
+````
+
+### API
+
+```{py:class} IptrunkType()
+:canonical: gso.products.product_blocks.iptrunk.IptrunkType
+
+Bases: {py:obj}`orchestrator.types.strEnum`
+
+```
+
+```{py:class} IptrunkSides()
+:canonical: gso.products.product_blocks.iptrunk.IptrunkSides
+
+Bases: {py:obj}`orchestrator.forms.validators.UniqueConstrainedList`\[{py:obj}`gso.products.product_blocks.iptrunk.T`\]
+
+```
+
+```{py:class} IptrunkSideBlockInactive
+:canonical: gso.products.product_blocks.iptrunk.IptrunkSideBlockInactive
+
+Bases: {py:obj}`orchestrator.domain.base.ProductBlockModel`
+
+```
+
+```{py:class} IptrunkSideBlockProvisioning
+:canonical: gso.products.product_blocks.iptrunk.IptrunkSideBlockProvisioning
+
+Bases: {py:obj}`gso.products.product_blocks.iptrunk.IptrunkSideBlockInactive`
+
+```
+
+```{py:class} IptrunkSideBlock
+:canonical: gso.products.product_blocks.iptrunk.IptrunkSideBlock
+
+Bases: {py:obj}`gso.products.product_blocks.iptrunk.IptrunkSideBlockProvisioning`
+
+```
+
+````{py:class} IptrunkBlockInactive
+:canonical: gso.products.product_blocks.iptrunk.IptrunkBlockInactive
+
+Bases: {py:obj}`orchestrator.domain.base.ProductBlockModel`
+
+```{autodoc2-docstring} gso.products.product_blocks.iptrunk.IptrunkBlockInactive
+```
+
+````
+
+````{py:class} IptrunkBlockProvisioning
+:canonical: gso.products.product_blocks.iptrunk.IptrunkBlockProvisioning
+
+Bases: {py:obj}`gso.products.product_blocks.iptrunk.IptrunkBlockInactive`
+
+```{autodoc2-docstring} gso.products.product_blocks.iptrunk.IptrunkBlockProvisioning
+```
+
+````
+
+`````{py:class} IptrunkBlock
+:canonical: gso.products.product_blocks.iptrunk.IptrunkBlock
+
+Bases: {py:obj}`gso.products.product_blocks.iptrunk.IptrunkBlockProvisioning`
+
+```{autodoc2-docstring} gso.products.product_blocks.iptrunk.IptrunkBlock
+```
+
+````{py:attribute} geant_s_sid
+:canonical: gso.products.product_blocks.iptrunk.IptrunkBlock.geant_s_sid
+:type: str
+:value: >
+   None
+
+```{autodoc2-docstring} gso.products.product_blocks.iptrunk.IptrunkBlock.geant_s_sid
+```
+
+````
+
+````{py:attribute} iptrunk_description
+:canonical: gso.products.product_blocks.iptrunk.IptrunkBlock.iptrunk_description
+:type: str
+:value: >
+   None
+
+```{autodoc2-docstring} gso.products.product_blocks.iptrunk.IptrunkBlock.iptrunk_description
+```
+
+````
+
+````{py:attribute} iptrunk_type
+:canonical: gso.products.product_blocks.iptrunk.IptrunkBlock.iptrunk_type
+:type: gso.products.product_blocks.iptrunk.IptrunkType
+:value: >
+   None
+
+```{autodoc2-docstring} gso.products.product_blocks.iptrunk.IptrunkBlock.iptrunk_type
+```
+
+````
+
+````{py:attribute} iptrunk_speed
+:canonical: gso.products.product_blocks.iptrunk.IptrunkBlock.iptrunk_speed
+:type: str
+:value: >
+   None
+
+```{autodoc2-docstring} gso.products.product_blocks.iptrunk.IptrunkBlock.iptrunk_speed
+```
+
+````
+
+````{py:attribute} iptrunk_minimum_links
+:canonical: gso.products.product_blocks.iptrunk.IptrunkBlock.iptrunk_minimum_links
+:type: int
+:value: >
+   None
+
+```{autodoc2-docstring} gso.products.product_blocks.iptrunk.IptrunkBlock.iptrunk_minimum_links
+```
+
+````
+
+````{py:attribute} iptrunk_isis_metric
+:canonical: gso.products.product_blocks.iptrunk.IptrunkBlock.iptrunk_isis_metric
+:type: int
+:value: >
+   None
+
+```{autodoc2-docstring} gso.products.product_blocks.iptrunk.IptrunkBlock.iptrunk_isis_metric
+```
+
+````
+
+````{py:attribute} iptrunk_ipv4_network
+:canonical: gso.products.product_blocks.iptrunk.IptrunkBlock.iptrunk_ipv4_network
+:type: ipaddress.IPv4Network
+:value: >
+   None
+
+```{autodoc2-docstring} gso.products.product_blocks.iptrunk.IptrunkBlock.iptrunk_ipv4_network
+```
+
+````
+
+````{py:attribute} iptrunk_ipv6_network
+:canonical: gso.products.product_blocks.iptrunk.IptrunkBlock.iptrunk_ipv6_network
+:type: ipaddress.IPv6Network
+:value: >
+   None
+
+```{autodoc2-docstring} gso.products.product_blocks.iptrunk.IptrunkBlock.iptrunk_ipv6_network
+```
+
+````
+
+`````
diff --git a/docs/source/apidocs/gso/gso.products.product_blocks.md b/docs/source/apidocs/gso/gso.products.product_blocks.md
new file mode 100644
index 0000000000000000000000000000000000000000..f6cdc93f3e0bef05b2f580ca7e410fdb4fce00e5
--- /dev/null
+++ b/docs/source/apidocs/gso/gso.products.product_blocks.md
@@ -0,0 +1,51 @@
+# {py:mod}`gso.products.product_blocks`
+
+```{py:module} gso.products.product_blocks
+```
+
+```{autodoc2-docstring} gso.products.product_blocks
+:allowtitles:
+```
+
+## Submodules
+
+```{toctree}
+:titlesonly:
+:maxdepth: 1
+
+gso.products.product_blocks.iptrunk
+gso.products.product_blocks.site
+gso.products.product_blocks.router
+```
+
+## Package Contents
+
+### Classes
+
+````{list-table}
+:class: autosummary longtable
+:align: left
+
+* - {py:obj}`PhyPortCapacity <gso.products.product_blocks.PhyPortCapacity>`
+  - ```{autodoc2-docstring} gso.products.product_blocks.PhyPortCapacity
+    :summary:
+    ```
+````
+
+### API
+
+````{py:class} PhyPortCapacity()
+:canonical: gso.products.product_blocks.PhyPortCapacity
+
+Bases: {py:obj}`orchestrator.types.strEnum`
+
+```{autodoc2-docstring} gso.products.product_blocks.PhyPortCapacity
+```
+
+```{rubric} Initialization
+```
+
+```{autodoc2-docstring} gso.products.product_blocks.PhyPortCapacity.__init__
+```
+
+````
diff --git a/docs/source/apidocs/gso/gso.products.product_blocks.router.md b/docs/source/apidocs/gso/gso.products.product_blocks.router.md
new file mode 100644
index 0000000000000000000000000000000000000000..0b1102a5a5417ca07ebcfc600a1998225aa9462b
--- /dev/null
+++ b/docs/source/apidocs/gso/gso.products.product_blocks.router.md
@@ -0,0 +1,245 @@
+# {py:mod}`gso.products.product_blocks.router`
+
+```{py:module} gso.products.product_blocks.router
+```
+
+```{autodoc2-docstring} gso.products.product_blocks.router
+:allowtitles:
+```
+
+## Module Contents
+
+### Classes
+
+````{list-table}
+:class: autosummary longtable
+:align: left
+
+* - {py:obj}`RouterVendor <gso.products.product_blocks.router.RouterVendor>`
+  - ```{autodoc2-docstring} gso.products.product_blocks.router.RouterVendor
+    :summary:
+    ```
+* - {py:obj}`RouterRole <gso.products.product_blocks.router.RouterRole>`
+  - ```{autodoc2-docstring} gso.products.product_blocks.router.RouterRole
+    :summary:
+    ```
+* - {py:obj}`RouterBlockInactive <gso.products.product_blocks.router.RouterBlockInactive>`
+  - ```{autodoc2-docstring} gso.products.product_blocks.router.RouterBlockInactive
+    :summary:
+    ```
+* - {py:obj}`RouterBlockProvisioning <gso.products.product_blocks.router.RouterBlockProvisioning>`
+  - ```{autodoc2-docstring} gso.products.product_blocks.router.RouterBlockProvisioning
+    :summary:
+    ```
+* - {py:obj}`RouterBlock <gso.products.product_blocks.router.RouterBlock>`
+  - ```{autodoc2-docstring} gso.products.product_blocks.router.RouterBlock
+    :summary:
+    ```
+````
+
+### API
+
+````{py:class} RouterVendor()
+:canonical: gso.products.product_blocks.router.RouterVendor
+
+Bases: {py:obj}`orchestrator.types.strEnum`
+
+```{autodoc2-docstring} gso.products.product_blocks.router.RouterVendor
+```
+
+```{rubric} Initialization
+```
+
+```{autodoc2-docstring} gso.products.product_blocks.router.RouterVendor.__init__
+```
+
+````
+
+````{py:class} RouterRole()
+:canonical: gso.products.product_blocks.router.RouterRole
+
+Bases: {py:obj}`orchestrator.types.strEnum`
+
+```{autodoc2-docstring} gso.products.product_blocks.router.RouterRole
+```
+
+```{rubric} Initialization
+```
+
+```{autodoc2-docstring} gso.products.product_blocks.router.RouterRole.__init__
+```
+
+````
+
+````{py:class} RouterBlockInactive
+:canonical: gso.products.product_blocks.router.RouterBlockInactive
+
+Bases: {py:obj}`orchestrator.domain.base.ProductBlockModel`
+
+```{autodoc2-docstring} gso.products.product_blocks.router.RouterBlockInactive
+```
+
+````
+
+````{py:class} RouterBlockProvisioning
+:canonical: gso.products.product_blocks.router.RouterBlockProvisioning
+
+Bases: {py:obj}`gso.products.product_blocks.router.RouterBlockInactive`
+
+```{autodoc2-docstring} gso.products.product_blocks.router.RouterBlockProvisioning
+```
+
+````
+
+`````{py:class} RouterBlock
+:canonical: gso.products.product_blocks.router.RouterBlock
+
+Bases: {py:obj}`gso.products.product_blocks.router.RouterBlockProvisioning`
+
+```{autodoc2-docstring} gso.products.product_blocks.router.RouterBlock
+```
+
+````{py:attribute} router_fqdn
+:canonical: gso.products.product_blocks.router.RouterBlock.router_fqdn
+:type: str
+:value: >
+   None
+
+```{autodoc2-docstring} gso.products.product_blocks.router.RouterBlock.router_fqdn
+```
+
+````
+
+````{py:attribute} router_ts_port
+:canonical: gso.products.product_blocks.router.RouterBlock.router_ts_port
+:type: gso.products.shared.PortNumber
+:value: >
+   None
+
+```{autodoc2-docstring} gso.products.product_blocks.router.RouterBlock.router_ts_port
+```
+
+````
+
+````{py:attribute} router_access_via_ts
+:canonical: gso.products.product_blocks.router.RouterBlock.router_access_via_ts
+:type: bool
+:value: >
+   None
+
+```{autodoc2-docstring} gso.products.product_blocks.router.RouterBlock.router_access_via_ts
+```
+
+````
+
+````{py:attribute} router_lo_ipv4_address
+:canonical: gso.products.product_blocks.router.RouterBlock.router_lo_ipv4_address
+:type: ipaddress.IPv4Address
+:value: >
+   None
+
+```{autodoc2-docstring} gso.products.product_blocks.router.RouterBlock.router_lo_ipv4_address
+```
+
+````
+
+````{py:attribute} router_lo_ipv6_address
+:canonical: gso.products.product_blocks.router.RouterBlock.router_lo_ipv6_address
+:type: ipaddress.IPv6Address
+:value: >
+   None
+
+```{autodoc2-docstring} gso.products.product_blocks.router.RouterBlock.router_lo_ipv6_address
+```
+
+````
+
+````{py:attribute} router_lo_iso_address
+:canonical: gso.products.product_blocks.router.RouterBlock.router_lo_iso_address
+:type: str
+:value: >
+   None
+
+```{autodoc2-docstring} gso.products.product_blocks.router.RouterBlock.router_lo_iso_address
+```
+
+````
+
+````{py:attribute} router_si_ipv4_network
+:canonical: gso.products.product_blocks.router.RouterBlock.router_si_ipv4_network
+:type: typing.Optional[ipaddress.IPv4Network]
+:value: >
+   None
+
+```{autodoc2-docstring} gso.products.product_blocks.router.RouterBlock.router_si_ipv4_network
+```
+
+````
+
+````{py:attribute} router_ias_lt_ipv4_network
+:canonical: gso.products.product_blocks.router.RouterBlock.router_ias_lt_ipv4_network
+:type: typing.Optional[ipaddress.IPv4Network]
+:value: >
+   None
+
+```{autodoc2-docstring} gso.products.product_blocks.router.RouterBlock.router_ias_lt_ipv4_network
+```
+
+````
+
+````{py:attribute} router_ias_lt_ipv6_network
+:canonical: gso.products.product_blocks.router.RouterBlock.router_ias_lt_ipv6_network
+:type: typing.Optional[ipaddress.IPv6Network]
+:value: >
+   None
+
+```{autodoc2-docstring} gso.products.product_blocks.router.RouterBlock.router_ias_lt_ipv6_network
+```
+
+````
+
+````{py:attribute} router_vendor
+:canonical: gso.products.product_blocks.router.RouterBlock.router_vendor
+:type: gso.products.product_blocks.router.RouterVendor
+:value: >
+   None
+
+```{autodoc2-docstring} gso.products.product_blocks.router.RouterBlock.router_vendor
+```
+
+````
+
+````{py:attribute} router_role
+:canonical: gso.products.product_blocks.router.RouterBlock.router_role
+:type: gso.products.product_blocks.router.RouterRole
+:value: >
+   None
+
+```{autodoc2-docstring} gso.products.product_blocks.router.RouterBlock.router_role
+```
+
+````
+
+````{py:attribute} router_site
+:canonical: gso.products.product_blocks.router.RouterBlock.router_site
+:type: gso.products.product_blocks.site.SiteBlock
+:value: >
+   None
+
+```{autodoc2-docstring} gso.products.product_blocks.router.RouterBlock.router_site
+```
+
+````
+
+````{py:attribute} router_is_ias_connected
+:canonical: gso.products.product_blocks.router.RouterBlock.router_is_ias_connected
+:type: bool
+:value: >
+   None
+
+```{autodoc2-docstring} gso.products.product_blocks.router.RouterBlock.router_is_ias_connected
+```
+
+````
+
+`````
diff --git a/docs/source/apidocs/gso/gso.products.product_blocks.site.md b/docs/source/apidocs/gso/gso.products.product_blocks.site.md
new file mode 100644
index 0000000000000000000000000000000000000000..8d8a36a23267738f06b3d359242563004ed7095e
--- /dev/null
+++ b/docs/source/apidocs/gso/gso.products.product_blocks.site.md
@@ -0,0 +1,192 @@
+# {py:mod}`gso.products.product_blocks.site`
+
+```{py:module} gso.products.product_blocks.site
+```
+
+```{autodoc2-docstring} gso.products.product_blocks.site
+:allowtitles:
+```
+
+## Module Contents
+
+### Classes
+
+````{list-table}
+:class: autosummary longtable
+:align: left
+
+* - {py:obj}`SiteTier <gso.products.product_blocks.site.SiteTier>`
+  - ```{autodoc2-docstring} gso.products.product_blocks.site.SiteTier
+    :summary:
+    ```
+* - {py:obj}`SiteBlockInactive <gso.products.product_blocks.site.SiteBlockInactive>`
+  - ```{autodoc2-docstring} gso.products.product_blocks.site.SiteBlockInactive
+    :summary:
+    ```
+* - {py:obj}`SiteBlockProvisioning <gso.products.product_blocks.site.SiteBlockProvisioning>`
+  - ```{autodoc2-docstring} gso.products.product_blocks.site.SiteBlockProvisioning
+    :summary:
+    ```
+* - {py:obj}`SiteBlock <gso.products.product_blocks.site.SiteBlock>`
+  - ```{autodoc2-docstring} gso.products.product_blocks.site.SiteBlock
+    :summary:
+    ```
+````
+
+### API
+
+````{py:class} SiteTier()
+:canonical: gso.products.product_blocks.site.SiteTier
+
+Bases: {py:obj}`orchestrator.types.strEnum`
+
+```{autodoc2-docstring} gso.products.product_blocks.site.SiteTier
+```
+
+```{rubric} Initialization
+```
+
+```{autodoc2-docstring} gso.products.product_blocks.site.SiteTier.__init__
+```
+
+````
+
+````{py:class} SiteBlockInactive
+:canonical: gso.products.product_blocks.site.SiteBlockInactive
+
+Bases: {py:obj}`orchestrator.domain.base.ProductBlockModel`
+
+```{autodoc2-docstring} gso.products.product_blocks.site.SiteBlockInactive
+```
+
+````
+
+````{py:class} SiteBlockProvisioning
+:canonical: gso.products.product_blocks.site.SiteBlockProvisioning
+
+Bases: {py:obj}`gso.products.product_blocks.site.SiteBlockInactive`
+
+```{autodoc2-docstring} gso.products.product_blocks.site.SiteBlockProvisioning
+```
+
+````
+
+`````{py:class} SiteBlock
+:canonical: gso.products.product_blocks.site.SiteBlock
+
+Bases: {py:obj}`gso.products.product_blocks.site.SiteBlockProvisioning`
+
+```{autodoc2-docstring} gso.products.product_blocks.site.SiteBlock
+```
+
+````{py:attribute} site_name
+:canonical: gso.products.product_blocks.site.SiteBlock.site_name
+:type: str
+:value: >
+   None
+
+```{autodoc2-docstring} gso.products.product_blocks.site.SiteBlock.site_name
+```
+
+````
+
+````{py:attribute} site_city
+:canonical: gso.products.product_blocks.site.SiteBlock.site_city
+:type: str
+:value: >
+   None
+
+```{autodoc2-docstring} gso.products.product_blocks.site.SiteBlock.site_city
+```
+
+````
+
+````{py:attribute} site_country
+:canonical: gso.products.product_blocks.site.SiteBlock.site_country
+:type: str
+:value: >
+   None
+
+```{autodoc2-docstring} gso.products.product_blocks.site.SiteBlock.site_country
+```
+
+````
+
+````{py:attribute} site_country_code
+:canonical: gso.products.product_blocks.site.SiteBlock.site_country_code
+:type: str
+:value: >
+   None
+
+```{autodoc2-docstring} gso.products.product_blocks.site.SiteBlock.site_country_code
+```
+
+````
+
+````{py:attribute} site_latitude
+:canonical: gso.products.product_blocks.site.SiteBlock.site_latitude
+:type: gso.schemas.types.LatitudeCoordinate
+:value: >
+   None
+
+```{autodoc2-docstring} gso.products.product_blocks.site.SiteBlock.site_latitude
+```
+
+````
+
+````{py:attribute} site_longitude
+:canonical: gso.products.product_blocks.site.SiteBlock.site_longitude
+:type: gso.schemas.types.LongitudeCoordinate
+:value: >
+   None
+
+```{autodoc2-docstring} gso.products.product_blocks.site.SiteBlock.site_longitude
+```
+
+````
+
+````{py:attribute} site_internal_id
+:canonical: gso.products.product_blocks.site.SiteBlock.site_internal_id
+:type: int
+:value: >
+   None
+
+```{autodoc2-docstring} gso.products.product_blocks.site.SiteBlock.site_internal_id
+```
+
+````
+
+````{py:attribute} site_bgp_community_id
+:canonical: gso.products.product_blocks.site.SiteBlock.site_bgp_community_id
+:type: int
+:value: >
+   None
+
+```{autodoc2-docstring} gso.products.product_blocks.site.SiteBlock.site_bgp_community_id
+```
+
+````
+
+````{py:attribute} site_tier
+:canonical: gso.products.product_blocks.site.SiteBlock.site_tier
+:type: gso.products.product_blocks.site.SiteTier
+:value: >
+   None
+
+```{autodoc2-docstring} gso.products.product_blocks.site.SiteBlock.site_tier
+```
+
+````
+
+````{py:attribute} site_ts_address
+:canonical: gso.products.product_blocks.site.SiteBlock.site_ts_address
+:type: typing.Optional[str]
+:value: >
+   None
+
+```{autodoc2-docstring} gso.products.product_blocks.site.SiteBlock.site_ts_address
+```
+
+````
+
+`````
diff --git a/docs/source/apidocs/gso/gso.products.product_types.iptrunk.md b/docs/source/apidocs/gso/gso.products.product_types.iptrunk.md
new file mode 100644
index 0000000000000000000000000000000000000000..18fb0d1c90070c1924dbe52f4b3471a6d0ebe06a
--- /dev/null
+++ b/docs/source/apidocs/gso/gso.products.product_types.iptrunk.md
@@ -0,0 +1,51 @@
+---
+orphan: true
+---
+
+# {py:mod}`gso.products.product_types.iptrunk`
+
+```{py:module} gso.products.product_types.iptrunk
+```
+
+```{autodoc2-docstring} gso.products.product_types.iptrunk
+:allowtitles:
+```
+
+## Module Contents
+
+### Classes
+
+````{list-table}
+:class: autosummary longtable
+:align: left
+
+* - {py:obj}`IptrunkInactive <gso.products.product_types.iptrunk.IptrunkInactive>`
+  -
+* - {py:obj}`IptrunkProvisioning <gso.products.product_types.iptrunk.IptrunkProvisioning>`
+  -
+* - {py:obj}`Iptrunk <gso.products.product_types.iptrunk.Iptrunk>`
+  -
+````
+
+### API
+
+```{py:class} IptrunkInactive
+:canonical: gso.products.product_types.iptrunk.IptrunkInactive
+
+Bases: {py:obj}`orchestrator.domain.base.SubscriptionModel`
+
+```
+
+```{py:class} IptrunkProvisioning
+:canonical: gso.products.product_types.iptrunk.IptrunkProvisioning
+
+Bases: {py:obj}`gso.products.product_types.iptrunk.IptrunkInactive`
+
+```
+
+```{py:class} Iptrunk
+:canonical: gso.products.product_types.iptrunk.Iptrunk
+
+Bases: {py:obj}`gso.products.product_types.iptrunk.IptrunkProvisioning`
+
+```
diff --git a/docs/source/apidocs/gso/gso.products.product_types.md b/docs/source/apidocs/gso/gso.products.product_types.md
new file mode 100644
index 0000000000000000000000000000000000000000..ce9c4719242d11c150e1ec6011eaf8a509a41f8f
--- /dev/null
+++ b/docs/source/apidocs/gso/gso.products.product_types.md
@@ -0,0 +1,8 @@
+# {py:mod}`gso.products.product_types`
+
+```{py:module} gso.products.product_types
+```
+
+```{autodoc2-docstring} gso.products.product_types
+:allowtitles:
+```
diff --git a/docs/source/apidocs/gso/gso.products.product_types.router.md b/docs/source/apidocs/gso/gso.products.product_types.router.md
new file mode 100644
index 0000000000000000000000000000000000000000..55f0553d3c5692d2bc6df8663a1575f49c26c2a9
--- /dev/null
+++ b/docs/source/apidocs/gso/gso.products.product_types.router.md
@@ -0,0 +1,51 @@
+---
+orphan: true
+---
+
+# {py:mod}`gso.products.product_types.router`
+
+```{py:module} gso.products.product_types.router
+```
+
+```{autodoc2-docstring} gso.products.product_types.router
+:allowtitles:
+```
+
+## Module Contents
+
+### Classes
+
+````{list-table}
+:class: autosummary longtable
+:align: left
+
+* - {py:obj}`RouterInactive <gso.products.product_types.router.RouterInactive>`
+  -
+* - {py:obj}`RouterProvisioning <gso.products.product_types.router.RouterProvisioning>`
+  -
+* - {py:obj}`Router <gso.products.product_types.router.Router>`
+  -
+````
+
+### API
+
+```{py:class} RouterInactive
+:canonical: gso.products.product_types.router.RouterInactive
+
+Bases: {py:obj}`orchestrator.domain.base.SubscriptionModel`
+
+```
+
+```{py:class} RouterProvisioning
+:canonical: gso.products.product_types.router.RouterProvisioning
+
+Bases: {py:obj}`gso.products.product_types.router.RouterInactive`
+
+```
+
+```{py:class} Router
+:canonical: gso.products.product_types.router.Router
+
+Bases: {py:obj}`gso.products.product_types.router.RouterProvisioning`
+
+```
diff --git a/docs/source/apidocs/gso/gso.products.product_types.site.md b/docs/source/apidocs/gso/gso.products.product_types.site.md
new file mode 100644
index 0000000000000000000000000000000000000000..07ee9eb5988080c4ddad2dc2f9c922eaf071a2d3
--- /dev/null
+++ b/docs/source/apidocs/gso/gso.products.product_types.site.md
@@ -0,0 +1,51 @@
+---
+orphan: true
+---
+
+# {py:mod}`gso.products.product_types.site`
+
+```{py:module} gso.products.product_types.site
+```
+
+```{autodoc2-docstring} gso.products.product_types.site
+:allowtitles:
+```
+
+## Module Contents
+
+### Classes
+
+````{list-table}
+:class: autosummary longtable
+:align: left
+
+* - {py:obj}`SiteInactive <gso.products.product_types.site.SiteInactive>`
+  -
+* - {py:obj}`SiteProvisioning <gso.products.product_types.site.SiteProvisioning>`
+  -
+* - {py:obj}`Site <gso.products.product_types.site.Site>`
+  -
+````
+
+### API
+
+```{py:class} SiteInactive
+:canonical: gso.products.product_types.site.SiteInactive
+
+Bases: {py:obj}`orchestrator.domain.base.SubscriptionModel`
+
+```
+
+```{py:class} SiteProvisioning
+:canonical: gso.products.product_types.site.SiteProvisioning
+
+Bases: {py:obj}`gso.products.product_types.site.SiteInactive`
+
+```
+
+```{py:class} Site
+:canonical: gso.products.product_types.site.Site
+
+Bases: {py:obj}`gso.products.product_types.site.SiteProvisioning`
+
+```
diff --git a/docs/source/apidocs/gso/gso.products.shared.md b/docs/source/apidocs/gso/gso.products.shared.md
new file mode 100644
index 0000000000000000000000000000000000000000..dde17d324293bc87d33137d085991c916645b993
--- /dev/null
+++ b/docs/source/apidocs/gso/gso.products.shared.md
@@ -0,0 +1,38 @@
+---
+orphan: true
+---
+
+# {py:mod}`gso.products.shared`
+
+```{py:module} gso.products.shared
+```
+
+```{autodoc2-docstring} gso.products.shared
+:allowtitles:
+```
+
+## Module Contents
+
+### Classes
+
+````{list-table}
+:class: autosummary longtable
+:align: left
+
+* - {py:obj}`PortNumber <gso.products.shared.PortNumber>`
+  - ```{autodoc2-docstring} gso.products.shared.PortNumber
+    :summary:
+    ```
+````
+
+### API
+
+````{py:class} PortNumber
+:canonical: gso.products.shared.PortNumber
+
+Bases: {py:obj}`pydantic.ConstrainedInt`
+
+```{autodoc2-docstring} gso.products.shared.PortNumber
+```
+
+````
diff --git a/docs/source/apidocs/gso/gso.schemas.enums.md b/docs/source/apidocs/gso/gso.schemas.enums.md
new file mode 100644
index 0000000000000000000000000000000000000000..5812c3583af1aedbdfbd3b8fa17b8ed0ebf15930
--- /dev/null
+++ b/docs/source/apidocs/gso/gso.schemas.enums.md
@@ -0,0 +1,42 @@
+---
+orphan: true
+---
+
+# {py:mod}`gso.schemas.enums`
+
+```{py:module} gso.schemas.enums
+```
+
+```{autodoc2-docstring} gso.schemas.enums
+:allowtitles:
+```
+
+## Module Contents
+
+### Classes
+
+````{list-table}
+:class: autosummary longtable
+:align: left
+
+* - {py:obj}`ProductType <gso.schemas.enums.ProductType>`
+  -
+* - {py:obj}`SubscriptionStatus <gso.schemas.enums.SubscriptionStatus>`
+  -
+````
+
+### API
+
+```{py:class} ProductType()
+:canonical: gso.schemas.enums.ProductType
+
+Bases: {py:obj}`orchestrator.types.strEnum`
+
+```
+
+```{py:class} SubscriptionStatus()
+:canonical: gso.schemas.enums.SubscriptionStatus
+
+Bases: {py:obj}`orchestrator.types.strEnum`
+
+```
diff --git a/docs/source/apidocs/gso/gso.schemas.imports.md b/docs/source/apidocs/gso/gso.schemas.imports.md
new file mode 100644
index 0000000000000000000000000000000000000000..24df6922cf8e50b98f8646803c68daacd7ccf9f1
--- /dev/null
+++ b/docs/source/apidocs/gso/gso.schemas.imports.md
@@ -0,0 +1,12 @@
+---
+orphan: true
+---
+
+# {py:mod}`gso.schemas.imports`
+
+```{py:module} gso.schemas.imports
+```
+
+```{autodoc2-docstring} gso.schemas.imports
+:allowtitles:
+```
diff --git a/docs/source/apidocs/gso/gso.schemas.md b/docs/source/apidocs/gso/gso.schemas.md
new file mode 100644
index 0000000000000000000000000000000000000000..671959e0e7133c08ee929c19822cacf6fd36e821
--- /dev/null
+++ b/docs/source/apidocs/gso/gso.schemas.md
@@ -0,0 +1,12 @@
+---
+orphan: true
+---
+
+# {py:mod}`gso.schemas`
+
+```{py:module} gso.schemas
+```
+
+```{autodoc2-docstring} gso.schemas
+:allowtitles:
+```
diff --git a/docs/source/apidocs/gso/gso.schemas.types.md b/docs/source/apidocs/gso/gso.schemas.types.md
new file mode 100644
index 0000000000000000000000000000000000000000..f6ffb00b74d6593553d0623a43d82ba30e267ce6
--- /dev/null
+++ b/docs/source/apidocs/gso/gso.schemas.types.md
@@ -0,0 +1,52 @@
+---
+orphan: true
+---
+
+# {py:mod}`gso.schemas.types`
+
+```{py:module} gso.schemas.types
+```
+
+```{autodoc2-docstring} gso.schemas.types
+:allowtitles:
+```
+
+## Module Contents
+
+### Classes
+
+````{list-table}
+:class: autosummary longtable
+:align: left
+
+* - {py:obj}`LatitudeCoordinate <gso.schemas.types.LatitudeCoordinate>`
+  - ```{autodoc2-docstring} gso.schemas.types.LatitudeCoordinate
+    :summary:
+    ```
+* - {py:obj}`LongitudeCoordinate <gso.schemas.types.LongitudeCoordinate>`
+  - ```{autodoc2-docstring} gso.schemas.types.LongitudeCoordinate
+    :summary:
+    ```
+````
+
+### API
+
+````{py:class} LatitudeCoordinate
+:canonical: gso.schemas.types.LatitudeCoordinate
+
+Bases: {py:obj}`pydantic.ConstrainedStr`
+
+```{autodoc2-docstring} gso.schemas.types.LatitudeCoordinate
+```
+
+````
+
+````{py:class} LongitudeCoordinate
+:canonical: gso.schemas.types.LongitudeCoordinate
+
+Bases: {py:obj}`pydantic.ConstrainedStr`
+
+```{autodoc2-docstring} gso.schemas.types.LongitudeCoordinate
+```
+
+````
diff --git a/docs/source/apidocs/gso/gso.services.crm.md b/docs/source/apidocs/gso/gso.services.crm.md
new file mode 100644
index 0000000000000000000000000000000000000000..6ed01e5b2ee48c6f52ff70bd9eb85c6d0100ba51
--- /dev/null
+++ b/docs/source/apidocs/gso/gso.services.crm.md
@@ -0,0 +1,32 @@
+---
+orphan: true
+---
+
+# {py:mod}`gso.services.crm`
+
+```{py:module} gso.services.crm
+```
+
+```{autodoc2-docstring} gso.services.crm
+:allowtitles:
+```
+
+## Module Contents
+
+### API
+
+````{py:exception} CustomerNotFoundError()
+:canonical: gso.services.crm.CustomerNotFoundError
+
+Bases: {py:obj}`Exception`
+
+```{autodoc2-docstring} gso.services.crm.CustomerNotFoundError
+```
+
+```{rubric} Initialization
+```
+
+```{autodoc2-docstring} gso.services.crm.CustomerNotFoundError.__init__
+```
+
+````
diff --git a/docs/source/apidocs/gso/gso.services.infoblox.md b/docs/source/apidocs/gso/gso.services.infoblox.md
new file mode 100644
index 0000000000000000000000000000000000000000..0d99dfcfbf2436ea5a8ed8a4ad766cb0b835c083
--- /dev/null
+++ b/docs/source/apidocs/gso/gso.services.infoblox.md
@@ -0,0 +1,170 @@
+---
+orphan: true
+---
+
+# {py:mod}`gso.services.infoblox`
+
+```{py:module} gso.services.infoblox
+```
+
+```{autodoc2-docstring} gso.services.infoblox
+:allowtitles:
+```
+
+## Module Contents
+
+### Functions
+
+````{list-table}
+:class: autosummary longtable
+:align: left
+
+* - {py:obj}`_setup_connection <gso.services.infoblox._setup_connection>`
+  - ```{autodoc2-docstring} gso.services.infoblox._setup_connection
+    :summary:
+    ```
+* - {py:obj}`_allocate_network <gso.services.infoblox._allocate_network>`
+  - ```{autodoc2-docstring} gso.services.infoblox._allocate_network
+    :summary:
+    ```
+* - {py:obj}`hostname_available <gso.services.infoblox.hostname_available>`
+  - ```{autodoc2-docstring} gso.services.infoblox.hostname_available
+    :summary:
+    ```
+* - {py:obj}`allocate_v4_network <gso.services.infoblox.allocate_v4_network>`
+  - ```{autodoc2-docstring} gso.services.infoblox.allocate_v4_network
+    :summary:
+    ```
+* - {py:obj}`allocate_v6_network <gso.services.infoblox.allocate_v6_network>`
+  - ```{autodoc2-docstring} gso.services.infoblox.allocate_v6_network
+    :summary:
+    ```
+* - {py:obj}`find_network_by_cidr <gso.services.infoblox.find_network_by_cidr>`
+  - ```{autodoc2-docstring} gso.services.infoblox.find_network_by_cidr
+    :summary:
+    ```
+* - {py:obj}`delete_network <gso.services.infoblox.delete_network>`
+  - ```{autodoc2-docstring} gso.services.infoblox.delete_network
+    :summary:
+    ```
+* - {py:obj}`allocate_host <gso.services.infoblox.allocate_host>`
+  - ```{autodoc2-docstring} gso.services.infoblox.allocate_host
+    :summary:
+    ```
+* - {py:obj}`find_host_by_ip <gso.services.infoblox.find_host_by_ip>`
+  - ```{autodoc2-docstring} gso.services.infoblox.find_host_by_ip
+    :summary:
+    ```
+* - {py:obj}`find_host_by_fqdn <gso.services.infoblox.find_host_by_fqdn>`
+  - ```{autodoc2-docstring} gso.services.infoblox.find_host_by_fqdn
+    :summary:
+    ```
+* - {py:obj}`delete_host_by_ip <gso.services.infoblox.delete_host_by_ip>`
+  - ```{autodoc2-docstring} gso.services.infoblox.delete_host_by_ip
+    :summary:
+    ```
+* - {py:obj}`delete_host_by_fqdn <gso.services.infoblox.delete_host_by_fqdn>`
+  - ```{autodoc2-docstring} gso.services.infoblox.delete_host_by_fqdn
+    :summary:
+    ```
+````
+
+### API
+
+```{py:exception} AllocationError()
+:canonical: gso.services.infoblox.AllocationError
+
+Bases: {py:obj}`Exception`
+
+```
+
+```{py:exception} DeletionError()
+:canonical: gso.services.infoblox.DeletionError
+
+Bases: {py:obj}`Exception`
+
+```
+
+````{py:function} _setup_connection() -> tuple[infoblox_client.connector.Connector, gso.settings.IPAMParams]
+:canonical: gso.services.infoblox._setup_connection
+
+```{autodoc2-docstring} gso.services.infoblox._setup_connection
+```
+````
+
+````{py:function} _allocate_network(conn: infoblox_client.connector.Connector, dns_view: str, netmask: int, containers: list[str], comment: str | None = '') -> ipaddress.IPv4Network | ipaddress.IPv6Network
+:canonical: gso.services.infoblox._allocate_network
+
+```{autodoc2-docstring} gso.services.infoblox._allocate_network
+```
+````
+
+````{py:function} hostname_available(hostname: str) -> bool
+:canonical: gso.services.infoblox.hostname_available
+
+```{autodoc2-docstring} gso.services.infoblox.hostname_available
+```
+````
+
+````{py:function} allocate_v4_network(service_type: str, comment: str | None = '') -> ipaddress.IPv4Network
+:canonical: gso.services.infoblox.allocate_v4_network
+
+```{autodoc2-docstring} gso.services.infoblox.allocate_v4_network
+```
+````
+
+````{py:function} allocate_v6_network(service_type: str, comment: str | None = '') -> ipaddress.IPv6Network
+:canonical: gso.services.infoblox.allocate_v6_network
+
+```{autodoc2-docstring} gso.services.infoblox.allocate_v6_network
+```
+````
+
+````{py:function} find_network_by_cidr(ip_network: ipaddress.IPv4Network | ipaddress.IPv6Network) -> infoblox_client.objects.Network | None
+:canonical: gso.services.infoblox.find_network_by_cidr
+
+```{autodoc2-docstring} gso.services.infoblox.find_network_by_cidr
+```
+````
+
+````{py:function} delete_network(ip_network: ipaddress.IPv4Network | ipaddress.IPv6Network) -> None
+:canonical: gso.services.infoblox.delete_network
+
+```{autodoc2-docstring} gso.services.infoblox.delete_network
+```
+````
+
+````{py:function} allocate_host(hostname: str, service_type: str, cname_aliases: list[str], comment: str) -> tuple[ipaddress.IPv4Address, ipaddress.IPv6Address]
+:canonical: gso.services.infoblox.allocate_host
+
+```{autodoc2-docstring} gso.services.infoblox.allocate_host
+```
+````
+
+````{py:function} find_host_by_ip(ip_addr: ipaddress.IPv4Address | ipaddress.IPv6Address) -> infoblox_client.objects.HostRecord | None
+:canonical: gso.services.infoblox.find_host_by_ip
+
+```{autodoc2-docstring} gso.services.infoblox.find_host_by_ip
+```
+````
+
+````{py:function} find_host_by_fqdn(fqdn: str) -> infoblox_client.objects.HostRecord | None
+:canonical: gso.services.infoblox.find_host_by_fqdn
+
+```{autodoc2-docstring} gso.services.infoblox.find_host_by_fqdn
+```
+````
+
+````{py:function} delete_host_by_ip(ip_addr: ipaddress.IPv4Address | ipaddress.IPv6Address) -> None
+:canonical: gso.services.infoblox.delete_host_by_ip
+
+```{autodoc2-docstring} gso.services.infoblox.delete_host_by_ip
+```
+````
+
+````{py:function} delete_host_by_fqdn(fqdn: str) -> None
+:canonical: gso.services.infoblox.delete_host_by_fqdn
+
+```{autodoc2-docstring} gso.services.infoblox.delete_host_by_fqdn
+```
+````
diff --git a/docs/source/apidocs/gso/gso.services.md b/docs/source/apidocs/gso/gso.services.md
new file mode 100644
index 0000000000000000000000000000000000000000..90595521396e48dcf954db40e3c41be14977d209
--- /dev/null
+++ b/docs/source/apidocs/gso/gso.services.md
@@ -0,0 +1,17 @@
+# {py:mod}`gso.services`
+
+```{py:module} gso.services
+```
+
+```{autodoc2-docstring} gso.services
+:allowtitles:
+```
+
+## Submodules
+
+```{toctree}
+:titlesonly:
+:maxdepth: 1
+
+gso.services.provisioning_proxy
+```
diff --git a/docs/source/apidocs/gso/gso.services.provisioning_proxy.md b/docs/source/apidocs/gso/gso.services.provisioning_proxy.md
new file mode 100644
index 0000000000000000000000000000000000000000..197681bed0cb06eb2b720a8834cb8b45d868aee5
--- /dev/null
+++ b/docs/source/apidocs/gso/gso.services.provisioning_proxy.md
@@ -0,0 +1,180 @@
+# {py:mod}`gso.services.provisioning_proxy`
+
+```{py:module} gso.services.provisioning_proxy
+```
+
+```{autodoc2-docstring} gso.services.provisioning_proxy
+:allowtitles:
+```
+
+## Module Contents
+
+### Classes
+
+````{list-table}
+:class: autosummary longtable
+:align: left
+
+* - {py:obj}`CUDOperation <gso.services.provisioning_proxy.CUDOperation>`
+  - ```{autodoc2-docstring} gso.services.provisioning_proxy.CUDOperation
+    :summary:
+    ```
+````
+
+### Functions
+
+````{list-table}
+:class: autosummary longtable
+:align: left
+
+* - {py:obj}`_send_request <gso.services.provisioning_proxy._send_request>`
+  - ```{autodoc2-docstring} gso.services.provisioning_proxy._send_request
+    :summary:
+    ```
+* - {py:obj}`provision_router <gso.services.provisioning_proxy.provision_router>`
+  - ```{autodoc2-docstring} gso.services.provisioning_proxy.provision_router
+    :summary:
+    ```
+* - {py:obj}`provision_ip_trunk <gso.services.provisioning_proxy.provision_ip_trunk>`
+  - ```{autodoc2-docstring} gso.services.provisioning_proxy.provision_ip_trunk
+    :summary:
+    ```
+* - {py:obj}`check_ip_trunk <gso.services.provisioning_proxy.check_ip_trunk>`
+  - ```{autodoc2-docstring} gso.services.provisioning_proxy.check_ip_trunk
+    :summary:
+    ```
+* - {py:obj}`deprovision_ip_trunk <gso.services.provisioning_proxy.deprovision_ip_trunk>`
+  - ```{autodoc2-docstring} gso.services.provisioning_proxy.deprovision_ip_trunk
+    :summary:
+    ```
+* - {py:obj}`migrate_ip_trunk <gso.services.provisioning_proxy.migrate_ip_trunk>`
+  - ```{autodoc2-docstring} gso.services.provisioning_proxy.migrate_ip_trunk
+    :summary:
+    ```
+* - {py:obj}`_await_pp_results <gso.services.provisioning_proxy._await_pp_results>`
+  - ```{autodoc2-docstring} gso.services.provisioning_proxy._await_pp_results
+    :summary:
+    ```
+* - {py:obj}`_reset_pp_success_state <gso.services.provisioning_proxy._reset_pp_success_state>`
+  - ```{autodoc2-docstring} gso.services.provisioning_proxy._reset_pp_success_state
+    :summary:
+    ```
+* - {py:obj}`_confirm_pp_results <gso.services.provisioning_proxy._confirm_pp_results>`
+  - ```{autodoc2-docstring} gso.services.provisioning_proxy._confirm_pp_results
+    :summary:
+    ```
+* - {py:obj}`pp_interaction <gso.services.provisioning_proxy.pp_interaction>`
+  - ```{autodoc2-docstring} gso.services.provisioning_proxy.pp_interaction
+    :summary:
+    ```
+````
+
+### Data
+
+````{list-table}
+:class: autosummary longtable
+:align: left
+
+* - {py:obj}`DEFAULT_LABEL <gso.services.provisioning_proxy.DEFAULT_LABEL>`
+  - ```{autodoc2-docstring} gso.services.provisioning_proxy.DEFAULT_LABEL
+    :summary:
+    ```
+````
+
+### API
+
+````{py:data} DEFAULT_LABEL
+:canonical: gso.services.provisioning_proxy.DEFAULT_LABEL
+:value: >
+   'Provisioning proxy is running. Please come back later for the results.'
+
+```{autodoc2-docstring} gso.services.provisioning_proxy.DEFAULT_LABEL
+```
+
+````
+
+````{py:class} CUDOperation()
+:canonical: gso.services.provisioning_proxy.CUDOperation
+
+Bases: {py:obj}`orchestrator.types.strEnum`
+
+```{autodoc2-docstring} gso.services.provisioning_proxy.CUDOperation
+```
+
+```{rubric} Initialization
+```
+
+```{autodoc2-docstring} gso.services.provisioning_proxy.CUDOperation.__init__
+```
+
+````
+
+````{py:function} _send_request(endpoint: str, parameters: dict, process_id: orchestrator.types.UUIDstr, operation: gso.services.provisioning_proxy.CUDOperation) -> None
+:canonical: gso.services.provisioning_proxy._send_request
+
+```{autodoc2-docstring} gso.services.provisioning_proxy._send_request
+```
+````
+
+````{py:function} provision_router(subscription: gso.products.product_types.router.RouterProvisioning, process_id: orchestrator.types.UUIDstr, tt_number: str, dry_run: bool = True) -> None
+:canonical: gso.services.provisioning_proxy.provision_router
+
+```{autodoc2-docstring} gso.services.provisioning_proxy.provision_router
+```
+````
+
+````{py:function} provision_ip_trunk(subscription: gso.products.product_types.iptrunk.IptrunkProvisioning, process_id: orchestrator.types.UUIDstr, tt_number: str, config_object: str, dry_run: bool = True) -> None
+:canonical: gso.services.provisioning_proxy.provision_ip_trunk
+
+```{autodoc2-docstring} gso.services.provisioning_proxy.provision_ip_trunk
+```
+````
+
+````{py:function} check_ip_trunk(subscription: gso.products.product_types.iptrunk.IptrunkProvisioning, process_id: orchestrator.types.UUIDstr, tt_number: str, check_name: str) -> None
+:canonical: gso.services.provisioning_proxy.check_ip_trunk
+
+```{autodoc2-docstring} gso.services.provisioning_proxy.check_ip_trunk
+```
+````
+
+````{py:function} deprovision_ip_trunk(subscription: gso.products.product_types.iptrunk.Iptrunk, process_id: orchestrator.types.UUIDstr, tt_number: str, dry_run: bool = True) -> None
+:canonical: gso.services.provisioning_proxy.deprovision_ip_trunk
+
+```{autodoc2-docstring} gso.services.provisioning_proxy.deprovision_ip_trunk
+```
+````
+
+````{py:function} migrate_ip_trunk(subscription: gso.products.product_types.iptrunk.Iptrunk, new_node: gso.products.product_types.router.Router, new_lag_interface: str, new_lag_member_interfaces: list[str], replace_index: int, process_id: orchestrator.types.UUIDstr, tt_number: str, verb: str, config_object: str, dry_run: bool = True) -> None
+:canonical: gso.services.provisioning_proxy.migrate_ip_trunk
+
+```{autodoc2-docstring} gso.services.provisioning_proxy.migrate_ip_trunk
+```
+````
+
+````{py:function} _await_pp_results(subscription: orchestrator.domain.SubscriptionModel, label_text: str = DEFAULT_LABEL) -> orchestrator.types.FormGenerator
+:canonical: gso.services.provisioning_proxy._await_pp_results
+
+```{autodoc2-docstring} gso.services.provisioning_proxy._await_pp_results
+```
+````
+
+````{py:function} _reset_pp_success_state() -> orchestrator.types.State
+:canonical: gso.services.provisioning_proxy._reset_pp_success_state
+
+```{autodoc2-docstring} gso.services.provisioning_proxy._reset_pp_success_state
+```
+````
+
+````{py:function} _confirm_pp_results(state: orchestrator.types.State) -> orchestrator.types.FormGenerator
+:canonical: gso.services.provisioning_proxy._confirm_pp_results
+
+```{autodoc2-docstring} gso.services.provisioning_proxy._confirm_pp_results
+```
+````
+
+````{py:function} pp_interaction(provisioning_step: orchestrator.workflow.Step, attempts: int, abort_on_failure: bool = True) -> orchestrator.workflow.StepList
+:canonical: gso.services.provisioning_proxy.pp_interaction
+
+```{autodoc2-docstring} gso.services.provisioning_proxy.pp_interaction
+```
+````
diff --git a/docs/source/apidocs/gso/gso.services.resource_manager.md b/docs/source/apidocs/gso/gso.services.resource_manager.md
new file mode 100644
index 0000000000000000000000000000000000000000..2fbd130b4b0eb06886b7a80084ece311448f7e2a
--- /dev/null
+++ b/docs/source/apidocs/gso/gso.services.resource_manager.md
@@ -0,0 +1,33 @@
+---
+orphan: true
+---
+
+# {py:mod}`gso.services.resource_manager`
+
+```{py:module} gso.services.resource_manager
+```
+
+```{autodoc2-docstring} gso.services.resource_manager
+:allowtitles:
+```
+
+## Module Contents
+
+### Classes
+
+````{list-table}
+:class: autosummary longtable
+:align: left
+
+* - {py:obj}`InterfaceAllocationState <gso.services.resource_manager.InterfaceAllocationState>`
+  -
+````
+
+### API
+
+```{py:class} InterfaceAllocationState(*args, **kwds)
+:canonical: gso.services.resource_manager.InterfaceAllocationState
+
+Bases: {py:obj}`enum.Enum`
+
+```
diff --git a/docs/source/apidocs/gso/gso.services.subscriptions.md b/docs/source/apidocs/gso/gso.services.subscriptions.md
new file mode 100644
index 0000000000000000000000000000000000000000..fbebf67a237a2b90d3ddde7f85cffda536e3435d
--- /dev/null
+++ b/docs/source/apidocs/gso/gso.services.subscriptions.md
@@ -0,0 +1,79 @@
+---
+orphan: true
+---
+
+# {py:mod}`gso.services.subscriptions`
+
+```{py:module} gso.services.subscriptions
+```
+
+```{autodoc2-docstring} gso.services.subscriptions
+:allowtitles:
+```
+
+## Module Contents
+
+### Functions
+
+````{list-table}
+:class: autosummary longtable
+:align: left
+
+* - {py:obj}`get_active_subscriptions <gso.services.subscriptions.get_active_subscriptions>`
+  - ```{autodoc2-docstring} gso.services.subscriptions.get_active_subscriptions
+    :summary:
+    ```
+* - {py:obj}`get_active_site_subscriptions <gso.services.subscriptions.get_active_site_subscriptions>`
+  - ```{autodoc2-docstring} gso.services.subscriptions.get_active_site_subscriptions
+    :summary:
+    ```
+* - {py:obj}`get_active_router_subscriptions <gso.services.subscriptions.get_active_router_subscriptions>`
+  - ```{autodoc2-docstring} gso.services.subscriptions.get_active_router_subscriptions
+    :summary:
+    ```
+* - {py:obj}`get_product_id_by_name <gso.services.subscriptions.get_product_id_by_name>`
+  - ```{autodoc2-docstring} gso.services.subscriptions.get_product_id_by_name
+    :summary:
+    ```
+* - {py:obj}`get_active_site_subscription_by_name <gso.services.subscriptions.get_active_site_subscription_by_name>`
+  - ```{autodoc2-docstring} gso.services.subscriptions.get_active_site_subscription_by_name
+    :summary:
+    ```
+````
+
+### API
+
+````{py:function} get_active_subscriptions(product_type: str, fields: list[str]) -> list[asyncio_redis.Subscription]
+:canonical: gso.services.subscriptions.get_active_subscriptions
+
+```{autodoc2-docstring} gso.services.subscriptions.get_active_subscriptions
+```
+````
+
+````{py:function} get_active_site_subscriptions(fields: list[str]) -> list[asyncio_redis.Subscription]
+:canonical: gso.services.subscriptions.get_active_site_subscriptions
+
+```{autodoc2-docstring} gso.services.subscriptions.get_active_site_subscriptions
+```
+````
+
+````{py:function} get_active_router_subscriptions(fields: list[str]) -> list[asyncio_redis.Subscription]
+:canonical: gso.services.subscriptions.get_active_router_subscriptions
+
+```{autodoc2-docstring} gso.services.subscriptions.get_active_router_subscriptions
+```
+````
+
+````{py:function} get_product_id_by_name(product_name: gso.schemas.enums.ProductType) -> uuid.UUID
+:canonical: gso.services.subscriptions.get_product_id_by_name
+
+```{autodoc2-docstring} gso.services.subscriptions.get_product_id_by_name
+```
+````
+
+````{py:function} get_active_site_subscription_by_name(site_name: str) -> asyncio_redis.Subscription
+:canonical: gso.services.subscriptions.get_active_site_subscription_by_name
+
+```{autodoc2-docstring} gso.services.subscriptions.get_active_site_subscription_by_name
+```
+````
diff --git a/docs/source/apidocs/gso/gso.settings.md b/docs/source/apidocs/gso/gso.settings.md
new file mode 100644
index 0000000000000000000000000000000000000000..6e053d48a2151903e1924de2eddc32f659a341a7
--- /dev/null
+++ b/docs/source/apidocs/gso/gso.settings.md
@@ -0,0 +1,176 @@
+# {py:mod}`gso.settings`
+
+```{py:module} gso.settings
+```
+
+```{autodoc2-docstring} gso.settings
+:allowtitles:
+```
+
+## Module Contents
+
+### Classes
+
+````{list-table}
+:class: autosummary longtable
+:align: left
+
+* - {py:obj}`GeneralParams <gso.settings.GeneralParams>`
+  - ```{autodoc2-docstring} gso.settings.GeneralParams
+    :summary:
+    ```
+* - {py:obj}`InfoBloxParams <gso.settings.InfoBloxParams>`
+  - ```{autodoc2-docstring} gso.settings.InfoBloxParams
+    :summary:
+    ```
+* - {py:obj}`V4NetworkParams <gso.settings.V4NetworkParams>`
+  - ```{autodoc2-docstring} gso.settings.V4NetworkParams
+    :summary:
+    ```
+* - {py:obj}`V6NetworkParams <gso.settings.V6NetworkParams>`
+  - ```{autodoc2-docstring} gso.settings.V6NetworkParams
+    :summary:
+    ```
+* - {py:obj}`ServiceNetworkParams <gso.settings.ServiceNetworkParams>`
+  - ```{autodoc2-docstring} gso.settings.ServiceNetworkParams
+    :summary:
+    ```
+* - {py:obj}`IPAMParams <gso.settings.IPAMParams>`
+  - ```{autodoc2-docstring} gso.settings.IPAMParams
+    :summary:
+    ```
+* - {py:obj}`ProvisioningProxyParams <gso.settings.ProvisioningProxyParams>`
+  - ```{autodoc2-docstring} gso.settings.ProvisioningProxyParams
+    :summary:
+    ```
+* - {py:obj}`ResourceManagementParams <gso.settings.ResourceManagementParams>`
+  - ```{autodoc2-docstring} gso.settings.ResourceManagementParams
+    :summary:
+    ```
+* - {py:obj}`OSSParams <gso.settings.OSSParams>`
+  - ```{autodoc2-docstring} gso.settings.OSSParams
+    :summary:
+    ```
+````
+
+### Functions
+
+````{list-table}
+:class: autosummary longtable
+:align: left
+
+* - {py:obj}`load_oss_params <gso.settings.load_oss_params>`
+  - ```{autodoc2-docstring} gso.settings.load_oss_params
+    :summary:
+    ```
+````
+
+### API
+
+`````{py:class} GeneralParams
+:canonical: gso.settings.GeneralParams
+
+Bases: {py:obj}`pydantic.BaseSettings`
+
+```{autodoc2-docstring} gso.settings.GeneralParams
+```
+
+````{py:attribute} public_hostname
+:canonical: gso.settings.GeneralParams.public_hostname
+:type: str
+:value: >
+   None
+
+```{autodoc2-docstring} gso.settings.GeneralParams.public_hostname
+```
+
+````
+
+`````
+
+````{py:class} InfoBloxParams
+:canonical: gso.settings.InfoBloxParams
+
+Bases: {py:obj}`pydantic.BaseSettings`
+
+```{autodoc2-docstring} gso.settings.InfoBloxParams
+```
+
+````
+
+````{py:class} V4NetworkParams
+:canonical: gso.settings.V4NetworkParams
+
+Bases: {py:obj}`pydantic.BaseSettings`
+
+```{autodoc2-docstring} gso.settings.V4NetworkParams
+```
+
+````
+
+````{py:class} V6NetworkParams
+:canonical: gso.settings.V6NetworkParams
+
+Bases: {py:obj}`pydantic.BaseSettings`
+
+```{autodoc2-docstring} gso.settings.V6NetworkParams
+```
+
+````
+
+````{py:class} ServiceNetworkParams
+:canonical: gso.settings.ServiceNetworkParams
+
+Bases: {py:obj}`pydantic.BaseSettings`
+
+```{autodoc2-docstring} gso.settings.ServiceNetworkParams
+```
+
+````
+
+````{py:class} IPAMParams
+:canonical: gso.settings.IPAMParams
+
+Bases: {py:obj}`pydantic.BaseSettings`
+
+```{autodoc2-docstring} gso.settings.IPAMParams
+```
+
+````
+
+````{py:class} ProvisioningProxyParams
+:canonical: gso.settings.ProvisioningProxyParams
+
+Bases: {py:obj}`pydantic.BaseSettings`
+
+```{autodoc2-docstring} gso.settings.ProvisioningProxyParams
+```
+
+````
+
+````{py:class} ResourceManagementParams
+:canonical: gso.settings.ResourceManagementParams
+
+Bases: {py:obj}`pydantic.BaseSettings`
+
+```{autodoc2-docstring} gso.settings.ResourceManagementParams
+```
+
+````
+
+````{py:class} OSSParams
+:canonical: gso.settings.OSSParams
+
+Bases: {py:obj}`pydantic.BaseSettings`
+
+```{autodoc2-docstring} gso.settings.OSSParams
+```
+
+````
+
+````{py:function} load_oss_params() -> gso.settings.OSSParams
+:canonical: gso.settings.load_oss_params
+
+```{autodoc2-docstring} gso.settings.load_oss_params
+```
+````
diff --git a/docs/source/apidocs/gso/gso.workflows.iptrunk.create_iptrunk.md b/docs/source/apidocs/gso/gso.workflows.iptrunk.create_iptrunk.md
new file mode 100644
index 0000000000000000000000000000000000000000..b2cf9654595b89c8c488e08384453bfa6dacb9fe
--- /dev/null
+++ b/docs/source/apidocs/gso/gso.workflows.iptrunk.create_iptrunk.md
@@ -0,0 +1,12 @@
+---
+orphan: true
+---
+
+# {py:mod}`gso.workflows.iptrunk.create_iptrunk`
+
+```{py:module} gso.workflows.iptrunk.create_iptrunk
+```
+
+```{autodoc2-docstring} gso.workflows.iptrunk.create_iptrunk
+:allowtitles:
+```
diff --git a/docs/source/apidocs/gso/gso.workflows.iptrunk.md b/docs/source/apidocs/gso/gso.workflows.iptrunk.md
new file mode 100644
index 0000000000000000000000000000000000000000..4aec5c9b51e1f60e488a65cd326e09af39b41eb7
--- /dev/null
+++ b/docs/source/apidocs/gso/gso.workflows.iptrunk.md
@@ -0,0 +1,12 @@
+---
+orphan: true
+---
+
+# {py:mod}`gso.workflows.iptrunk`
+
+```{py:module} gso.workflows.iptrunk
+```
+
+```{autodoc2-docstring} gso.workflows.iptrunk
+:allowtitles:
+```
diff --git a/docs/source/apidocs/gso/gso.workflows.iptrunk.migrate_iptrunk.md b/docs/source/apidocs/gso/gso.workflows.iptrunk.migrate_iptrunk.md
new file mode 100644
index 0000000000000000000000000000000000000000..b34ebd283d5c3b7cbb2e8e827b01b6bf641e0900
--- /dev/null
+++ b/docs/source/apidocs/gso/gso.workflows.iptrunk.migrate_iptrunk.md
@@ -0,0 +1,12 @@
+---
+orphan: true
+---
+
+# {py:mod}`gso.workflows.iptrunk.migrate_iptrunk`
+
+```{py:module} gso.workflows.iptrunk.migrate_iptrunk
+```
+
+```{autodoc2-docstring} gso.workflows.iptrunk.migrate_iptrunk
+:allowtitles:
+```
diff --git a/docs/source/apidocs/gso/gso.workflows.iptrunk.modify_isis_metric.md b/docs/source/apidocs/gso/gso.workflows.iptrunk.modify_isis_metric.md
new file mode 100644
index 0000000000000000000000000000000000000000..b46fafd6f96143eddd77694189f9043c1f99badc
--- /dev/null
+++ b/docs/source/apidocs/gso/gso.workflows.iptrunk.modify_isis_metric.md
@@ -0,0 +1,12 @@
+---
+orphan: true
+---
+
+# {py:mod}`gso.workflows.iptrunk.modify_isis_metric`
+
+```{py:module} gso.workflows.iptrunk.modify_isis_metric
+```
+
+```{autodoc2-docstring} gso.workflows.iptrunk.modify_isis_metric
+:allowtitles:
+```
diff --git a/docs/source/apidocs/gso/gso.workflows.iptrunk.modify_trunk_interface.md b/docs/source/apidocs/gso/gso.workflows.iptrunk.modify_trunk_interface.md
new file mode 100644
index 0000000000000000000000000000000000000000..a43baeee8fd1fd68a30e8c8874caf58ef09af11e
--- /dev/null
+++ b/docs/source/apidocs/gso/gso.workflows.iptrunk.modify_trunk_interface.md
@@ -0,0 +1,12 @@
+---
+orphan: true
+---
+
+# {py:mod}`gso.workflows.iptrunk.modify_trunk_interface`
+
+```{py:module} gso.workflows.iptrunk.modify_trunk_interface
+```
+
+```{autodoc2-docstring} gso.workflows.iptrunk.modify_trunk_interface
+:allowtitles:
+```
diff --git a/docs/source/apidocs/gso/gso.workflows.iptrunk.terminate_iptrunk.md b/docs/source/apidocs/gso/gso.workflows.iptrunk.terminate_iptrunk.md
new file mode 100644
index 0000000000000000000000000000000000000000..b8f4064cbf312244c2edac7a6ca8aea0dd8b6d24
--- /dev/null
+++ b/docs/source/apidocs/gso/gso.workflows.iptrunk.terminate_iptrunk.md
@@ -0,0 +1,12 @@
+---
+orphan: true
+---
+
+# {py:mod}`gso.workflows.iptrunk.terminate_iptrunk`
+
+```{py:module} gso.workflows.iptrunk.terminate_iptrunk
+```
+
+```{autodoc2-docstring} gso.workflows.iptrunk.terminate_iptrunk
+:allowtitles:
+```
diff --git a/docs/source/apidocs/gso/gso.workflows.iptrunk.utils.md b/docs/source/apidocs/gso/gso.workflows.iptrunk.utils.md
new file mode 100644
index 0000000000000000000000000000000000000000..bfb1debc090754b749be11448296c71eb4402392
--- /dev/null
+++ b/docs/source/apidocs/gso/gso.workflows.iptrunk.utils.md
@@ -0,0 +1,12 @@
+---
+orphan: true
+---
+
+# {py:mod}`gso.workflows.iptrunk.utils`
+
+```{py:module} gso.workflows.iptrunk.utils
+```
+
+```{autodoc2-docstring} gso.workflows.iptrunk.utils
+:allowtitles:
+```
diff --git a/docs/source/apidocs/gso/gso.workflows.md b/docs/source/apidocs/gso/gso.workflows.md
new file mode 100644
index 0000000000000000000000000000000000000000..1fd9feee84b9a3f188ed1bc7a1eddfa4d1de91d0
--- /dev/null
+++ b/docs/source/apidocs/gso/gso.workflows.md
@@ -0,0 +1,8 @@
+# {py:mod}`gso.workflows`
+
+```{py:module} gso.workflows
+```
+
+```{autodoc2-docstring} gso.workflows
+:allowtitles:
+```
diff --git a/docs/source/apidocs/gso/gso.workflows.router.create_router.md b/docs/source/apidocs/gso/gso.workflows.router.create_router.md
new file mode 100644
index 0000000000000000000000000000000000000000..144df1de98b06f2113ea4c861cb64f76e36bd81d
--- /dev/null
+++ b/docs/source/apidocs/gso/gso.workflows.router.create_router.md
@@ -0,0 +1,12 @@
+---
+orphan: true
+---
+
+# {py:mod}`gso.workflows.router.create_router`
+
+```{py:module} gso.workflows.router.create_router
+```
+
+```{autodoc2-docstring} gso.workflows.router.create_router
+:allowtitles:
+```
diff --git a/docs/source/apidocs/gso/gso.workflows.router.md b/docs/source/apidocs/gso/gso.workflows.router.md
new file mode 100644
index 0000000000000000000000000000000000000000..fd21bf949b4ba2a88380c82557599d8c109ba3ba
--- /dev/null
+++ b/docs/source/apidocs/gso/gso.workflows.router.md
@@ -0,0 +1,12 @@
+---
+orphan: true
+---
+
+# {py:mod}`gso.workflows.router`
+
+```{py:module} gso.workflows.router
+```
+
+```{autodoc2-docstring} gso.workflows.router
+:allowtitles:
+```
diff --git a/docs/source/apidocs/gso/gso.workflows.router.terminate_router.md b/docs/source/apidocs/gso/gso.workflows.router.terminate_router.md
new file mode 100644
index 0000000000000000000000000000000000000000..f157cdba8a17506589bbcd627a1bc939c8d78ed1
--- /dev/null
+++ b/docs/source/apidocs/gso/gso.workflows.router.terminate_router.md
@@ -0,0 +1,12 @@
+---
+orphan: true
+---
+
+# {py:mod}`gso.workflows.router.terminate_router`
+
+```{py:module} gso.workflows.router.terminate_router
+```
+
+```{autodoc2-docstring} gso.workflows.router.terminate_router
+:allowtitles:
+```
diff --git a/docs/source/apidocs/gso/gso.workflows.site.create_site.md b/docs/source/apidocs/gso/gso.workflows.site.create_site.md
new file mode 100644
index 0000000000000000000000000000000000000000..aeba1128fe8100a39e8c4b2671475ff7a8b5d168
--- /dev/null
+++ b/docs/source/apidocs/gso/gso.workflows.site.create_site.md
@@ -0,0 +1,12 @@
+---
+orphan: true
+---
+
+# {py:mod}`gso.workflows.site.create_site`
+
+```{py:module} gso.workflows.site.create_site
+```
+
+```{autodoc2-docstring} gso.workflows.site.create_site
+:allowtitles:
+```
diff --git a/docs/source/apidocs/gso/gso.workflows.site.md b/docs/source/apidocs/gso/gso.workflows.site.md
new file mode 100644
index 0000000000000000000000000000000000000000..57164957ab4cdf4cdf9948b0a583718037d110c1
--- /dev/null
+++ b/docs/source/apidocs/gso/gso.workflows.site.md
@@ -0,0 +1,12 @@
+---
+orphan: true
+---
+
+# {py:mod}`gso.workflows.site`
+
+```{py:module} gso.workflows.site
+```
+
+```{autodoc2-docstring} gso.workflows.site
+:allowtitles:
+```
diff --git a/docs/source/apidocs/gso/gso.workflows.tasks.import_iptrunk.md b/docs/source/apidocs/gso/gso.workflows.tasks.import_iptrunk.md
new file mode 100644
index 0000000000000000000000000000000000000000..495e0dda5db089bc56b03488d6c264f7fd2c5511
--- /dev/null
+++ b/docs/source/apidocs/gso/gso.workflows.tasks.import_iptrunk.md
@@ -0,0 +1,35 @@
+---
+orphan: true
+---
+
+# {py:mod}`gso.workflows.tasks.import_iptrunk`
+
+```{py:module} gso.workflows.tasks.import_iptrunk
+```
+
+```{autodoc2-docstring} gso.workflows.tasks.import_iptrunk
+:allowtitles:
+```
+
+## Module Contents
+
+### Functions
+
+````{list-table}
+:class: autosummary longtable
+:align: left
+
+* - {py:obj}`_generate_routers <gso.workflows.tasks.import_iptrunk._generate_routers>`
+  - ```{autodoc2-docstring} gso.workflows.tasks.import_iptrunk._generate_routers
+    :summary:
+    ```
+````
+
+### API
+
+````{py:function} _generate_routers() -> dict[str, str]
+:canonical: gso.workflows.tasks.import_iptrunk._generate_routers
+
+```{autodoc2-docstring} gso.workflows.tasks.import_iptrunk._generate_routers
+```
+````
diff --git a/docs/source/apidocs/gso/gso.workflows.tasks.import_router.md b/docs/source/apidocs/gso/gso.workflows.tasks.import_router.md
new file mode 100644
index 0000000000000000000000000000000000000000..d357f6ea3ac9cc6aa92d0a859d2c4af073fd2809
--- /dev/null
+++ b/docs/source/apidocs/gso/gso.workflows.tasks.import_router.md
@@ -0,0 +1,35 @@
+---
+orphan: true
+---
+
+# {py:mod}`gso.workflows.tasks.import_router`
+
+```{py:module} gso.workflows.tasks.import_router
+```
+
+```{autodoc2-docstring} gso.workflows.tasks.import_router
+:allowtitles:
+```
+
+## Module Contents
+
+### Functions
+
+````{list-table}
+:class: autosummary longtable
+:align: left
+
+* - {py:obj}`_get_site_by_name <gso.workflows.tasks.import_router._get_site_by_name>`
+  - ```{autodoc2-docstring} gso.workflows.tasks.import_router._get_site_by_name
+    :summary:
+    ```
+````
+
+### API
+
+````{py:function} _get_site_by_name(site_name: str) -> gso.products.product_types.site.Site
+:canonical: gso.workflows.tasks.import_router._get_site_by_name
+
+```{autodoc2-docstring} gso.workflows.tasks.import_router._get_site_by_name
+```
+````
diff --git a/docs/source/apidocs/gso/gso.workflows.tasks.import_site.md b/docs/source/apidocs/gso/gso.workflows.tasks.import_site.md
new file mode 100644
index 0000000000000000000000000000000000000000..eb4b160617dfc8e14f59badccb27c2f09a7b9c1a
--- /dev/null
+++ b/docs/source/apidocs/gso/gso.workflows.tasks.import_site.md
@@ -0,0 +1,35 @@
+---
+orphan: true
+---
+
+# {py:mod}`gso.workflows.tasks.import_site`
+
+```{py:module} gso.workflows.tasks.import_site
+```
+
+```{autodoc2-docstring} gso.workflows.tasks.import_site
+:allowtitles:
+```
+
+## Module Contents
+
+### Functions
+
+````{list-table}
+:class: autosummary longtable
+:align: left
+
+* - {py:obj}`import_site <gso.workflows.tasks.import_site.import_site>`
+  - ```{autodoc2-docstring} gso.workflows.tasks.import_site.import_site
+    :summary:
+    ```
+````
+
+### API
+
+````{py:function} import_site() -> orchestrator.workflow.StepList
+:canonical: gso.workflows.tasks.import_site.import_site
+
+```{autodoc2-docstring} gso.workflows.tasks.import_site.import_site
+```
+````
diff --git a/docs/source/apidocs/gso/gso.workflows.tasks.md b/docs/source/apidocs/gso/gso.workflows.tasks.md
new file mode 100644
index 0000000000000000000000000000000000000000..1d9cca39986b72155ff6ade547f8f6f22376ea45
--- /dev/null
+++ b/docs/source/apidocs/gso/gso.workflows.tasks.md
@@ -0,0 +1,12 @@
+---
+orphan: true
+---
+
+# {py:mod}`gso.workflows.tasks`
+
+```{py:module} gso.workflows.tasks
+```
+
+```{autodoc2-docstring} gso.workflows.tasks
+:allowtitles:
+```
diff --git a/docs/source/apidocs/gso/gso.workflows.utils.md b/docs/source/apidocs/gso/gso.workflows.utils.md
new file mode 100644
index 0000000000000000000000000000000000000000..b6fc77e1329865d4ebcf80e700c771d9468859bc
--- /dev/null
+++ b/docs/source/apidocs/gso/gso.workflows.utils.md
@@ -0,0 +1,35 @@
+---
+orphan: true
+---
+
+# {py:mod}`gso.workflows.utils`
+
+```{py:module} gso.workflows.utils
+```
+
+```{autodoc2-docstring} gso.workflows.utils
+:allowtitles:
+```
+
+## Module Contents
+
+### Functions
+
+````{list-table}
+:class: autosummary longtable
+:align: left
+
+* - {py:obj}`iso_from_ipv4 <gso.workflows.utils.iso_from_ipv4>`
+  - ```{autodoc2-docstring} gso.workflows.utils.iso_from_ipv4
+    :summary:
+    ```
+````
+
+### API
+
+````{py:function} iso_from_ipv4(ipv4_address: ipaddress.IPv4Address) -> str
+:canonical: gso.workflows.utils.iso_from_ipv4
+
+```{autodoc2-docstring} gso.workflows.utils.iso_from_ipv4
+```
+````
diff --git a/requirements.txt b/requirements.txt
index b103da38a717e01e8c339a38c8e5534d778183e6..8509293b655fcf5b739c9a92b75fef43eaf9ce0f 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -2,15 +2,17 @@ orchestrator-core==1.3.0
 requests==2.31.0
 infoblox-client~=0.6.0
 pycountry==22.3.5
+pynetbox==7.2.0
+
+# Test and linting dependencies
 pytest==7.4.2
-faker==19.6.2
+faker==19.10.0
 responses==0.23.3
 black==23.9.1
 isort==5.12.0
 flake8==6.1.0
-mypy==1.5.1
-ruff==0.0.290
+mypy==1.6.0
+ruff==0.0.292
 sphinx==7.2.6
 sphinx-rtd-theme==1.3.0
-urllib3_mock==0.3.3
-pynetbox==7.2.0
+urllib3_mock==0.3.3
\ No newline at end of file