diff --git a/nomad/app/optimade/filterparser.py b/nomad/app/optimade/filterparser.py
index 0147802d27f47a5d840c5d9fe18ddc0146c457a5..48246a07130d6cb29e3c6352281fa5545be2ba13 100644
--- a/nomad/app/optimade/filterparser.py
+++ b/nomad/app/optimade/filterparser.py
@@ -46,7 +46,6 @@ def _get_transformer(nomad_properties, without_prefix):
         if 'search' in q.m_annotations}
 
     quantities['elements'].length_quantity = quantities['nelements']
-    quantities['dimension_types'].length_quantity = quantities['dimension_types']
     quantities['elements'].has_only_quantity = Quantity(name='only_atoms')
     quantities['elements'].nested_quantity = quantities['elements_ratios']
     quantities['elements_ratios'].nested_quantity = quantities['elements_ratios']
diff --git a/nomad/app/optimade/infolinks.py b/nomad/app/optimade/infolinks.py
index 0c0d52a6f2f45f957330f47ecfbd5918fa1db77c..dfd82af6562d6aff898b0133d54a3bc70f7285f9 100644
--- a/nomad/app/optimade/infolinks.py
+++ b/nomad/app/optimade/infolinks.py
@@ -48,7 +48,7 @@ class Info(Resource):
                 }],
                 'formats': ['json'],
                 'entry_types_by_format': {
-                    'json': ['structures', 'calculations', 'info']
+                    'json': ['structures', 'calculations']
                 },
                 'available_endpoints': ['structures', 'calculations', 'info'],
                 'is_index': False
@@ -73,11 +73,12 @@ class Links(Resource):
 
         result = [
             {
-                "type": "parent",
+                "type": "links",
                 "id": "index",
                 "attributes": {
                     "name": config.meta.name,
                     "description": config.meta.description,
+                    "link_type": "root",
                     "base_url": {
                         "href": url(version=None, prefix='index'),
                     },
diff --git a/nomad/app/optimade/models.py b/nomad/app/optimade/models.py
index b34a034b497937044a01796095c736b6d3591955..6516b185112c393c222fa6075538fd8a9bea2edc 100644
--- a/nomad/app/optimade/models.py
+++ b/nomad/app/optimade/models.py
@@ -25,9 +25,12 @@ from flask_restplus import fields
 import datetime
 import math
 from cachetools import cached
+import numpy as np
 
 from nomad import config, datamodel, files
 from nomad.app.common import RFC3339DateTime
+from nomad.normalizing.optimade import optimade_chemical_formula_reduced
+from nomad.metainfo import Datetime, MEnum
 from nomad.datamodel import EntryMetadata
 from nomad.datamodel.dft import DFTMetadata
 from nomad.datamodel.optimade import OptimadeEntry
@@ -248,7 +251,28 @@ def get_entry_properties(include_optimade: bool = True):
     def add_nmd_properties(prefix, section_cls):
         for quantity in section_cls.m_def.all_quantities.values():
             name = prefix + quantity.name
-            properties[name] = dict(description=quantity.description)
+            if quantity.is_scalar:
+                if quantity.type == int:
+                    prop_type = 'integer'
+                elif quantity.type == float:
+                    prop_type = 'float'
+                elif quantity.type == str:
+                    prop_type = 'string'
+                elif quantity.type == bool:
+                    prop_type = 'boolean'
+                elif quantity.type == Datetime:
+                    prop_type = 'timestamp'
+                elif isinstance(quantity.type, MEnum):
+                    prop_type = 'string'
+                elif isinstance(quantity.type, np.dtype):
+                    prop_type = 'float'
+                else:
+                    prop_type = 'unknown'
+            else:
+                prop_type = 'list'
+            properties[name] = dict(
+                description=quantity.description if quantity.description else quantity.name,
+                type=prop_type)
 
     add_nmd_properties('_nmd_', EntryMetadata)
     add_nmd_properties('_nmd_dft_', DFTMetadata)
@@ -276,6 +300,21 @@ class EntryDataObject:
 
         if response_fields is not None:
             for request_field in response_fields:
+                if request_field == 'chemical_formula_reduced':
+                    # TODO remove when this is fixed in the index
+                    # ensure correct order of elements in formula
+                    attrs[request_field] = optimade_chemical_formula_reduced(attrs[request_field])
+
+                if request_field == 'dimension_types':
+                    # TODO remove when this is fixed in the index
+                    # ensure correct order of elements in formula
+                    dts = attrs[request_field]
+                    if isinstance(dts, int):
+                        attrs[request_field] = [1] * dts + [0] * (3 - dts)
+                        attrs['nperiodic_dimensions'] = dts
+                    elif isinstance(dts, list):
+                        attrs['nperiodic_dimensions'] = sum(dts)
+
                 if not request_field.startswith('_nmd_'):
                     continue
 
diff --git a/nomad/datamodel/optimade.py b/nomad/datamodel/optimade.py
index d29e6762dd0a78073b53cd7b8032d21f3b984b0f..df596b9ecc6c4ee22cc91f9ebb18bb29671701ca 100644
--- a/nomad/datamodel/optimade.py
+++ b/nomad/datamodel/optimade.py
@@ -193,8 +193,7 @@ class OptimadeEntry(MSection):
     dimension_types = Quantity(
         type=int, shape=[3], default=[0, 0, 0],
         links=optimade_links('h.6.2.8'),
-        a_search=Search(value=lambda a: sum(a.dimension_types), mapping=Integer()),
-        a_optimade=Optimade(query=True, entry=True, sortable=False, type='list'),
+        a_optimade=Optimade(query=False, entry=True, sortable=False, type='list'),
         description='''
             List of three integers. For each of the three directions indicated by the three lattice
             vectors (see property lattice_vectors). This list indicates if the direction is
@@ -203,6 +202,16 @@ class OptimadeEntry(MSection):
             the Cartesian x, y, z directions.
         ''')
 
+    nperiodic_dimensions = Quantity(
+        type=int, derived=lambda a: sum(a.dimension_types),
+        links=optimade_links('h.6.2.8'),
+        a_search=Search(mapping=Integer()),
+        a_optimade=Optimade(query=True, entry=True, sortable=True, type='integer'),
+        description='''
+            An integer specifying the number of periodic dimensions in the structure, equivalent
+            to the number of non-zero entries in dimension_types.
+        ''')
+
     lattice_vectors = Quantity(
         type=np.dtype('f8'), shape=[3, 3], unit=ureg.angstrom,
         links=optimade_links('h.6.2.9'),
@@ -240,7 +249,7 @@ class OptimadeEntry(MSection):
     # TODO assemblies
 
     structure_features = Quantity(
-        type=MEnum(['disorder', 'unknown_positions', 'assemblies']), shape=['1..*'],
+        type=MEnum(['disorder', 'unknown_positions', 'assemblies']), shape=['1..*'], default=[],
         links=optimade_links('h.6.2.15'),
         a_search=Search(),
         a_optimade=Optimade(query=True, entry=True, sortable=False, type='list'), description='''
diff --git a/nomad/normalizing/optimade.py b/nomad/normalizing/optimade.py
index a3fea0e3f207ea333f978a7509ddd888365cb4ad..201dcc1dbd9fcb106062cec5b5c6defd7c8d0282 100644
--- a/nomad/normalizing/optimade.py
+++ b/nomad/normalizing/optimade.py
@@ -20,6 +20,7 @@ from typing import Any, Dict
 import numpy as np
 import re
 import ase.data
+import ase.formula
 from string import ascii_uppercase
 import pint.quantity
 
@@ -31,6 +32,24 @@ from nomad.datamodel.metainfo.public import section_system
 species_re = re.compile(r'^([A-Z][a-z]?)(\d*)$')
 
 
+def optimade_chemical_formula_reduced(formula: str):
+    if formula is None:
+        return formula
+
+    try:
+        ase_formula = ase.formula.Formula(formula).count()
+        result_formula = ''
+        for element in sorted(ase_formula.keys()):
+            result_formula += element
+            element_count = ase_formula[element]
+            if element_count > 1:
+                result_formula += str(element_count)
+
+        return result_formula
+    except Exception:
+        return formula
+
+
 class OptimadeNormalizer(SystemBasedNormalizer):
 
     '''
@@ -92,7 +111,8 @@ class OptimadeNormalizer(SystemBasedNormalizer):
             for element in optimade.elements]
 
         # formulas
-        optimade.chemical_formula_reduced = get_value(section_system.chemical_composition_reduced)
+        optimade.chemical_formula_reduced = optimade_chemical_formula_reduced(
+            get_value(section_system.chemical_composition_reduced))
         optimade.chemical_formula_hill = get_value(section_system.chemical_composition_bulk_reduced)
         optimade.chemical_formula_descriptive = optimade.chemical_formula_hill
         optimade.chemical_formula_anonymous = ''
diff --git a/tests/app/test_optimade.py b/tests/app/test_optimade.py
index 09d9c417dc9684e6a0813273e83719070cfe1341..e0f186a55fc148fbc9c1589217fe69c5a864ee56 100644
--- a/tests/app/test_optimade.py
+++ b/tests/app/test_optimade.py
@@ -122,10 +122,10 @@ def example_structures(elastic_infra, mongo_infra, raw_files_infra):
     ('chemical_formula_reduced CONTAINS "H2"', 3),
     ('chemical_formula_reduced CONTAINS "H"', 4),
     ('chemical_formula_reduced CONTAINS "C"', 1),
-    ('chemical_formula_reduced STARTS "H2"', 3),
-    ('chemical_formula_reduced STARTS WITH "H2"', 3),
-    ('chemical_formula_reduced ENDS WITH "C"', 1),
-    ('chemical_formula_reduced ENDS "C"', 1),
+    ('chemical_formula_reduced STARTS "H2"', 2),
+    ('chemical_formula_reduced STARTS WITH "H2"', 2),
+    ('chemical_formula_reduced ENDS WITH "O"', 4),
+    ('chemical_formula_reduced ENDS "C"', 0),
     ('chemical_formula_hill CONTAINS "1"', 0),
     ('chemical_formula_hill STARTS WITH "H" AND chemical_formula_hill ENDS WITH "O"', 3),
     ('NOT chemical_formula_descriptive ENDS WITH "1"', 4),
@@ -136,14 +136,14 @@ def example_structures(elastic_infra, mongo_infra, raw_files_infra):
     ('elements LENGTH = 2', 3),
     ('elements LENGTH 2', 3),
     ('elements LENGTH = 3', 1),
-    ('dimension_types LENGTH = 0', 3),
-    ('dimension_types LENGTH = 1', 1),
-    ('nelements = 2 AND dimension_types LENGTH = 1', 1),
-    ('nelements = 3 AND dimension_types LENGTH = 1', 0),
-    ('nelements = 3 OR dimension_types LENGTH = 1', 2),
-    ('nelements > 1 OR dimension_types LENGTH = 1 AND nelements = 2', 4),
-    ('(nelements > 1 OR dimension_types LENGTH = 1) AND nelements = 2', 3),
-    ('NOT dimension_types LENGTH 1', 3),
+    ('nperiodic_dimensions = 0', 3),
+    ('nperiodic_dimensions = 1', 1),
+    ('nelements = 2 AND nperiodic_dimensions = 1', 1),
+    ('nelements = 3 AND nperiodic_dimensions = 1', 0),
+    ('nelements = 3 OR nperiodic_dimensions = 1', 2),
+    ('nelements > 1 OR nperiodic_dimensions = 1 AND nelements = 2', 4),
+    ('(nelements > 1 OR nperiodic_dimensions = 1) AND nelements = 2', 3),
+    ('NOT nperiodic_dimensions = 1', 3),
     ('nelements LENGTH = 1', -1),
     ('LENGTH nelements = 1', -1),
     ('chemical_formula_anonymous starts with "A"', -1),