diff --git a/gso/oss-params-example.json b/gso/oss-params-example.json
index 73b7a6302bb3bd971af17b051d64f10888797fca..84ce7df3190d7df29df57174d5b3d6f6adbf5c48 100644
--- a/gso/oss-params-example.json
+++ b/gso/oss-params-example.json
@@ -12,7 +12,7 @@
       "V4": {"container": "1.1.0.0/24", "mask": 31},
       "V6": {"container": "dead:beef::/64", "mask": 126},
       "domain_name": ".lo"
-	},
+    },
     "TRUNK": {
       "V4": {"container": "1.1.1.0/24", "mask": 31},
       "V6": {"container": "dead:beef::/64", "mask": 126},
diff --git a/gso/services/_ipam.py b/gso/services/_ipam.py
index 1c9f7d4c1e667694b78a8a1ee4bb7ed36fc14fde..7e9ad241a91a0b86b25e8a7c75b44cb64981976b 100644
--- a/gso/services/_ipam.py
+++ b/gso/services/_ipam.py
@@ -106,6 +106,7 @@ def find_networks(network_container=None, network=None, ip_version=4):
         auth=HTTPBasicAuth(infoblox_params.username, infoblox_params.password),
         verify=False
     )
+    # TODO: propagate "network not found" error to caller
     assert r.status_code >= 200 and r.status_code < 300, f"HTTP error {r.status_code}: {r.reason}\n\n{r.text}"
     return r.json()
 
@@ -135,7 +136,7 @@ def get_network_capacity(network=None):
     return utilization
 
 
-def _allocate_network(infoblox_params: settings.InfoBloxParams, network_params: Union[settings.V4NetworkParams, settings.V6NetworkParams], ip_version=4):
+def _allocate_network(infoblox_params: settings.InfoBloxParams, network_params: Union[settings.V4NetworkParams, settings.V6NetworkParams], ip_version=4) -> Union[V4ServiceNetwork, V6ServiceNetwork]:
     assert ip_version in [4, 6]
     endpoint = 'network' if ip_version == 4 else 'ipv6network'
 
@@ -177,15 +178,17 @@ def _allocate_network(infoblox_params: settings.InfoBloxParams, network_params:
         headers={'content-type': "application/json"},
         verify=False
     )
+    # TODO: handle no more available space for networks in the container
     assert r.status_code >= 200 and r.status_code < 300, f"HTTP error {r.status_code}: {r.reason}\n\n{r.text}"
 
+    assert 'network' in r.json()
     allocated_network = r.json()['network']
     if ip_version==4:
         return V4ServiceNetwork(v4=allocated_network)
     else:
         return V6ServiceNetwork(v6=allocated_network)
 
-def allocate_service_ipv4_network(service_type):
+def allocate_service_ipv4_network(service_type) -> V4ServiceNetwork:
     """
     Allocate IPv4 network within the container of the specified service type.
     """
@@ -195,7 +198,7 @@ def allocate_service_ipv4_network(service_type):
     assert hasattr(ipam_params, service_type) and service_type != 'INFOBLOX', "Invalid service type."
     return _allocate_network(ipam_params.INFOBLOX, getattr(ipam_params, service_type).V4, 4)
 
-def allocate_service_ipv6_network(service_type):
+def allocate_service_ipv6_network(service_type) -> V6ServiceNetwork:
     """
     Allocate IPv6 network within the container of the specified service type.
     """
@@ -205,10 +208,12 @@ def allocate_service_ipv6_network(service_type):
     assert hasattr(ipam_params, service_type) and service_type != 'INFOBLOX', "Invalid service type."
     return _allocate_network(ipam_params.INFOBLOX, getattr(ipam_params, service_type).V6, 6)
 
-def delete_network(network):
+def delete_network(network) -> Union[V4ServiceNetwork, V6ServiceNetwork]:
     """
     Delete IPv4 or IPv6 network by CIDR.
     """
+    # TODO: should we check that there are no hosts in this network?
+    # Deleting a network deletes the hosts in it, but not the associated DNS records.
     oss = settings.load_oss_params()
     assert oss.IPAM.INFOBLOX
     infoblox_params = oss.IPAM.INFOBLOX
@@ -240,17 +245,20 @@ def _find_next_available_ip(infoblox_params, network_ref):
         auth=HTTPBasicAuth(infoblox_params.username, infoblox_params.password),
         verify=False
     )
+    # TODO: handle no more available IPs in the network
     assert r.status_code >= 200 and r.status_code < 300, f"HTTP error {r.status_code}: {r.reason}\n\n{r.text}"
     assert 'ips' in r.json()
     received_ip = r.json()['ips']
     assert len(received_ip) == 1
     return received_ip[0]
 
-def allocate_host(hostname=None, addr=None, network=None):
+def allocate_host(hostname=None, addr=None, network=None) -> Union[V4HostAddress, V6HostAddress]:
     """
     If network is not None, allocate host in that network.
     Otherwise if addr is not None, allocate host with that address.
+    hostname parameter must be full name including domain name.
     """
+    # TODO: should hostnames be unique (i.e. fail if hostname already exists in this domain)?
     assert addr or network, "You must specify either the host address or the network CIDR."
     oss = settings.load_oss_params()
     assert oss.IPAM.INFOBLOX
@@ -267,8 +275,6 @@ def allocate_host(hostname=None, addr=None, network=None):
     else:
         ip_version = _ip_addr_version(addr)
 
-    # TODO: use same request for both IP and DNS records
-
     ipv4_req_payload = {
         "ipv4addrs": [
             {
@@ -333,7 +339,7 @@ def allocate_host(hostname=None, addr=None, network=None):
     else:
         return V6HostAddress(v6=addr)
 
-def allocate_host_by_service_type(hostname=None, service_type=None):
+def allocate_service_host(hostname=None, service_type=None) -> HostAddresses:
     """
     Allocate host with both IPv4 and IPv6 address (and respective DNS records).
     The first network with available space for this service type is used.
@@ -359,7 +365,9 @@ def allocate_host_by_service_type(hostname=None, service_type=None):
         if capacity < 1000:
             first_nonfull_ipv4_network = ipv4_network_info["network"]
             break
-    # TODO: create a new network if available space in the container.
+    # Create a new network if the existing networks in the container for the service type are all full.
+    if not first_nonfull_ipv4_network:
+        first_nonfull_ipv4_network = str(allocate_service_ipv4_network(service_type=service_type).v4)
     assert first_nonfull_ipv4_network, "No available IPv4 addresses for this service type."
     v4_host = allocate_host(hostname=hostname+domain_name, network=first_nonfull_ipv4_network)
 
@@ -368,6 +376,7 @@ def allocate_host_by_service_type(hostname=None, service_type=None):
     ipv6_networks_info = find_networks(network_container=str(ipv6_container), ip_version=6)
     assert len(ipv6_networks_info) >= 1, "No IPv6 network exists in the container for this service type."
     assert 'network' in ipv6_networks_info[0]
+    # TODO: if "no available IP" error, create a new network?
     v6_host = allocate_host(hostname=hostname+domain_name, network=ipv6_networks_info[0]['network'])
 
     return HostAddresses(v4=v4_host,v6=v6_host)
@@ -451,7 +460,7 @@ if __name__ == '__main__':
 
         elif choice == '2':
             ip_version = int(input("Enter IP version (4 or 6): "))
-            networks = find_networks(ip_version=ip_version) #, network_container="10.255.255.0/24"
+            networks = find_networks(ip_version=ip_version)
             print(json.dumps(networks, indent=2))
 
         elif choice == '3':
@@ -477,21 +486,21 @@ if __name__ == '__main__':
             print(json.dumps(str(deleted_network), indent=2))
 
         elif choice == '6':
-            hostname = input("Enter host name: ")
+            hostname = input("Enter host name (full name including domain name): ")
             addr = input("Enter IP address to allocate: ")
             alloc_ip = allocate_host(hostname=hostname, addr=addr)
             print(json.dumps(str(alloc_ip), indent=2))
 
         elif choice == '7':
-            hostname = input("Enter host name: ")
+            hostname = input("Enter host name (full name including domain name): ")
             network = input("Enter an existing network to allocate from (in CIDR notation): ")
             alloc_ip = allocate_host(hostname=hostname, network=network)
             print(json.dumps(str(alloc_ip), indent=2))
 
         elif choice == '8':
-            hostname = input("Enter host name: ")
+            hostname = input("Enter host name (not including domain name): ")
             service_type = input("Enter service type: ")
-            alloc_ip = allocate_host_by_service_type(hostname=hostname, service_type=service_type)
+            alloc_ip = allocate_service_host(hostname=hostname, service_type=service_type)
             print(json.dumps(str(alloc_ip), indent=2))
 
         elif choice == '9':
diff --git a/gso/services/ipam.py b/gso/services/ipam.py
index 14c80ce782c1920e9e3ca3ac5b85cf7e3468fe57..fc646e433c0532050d3e82e2466c5cd74d7449a9 100644
--- a/gso/services/ipam.py
+++ b/gso/services/ipam.py
@@ -39,10 +39,10 @@ def new_service_networks(service_type) -> ServiceNetworks:
         v6=v6_service_network)
 
 
-def new_device_lo_address(hostname) -> HostAddresses:
-    return _ipam.allocate_host_by_service_type(hostname=hostname, service_type='LO')
+def new_service_host(hostname, service_type) -> HostAddresses:
+    return _ipam.allocate_service_host(hostname=hostname, service_type=service_type)
 
 
 if __name__ == '__main__':
-    #new_service_networks('TRUNK')
-    new_device_lo_address('newhost1')
\ No newline at end of file
+    new_service_networks('TRUNK')
+    #new_service_host('newhost12', 'TRUNK')
\ No newline at end of file