diff --git a/docs/about/naming_rest_api_brief_introduction.odt b/docs/about/naming_rest_api_brief_introduction.odt
index 08b862cb4f464caa49450f038d2e5b0c6e0fff76..db978abbf8b8ee8b7255e91744f87661348d86e0 100644
Binary files a/docs/about/naming_rest_api_brief_introduction.odt and b/docs/about/naming_rest_api_brief_introduction.odt differ
diff --git a/docs/about/naming_rest_api_brief_introduction.pdf b/docs/about/naming_rest_api_brief_introduction.pdf
index 04f08ee6b32ef01dd12888887e73e2e52a8cc47e..a57e2cddc350ad52c2edff95c7e9fca4b8b6d80a 100644
Binary files a/docs/about/naming_rest_api_brief_introduction.pdf and b/docs/about/naming_rest_api_brief_introduction.pdf differ
diff --git a/docs/about/naming_rest_api_migration.odt b/docs/about/naming_rest_api_migration.odt
index 6ea3ad635b56bd1229294729da10f6a2e66954a4..c2c8156a26bfe75823d2e73d91a71db0e1284aba 100644
Binary files a/docs/about/naming_rest_api_migration.odt and b/docs/about/naming_rest_api_migration.odt differ
diff --git a/docs/about/naming_rest_api_migration.pdf b/docs/about/naming_rest_api_migration.pdf
index 74cde2c881182cfd7b0eab7f84ebf84ffd42dd11..a03af63e32af5099877147527b8461d414db1b1a 100644
Binary files a/docs/about/naming_rest_api_migration.pdf and b/docs/about/naming_rest_api_migration.pdf differ
diff --git a/src/main/java/org/openepics/names/repository/NameRepository.java b/src/main/java/org/openepics/names/repository/NameRepository.java
index b949d580184b3a27711508b80ae364119f2e6fb9..31e2c1eb84577447f248435d7a761c39710c183e 100644
--- a/src/main/java/org/openepics/names/repository/NameRepository.java
+++ b/src/main/java/org/openepics/names/repository/NameRepository.java
@@ -29,11 +29,13 @@ import javax.persistence.criteria.CriteriaBuilder;
 import javax.persistence.criteria.CriteriaQuery;
 import javax.persistence.criteria.Predicate;
 import javax.persistence.criteria.Root;
+import javax.persistence.criteria.Subquery;
 
 import org.apache.commons.lang3.BooleanUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.openepics.names.repository.model.Name;
 import org.openepics.names.repository.model.NameStructure;
+import org.openepics.names.repository.model.Persistable;
 import org.openepics.names.rest.beans.FieldName;
 import org.openepics.names.util.RepositoryUtil;
 import org.springframework.stereotype.Repository;
@@ -60,12 +62,13 @@ public class NameRepository {
      * @param deviceStructure device structure mnemonic
      * @param index index
      * @param description description
+     * @param who who
      * @return count of names
      */
     public Long countNames(Boolean deleted,
-            String uuid, String name, String nameEquivalence, String systemStructure, String deviceStructure, String index, String description) {
+            String uuid, String name, String nameEquivalence, String systemStructure, String deviceStructure, String index, String description, String who) {
         return countNames(deleted,
-                uuid, name, nameEquivalence, systemStructure, deviceStructure, index, description,
+                uuid, name, nameEquivalence, systemStructure, deviceStructure, index, description, who,
                 Boolean.FALSE);
     }
 
@@ -80,11 +83,12 @@ public class NameRepository {
      * @param deviceStructure device structure mnemonic
      * @param index index
      * @param description description
+     * @param who who
      * @param includeHistory include history
      * @return count of names
      */
     public Long countNames(Boolean deleted,
-            String uuid, String name, String nameEquivalence, String systemStructure, String deviceStructure, String index, String description,
+            String uuid, String name, String nameEquivalence, String systemStructure, String deviceStructure, String index, String description, String who,
             Boolean includeHistory) {
 
         // note
@@ -98,7 +102,7 @@ public class NameRepository {
         Root<Name> from = cq.from(Name.class);
 
         cq.where(cb.and(preparePredicatesNames(cb, from, deleted,
-                uuid, name, nameEquivalence, systemStructure, deviceStructure, index, description,
+                uuid, name, nameEquivalence, systemStructure, deviceStructure, index, description, who,
                 includeHistory).toArray(new Predicate[0])));
         cq.select(cb.count(from));
 
@@ -116,13 +120,14 @@ public class NameRepository {
      * @param deviceStructure device structure mnemonic
      * @param index index
      * @param description description
+     * @param who who
      * @return list of names
      */
     public List<Name> readNames(Boolean deleted,
-            String uuid, String name, String nameEquivalence, String systemStructure, String deviceStructure, String index, String description) {
+            String uuid, String name, String nameEquivalence, String systemStructure, String deviceStructure, String index, String description, String who) {
 
         return readNames(deleted,
-                uuid, name, nameEquivalence, systemStructure, deviceStructure, index, description,
+                uuid, name, nameEquivalence, systemStructure, deviceStructure, index, description, who,
                 Boolean.FALSE, null, null, null, null);
     }
 
@@ -137,6 +142,7 @@ public class NameRepository {
      * @param deviceStructure device structure mnemonic
      * @param index index
      * @param description description
+     * @param who who
      * @param orderBy order by
      * @param isAsc is ascending
      * @param offset offset
@@ -144,10 +150,10 @@ public class NameRepository {
      * @return list of names
      */
     public List<Name> readNames(Boolean deleted,
-            String uuid, String name, String nameEquivalence, String systemStructure, String deviceStructure, String index, String description,
+            String uuid, String name, String nameEquivalence, String systemStructure, String deviceStructure, String index, String description, String who,
             FieldName orderBy, Boolean isAsc, Integer offset, Integer limit) {
         return readNames(deleted,
-                uuid, name, nameEquivalence, systemStructure, deviceStructure, index, description,
+                uuid, name, nameEquivalence, systemStructure, deviceStructure, index, description, who,
                 Boolean.FALSE, orderBy, isAsc, offset, limit);
     }
 
@@ -162,6 +168,7 @@ public class NameRepository {
      * @param deviceStructure device structure mnemonic
      * @param index index
      * @param description description
+     * @param who who
      * @param includeHistory include history
      * @param orderBy order by
      * @param isAsc is ascending
@@ -170,7 +177,7 @@ public class NameRepository {
      * @return list of names
      */
     public List<Name> readNames(Boolean deleted,
-            String uuid, String name, String nameEquivalence, String systemStructure, String deviceStructure, String index, String description,
+            String uuid, String name, String nameEquivalence, String systemStructure, String deviceStructure, String index, String description, String who,
             Boolean includeHistory, FieldName orderBy, Boolean isAsc, Integer offset, Integer limit) {
 
         // note
@@ -188,7 +195,7 @@ public class NameRepository {
         Root<Name> from = cq.from(Name.class);
 
         cq.where(cb.and(preparePredicatesNames(cb, from, deleted,
-                uuid, name, nameEquivalence, systemStructure, deviceStructure, index, description,
+                uuid, name, nameEquivalence, systemStructure, deviceStructure, index, description, who,
                 includeHistory).toArray(new Predicate[0])));
         cq.select(from);
 
@@ -241,6 +248,215 @@ public class NameRepository {
         return query.getResultList();
     }
 
+    /**
+     * Prepare predicates for names.
+     *
+     * @param cb criteria builder
+     * @param from criteria query root
+     * @param deleted deleted
+     * @param uuid uuid
+     * @param name name
+     * @param nameEquivalence name equivalence
+     * @param systemStructure system structure mnemonic
+     * @param deviceStructure device structure mnemonic
+     * @param index index
+     * @param description description
+     * @param who who
+     * @param includeHistory include history
+     * @return list of predicates
+     */
+    private List<Predicate> preparePredicatesNames(CriteriaBuilder cb, Root<Name> from, Boolean deleted,
+            String uuid, String name, String nameEquivalence, String systemStructure, String deviceStructure, String index, String description, String who,
+            Boolean includeHistory) {
+
+        List<Predicate> predicates = new ArrayList<>();
+
+        if (!Boolean.TRUE.equals(includeHistory)) {
+            // purpose of Naming to show valid entries
+            //     therefore
+            //         exclude some values unless history requested
+            //         make sure to not exclude present and future values
+            //
+            // exclude not latest
+            //     select * from Name n where
+            //         not(n.latest = false)
+
+            Predicate predicateNotLatest = cb.equal(from.get(NameStructure.FIELD_LATEST), Boolean.FALSE);
+            Predicate predicateExclude   = cb.not(cb.and(predicateNotLatest));
+            predicates.add(predicateExclude);
+        }
+
+        if (deleted != null) {
+            predicates.add(cb.equal(from.get(NameStructure.FIELD_DELETED), deleted));
+        }
+
+        // prepare pattern
+        //     jpa query characters % and _
+        //     remove excess % characters
+
+        if (!StringUtils.isEmpty(uuid)) {
+            predicates.add(cb.and(cb.equal(from.get(NameStructure.FIELD_UUID), RepositoryUtil.preparePattern(uuid))));
+        }
+        if (!StringUtils.isEmpty(name)) {
+            predicates.add(cb.and(cb.like(from.get(Name.FIELD_CONVENTION_NAME), RepositoryUtil.preparePattern(name))));
+        }
+        if (!StringUtils.isEmpty(nameEquivalence)) {
+            predicates.add(cb.and(cb.like(from.get(Name.FIELD_CONVENTION_NAME_EQUIVALENCE), RepositoryUtil.preparePattern(nameEquivalence))));
+        }
+        if (!StringUtils.isEmpty(systemStructure)) {
+            predicates.add(cb.and(cb.like(cb.function(NameStructure.FUNCTION_GET_MNEMONIC_PATH_SYSTEM_STRUCTURE, String.class, from.get(Name.FIELD_CONVENTION_NAME)), RepositoryUtil.preparePattern(systemStructure))));
+        }
+        if (!StringUtils.isEmpty(deviceStructure)) {
+            predicates.add(cb.and(cb.like(cb.function(NameStructure.FUNCTION_GET_MNEMONIC_PATH_DEVICE_STRUCTURE, String.class, from.get(Name.FIELD_CONVENTION_NAME)), RepositoryUtil.preparePattern(deviceStructure))));
+        }
+        if (!StringUtils.isEmpty(index)) {
+            predicates.add(cb.and(cb.like(cb.function(NameStructure.FUNCTION_GET_INSTANCE_INDEX, String.class, from.get(Name.FIELD_CONVENTION_NAME)), RepositoryUtil.preparePattern(index))));
+        }
+        if (!StringUtils.isEmpty(description)) {
+            predicates.add(cb.and(cb.like(from.get(NameStructure.FIELD_DESCRIPTION), RepositoryUtil.preparePattern(description))));
+        }
+        if (!StringUtils.isEmpty(who)) {
+            predicates.add(cb.and(cb.like(from.get(NameStructure.FIELD_REQUESTED_BY), RepositoryUtil.preparePattern(who))));
+        }
+
+        return predicates;
+    }
+
+    /**
+     * Count names history.
+     *
+     * @param uuid uuid
+     * @param name name
+     * @param nameEquivalence name equivalence
+     * @param systemStructure system structure mnemonic
+     * @param deviceStructure device structure mnemonic
+     * @param index index
+     * @param description description
+     * @param who who
+     * @return count of names
+     */
+    public Long countNamesHistory(
+            String uuid, String name, String nameEquivalence, String systemStructure, String deviceStructure, String index, String description, String who) {
+
+        // note
+        //     use of function for mnemonic path
+        //     deleted - null
+        //     includeHistory - true
+        // where
+        //     queryFields, queryValues
+
+        CriteriaBuilder cb = em.getCriteriaBuilder();
+        CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+        Root<Name> from = cq.from(Name.class);
+
+        Subquery<String> sub = cq.subquery(String.class);
+        Root<Name> fromSub = sub.from(Name.class);
+        sub.where(cb.and(preparePredicatesNames(cb, fromSub, null,
+                uuid, name, nameEquivalence, systemStructure, deviceStructure, index, description, who,
+                Boolean.TRUE).toArray(new Predicate[0])));
+        sub.select(fromSub.get(NameStructure.FIELD_UUID));
+
+        cq.where(cb.and(cb.in(from.get(NameStructure.FIELD_UUID)).value(sub)));
+        cq.select(cb.count(from));
+
+        return em.createQuery(cq).getSingleResult();
+    }
+
+    /**
+     * Find names history.
+     *
+     * @param uuid uuid
+     * @param name name
+     * @param nameEquivalence name equivalence
+     * @param systemStructure system structure mnemonic
+     * @param deviceStructure device structure mnemonic
+     * @param index index
+     * @param description description
+     * @param who who
+     * @param orderBy order by
+     * @param isAsc is ascending
+     * @param offset offset
+     * @param limit limit
+     * @return list of names
+     */
+    public List<Name> readNamesHistory(
+            String uuid, String name, String nameEquivalence, String systemStructure, String deviceStructure, String index, String description, String who,
+            FieldName orderBy, Boolean isAsc, Integer offset, Integer limit) {
+
+        // note
+        //     use of function for mnemonic path
+        //     deleted - null
+        //     includeHistory - true
+        // where
+        //     queryFields, queryValues
+        // order
+        //     orderBy, isAsc
+        // paging
+        //     offset, limit
+
+        CriteriaBuilder cb = em.getCriteriaBuilder();
+        CriteriaQuery<Name> cq = cb.createQuery(Name.class);
+        Root<Name> from = cq.from(Name.class);
+
+        Subquery<String> sub = cq.subquery(String.class);
+        Root<Name> fromSub = sub.from(Name.class);
+        sub.where(cb.and(preparePredicatesNames(cb, fromSub, null,
+                uuid, name, nameEquivalence, systemStructure, deviceStructure, index, description, who,
+                Boolean.TRUE).toArray(new Predicate[0])));
+        sub.select(fromSub.get(NameStructure.FIELD_UUID));
+
+        cq.where(cb.and(cb.in(from.get(NameStructure.FIELD_UUID)).value(sub)));
+        cq.select(from);
+
+        if (orderBy != null) {
+            if (BooleanUtils.toBoolean(isAsc)) {
+                if (FieldName.NAME.equals(orderBy)) {
+                    cq.orderBy(cb.asc(from.get(Name.FIELD_CONVENTION_NAME)));
+                } else if (FieldName.NAMEEQUIVALENCE.equals(orderBy)) {
+                    cq.orderBy(cb.asc(from.get(Name.FIELD_CONVENTION_NAME_EQUIVALENCE)));
+                } else if (FieldName.SYSTEMSTRUCTURE.equals(orderBy)) {
+                    cq.orderBy(cb.asc(cb.function(NameStructure.FUNCTION_GET_MNEMONIC_PATH_SYSTEM_STRUCTURE, String.class, from.get(Name.FIELD_CONVENTION_NAME))));
+                } else if (FieldName.DEVICESTRUCTURE.equals(orderBy)) {
+                    cq.orderBy(cb.asc(cb.function(NameStructure.FUNCTION_GET_MNEMONIC_PATH_DEVICE_STRUCTURE, String.class, from.get(Name.FIELD_CONVENTION_NAME))));
+                } else if (FieldName.INDEX.equals(orderBy)) {
+                    cq.orderBy(cb.asc(cb.function(NameStructure.FUNCTION_GET_INSTANCE_INDEX, String.class, from.get(Name.FIELD_CONVENTION_NAME))));
+                } else if (FieldName.DESCRIPTION.equals(orderBy)) {
+                    cq.orderBy(cb.asc(from.get(NameStructure.FIELD_DESCRIPTION)));
+                } else if (FieldName.WHEN.equals(orderBy)) {
+                    cq.orderBy(cb.asc(from.get(NameStructure.FIELD_REQUESTED)));
+                } else {
+                    cq.orderBy(cb.asc(from.get(NameStructure.FIELD_UUID)), cb.asc(from.get(Persistable.FIELD_ID)));
+                }
+            } else {
+                if (FieldName.NAME.equals(orderBy)) {
+                    cq.orderBy(cb.desc(from.get(Name.FIELD_CONVENTION_NAME)));
+                } else if (FieldName.NAMEEQUIVALENCE.equals(orderBy)) {
+                    cq.orderBy(cb.desc(from.get(Name.FIELD_CONVENTION_NAME_EQUIVALENCE)));
+                } else if (FieldName.SYSTEMSTRUCTURE.equals(orderBy)) {
+                    cq.orderBy(cb.desc(cb.function(NameStructure.FUNCTION_GET_MNEMONIC_PATH_SYSTEM_STRUCTURE, String.class, from.get(Name.FIELD_CONVENTION_NAME))));
+                } else if (FieldName.DEVICESTRUCTURE.equals(orderBy)) {
+                    cq.orderBy(cb.desc(cb.function(NameStructure.FUNCTION_GET_MNEMONIC_PATH_DEVICE_STRUCTURE, String.class, from.get(Name.FIELD_CONVENTION_NAME))));
+                } else if (FieldName.INDEX.equals(orderBy)) {
+                    cq.orderBy(cb.desc(cb.function(NameStructure.FUNCTION_GET_INSTANCE_INDEX, String.class, from.get(Name.FIELD_CONVENTION_NAME))));
+                } else if (FieldName.DESCRIPTION.equals(orderBy)) {
+                    cq.orderBy(cb.desc(from.get(NameStructure.FIELD_DESCRIPTION)));
+                } else if (FieldName.WHEN.equals(orderBy)) {
+                    cq.orderBy(cb.desc(from.get(NameStructure.FIELD_REQUESTED)));
+                } else {
+                    cq.orderBy(cb.desc(from.get(NameStructure.FIELD_UUID)), cb.desc(from.get(Persistable.FIELD_ID)));
+                }
+            }
+        }
+
+        TypedQuery<Name> query = em.createQuery(cq);
+        if (offset != null && limit != null) {
+            query.setFirstResult(offset * limit);
+            query.setMaxResults(limit);
+        }
+
+        return query.getResultList();
+    }
+
     /**
      * Count legacy names
      *
@@ -283,11 +499,11 @@ public class NameRepository {
      * Find legacy names.
      *
      * @param name name
-    * @param orderBy order by
-    * @param isAsc is ascending
-    * @param offset offset
-    * @param limit limit
-    * @return list of names
+     * @param orderBy order by
+     * @param isAsc is ascending
+     * @param offset offset
+     * @param limit limit
+     * @return list of names
      * @return
      */
     @SuppressWarnings("unchecked")
@@ -370,76 +586,6 @@ public class NameRepository {
         return query.getResultList();
     }
 
-    /**
-     * Prepare predicates for names.
-     *
-     * @param cb criteria builder
-     * @param from criteria query root
-     * @param deleted deleted
-     * @param uuid uuid
-     * @param name name
-     * @param nameEquivalence name equivalence
-     * @param systemStructure system structure mnemonic
-     * @param deviceStructure device structure mnemonic
-     * @param index index
-     * @param description description
-     * @param includeHistory include history
-     * @return list of predicates
-     */
-    private List<Predicate> preparePredicatesNames(CriteriaBuilder cb, Root<Name> from, Boolean deleted,
-            String uuid, String name, String nameEquivalence, String systemStructure, String deviceStructure, String index, String description,
-            Boolean includeHistory) {
-
-        List<Predicate> predicates = new ArrayList<>();
-
-        if (!Boolean.TRUE.equals(includeHistory)) {
-            // purpose of Naming to show valid entries
-            //     therefore
-            //         exclude some values unless history requested
-            //         make sure to not exclude present and future values
-            //
-            // exclude not latest
-            //     select * from Name n where
-            //         not(n.latest = false)
-
-            Predicate predicateNotLatest = cb.equal(from.get(NameStructure.FIELD_LATEST), Boolean.FALSE);
-            Predicate predicateExclude   = cb.not(cb.and(predicateNotLatest));
-            predicates.add(predicateExclude);
-        }
-
-        if (deleted != null) {
-            predicates.add(cb.equal(from.get(NameStructure.FIELD_DELETED), deleted));
-        }
-
-        // prepare pattern
-        //     jpa query characters % and _
-        //     remove excess % characters
-
-        if (!StringUtils.isEmpty(uuid)) {
-            predicates.add(cb.and(cb.equal(from.get(NameStructure.FIELD_UUID), RepositoryUtil.preparePattern(uuid))));
-        }
-        if (!StringUtils.isEmpty(name)) {
-            predicates.add(cb.and(cb.like(from.get(Name.FIELD_CONVENTION_NAME), RepositoryUtil.preparePattern(name))));
-        }
-        if (!StringUtils.isEmpty(nameEquivalence)) {
-            predicates.add(cb.and(cb.like(from.get(Name.FIELD_CONVENTION_NAME_EQUIVALENCE), RepositoryUtil.preparePattern(nameEquivalence))));
-        }
-        if (!StringUtils.isEmpty(systemStructure)) {
-            predicates.add(cb.and(cb.like(cb.function(NameStructure.FUNCTION_GET_MNEMONIC_PATH_SYSTEM_STRUCTURE, String.class, from.get(Name.FIELD_CONVENTION_NAME)), RepositoryUtil.preparePattern(systemStructure))));
-        }
-        if (!StringUtils.isEmpty(deviceStructure)) {
-            predicates.add(cb.and(cb.like(cb.function(NameStructure.FUNCTION_GET_MNEMONIC_PATH_DEVICE_STRUCTURE, String.class, from.get(Name.FIELD_CONVENTION_NAME)), RepositoryUtil.preparePattern(deviceStructure))));
-        }
-        if (!StringUtils.isEmpty(index)) {
-            predicates.add(cb.and(cb.like(cb.function(NameStructure.FUNCTION_GET_INSTANCE_INDEX, String.class, from.get(Name.FIELD_CONVENTION_NAME)), RepositoryUtil.preparePattern(index))));
-        }
-        if (!StringUtils.isEmpty(description)) {
-            predicates.add(cb.and(cb.like(from.get(NameStructure.FIELD_DESCRIPTION), RepositoryUtil.preparePattern(description))));
-        }
-
-        return predicates;
-    }
-
     /**
      * Persist name into persistence context.
      *
diff --git a/src/main/java/org/openepics/names/rest/api/v1/INames.java b/src/main/java/org/openepics/names/rest/api/v1/INames.java
index f353cb126b99a492d079b5d027235896997bdc1e..463f51ce71678464b729c8d7ae7214e50c3b60a1 100644
--- a/src/main/java/org/openepics/names/rest/api/v1/INames.java
+++ b/src/main/java/org/openepics/names/rest/api/v1/INames.java
@@ -89,30 +89,32 @@ public interface INames {
                      who                      (String)
 
        Methods
-           create    POST   /names                                - createNames                  (List<NameElementCommandCreate>)
-           create    POST   /names/upload                         - createNames                  (MultipartFile)
+           create    POST   /names                                - createNames
+           create    POST   /names/upload                         - createNames                  upload Excel file
            ----------------------------------------------------------------------------------------------------
-           read      GET    /names                                - readNames                    (Boolean, String, String, String, String, String, String, FieldName, Boolean, Integer, Integer)
-           read      GET    /names/download                       - readNamesDownload            (Boolean, String, String, String, String, String, String, FieldName, Boolean, Integer, Integer)
-           read      GET    /names/{name}                         - readNames                    (String, FieldName, Boolean, Integer, Integer)
-           read      GET    /names/systemStructure/{mnemonicPath} - readNamesSystemStructure     (String, FieldName, Boolean, Integer, Integer)
-           read      GET    /names/deviceStructure/{mnemonicPath} - readNamesDeviceStructure     (String, FieldName, Boolean, Integer, Integer)
-           read      GET    /names/history/{uuid}                 - readNamesHistory             (String, FieldName, Boolean, Integer, Integer)
+           read      GET    /names                                - readNames
+           read      GET    /names/download                       - readNamesDownload            download Excel file
+           read      GET    /names/{name}                         - readNames
+           read      GET    /names/systemStructure/{mnemonicPath} - readNamesSystemStructure
+           read      GET    /names/deviceStructure/{mnemonicPath} - readNamesDeviceStructure
+           read      GET    /names/history                        - readNamesHistory
+           read      GET    /names/history/{uuid}                 - readNamesHistory
+           read      GET    /names/legacy                         - readNamesLegacy
            ----------------------------------------------------------------------------------------------------
-           read      GET    /names/equivalence/{name}             - equivalenceName              (String)
-           read      GET    /names/exists/{name}                  - existsName                   (String)
-           read      GET    /names/isLegacy/{name}                - isLegacyName                 (String)
-           read      GET    /names/isValidToCreate/{name}         - isValidToCreateName          (String)
+           read      GET    /names/equivalence/{name}             - equivalenceName
+           read      GET    /names/exists/{name}                  - existsName
+           read      GET    /names/isLegacy/{name}                - isLegacyName
+           read      GET    /names/isValidToCreate/{name}         - isValidToCreateName
            ----------------------------------------------------------------------------------------------------
-           read      GET    /names/validateCreate                 - validateNamesCreate          (List<NameElementCommandCreate>)
-           read      GET    /names/validateUpdate                 - validateNamesUpdate          (List<NameElementCommandUpdate>)
-           read      GET    /names/validateDelete                 - validateNamesDelete          (List<NameElementCommandConfirm>)
+           read      GET    /names/validateCreate                 - validateNamesCreate          hidden from Swagger UI
+           read      GET    /names/validateUpdate                 - validateNamesUpdate          hidden from Swagger UI
+           read      GET    /names/validateDelete                 - validateNamesDelete          hidden from Swagger UI
            ----------------------------------------------------------------------------------------------------
-           update    PUT    /names                                - updateNames                  (List<NameElementCommandUpdate>)
-           update    PUT    /names/upload                         - updateNames                  (MultipartFile)
+           update    PUT    /names                                - updateNames
+           update    PUT    /names/upload                         - updateNames                  upload Excel file
            ----------------------------------------------------------------------------------------------------
-           delete    DELETE /names                                - deleteNames                  (List<NameElementCommandConfirm>)
-           delete    DELETE /names/upload                         - deleteNames                  (MultipartFile)
+           delete    DELETE /names                                - deleteNames
+           delete    DELETE /names/upload                         - deleteNames                  upload Excel file
 
        Note
            read      GET    /names/{name} - both name and uuid (name - exact and search, uuid exact)
@@ -298,6 +300,7 @@ public interface INames {
      * @param deviceStructure device structure mnemonic path
      * @param index index
      * @param description description
+     * @param who who
      * @param orderBy order by field
      * @param isAsc sort order, ascending or descending
      * @param page page starting from 0, offset
@@ -341,13 +344,14 @@ public interface INames {
             produces = {"application/json"})
     public ResponsePageNameElements readNames(
             @Parameter(in = ParameterIn.QUERY, description = "if deleted names are to be included or not, omitted for both deleted and not deleted names") @RequestParam(required = false) Boolean deleted,
-            @Parameter(in = ParameterIn.QUERY, description = "search by uuid") @RequestParam(required = false) String uuid,
+            @Parameter(in = ParameterIn.QUERY, description = "find by uuid") @RequestParam(required = false) String uuid,
             @Parameter(in = ParameterIn.QUERY, description = "search by name") @RequestParam(required = false) String name,
             @Parameter(in = ParameterIn.QUERY, description = "search by name equivalence") @RequestParam(required = false) String nameEquivalence,
             @Parameter(in = ParameterIn.QUERY, description = "search by system structure mnemonic path") @RequestParam(required = false) String systemStructure,
             @Parameter(in = ParameterIn.QUERY, description = "search by device structure mnemonic path") @RequestParam(required = false) String deviceStructure,
             @Parameter(in = ParameterIn.QUERY, description = "search by index") @RequestParam(required = false) String index,
             @Parameter(in = ParameterIn.QUERY, description = "search by description") @RequestParam(required = false) String description,
+            @Parameter(in = ParameterIn.QUERY, description = "search by who") @RequestParam(required = false) String who,
             @Parameter(in = ParameterIn.QUERY, description = "order by field") @RequestParam(required = false) FieldName orderBy,
             @Parameter(in = ParameterIn.QUERY, description = "sort order, ascending or descending") @RequestParam(required = false) Boolean isAsc,
             @Parameter(in = ParameterIn.QUERY, description = "page starting from 0, offset") @RequestParam(required = false, defaultValue = DEFAULT_PAGE) Integer page,
@@ -366,6 +370,7 @@ public interface INames {
      * @param deviceStructure device structure mnemonic path
      * @param index index
      * @param description description
+     * @param who who
      * @param orderBy order by field
      * @param isAsc sort order, ascending or descending
      * @param page page starting from 0, offset
@@ -408,13 +413,14 @@ public interface INames {
             produces = {"application/vnd.ms-excel"})
     public ResponseEntity<Resource> readNamesDownload(
             @Parameter(in = ParameterIn.QUERY, description = "if deleted names are to be included or not, omitted for both deleted and not deleted names") @RequestParam(required = false) Boolean deleted,
-            @Parameter(in = ParameterIn.QUERY, description = "search by uuid") @RequestParam(required = false) String uuid,
+            @Parameter(in = ParameterIn.QUERY, description = "find by uuid") @RequestParam(required = false) String uuid,
             @Parameter(in = ParameterIn.QUERY, description = "search by name") @RequestParam(required = false) String name,
             @Parameter(in = ParameterIn.QUERY, description = "search by name equivalence") @RequestParam(required = false) String nameEquivalence,
             @Parameter(in = ParameterIn.QUERY, description = "search by system structure mnemonic path") @RequestParam(required = false) String systemStructure,
             @Parameter(in = ParameterIn.QUERY, description = "search by device structure mnemonic path") @RequestParam(required = false) String deviceStructure,
             @Parameter(in = ParameterIn.QUERY, description = "search by index") @RequestParam(required = false) String index,
             @Parameter(in = ParameterIn.QUERY, description = "search by description") @RequestParam(required = false) String description,
+            @Parameter(in = ParameterIn.QUERY, description = "search by who") @RequestParam(required = false) String who,
             @Parameter(in = ParameterIn.QUERY, description = "order by field") @RequestParam(required = false) FieldName orderBy,
             @Parameter(in = ParameterIn.QUERY, description = "sort order, ascending or descending") @RequestParam(required = false) Boolean isAsc,
             @Parameter(in = ParameterIn.QUERY, description = "page starting from 0, offset") @RequestParam(required = false, defaultValue = DEFAULT_PAGE) Integer page,
@@ -468,7 +474,7 @@ public interface INames {
             value = "/{name}",
             produces = {"application/json"})
     public ResponsePageNameElements readNames(
-            @Parameter(in = ParameterIn.PATH,  description = "search by name or uuid") @PathVariable("name") String name,
+            @Parameter(in = ParameterIn.PATH,  description = "search by name or find by uuid") @PathVariable("name") String name,
             @Parameter(in = ParameterIn.QUERY, description = "order by field") @RequestParam(required = false) FieldName orderBy,
             @Parameter(in = ParameterIn.QUERY, description = "sort order, ascending or descending") @RequestParam(required = false) Boolean isAsc,
             @Parameter(in = ParameterIn.QUERY, description = "page starting from 0, offset") @RequestParam(required = false, defaultValue = DEFAULT_PAGE) Integer page,
@@ -582,9 +588,82 @@ public interface INames {
             @Parameter(in = ParameterIn.QUERY, description = "page starting from 0, offset") @RequestParam(required = false, defaultValue = DEFAULT_PAGE) Integer page,
             @Parameter(in = ParameterIn.QUERY, description = "page size, limit") @RequestParam(required = false, defaultValue = DEFAULT_PAGE_SIZE) Integer pageSize);
 
+    /**
+     * Find history for name (search).
+     * History consists of lines of uuid.
+     * The line of uuid is not broken in retrieving history. If combination of parameters is found in name entries, the entire lines of uuid are returned.
+     * Return paged list of name elements.
+     *
+     * @param uuid uuid
+     * @param name name
+     * @param nameEquivalence name equivalence
+     * @param systemStructure system structure mnemonic path
+     * @param deviceStructure device structure mnemonic path
+     * @param index index
+     * @param description description
+     * @param who who
+     * @param orderBy order by field
+     * @param isAsc sort order, ascending or descending
+     * @param page page starting from 0, offset
+     * @param pageSize page size, limit
+     * @return paged list of name elements
+     */
+    @Operation(
+            summary     = "Find history for name (search)",
+            description = """
+                          Find history for name (search).
+                          History consists of lines of uuid.
+                          The line of uuid is not broken in retrieving history. If combination of parameters is found in name entries, the entire lines of uuid are returned.
+                          Return paged array of name elements.
+                          """
+    )
+    @ApiResponses(value = {
+            @ApiResponse(
+                    responseCode = "200",
+                    description  = "OK. Return paged array of name elements.",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ResponsePageNameElements.class))),
+            @ApiResponse(
+                    responseCode = "400",
+                    description  = "Bad request. Reason and information such as message, details, field are available.",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = Response.class))),
+            @ApiResponse(
+                    responseCode = "422",
+                    description  = "Unprocessable entity. Reason and information such as message, details, field are available.",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = Response.class))),
+            @ApiResponse(
+                    responseCode = "500",
+                    description  = "Internal server error. Reason and information such as message, details, field are available.",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = Response.class)))
+    })
+    @GetMapping(
+            value = "/history",
+            produces = {"application/json"})
+    public ResponsePageNameElements readNamesHistory(
+            @Parameter(in = ParameterIn.QUERY, description = "find by uuid") @RequestParam(required = false) String uuid,
+            @Parameter(in = ParameterIn.QUERY, description = "search by name") @RequestParam(required = false) String name,
+            @Parameter(in = ParameterIn.QUERY, description = "search by name equivalence") @RequestParam(required = false) String nameEquivalence,
+            @Parameter(in = ParameterIn.QUERY, description = "search by system structure mnemonic path") @RequestParam(required = false) String systemStructure,
+            @Parameter(in = ParameterIn.QUERY, description = "search by device structure mnemonic path") @RequestParam(required = false) String deviceStructure,
+            @Parameter(in = ParameterIn.QUERY, description = "search by index") @RequestParam(required = false) String index,
+            @Parameter(in = ParameterIn.QUERY, description = "search by description") @RequestParam(required = false) String description,
+            @Parameter(in = ParameterIn.QUERY, description = "search by who") @RequestParam(required = false) String who,
+            @Parameter(in = ParameterIn.QUERY, description = "order by field") @RequestParam(required = false, defaultValue = DEFAULT_SORT_FIELD_WHEN) FieldName orderBy,
+            @Parameter(in = ParameterIn.QUERY, description = "sort order, ascending or descending") @RequestParam(required = false, defaultValue = DEFAULT_SORT_ORDER_ASC) Boolean isAsc,
+            @Parameter(in = ParameterIn.QUERY, description = "page starting from 0, offset") @RequestParam(required = false, defaultValue = DEFAULT_PAGE) Integer page,
+            @Parameter(in = ParameterIn.QUERY, description = "page size, limit") @RequestParam(required = false, defaultValue = DEFAULT_PAGE_SIZE) Integer pageSize);
+
     /**
      * Find history for name by uuid (exact match).
      * History consists of line of uuid.
+     * The line of uuid is not broken in retrieving history. If the uuid is found in a name entry, the entire line of uuid is returned.
      * Return paged list of name elements.
      *
      * @param uuid uuid
@@ -599,6 +678,7 @@ public interface INames {
             description = """
                           Find history for name by uuid (exact match).
                           History consists of line of uuid.
+                          The line of uuid is not broken in retrieving history. If the uuid is found in a name entry, the entire line of uuid is returned.
                           Return paged array of name elements.
                           """
     )
@@ -632,7 +712,7 @@ public interface INames {
             value = "/history/{uuid}",
             produces = {"application/json"})
     public ResponsePageNameElements readNamesHistory(
-            @Parameter(in = ParameterIn.PATH,  description = "search by uuid") @PathVariable("uuid") String uuid,
+            @Parameter(in = ParameterIn.PATH,  description = "find by uuid") @PathVariable("uuid") String uuid,
             @Parameter(in = ParameterIn.QUERY, description = "order by field") @RequestParam(required = false, defaultValue = DEFAULT_SORT_FIELD_WHEN) FieldName orderBy,
             @Parameter(in = ParameterIn.QUERY, description = "sort order, ascending or descending") @RequestParam(required = false, defaultValue = DEFAULT_SORT_ORDER_ASC) Boolean isAsc,
             @Parameter(in = ParameterIn.QUERY, description = "page starting from 0, offset") @RequestParam(required = false, defaultValue = DEFAULT_PAGE) Integer page,
diff --git a/src/main/java/org/openepics/names/rest/controller/NamesController.java b/src/main/java/org/openepics/names/rest/controller/NamesController.java
index 61f92e1463c55a71e3c49379b0672c444960e495..a30f1c23744a43c42a4549c04c9e0dcc5958aa87 100644
--- a/src/main/java/org/openepics/names/rest/controller/NamesController.java
+++ b/src/main/java/org/openepics/names/rest/controller/NamesController.java
@@ -152,7 +152,7 @@ public class NamesController implements INames {
 
     @Override
     public ResponsePageNameElements readNames(Boolean deleted,
-            String uuid, String name, String nameEquivalence, String systemStructure, String deviceStructure, String index, String description,
+            String uuid, String name, String nameEquivalence, String systemStructure, String deviceStructure, String index, String description, String who,
             FieldName orderBy, Boolean isAsc, Integer page, Integer pageSize) {
         // validate
         // read names
@@ -160,12 +160,12 @@ public class NamesController implements INames {
         try {
             ValidateNameElementUtil.validateNamesInputRead(
                     deleted,
-                    uuid, name, nameEquivalence, systemStructure, deviceStructure, index, description,
+                    uuid, name, nameEquivalence, systemStructure, deviceStructure, index, description, who,
                     null,
                     orderBy, isAsc,
                     page, pageSize);
             return namesService.readNames(deleted,
-                    uuid, name, nameEquivalence, systemStructure, deviceStructure, index, description,
+                    uuid, name, nameEquivalence, systemStructure, deviceStructure, index, description, who,
                     orderBy, isAsc, page, pageSize);
         } catch (ServiceException e) {
             logService.logServiceException(LOGGER, Level.WARNING, e);
@@ -179,14 +179,14 @@ public class NamesController implements INames {
 
     @Override
     public ResponseEntity<Resource> readNamesDownload(Boolean deleted,
-            String uuid, String name, String nameEquivalence, String systemStructure, String deviceStructure, String index, String description,
+            String uuid, String name, String nameEquivalence, String systemStructure, String deviceStructure, String index, String description, String who,
             FieldName orderBy, Boolean isAsc, Integer page, Integer pageSize) {
         // validate
         // read names
         // convert to output
 
         ResponsePageNameElements nameElements = readNames(deleted,
-                uuid, name, nameEquivalence, systemStructure, deviceStructure, index, description,
+                uuid, name, nameEquivalence, systemStructure, deviceStructure, index, description, who,
                 orderBy, isAsc, page, pageSize);
         InputStreamResource isr = new InputStreamResource(ExcelUtil.nameElementsToExcel(nameElements));
         return ResponseEntity.ok()
@@ -254,6 +254,35 @@ public class NamesController implements INames {
         }
     }
 
+    @Override
+    public ResponsePageNameElements readNamesHistory(
+            String uuid, String name, String nameEquivalence, String systemStructure, String deviceStructure, String index, String description, String who,
+            FieldName orderBy, Boolean isAsc, Integer page, Integer pageSize) {
+        // validate
+        // read names
+
+        try {
+            ValidateUtil.validateInputAvailable(
+                    !ValidateUtil.areAllNull(uuid, name, nameEquivalence, systemStructure, deviceStructure, index, description, who));
+            ValidateNameElementUtil.validateNamesInputRead(
+                    null,
+                    uuid, name, nameEquivalence, systemStructure, deviceStructure, index, description, who,
+                    null,
+                    orderBy, isAsc,
+                    page, pageSize);
+            return namesService.readNamesHistory(
+                    uuid, name, nameEquivalence, systemStructure, deviceStructure, index, description, who,
+                    orderBy, isAsc, page, pageSize);
+        } catch (ServiceException e) {
+            logService.logServiceException(LOGGER, Level.WARNING, e);
+            logService.logStackTraceElements(LOGGER, Level.WARNING, e);
+            throw e;
+        } catch (Exception e) {
+            logService.logStackTraceElements(LOGGER, Level.WARNING, e);
+            throw e;
+        }
+    }
+
     @Override
     public ResponsePageNameElements readNamesHistory(String uuid,
             FieldName orderBy, Boolean isAsc, Integer page, Integer pageSize) {
diff --git a/src/main/java/org/openepics/names/rest/controller/ReportController.java b/src/main/java/org/openepics/names/rest/controller/ReportController.java
index 146c0f5adc9d8ed2ec40182be2e8cbff05844dd1..5ae9c2d478f643bbdffaca6386fce4a446f1f4b6 100644
--- a/src/main/java/org/openepics/names/rest/controller/ReportController.java
+++ b/src/main/java/org/openepics/names/rest/controller/ReportController.java
@@ -139,9 +139,9 @@ public class ReportController {
         // prepare metrics
         //     read names - latest, latest deleted, latest not deleted
         //     count names - kind of name
-        ResponsePageNameElements nameElementsEssNames = namesService.readNames(null, null, null, null, null, null, null, null, Boolean.FALSE, null, null, null, null);
-        ResponsePageNameElements nameElementsEssNamesDeleted = namesService.readNames(Boolean.TRUE, null, null, null, null, null, null, null, Boolean.FALSE, null, null, null, null);
-        ResponsePageNameElements nameElementsEssNamesNotDeleted = namesService.readNames(Boolean.FALSE, null, null, null, null, null, null, null, Boolean.FALSE, null, null, null, null);
+        ResponsePageNameElements nameElementsEssNames = namesService.readNames(null, null, null, null, null, null, null, null, null, Boolean.FALSE, null, null, null, null);
+        ResponsePageNameElements nameElementsEssNamesDeleted = namesService.readNames(Boolean.TRUE, null, null, null, null, null, null, null, null, Boolean.FALSE, null, null, null, null);
+        ResponsePageNameElements nameElementsEssNamesNotDeleted = namesService.readNames(Boolean.FALSE, null, null, null, null, null, null, null, null, Boolean.FALSE, null, null, null, null);
         ResponsePageNameElements nameElementsEssNamesNotDeletedLegacy = namesService.readNamesLegacy(null, null, null, null, null);
 
         long nbrEssNameSystemstructure = 0;
diff --git a/src/main/java/org/openepics/names/service/NamesService.java b/src/main/java/org/openepics/names/service/NamesService.java
index e69af5870999eea46ec36733aecd42722796ca7e..cb099d6dd6bf42dcc540f877056d867e74271e21 100644
--- a/src/main/java/org/openepics/names/service/NamesService.java
+++ b/src/main/java/org/openepics/names/service/NamesService.java
@@ -228,15 +228,15 @@ public class NamesService {
     // ----------------------------------------------------------------------------------------------------
 
     public ResponsePageNameElements readNames(Boolean deleted,
-            String uuid, String name, String nameEquivalence, String systemStructure, String deviceStructure, String index, String description,
+            String uuid, String name, String nameEquivalence, String systemStructure, String deviceStructure, String index, String description, String who,
             FieldName orderBy, Boolean isAsc, Integer offset, Integer limit) {
         return readNames(deleted,
-                uuid, name, nameEquivalence, systemStructure, deviceStructure, index, description,
+                uuid, name, nameEquivalence, systemStructure, deviceStructure, index, description, who,
                 Boolean.FALSE, orderBy, isAsc, offset, limit);
     }
 
     public ResponsePageNameElements readNames(Boolean deleted,
-            String uuid, String name, String nameEquivalence, String systemStructure, String deviceStructure, String index, String description,
+            String uuid, String name, String nameEquivalence, String systemStructure, String deviceStructure, String index, String description, String who,
             Boolean includeHistory, FieldName orderBy, Boolean isAsc, Integer offset, Integer limit) {
         // validation outside method
         // read names
@@ -251,6 +251,7 @@ public class NamesService {
             LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_NAMES, "deviceStructure", deviceStructure));
             LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_NAMES, "index", index));
             LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_NAMES, "description", description));
+            LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_NAMES, "who", who));
             LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_NAMES, "includeHistory", includeHistory));
             LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_NAMES, "orderBy", orderBy));
             LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_NAMES, "isAsc", isAsc));
@@ -258,8 +259,15 @@ public class NamesService {
             LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_NAMES, "limit", limit));
         }
 
-        List<Name> names = nameRepository.readNames(deleted, uuid, name, nameEquivalence, systemStructure, deviceStructure, index, description, includeHistory, orderBy, isAsc, offset, limit);
-        Long totalCount = nameRepository.countNames(deleted, uuid, name, nameEquivalence, systemStructure, deviceStructure, index, description, includeHistory);
+        List<Name> names = null;
+        Long totalCount = null;
+        if (Boolean.TRUE.equals(includeHistory)) {
+            names = nameRepository.readNamesHistory(uuid, name, nameEquivalence, systemStructure, deviceStructure, index, description, who, orderBy, isAsc, offset, limit);
+            totalCount = nameRepository.countNamesHistory(uuid, name, nameEquivalence, systemStructure, deviceStructure, index, description, who);
+        } else {
+            names = nameRepository.readNames(deleted, uuid, name, nameEquivalence, systemStructure, deviceStructure, index, description, who, includeHistory, orderBy, isAsc, offset, limit);
+            totalCount = nameRepository.countNames(deleted, uuid, name, nameEquivalence, systemStructure, deviceStructure, index, description, who, includeHistory);
+        }
 
         final List<NameElement> nameElements = NameElementUtil.getNameElements(names);
 
@@ -290,7 +298,7 @@ public class NamesService {
             }
         } catch (IllegalArgumentException e) {
             return readNames(false,
-                    null, name, null, null, null, null, null,
+                    null, name, null, null, null, null, null, null,
                     orderBy, isAsc, offset, limit);
         }
 
@@ -303,10 +311,10 @@ public class NamesService {
         // read mnemonic path
         // return name elements
 
-        LOGGER.log(Level.FINE, () -> MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, "Read names system structure", "mnemonicPath", mnemonicPath));
+        LOGGER.log(Level.FINE, () -> MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_NAMES_SYSTEM_STRUCTURE, "mnemonicPath", mnemonicPath));
 
         return readNames(false,
-                null, null, null, mnemonicPath, null, null, null,
+                null, null, null, mnemonicPath, null, null, null, null,
                 orderBy, isAsc, offset, limit);
     }
 
@@ -316,23 +324,50 @@ public class NamesService {
         // read mnemonic path
         // return name elements
 
-        LOGGER.log(Level.FINE, () -> MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, "Read names device structure", "mnemonicPath", mnemonicPath));
+        LOGGER.log(Level.FINE, () -> MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_NAMES_DEVICE_STRUCTURE, "mnemonicPath", mnemonicPath));
 
         return readNames(false,
-                null, null, null, null,mnemonicPath, null, null,
+                null, null, null, null,mnemonicPath, null, null, null,
                 orderBy, isAsc, offset, limit);
     }
 
+    public ResponsePageNameElements readNamesHistory(
+            String uuid, String name, String nameEquivalence, String systemStructure, String deviceStructure, String index, String description, String who,
+            FieldName orderBy, Boolean isAsc, Integer offset, Integer limit) {
+        // validation outside method
+        // read history for name
+        // return name elements for names
+
+        if (LOGGER.isLoggable(Level.FINE)) {
+            LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_NAMES_HISTORY, "uuid", uuid));
+            LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_NAMES_HISTORY, "name", name));
+            LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_NAMES_HISTORY, "nameEquivalence", nameEquivalence));
+            LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_NAMES_HISTORY, "systemStructure", systemStructure));
+            LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_NAMES_HISTORY, "deviceStructure", deviceStructure));
+            LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_NAMES_HISTORY, "index", index));
+            LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_NAMES_HISTORY, "description", description));
+            LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_NAMES_HISTORY, "who", who));
+            LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_NAMES_HISTORY, "orderBy", orderBy));
+            LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_NAMES_HISTORY, "isAsc", isAsc));
+            LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_NAMES_HISTORY, "offset", offset));
+            LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_NAMES_HISTORY, "limit", limit));
+        }
+
+        return readNames(null,
+                uuid, name, nameEquivalence, systemStructure, deviceStructure, index, description, who,
+                Boolean.TRUE, orderBy, isAsc, offset, limit);
+    }
+
     public ResponsePageNameElements readNamesHistory(String uuid,
             FieldName orderBy, Boolean isAsc, Integer offset, Integer limit) {
         // validation outside method
         // read history for name
         // return name elements for names
 
-        LOGGER.log(Level.FINE, () -> MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, "Read names history", "uuid", uuid));
+        LOGGER.log(Level.INFO, () -> MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_NAMES_HISTORY, "uuid", uuid));
 
         return readNames(null,
-                uuid, null, null, null, null, null, null,
+                uuid, null, null, null, null, null, null, null,
                 Boolean.TRUE, orderBy, isAsc, offset, limit);
     }
 
@@ -371,7 +406,7 @@ public class NamesService {
         // validation outside method
         // read equivalence
 
-        LOGGER.log(Level.FINE, () -> MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, "Equivalence name", "name", name));
+        LOGGER.log(Level.FINE, () -> MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.EQUIVALENCE_NAME, "name", name));
 
         return namingConvention.equivalenceClassRepresentative(name);
     }
@@ -380,10 +415,10 @@ public class NamesService {
         // validation outside method
         // read exists
 
-        LOGGER.log(Level.FINE, () -> MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, "Exists name", "name", name));
+        LOGGER.log(Level.FINE, () -> MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.EXISTS_NAME, "name", name));
 
         List<Name> names = nameRepository.readNames(false,
-                null, name, null, null, null, null, null);
+                null, name, null, null, null, null, null, null);
         return !names.isEmpty();
     }
 
@@ -393,9 +428,9 @@ public class NamesService {
         // note
         //     legacy - name exists but either parent does not exist (latest, not deleted, by uuid)
 
-        LOGGER.log(Level.FINE, () -> MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, "Is legacy name", "name", name));
+        LOGGER.log(Level.FINE, () -> MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.IS_LEGACY_NAME, "name", name));
 
-        List<Name> names = nameRepository.readNames(false, null, name, null, null, null, null, null);
+        List<Name> names = nameRepository.readNames(false, null, name, null, null, null, null, null, null);
         ExceptionUtil.validateConditionDataNotFoundException(ValidateUtil.isSize(names, 1), "name not found", name, null);
 
         Name toBeChecked = names.get(0);
@@ -470,7 +505,7 @@ public class NamesService {
         // validation outside method
         // validate data - not exists
 
-        LOGGER.log(Level.FINE, () -> MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, "Is valid to create name", "name", name));
+        LOGGER.log(Level.FINE, () -> MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.IS_VALID_TO_CREATE_NAME, "name", name));
 
         // initiate holder of system and device structure content, for performance reasons
         //     note false to not include deleted entries
diff --git a/src/main/java/org/openepics/names/util/TextUtil.java b/src/main/java/org/openepics/names/util/TextUtil.java
index 008fec0c59bcadb71b9a7453f22a02fc89a3848c..0280213333a61922d5afa7db84a506f276212f4a 100644
--- a/src/main/java/org/openepics/names/util/TextUtil.java
+++ b/src/main/java/org/openepics/names/util/TextUtil.java
@@ -133,18 +133,27 @@ public class TextUtil {
     public static final String ELEMENT_IN                         = "element (in)";
     public static final String ELEMENT_OUT                        = "element (out)";
     public static final String NOTIFICATION                       = "notification";
+    public static final String PREPARE_NOTIFICATION               = "Prepare notification";
+
     public static final String CREATE_NAME                        = "Create name";
     public static final String UPDATE_NAME                        = "Update name";
     public static final String DELETE_NAME                        = "Delete name";
+    public static final String READ_NAMES                         = "Read names";
+    public static final String READ_NAMES_SYSTEM_STRUCTURE        = "Read names system structure";
+    public static final String READ_NAMES_DEVICE_STRUCTURE        = "Read names device structure";
+    public static final String READ_NAMES_HISTORY                 = "Read names history";
+    public static final String EQUIVALENCE_NAME                   = "Equivalence name";
+    public static final String EXISTS_NAME                        = "Exists name";
+    public static final String IS_LEGACY_NAME                     = "Is legacy name";
+    public static final String IS_VALID_TO_CREATE_NAME            = "Is valid to create name";
+
     public static final String CREATE_STRUCTURE                   = "Create structure";
     public static final String UPDATE_STRUCTURE                   = "Update structure";
     public static final String DELETE_STRUCTURE                   = "Delete structure";
     public static final String APPROVE_STRUCTURE                  = "Approve structure";
     public static final String CANCEL_STRUCTURE                   = "Cancel structure";
     public static final String REJECT_STRUCTURE                   = "Reject structure";
-    public static final String READ_NAMES                         = "Read names";
     public static final String READ_STRUCTURES                    = "Read structures";
-    public static final String PREPARE_NOTIFICATION               = "Prepare notification";
 
     /**
      * This class is not to be instantiated.
diff --git a/src/main/java/org/openepics/names/util/ValidateNameElementUtil.java b/src/main/java/org/openepics/names/util/ValidateNameElementUtil.java
index aa37d8bac7a735d5c5291990575973432c7d3c39..fb6da8304d5a88470aa71941d0e56c78d084aab0 100644
--- a/src/main/java/org/openepics/names/util/ValidateNameElementUtil.java
+++ b/src/main/java/org/openepics/names/util/ValidateNameElementUtil.java
@@ -72,6 +72,7 @@ public class ValidateNameElementUtil {
      * @param deviceStructure device structure mnemonic
      * @param index index
      * @param description description
+     * @param who, who
      * @param includeHistory include history
      * @param orderBy order by
      * @param isAsc is ascending
@@ -79,7 +80,7 @@ public class ValidateNameElementUtil {
      * @param limit limit
      */
     public static void validateNamesInputRead(Boolean deleted,
-            String uuid, String name, String nameEquivalence, String systemStructure, String deviceStructure, String index, String description,
+            String uuid, String name, String nameEquivalence, String systemStructure, String deviceStructure, String index, String description, String who,
             Boolean includeHistory, FieldName orderBy, Boolean isAsc, Integer offset, Integer limit) {
 
         // validate input
@@ -249,7 +250,7 @@ public class ValidateNameElementUtil {
         //     update, delete - uuid available, not deleted
         //     retrieve for uuid and check
         if (ValidateUtil.isAnyEqual(nameCommand, NameCommand.UPDATE, NameCommand.DELETE)) {
-            List<Name> names = nameRepository.readNames(false, uuid.toString(), null, null, null, null, null, null);
+            List<Name> names = nameRepository.readNames(false, uuid.toString(), null, null, null, null, null, null, null);
             ExceptionUtil.validateConditionDataNotFoundException(ValidateUtil.isSize(names, 1),
                     TextUtil.DATA_IS_NOT_FOUND, details, TextUtil.UUID);
         }
@@ -329,7 +330,7 @@ public class ValidateNameElementUtil {
 
             // name
             //     ok with same name, name equivalence if same uuid
-            List<Name> names = nameRepository.readNames(false, null, derivedName, null, null, null, null, null);
+            List<Name> names = nameRepository.readNames(false, null, derivedName, null, null, null, null, null, null);
             if (NameCommand.CREATE.equals(nameCommand)) {
                 condition = ValidateUtil.isNullOrEmpty(names);
             } else {
@@ -339,7 +340,7 @@ public class ValidateNameElementUtil {
             ExceptionUtil.validateConditionDataConflictException(condition,
                     TextUtil.CONVENTION_NAME_EXISTS, details, TextUtil.PARENTSYSTEMSTRUCTURE);
 
-            names = nameRepository.readNames(false, null, null, namingConvention.equivalenceClassRepresentative(derivedName), null, null, null, null);
+            names = nameRepository.readNames(false, null, null, namingConvention.equivalenceClassRepresentative(derivedName), null, null, null, null, null);
             if (NameCommand.CREATE.equals(nameCommand)) {
                 condition = ValidateUtil.isNullOrEmpty(names);
             } else {
@@ -468,11 +469,11 @@ public class ValidateNameElementUtil {
         ExceptionUtil.validateConditionDataNotCorrectException(StringUtils.equals(name, derivedName),
                 TextUtil.CONVENTION_NAME_IS_NOT_CORRECT, details, field);
 
-        List<Name> names = holderRepositories.nameRepository().readNames(false, null, name, null, null, null, null, null);
+        List<Name> names = holderRepositories.nameRepository().readNames(false, null, name, null, null, null, null, null, null);
         ExceptionUtil.validateConditionDataConflictException(names.isEmpty(),
                 TextUtil.CONVENTION_NAME_EXISTS, details, field);
 
-        names = holderRepositories.nameRepository().readNames(false, null, null, namingConvention.equivalenceClassRepresentative(name), null, null, null, null);
+        names = holderRepositories.nameRepository().readNames(false, null, null, namingConvention.equivalenceClassRepresentative(name), null, null, null, null, null);
         ExceptionUtil.validateConditionDataConflictException(names.isEmpty(),
                 TextUtil.CONVENTION_NAME_EQUIVALENCE_EXISTS, details, field);
     }
diff --git a/src/main/java/org/openepics/names/util/ValidateUtil.java b/src/main/java/org/openepics/names/util/ValidateUtil.java
index 7094dcd97f0d7362cd3a3493332b5b24faf622d0..a49d1c3f1c701193c108924b1d46861f99ed6f8e 100644
--- a/src/main/java/org/openepics/names/util/ValidateUtil.java
+++ b/src/main/java/org/openepics/names/util/ValidateUtil.java
@@ -177,6 +177,11 @@ public class ValidateUtil {
         }
     }
 
+    public static void validateInputAvailable(boolean inputAvailable) {
+        ExceptionUtil.validateConditionInputNotAvailableException(inputAvailable,
+                TextUtil.VALUE_IS_NOT_AVAILABLE, null, null);
+    }
+
     // ----------------------------------------------------------------------------------------------------
 
     /**
@@ -275,6 +280,25 @@ public class ValidateUtil {
         return false;
     }
 
+    /**
+     * Validate given objects such that <tt>true</tt> is returned if all objects are null.
+     * This may be used to validate that given objects are not null.
+     *
+     * @param values values
+     * @return boolean if validation is ok
+     */
+    public static boolean areAllNull(Object... values) {
+        if (values == null) {
+            return true;
+        }
+        for (Object value : values) {
+            if (value != null) {
+                return false;
+            }
+        }
+        return true;
+    }
+
     /**
      * Validate given enums such that <tt>true</tt> is returned if any enum in values is equal to given input enum.
      *
diff --git a/src/main/resources/static/pdfs/naming_rest_api_brief_introduction.pdf b/src/main/resources/static/pdfs/naming_rest_api_brief_introduction.pdf
index 04f08ee6b32ef01dd12888887e73e2e52a8cc47e..a57e2cddc350ad52c2edff95c7e9fca4b8b6d80a 100644
Binary files a/src/main/resources/static/pdfs/naming_rest_api_brief_introduction.pdf and b/src/main/resources/static/pdfs/naming_rest_api_brief_introduction.pdf differ
diff --git a/src/main/resources/static/pdfs/naming_rest_api_migration.pdf b/src/main/resources/static/pdfs/naming_rest_api_migration.pdf
index 74cde2c881182cfd7b0eab7f84ebf84ffd42dd11..a03af63e32af5099877147527b8461d414db1b1a 100644
Binary files a/src/main/resources/static/pdfs/naming_rest_api_migration.pdf and b/src/main/resources/static/pdfs/naming_rest_api_migration.pdf differ
diff --git a/src/test/java/org/openepics/names/docker/NamesIT.java b/src/test/java/org/openepics/names/docker/NamesIT.java
index dbd9fb2be13c9f99e8d21f50e89b5f0352a723bb..abfbd8e9622e4aa27b276b97c33e70245d924f43 100644
--- a/src/test/java/org/openepics/names/docker/NamesIT.java
+++ b/src/test/java/org/openepics/names/docker/NamesIT.java
@@ -1005,6 +1005,17 @@ class NamesIT {
             ITUtilNameElement.assertRead("?description=updated description%",      1, -1);
             ITUtilNameElement.assertRead("?description=updated description again", 1);
 
+            ITUtilNameElement.assertRead("?who=test who",          8, -1);
+            ITUtilNameElement.assertRead("?who=test",              0);
+            ITUtilNameElement.assertRead("?who=who",               0);
+            ITUtilNameElement.assertRead("?who=test%",             8, -1);
+            ITUtilNameElement.assertRead("?who=%who",              8, -1);
+            ITUtilNameElement.assertRead("?who=%est%",             8, -1);
+            ITUtilNameElement.assertRead("?who=%wh%",              8, -1);
+            ITUtilNameElement.assertRead("?who=wh%",               0);
+            ITUtilNameElement.assertRead("?who=asdf",              0);
+            ITUtilNameElement.assertRead("?who=%asdf%",            0);
+
             ITUtilNameElement.assertRead("?nameEquivalence=RFQ-10%&deviceStructure=EMR-FS", 6, -1);
 
             // name or uuid
@@ -1045,6 +1056,20 @@ class NamesIT {
             ITUtilNameElement.assertRead("/history/" + deviceTypeFS.toString(),   0);
             ITUtilNameElement.assertRead("/history/" + uuid.toString(),           3);
             ITUtilNameElement.assertRead("/history/" + uuid2.toString(),          1);
+
+            //     /history?parameter=value
+            //         parameter must be available
+            ITUtilNameElement.assertRead("/history?uuid=" + uuid.toString(),           3);
+            ITUtilNameElement.assertRead("/history?uuid=" + uuid2.toString(),          1);
+            ITUtilNameElement.assertRead("/history?name=%010%",                       14, -1);
+            ITUtilNameElement.assertRead("/history?nameEquivalence=RFQ-10%",          14, -1);
+            ITUtilNameElement.assertRead("/history?systemStructure=RFQ-0__",          13, -1);
+            ITUtilNameElement.assertRead("/history?deviceStructure=EMR-FS",           12, -1);
+            ITUtilNameElement.assertRead("/history?index=003",                         1, -1);
+            ITUtilNameElement.assertRead("/history?description=updated description%",  3, -1);
+            ITUtilNameElement.assertRead("/history?who=test%",                         8, -1);
+
+            ITUtilNameElement.assertRead("/history?uuid=" + uuid.toString() + "&description=updated%", 3);
         } catch (Exception e) {
             fail();
         }
diff --git a/src/test/java/org/openepics/names/util/ValidateUtilTest.java b/src/test/java/org/openepics/names/util/ValidateUtilTest.java
index 00fab6391f6a0248774df52f41549af81a168ef1..82822acbe9cb962d1c8b9bdc2d3f8e9b1580ca12 100644
--- a/src/test/java/org/openepics/names/util/ValidateUtilTest.java
+++ b/src/test/java/org/openepics/names/util/ValidateUtilTest.java
@@ -553,6 +553,39 @@ class ValidateUtilTest {
         assertEquals(expected, ValidateUtil.isAnyNull(s, i, f));
     }
 
+    /**
+     * Test of validate an array if all objects in array are null.
+     */
+    @Test
+    void areAllNull() {
+        String s = null;
+        Calendar c = null;
+
+        assertTrue (ValidateUtil.areAllNull(s));
+        assertTrue (ValidateUtil.areAllNull(c));
+        assertTrue (ValidateUtil.areAllNull(s, c));
+
+        s = "a";
+
+        assertFalse(ValidateUtil.areAllNull(s));
+        assertTrue (ValidateUtil.areAllNull(c));
+        assertFalse(ValidateUtil.areAllNull(s, c));
+
+        s = null;
+        c = Calendar.getInstance();
+
+        assertTrue (ValidateUtil.areAllNull(s));
+        assertFalse(ValidateUtil.areAllNull(c));
+        assertFalse(ValidateUtil.areAllNull(s, c));
+
+        s = "a";
+        c = Calendar.getInstance();
+
+        assertFalse(ValidateUtil.areAllNull(s));
+        assertFalse(ValidateUtil.areAllNull(c));
+        assertFalse(ValidateUtil.areAllNull(s, c));
+    }
+
     /**
      * Test to validate an array if any object is equal to given enum.
      */
@@ -636,7 +669,7 @@ class ValidateUtilTest {
     @Test
     void validateInputReadNames() {
         ValidateNameElementUtil.validateNamesInputRead(
-                null, null, null, null, null, null, null, null,
+                null, null, null, null, null, null, null, null, null,
                 null, null, null, null, null);
     }