diff --git a/app/api/network.py b/app/api/network.py
index d20aa525a2f2876c26d6dc2aaf084c1728f9ab1b..104a4cb7847d6f7197c01cf787cfac8884491c52 100644
--- a/app/api/network.py
+++ b/app/api/network.py
@@ -164,3 +164,28 @@ def create_macs():
     """
     return create_generic_model(models.Mac,
                                 mandatory_fields=('address',))
+
+
+@bp.route('/domains')
+@jwt_required
+def get_domains():
+    """Return domains
+
+    .. :quickref: Network; Get domains
+    """
+    return get_generic_model(models.Domain,
+                             order_by=models.Domain.name)
+
+
+@bp.route('/domains', methods=['POST'])
+@jwt_required
+@jwt_groups_accepted('admin')
+def create_domain():
+    """Create a new domain
+
+    .. :quickref: Network; Create new domain
+
+    :jsonparam name: domain name
+    """
+    return create_generic_model(models.Domain,
+                                mandatory_fields=('name',))
diff --git a/tests/functional/test_api.py b/tests/functional/test_api.py
index 6954f28cec1f65b682bee7cc3802e2d6bd0be6d1..29090234aa1d968938b03a67134396852398eef8 100644
--- a/tests/functional/test_api.py
+++ b/tests/functional/test_api.py
@@ -27,6 +27,7 @@ ENDPOINT_MODEL = {
     'network/interfaces': models.Interface,
     'network/hosts': models.Host,
     'network/macs': models.Mac,
+    'network/domains': models.Domain,
 }
 GENERIC_GET_ENDPOINTS = [key for key in ENDPOINT_MODEL.keys()
                          if key.startswith('inventory') and key != 'inventory/items']
@@ -765,3 +766,31 @@ def test_get_user_profile(client, readonly_token):
     assert user['username'] == 'user_ro'
     assert user['display_name'] == 'User RO'
     assert user['email'] == 'user_ro@example.com'
+
+
+def test_get_domains(client, domain_factory, readonly_token):
+    # Create some domains
+    domain1 = domain_factory()
+    domain2 = domain_factory()
+    response = get(client, f'{API_URL}/network/domains', token=readonly_token)
+    assert response.status_code == 200
+    assert len(response.json) == 2
+    check_input_is_subset_of_response(response, (domain1.to_dict(), domain2.to_dict()))
+
+
+def test_create_domain(client, admin_token):
+    # check that name is mandatory
+    response = post(client, f'{API_URL}/network/domains', data={}, token=admin_token)
+    check_response_message(response, "Missing mandatory field 'name'", 422)
+
+    data = {'name': 'tn.esss.lu.se'}
+    response = post(client, f'{API_URL}/network/domains', data=data, token=admin_token)
+    assert response.status_code == 201
+    assert {'id', 'name', 'scopes',
+            'networks', 'created_at',
+            'updated_at', 'user'} == set(response.json.keys())
+    assert response.json['name'] == data['name']
+
+    # Check that name shall be unique
+    response = post(client, f'{API_URL}/network/domains', data=data, token=admin_token)
+    check_response_message(response, '(psycopg2.IntegrityError) duplicate key value violates unique constraint', 422)