diff --git a/smp-angular/src/app/app.module.ts b/smp-angular/src/app/app.module.ts
index ad34702c5489ad0eb2049774da49fa83014daf1d..7fd94163d9f1a9451053a243a702d12cd48640ca 100644
--- a/smp-angular/src/app/app.module.ts
+++ b/smp-angular/src/app/app.module.ts
@@ -147,6 +147,7 @@ import {DnsToolsService} from "./tools/dns-tools/dns-tools.service";
 import {
   DnsQueryPanelComponent
 } from "./tools/dns-tools/dns-query-panel/dns-query-panel.component";
+import {ResourceFilterOptionsService} from "./common/services/resource-filter-options.service";
 
 
 @NgModule({
@@ -296,6 +297,7 @@ import {
     GlobalLookups,
     HttpEventService,
     NavigationService,
+    ResourceFilterOptionsService,
     SecurityEventService,
     SecurityService,
     SmlIntegrationService,
diff --git a/smp-angular/src/app/common/model/resource-filter-options-ro.model.ts b/smp-angular/src/app/common/model/resource-filter-options-ro.model.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ed8232347a749d1c86877a2540ccdc611c791d74
--- /dev/null
+++ b/smp-angular/src/app/common/model/resource-filter-options-ro.model.ts
@@ -0,0 +1,7 @@
+export interface ResourceFilterOptionsRo {
+
+  availableDomains: string[];
+
+  availableDocumentTypes: string[];
+
+}
diff --git a/smp-angular/src/app/common/search-table/search-table.component.html b/smp-angular/src/app/common/search-table/search-table.component.html
index b09d92dcdc7bbe6ca85c402ce2efa2ef57249f32..b8f114aa06dcf7242ddfc4bcaa7f780cd3b2840d 100644
--- a/smp-angular/src/app/common/search-table/search-table.component.html
+++ b/smp-angular/src/app/common/search-table/search-table.component.html
@@ -7,10 +7,13 @@
           <form name="filterForm" #filterForm="ngForm" (ngSubmit)="search()">
             <ng-container *ngTemplateOutlet="searchPanel"></ng-container>
             <div class="searchArea">
-              <button mat-raised-button color="primary" [disabled]="!filterForm.form.valid" id="searchbutton_id">
-                <mat-icon>search</mat-icon>
-                <span>Search</span>
-              </button>
+              <mat-toolbar-row class="smp-toolbar-row">
+                <button mat-raised-button color="primary" [disabled]="!filterForm.form.valid" id="searchbutton_id">
+                  <mat-icon>search</mat-icon>
+                  <span>Search</span>
+                </button>
+                <ng-container *ngTemplateOutlet="additionalSearchAreaButtons"></ng-container>
+              </mat-toolbar-row>
             </div>
           </form>
         </div>
diff --git a/smp-angular/src/app/common/search-table/search-table.component.ts b/smp-angular/src/app/common/search-table/search-table.component.ts
index 46c9dadb576b6749ce0bb35516f9671b974a1db5..640830819195e3eab2d6007616f298d9595d84d5 100644
--- a/smp-angular/src/app/common/search-table/search-table.component.ts
+++ b/smp-angular/src/app/common/search-table/search-table.component.ts
@@ -30,6 +30,7 @@ export class SearchTableComponent implements OnInit {
   @ViewChild('rowExpand', {static: true}) rowExpand: TemplateRef<any>;
   @ViewChild('rowIndex', {static: true}) rowIndex: TemplateRef<any>;
   @Input() additionalToolButtons: TemplateRef<any>;
+  @Input() additionalSearchAreaButtons: TemplateRef<any>;
   @Input() additionalRowActionButtons: TemplateRef<any>;
   @Input() searchPanel: TemplateRef<any>;
   @Input() tableRowDetailContainer: TemplateRef<any>;
diff --git a/smp-angular/src/app/common/services/resource-filter-options.service.ts b/smp-angular/src/app/common/services/resource-filter-options.service.ts
new file mode 100644
index 0000000000000000000000000000000000000000..12ae585d83f6331d2b220b0bf8e5766f9ed67042
--- /dev/null
+++ b/smp-angular/src/app/common/services/resource-filter-options.service.ts
@@ -0,0 +1,15 @@
+import {Injectable} from "@angular/core";
+import {HttpClient} from "@angular/common/http";
+import {Observable} from "rxjs";
+import {SmpConstants} from "../../smp.constants";
+import {ResourceFilterOptionsRo} from "../model/resource-filter-options-ro.model";
+
+@Injectable()
+export class ResourceFilterOptionsService {
+
+  constructor(private http: HttpClient) { }
+
+  getResourceFilterOptions$(): Observable<ResourceFilterOptionsRo> {
+    return this.http.get<ResourceFilterOptionsRo>(SmpConstants.REST_PUBLIC_SEARCH_RESOURCE_METADATA);
+  }
+}
diff --git a/smp-angular/src/app/resource-search/resource-search.component.html b/smp-angular/src/app/resource-search/resource-search.component.html
index ecb41d8f46c089142d7cb91a290b1658bfbc69de..ca86e8949133c3f51a310ab26430b9f13dbcfd05 100644
--- a/smp-angular/src/app/resource-search/resource-search.component.html
+++ b/smp-angular/src/app/resource-search/resource-search.component.html
@@ -1,9 +1,10 @@
-<smp-search-table  #searchTable
+<smp-search-table #searchTable
   page_id='search_id'
   [title]="'Search'"
   [columnPicker]="columnPicker"
   [url]="baseUrl"
   [additionalToolButtons]="additionalToolButtons"
+  [additionalSearchAreaButtons]="additionalSearchAreaButtons"
   [searchPanel]="searchPanel"
   [filter]="filter"
   [searchTableController]="resourceSearchController"
@@ -16,7 +17,6 @@
        href="{{contextPath}}{{createResourceURL(row)}}">Open URL</a>
   </ng-template>
 
-
   <ng-template #searchPanel>
     <div style="display: flex;flex-direction: row;width: 100%">
     <mat-form-field class="smp-data-panel-field">
@@ -30,15 +30,44 @@
       <input matInput  name="ResourceScheme" [(ngModel)]="filter.participantScheme"
              #messageId="ngModel" id="ResourceScheme">
     </mat-form-field>
+    <mat-form-field class="smp-data-panel-field">
+      <mat-label>Domain</mat-label>
+      <mat-select class="mat-select" placeholder="Domain"
+                  matTooltip="Domain"
+                  id="Domain"
+                  [(value)]="filter.domainCode">
+        <mat-option *ngFor="let domainCode of domainList"
+                    [value]="domainCode">
+          {{domainCode}}
+        </mat-option>
+      </mat-select>
+    </mat-form-field>
+      <mat-form-field class="smp-data-panel-field">
+        <mat-label>Document Type</mat-label>
+        <mat-select class="mat-select" placeholder="Document type"
+                    matTootip="Document type"
+                    id="DocumentType"
+                    [(value)]="filter.documentType">
+          <mat-option *ngFor="let documentType of documentTypeList"
+                      [value]="documentType">
+            {{documentType}}
+          </mat-option>
+        </mat-select>
+      </mat-form-field>
     </div>
   </ng-template>
 
+  <ng-template #additionalSearchAreaButtons>
+    <button mat-raised-button color="primary" (click)="clearFilters()" id="clearallbutton_id">
+      <mat-icon>search</mat-icon>
+      <span>Clear All</span>
+    </button>
+  </ng-template>
 
   <ng-template #additionalToolButtons>
   </ng-template>
 
   <ng-template #tableRowDetailContainer let-row="row">
-
     <div *ngIf="row.serviceMetadata.length===0" style="padding-left:20px;">
       No subresources
     </div>
@@ -64,8 +93,6 @@
             URL</a>
         </ng-template>
       </ngx-datatable>
-
     </div>
   </ng-template>
-
 </smp-search-table>
diff --git a/smp-angular/src/app/resource-search/resource-search.component.ts b/smp-angular/src/app/resource-search/resource-search.component.ts
index 9f78ec7bf591319e08d44bea282174a5eddacaea..6e1ded78c1bd4c9cc6f105aa424087f8d8240370 100644
--- a/smp-angular/src/app/resource-search/resource-search.component.ts
+++ b/smp-angular/src/app/resource-search/resource-search.component.ts
@@ -18,6 +18,8 @@ import {GlobalLookups} from "../common/global-lookups";
 import {SearchTableComponent} from "../common/search-table/search-table.component";
 import {ResourceSearchRo} from "./resource-search-ro.model";
 import {SubresourceSearchRo} from "./subresource-search-ro.model";
+import {ResourceFilterOptionsService} from "../common/services/resource-filter-options.service";
+import {ResourceFilterOptionsRo} from "../common/model/resource-filter-options-ro.model";
 
 @Component({
   templateUrl: './resource-search.component.html',
@@ -34,19 +36,29 @@ export class ResourceSearchComponent implements OnInit, AfterViewInit, AfterView
   filter: any = {};
   contextPath: string = location.pathname.substring(0, location.pathname.length - 3); // remove /ui s
   baseUrl: string;
+  domainList: string[];
+  documentTypeList: string[];
 
   constructor(protected lookups: GlobalLookups,
               protected http: HttpClient,
-              protected alertService:
-                AlertMessageService,
+              protected alertService: AlertMessageService,
               public dialog: MatDialog,
-              private changeDetector: ChangeDetectorRef) {
+              private changeDetector: ChangeDetectorRef,
+              private resourceFilterOptionsService: ResourceFilterOptionsService) {
 
     this.baseUrl = SmpConstants.REST_PUBLIC_SEARCH_RESOURCE;
   }
 
-  ngOnInit(): void {
-    this.resourceSearchController = new ResourceSearchController(this.dialog);
+  ngOnInit() {
+    this.resourceFilterOptionsService.getResourceFilterOptions$().subscribe({
+      next: (value: ResourceFilterOptionsRo) => {
+        this.domainList = [''].concat(value.availableDomains || []);
+        this.documentTypeList = [''].concat(value.availableDocumentTypes || []);
+
+        this.resourceSearchController = new ResourceSearchController(this.dialog);
+      },
+      error: (err) => this.alertService.exception('Error occurred while retrieving the resource metadata', err)
+    });
   }
 
   initColumns(): void {
@@ -82,6 +94,13 @@ export class ResourceSearchComponent implements OnInit, AfterViewInit, AfterView
         resizable: 'true',
         showInitially: true,
       },
+      {
+        name: 'Document type',
+        prop: 'documentType',
+        width: 450,
+        resizable: 'true',
+        showInitially: true,
+      },
       {
         cellTemplate: this.rowSMPUrlLinkAction,
         name: 'Resource URL',
@@ -103,23 +122,22 @@ export class ResourceSearchComponent implements OnInit, AfterViewInit, AfterView
   }
 
   createResourceURL(row: ResourceSearchRo) {
-
     return (!row?.domainCode? "" : row.domainCode+ '/')
           + (!row?.resourceDefUrlSegment?"" : row.resourceDefUrlSegment + '/')
           + encodeURIComponent((!row.participantScheme ? '' : row.participantScheme) + '::' + row.participantIdentifier);
   }
 
   createServiceMetadataURL(row: ResourceSearchRo, rowSMD: SubresourceSearchRo) {
-
     return this.createResourceURL(row)
             + '/' + rowSMD.subresourceDefUrlSegment + '/'
             + encodeURIComponent((!rowSMD.documentIdentifierScheme ? '' : rowSMD.documentIdentifierScheme) + '::' + rowSMD.documentIdentifier);
   }
 
-
-
   details(row: any) {
     this.resourceSearchController.showDetails(row);
+  }
 
+  clearFilters(): void {
+    this.filter = {};
   }
 }
diff --git a/smp-angular/src/app/smp.constants.ts b/smp-angular/src/app/smp.constants.ts
index 05cf40aeaf96ee9e24636f2a6ea4894da79441be..5d8546138acb5045e2ed15605839eb7c9e9bcf78 100644
--- a/smp-angular/src/app/smp.constants.ts
+++ b/smp-angular/src/app/smp.constants.ts
@@ -19,6 +19,7 @@ export class SmpConstants {
   public static readonly PATH_ACTION_UPDATE_RESOURCE_TYPES = 'update-resource-types';
   public static readonly PATH_ACTION_UPDATE_SML_INTEGRATION = 'update-sml-integration-data';
   public static readonly PATH_ACTION_GENERATE_DNS_QUERY : string = 'generate-dns-query';
+
   /* URL variables */
   public static readonly PATH_PARAM_ENC_USER_ID = '{user-id}';
   public static readonly PATH_PARAM_ENC_DOMAIN_ID = '{domain-id}';
@@ -46,7 +47,6 @@ export class SmpConstants {
   public static readonly PATH_RESOURCE_TYPE_DOCUMENT = 'document';
   public static readonly PATH_QUERY_FILTER_TYPE = 'type'
 
-
   //------------------------------
   // public endpoints
   public static readonly REST_PUBLIC = 'public/rest/';
@@ -72,6 +72,7 @@ export class SmpConstants {
 
   /* Public services */
   public static readonly REST_PUBLIC_SEARCH_RESOURCE = SmpConstants.REST_PUBLIC + SmpConstants.PATH_ACTION_SEARCH;
+  public static readonly REST_PUBLIC_SEARCH_RESOURCE_METADATA = SmpConstants.REST_PUBLIC + SmpConstants.PATH_ACTION_SEARCH + "/metadata";
   public static readonly REST_PUBLIC_DOMAIN = SmpConstants.REST_PUBLIC + SmpConstants.PATH_RESOURCE_TYPE_DOMAIN;
   public static readonly REST_PUBLIC_DNS_TOOLS = SmpConstants.REST_PUBLIC  + SmpConstants.PATH_DNS_TOOLS;
   public static readonly REST_PUBLIC_DNS_TOOLS_GEN_QUERY: string = SmpConstants.REST_PUBLIC_DNS_TOOLS + '/' + SmpConstants.PATH_ACTION_GENERATE_DNS_QUERY;
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/DomainDao.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/DomainDao.java
index 4c739082a84a067ece0f8903bcc302563b7193eb..a31bc1cb564aa80c42a69afe66e36211449e9c60 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/DomainDao.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/DomainDao.java
@@ -77,6 +77,16 @@ public class DomainDao extends BaseDao<DBDomain> {
         return query.getResultList();
     }
 
+    /**
+     * Returns domain code records from smp_domain table.
+     *
+     * @return the list of domain codes from smp_domain table
+     */
+    public List<String> getAllDomainCodes() {
+        TypedQuery<String> query = memEManager.createNamedQuery(QUERY_DOMAIN_ALL_CODES, String.class);
+        return query.getResultList();
+    }
+
 
     public Optional<DBDomain> getFirstDomain() {
         TypedQuery<DBDomain> query = memEManager.createNamedQuery(QUERY_DOMAIN_ALL, DBDomain.class);
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/QueryNames.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/QueryNames.java
index 7d77d21af838d2b0dcc9a0b8bcc45b32103cf751..f87b41973f5472f7950133b0881d34bcad59c134 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/QueryNames.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/QueryNames.java
@@ -30,6 +30,7 @@ public class QueryNames {
 
 
     public static final String QUERY_DOMAIN_ALL = "DBDomain.getAll";
+    public static final String QUERY_DOMAIN_ALL_CODES = "DBDomain.getAllCodes";
     public static final String QUERY_DOMAIN_CODE = "DBDomain.getDomainByCode";
 
     public static final String QUERY_DOMAIN_SMP_SML_ID = "DBDomain.getDomainBySmlSmpId";
@@ -189,6 +190,7 @@ public class QueryNames {
     public static final String PARAM_DOMAIN_IDS = "domain_ids";
 
     public static final String PARAM_DOCUMENT_ID = "document_id";
+    public static final String PARAM_DOCUMENT_TYPE = "document_type";
 
     public static final String PARAM_GROUP_ID = "group_id";
     public static final String PARAM_GROUP_IDS = "group_ids";
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/ResourceDao.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/ResourceDao.java
index 7de33a2b32fa6df481bfd4d5c6fa222343910157..93b25d5d66497fdd9cba54d4bb66bf05a981927a 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/ResourceDao.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/ResourceDao.java
@@ -33,9 +33,11 @@ import org.springframework.transaction.annotation.Transactional;
 
 import javax.persistence.NoResultException;
 import javax.persistence.NonUniqueResultException;
+import javax.persistence.Tuple;
 import javax.persistence.TypedQuery;
 import java.util.List;
 import java.util.Optional;
+import java.util.stream.Collectors;
 
 import static eu.europa.ec.edelivery.smp.data.dao.QueryNames.*;
 
@@ -49,6 +51,39 @@ public class ResourceDao extends BaseDao<DBResource> {
 
     private static final SMPLogger LOG = SMPLoggerFactory.getLogger(ResourceDao.class);
 
+    public static final class DBResourceWrapper {
+
+        private final DBResource dbResource;
+
+        private final String domainCode;
+
+        private final String documentType;
+
+        private final String urlSegment;
+
+        public DBResourceWrapper(DBResource dbResource, String domainCode, String documentType, String urlSegment) {
+            this.dbResource = dbResource;
+            this.domainCode = domainCode;
+            this.documentType = documentType;
+            this.urlSegment = urlSegment;
+        }
+
+        public DBResource getDbResource() {
+            return dbResource;
+        }
+
+        public String getDomainCode() {
+            return domainCode;
+        }
+
+        public String getDocumentType() {
+            return documentType;
+        }
+
+        public String getUrlSegment() {
+            return urlSegment;
+        }
+    }
 
     /**
      * The method returns DBResource for the participant identifier, domain, and resource type. If the resource does not exist, it returns an empty Option.
@@ -76,7 +111,6 @@ public class ResourceDao extends BaseDao<DBResource> {
         }
     }
 
-
     public Long getResourcesForFilterCount(DBResourceFilter resourceFilter) {
         LOG.debug("Get resources count for filter [{}]", resourceFilter);
 
@@ -110,10 +144,10 @@ public class ResourceDao extends BaseDao<DBResource> {
         return query.getResultList();
     }
 
-    public List<DBResource> getPublicResourcesSearch(int iPage, int iPageSize, DBUser user, String schema, String identifier) {
+    public List<DBResourceWrapper> getPublicResourcesSearch(int iPage, int iPageSize, DBUser user, String schema, String identifier, String domainCode, String documentType) {
         LOG.debug("Get resources list for user [{}], search scheme [{}] and search value [{}]", user, schema, identifier);
 
-        TypedQuery<DBResource> query = memEManager.createNamedQuery(QUERY_RESOURCE_ALL_FOR_USER, DBResource.class);
+        TypedQuery<Tuple> query = memEManager.createNamedQuery(QUERY_RESOURCE_ALL_FOR_USER, Tuple.class);
         if (iPageSize > -1 && iPage > -1) {
             query.setFirstResult(iPage * iPageSize);
         }
@@ -123,17 +157,28 @@ public class ResourceDao extends BaseDao<DBResource> {
         query.setParameter(PARAM_USER_ID, user != null ? user.getId() : null);
         query.setParameter(PARAM_RESOURCE_SCHEME, StringUtils.isBlank(schema) ? null : StringUtils.wrapIfMissing(schema, "%"));
         query.setParameter(PARAM_RESOURCE_IDENTIFIER, StringUtils.isBlank(identifier) ? null : StringUtils.wrapIfMissing(identifier, "%"));
-
-        return query.getResultList();
+        query.setParameter(PARAM_DOMAIN_CODE, StringUtils.defaultIfBlank(domainCode, null));
+        query.setParameter(PARAM_DOCUMENT_TYPE, StringUtils.defaultIfBlank(documentType, null));
+        List<Tuple> resultList = query.getResultList();
+
+        return resultList.stream().map(tuple -> {
+            DBResource resource = tuple.get(0, DBResource.class);
+            String domainCodeValue = tuple.get("domainCode").toString();
+            String documentTypeValue = tuple.get("documentType").toString();
+            String urlSegment = tuple.get("urlSegment").toString();
+            return new DBResourceWrapper(resource, domainCodeValue, documentTypeValue, urlSegment);
+        }).collect(Collectors.toList());
     }
 
-    public Long getPublicResourcesSearchCount(DBUser user, String schema, String identifier) {
+    public Long getPublicResourcesSearchCount(DBUser user, String schema, String identifier, String domainCode, String documentType) {
         LOG.debug("Get resources count for user [{}], search scheme [{}] and search value [{}]", user, schema, identifier);
         TypedQuery<Long> query = memEManager.createNamedQuery(QUERY_RESOURCE_ALL_FOR_USER_COUNT, Long.class);
 
         query.setParameter(PARAM_USER_ID, user != null ? user.getId() : null);
         query.setParameter(PARAM_RESOURCE_SCHEME, StringUtils.isBlank(schema) ? null : StringUtils.wrapIfMissing(schema, "%"));
         query.setParameter(PARAM_RESOURCE_IDENTIFIER, StringUtils.isBlank(identifier) ? null : StringUtils.wrapIfMissing(identifier, "%"));
+        query.setParameter(PARAM_DOMAIN_CODE, StringUtils.defaultIfBlank(domainCode, null));
+        query.setParameter(PARAM_DOCUMENT_TYPE, StringUtils.defaultIfBlank(documentType, null));
 
         return query.getSingleResult();
     }
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBDomain.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBDomain.java
index c826b4c6b7efc6fa8b801a4e1b4811b3284111e9..e3bc53f7b6066ad9db1adef944abb8e9d906db57 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBDomain.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBDomain.java
@@ -41,6 +41,7 @@ import static eu.europa.ec.edelivery.smp.data.dao.QueryNames.*;
         indexes = {@Index(name = "SMP_DOM_UNIQ_CODE_IDX", columnList = "DOMAIN_CODE", unique = true)
         })
 @NamedQuery(name = QUERY_DOMAIN_ALL, query = "SELECT d FROM DBDomain d order by d.id asc")
+@NamedQuery(name = QUERY_DOMAIN_ALL_CODES, query = "SELECT d.domainCode FROM DBDomain d")
 @NamedQuery(name = QUERY_DOMAIN_CODE, query = "SELECT d FROM DBDomain d WHERE d.domainCode = :domain_code")
 @NamedQuery(name = QUERY_DOMAIN_SMP_SML_ID, query = "SELECT d FROM DBDomain d WHERE lower(d.smlSmpId) = lower(:sml_smp_id)")
 
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/doc/DBDocument.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/doc/DBDocument.java
index b4f9dd9db96f8ed20935abc050035a0c0fdeba9f..dcf41cc1c5f2c509526bb0ea387c6b78356f3694 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/doc/DBDocument.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/doc/DBDocument.java
@@ -46,7 +46,7 @@ import static eu.europa.ec.edelivery.smp.data.dao.QueryNames.QUERY_DOCUMENT_FOR_
 @Table(name = "SMP_DOCUMENT")
 @org.hibernate.annotations.Table(appliesTo = "SMP_DOCUMENT", comment = "SMP document entity for resources and subresources")
 @NamedQueries({
-        @NamedQuery(name = QUERY_DOCUMENT_FOR_RESOURCE, query = "SELECT d FROM DBResource r JOIN r.document d WHERE r.id =:resource_id"),
+        @NamedQuery(name = QUERY_DOCUMENT_FOR_RESOURCE, query = "SELECT d FROM DBResource r JOIN r.document d WHERE r.id =:resource_id")
 })
 public class DBDocument extends BaseEntity {
     private static final SMPLogger LOG = SMPLoggerFactory.getLogger(DBDocument.class);
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/doc/DBResource.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/doc/DBResource.java
index 34c01df66b259af7a2c23ddc272fb44d2505966d..1f1b06cf4b7264f4e468775751e819df197bfc55 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/doc/DBResource.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/doc/DBResource.java
@@ -99,7 +99,9 @@ import static eu.europa.ec.edelivery.smp.data.dao.QueryNames.*;
         " AND (:resource_identifier IS NULL OR r.identifierValue like :resource_identifier )" +
         " AND (:resource_scheme IS NULL OR r.identifierScheme like :resource_scheme) order by r.identifierScheme, r.identifierValue"
 )
-@NamedQuery(name = QUERY_RESOURCE_ALL_FOR_USER, query = "SELECT DISTINCT r FROM  DBResource r LEFT JOIN DBResourceMember rm ON r.id = rm.resource.id WHERE " +
+@NamedQuery(name = QUERY_RESOURCE_ALL_FOR_USER, query = "SELECT DISTINCT r, r.domainResourceDef.domain.domainCode as domainCode, " +
+        "   r.domainResourceDef.resourceDef.urlSegment as urlSegment, r.domainResourceDef.resourceDef.name as documentType " +
+        "FROM  DBResource r LEFT JOIN DBResourceMember rm ON r.id = rm.resource.id WHERE " +
         " (:resource_identifier IS NULL OR r.identifierValue like :resource_identifier) " +
         " AND (:resource_scheme IS NULL OR r.identifierScheme like :resource_scheme) " +
         " AND ( :user_id IS NOT NULL AND rm.user.id = :user_id "  +
@@ -112,8 +114,10 @@ import static eu.europa.ec.edelivery.smp.data.dao.QueryNames.*;
         "            OR  (select count(dm.id) from DBDomainMember dm where dm.user.id = :user_id and dm.domain.id = r.group.domain.id) > 0 " +
         "            OR (select count(gm.id) from DBGroupMember gm where gm.user.id = :user_id and gm.group.domain.id = r.group.domain.id) > 0 " +
         "            OR (select count(rm.id) from DBResourceMember rm where rm.user.id = :user_id and rm.resource.group.domain.id = r.group.domain.id) > 0 " +
-        ")))"+
-        "order by r.identifierScheme, r.identifierValue"
+        "))) " +
+        " AND (:domain_code IS NULL OR r.domainResourceDef.domain.domainCode = :domain_code) " +
+        " AND (:document_type IS NULL OR r.domainResourceDef.resourceDef.name = :document_type) " +
+        " ORDER BY r.identifierScheme, r.identifierValue"
 )
 @NamedQuery(name = QUERY_RESOURCE_ALL_FOR_USER_COUNT, query = "SELECT count(distinct r.id) FROM  DBResource r LEFT JOIN DBResourceMember rm ON r.id = rm.resource.id WHERE " +
         " (:resource_identifier IS NULL OR r.identifierValue like :resource_identifier) " +
@@ -128,7 +132,9 @@ import static eu.europa.ec.edelivery.smp.data.dao.QueryNames.*;
         "            OR  (select count(dm.id) from DBDomainMember dm where dm.user.id = :user_id and dm.domain.id = r.group.domain.id) > 0 " +
         "            OR (select count(gm.id) from DBGroupMember gm where gm.user.id = :user_id and gm.group.domain.id = r.group.domain.id) > 0 " +
         "            OR (select count(rm.id) from DBResourceMember rm where rm.user.id = :user_id and rm.resource.group.domain.id = r.group.domain.id) > 0 " +
-        ")))"
+        "))) " +
+        " AND (:domain_code IS NULL OR r.domainResourceDef.domain.domainCode = :domain_code) " +
+        " AND (:document_type IS NULL OR r.domainResourceDef.resourceDef.name = :document_type) "
 )
 public class DBResource extends BaseEntity {
 
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/ResourceFilterOptionsResult.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/ResourceFilterOptionsResult.java
new file mode 100644
index 0000000000000000000000000000000000000000..9a01232b10d90793e36aa14af3ba2eedc92dc6af
--- /dev/null
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/ResourceFilterOptionsResult.java
@@ -0,0 +1,50 @@
+/*-
+ * #START_LICENSE#
+ * smp-server-library
+ * %%
+ * Copyright (C) 2017 - 2024 European Commission | eDelivery | DomiSMP
+ * %%
+ * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by the European Commission - subsequent
+ * versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ *
+ * [PROJECT_HOME]\license\eupl-1.2\license.txt or https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence is
+ * distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ * #END_LICENSE#
+ */
+package eu.europa.ec.edelivery.smp.data.ui;
+
+import java.io.Serializable;
+import java.util.*;
+
+/**
+ * @since 5.1
+ * @author Sebastian-Ion TINCU
+ */
+public class ResourceFilterOptionsResult implements Serializable {
+
+    private static final long serialVersionUID = 6677275164291128366L;
+
+    // The set of all the available domain codes
+    private Set<String> availableDomains = new LinkedHashSet<>();
+
+    // The set of all the available document types
+    private Set<String> availableDocumentTypes = new LinkedHashSet<>();
+
+    public ResourceFilterOptionsResult(List<String> domainCodes, List<String> documentTypes) {
+        this.availableDomains.addAll(new TreeSet<>(domainCodes));
+        this.availableDocumentTypes.addAll(new TreeSet<>(documentTypes));
+    }
+
+    public Set<String> getAvailableDomains() {
+        return availableDomains;
+    }
+
+    public Set<String> getAvailableDocumentTypes() {
+        return availableDocumentTypes;
+    }
+}
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/ServiceGroupSearchRO.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/ServiceGroupSearchRO.java
index cdf665c99c48dbd8084752d22fa950d6eda06c96..cf080ac997fa8bccabf073e016f4fe716357050c 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/ServiceGroupSearchRO.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/ServiceGroupSearchRO.java
@@ -36,6 +36,7 @@ public class ServiceGroupSearchRO extends BaseRO {
     private Long id;
 
     private String domainCode;
+    private String documentType;
     private String resourceDefUrlSegment;
     private String participantIdentifier;
     private String participantScheme;
@@ -85,4 +86,12 @@ public class ServiceGroupSearchRO extends BaseRO {
     public List<ServiceMetadataRO> getServiceMetadata() {
         return lstServiceMetadata;
     }
+
+    public String getDocumentType() {
+        return documentType;
+    }
+
+    public void setDocumentType(String documentType) {
+        this.documentType = documentType;
+    }
 }
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIResourceSearchService.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIResourceSearchService.java
index df80781d4f0f0e608b82c01b74bbeea448cd2bb1..44be22aa37259580cb71975b934e6ebcb1bf9332 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIResourceSearchService.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIResourceSearchService.java
@@ -18,12 +18,11 @@
  */
 package eu.europa.ec.edelivery.smp.services.ui;
 
-import eu.europa.ec.edelivery.smp.data.dao.BaseDao;
-import eu.europa.ec.edelivery.smp.data.dao.DomainDao;
-import eu.europa.ec.edelivery.smp.data.dao.ResourceDao;
-import eu.europa.ec.edelivery.smp.data.dao.UserDao;
+import eu.europa.ec.edelivery.smp.data.dao.*;
 import eu.europa.ec.edelivery.smp.data.model.doc.DBResource;
+import eu.europa.ec.edelivery.smp.data.model.ext.DBResourceDef;
 import eu.europa.ec.edelivery.smp.data.model.user.DBUser;
+import eu.europa.ec.edelivery.smp.data.ui.ResourceFilterOptionsResult;
 import eu.europa.ec.edelivery.smp.data.ui.ServiceGroupSearchRO;
 import eu.europa.ec.edelivery.smp.data.ui.ServiceMetadataRO;
 import eu.europa.ec.edelivery.smp.data.ui.ServiceResult;
@@ -31,25 +30,35 @@ import eu.europa.ec.edelivery.smp.logging.SMPLogger;
 import eu.europa.ec.edelivery.smp.logging.SMPLoggerFactory;
 import eu.europa.ec.edelivery.smp.services.ui.filters.ResourceFilter;
 import eu.europa.ec.edelivery.smp.utils.SessionSecurityUtils;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.convert.ConversionService;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.stream.Collectors;
 
 @Service
 public class UIResourceSearchService extends UIServiceBase<DBResource, ServiceGroupSearchRO> {
     private static final SMPLogger LOG = SMPLoggerFactory.getLogger(UIResourceSearchService.class);
 
-    @Autowired
-    DomainDao domainDao;
+    private final DomainDao domainDao;
 
-    @Autowired
-    ResourceDao resourceDao;
+    private final ResourceDao resourceDao;
 
-    @Autowired
-    UserDao userDao;
+    private final UserDao userDao;
+
+    private final ResourceDefDao resourceDefDao;
+
+    private final ConversionService conversionService;
+
+    public UIResourceSearchService(DomainDao domainDao, ResourceDao resourceDao, UserDao userDao, ResourceDefDao resourceDefDao, ConversionService conversionService) {
+        this.domainDao = domainDao;
+        this.resourceDao = resourceDao;
+        this.userDao = userDao;
+        this.resourceDefDao = resourceDefDao;
+        this.conversionService = conversionService;
+    }
 
 
     @Override
@@ -77,7 +86,7 @@ public class UIResourceSearchService extends UIServiceBase<DBResource, ServiceGr
         sg.setPageSize(pageSize);
         DBUser user = SessionSecurityUtils.getSessionUserDetails() != null ? SessionSecurityUtils.getSessionUserDetails().getUser() : null;
 
-        long iCnt = resourceDao.getPublicResourcesSearchCount(user, filter.getIdentifierSchemeLike(), filter.getIdentifierValueLike());
+        long iCnt = resourceDao.getPublicResourcesSearchCount(user, filter.getIdentifierSchemeLike(), filter.getIdentifierValueLike(), filter.getDomainCode(), filter.getDocumentType());
         sg.setCount(iCnt);
 
         if (iCnt > 0) {
@@ -87,10 +96,10 @@ public class UIResourceSearchService extends UIServiceBase<DBResource, ServiceGr
                 sg.setPage(page); // go back for a page
                 iStartIndex = pageSize < 0 ? -1 : page * pageSize;
             }
-            List<DBResource> lst = resourceDao.getPublicResourcesSearch(page, pageSize, user, filter.getIdentifierSchemeLike(), filter.getIdentifierValueLike());
+            List<ResourceDao.DBResourceWrapper> lst = resourceDao.getPublicResourcesSearch(page, pageSize, user, filter.getIdentifierSchemeLike(), filter.getIdentifierValueLike(), filter.getDomainCode(), filter.getDocumentType());
             List<ServiceGroupSearchRO> lstRo = new ArrayList<>();
-            for (DBResource resource : lst) {
-                ServiceGroupSearchRO serviceGroupRo = convertToRo(resource);
+            for (ResourceDao.DBResourceWrapper resource : lst) {
+                ServiceGroupSearchRO serviceGroupRo = convert(resource);
                 serviceGroupRo.setIndex(iStartIndex++);
                 lstRo.add(serviceGroupRo);
             }
@@ -102,19 +111,20 @@ public class UIResourceSearchService extends UIServiceBase<DBResource, ServiceGr
     /**
      * Convert Database object to Rest object for UI
      *
-     * @param resource - database  entity
+     * @param resource     - database entity wrapper
      * @return ServiceGroupRO
      */
-    public ServiceGroupSearchRO convertToRo(DBResource resource) {
+    private ServiceGroupSearchRO convert(ResourceDao.DBResourceWrapper resource) {
         ServiceGroupSearchRO serviceGroupRo = new ServiceGroupSearchRO();
 
-        serviceGroupRo.setId(resource.getId());
-        serviceGroupRo.setDomainCode(resource.getDomainResourceDef().getDomain().getDomainCode());
-        serviceGroupRo.setResourceDefUrlSegment(resource.getDomainResourceDef().getResourceDef().getUrlSegment());
-        serviceGroupRo.setParticipantIdentifier(resource.getIdentifierValue());
-        serviceGroupRo.setParticipantScheme(resource.getIdentifierScheme());
+        serviceGroupRo.setId(resource.getDbResource().getId());
+        serviceGroupRo.setDomainCode(resource.getDomainCode());
+        serviceGroupRo.setDocumentType(resource.getDocumentType());
+        serviceGroupRo.setResourceDefUrlSegment(resource.getUrlSegment());
+        serviceGroupRo.setParticipantIdentifier(resource.getDbResource().getIdentifierValue());
+        serviceGroupRo.setParticipantScheme(resource.getDbResource().getIdentifierScheme());
 
-        resource.getSubresources().forEach(subresource -> {
+        resource.getDbResource().getSubresources().forEach(subresource -> {
             ServiceMetadataRO smdro = new ServiceMetadataRO();
             smdro.setSubresourceDefUrlSegment(subresource.getSubresourceDef().getUrlSegment());
             smdro.setDocumentIdentifier(subresource.getIdentifierValue());
@@ -124,4 +134,10 @@ public class UIResourceSearchService extends UIServiceBase<DBResource, ServiceGr
 
         return serviceGroupRo;
     }
+
+    public ResourceFilterOptionsResult getResourceMetadata() {
+        List<String> domainCodes = domainDao.getAllDomainCodes();
+        List<String> documentTypes = resourceDefDao.getAllResourceDef().stream().map(DBResourceDef::getName).collect(Collectors.toList());
+        return new ResourceFilterOptionsResult(domainCodes, documentTypes);
+    }
 }
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/filters/ResourceFilter.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/filters/ResourceFilter.java
index 79e0417160192d7395c1e30d15727437fcb0e9f1..d4da3d9c620ba33a5c5d59454c2782af10ce109d 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/filters/ResourceFilter.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/filters/ResourceFilter.java
@@ -27,6 +27,7 @@ public class ResourceFilter {
 
     private DBUser owner;
     private DBDomain domain;
+    private String documentType;
 
     public String getIdentifierValueLike() {
         return identifierValue;
@@ -59,4 +60,19 @@ public class ResourceFilter {
     public void setDomain(DBDomain domain) {
         this.domain = domain;
     }
+
+    public String getDomainCode() {
+        if (domain == null) {
+            return null;
+        }
+        return domain.getDomainCode();
+    }
+
+    public String getDocumentType() {
+        return documentType;
+    }
+
+    public void setDocumentType(String documentType) {
+        this.documentType = documentType;
+    }
 }
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/ResourceDaoSearchTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/ResourceDaoSearchTest.java
index 9be8653f624167a0a0bba10742198ceeca32a48f..cbab7cad2186763c8e2139f64b9c6e33b6a94ed0 100644
--- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/ResourceDaoSearchTest.java
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/ResourceDaoSearchTest.java
@@ -62,44 +62,44 @@ class ResourceDaoSearchTest extends AbstractBaseDao {
         assertEquals(8, allResources.size());
 
         // only one group is public -
-        List<DBResource> result = testInstance.getPublicResourcesSearch(-1, -1, null, null, null);
+        List<ResourceDao.DBResourceWrapper> result = testInstance.getPublicResourcesSearch(-1, -1, null, null, null, null, null);
         assertEquals(1, result.size());
         assertResources(result, "1-1-1::pubPubPub");
 
         // user1 (admin) and user2 (viewer) are members of all resources
-        result = testInstance.getPublicResourcesSearch(-1, -1, testUtilsDao.getUser2(), null, null);
+        result = testInstance.getPublicResourcesSearch(-1, -1, testUtilsDao.getUser2(), null, null, null, null);
         assertEquals(8, result.size());
 
-        result = testInstance.getPublicResourcesSearch(-1, -1, testUtilsDao.getUser1(), null, "pubPub");
+        result = testInstance.getPublicResourcesSearch(-1, -1, testUtilsDao.getUser1(), null, "pubPub", null, null);
         assertEquals(2, result.size());
-        result.forEach(resource -> assertThat(resource.getIdentifierValue(), CoreMatchers.containsString("pubPub")));
+        result.forEach(resource -> assertThat(resource.getDbResource().getIdentifierValue(), CoreMatchers.containsString("pubPub")));
 
-        result = testInstance.getPublicResourcesSearch(-1, -1, testUtilsDao.getUser1(), "1-1", null);
+        result = testInstance.getPublicResourcesSearch(-1, -1, testUtilsDao.getUser1(), "1-1", null, null, null);
         assertEquals(1, result.size());
-        result.forEach(resource -> assertThat(resource.getIdentifierScheme(), CoreMatchers.containsString("1-1")));
+        result.forEach(resource -> assertThat(resource.getDbResource().getIdentifierScheme(), CoreMatchers.containsString("1-1")));
 
-        result = testInstance.getPublicResourcesSearch(-1, -1, testUtilsDao.getUser1(), "1-1", "priv");
+        result = testInstance.getPublicResourcesSearch(-1, -1, testUtilsDao.getUser1(), "1-1", "priv", null, null);
         assertEquals(0, result.size());
 
-        result = testInstance.getPublicResourcesSearch(-1, -1, testUtilsDao.getUser2(), null, null);
+        result = testInstance.getPublicResourcesSearch(-1, -1, testUtilsDao.getUser2(), null, null, null, null);
         assertEquals(8, result.size());
 
 
         // user3 is direct member of private domain - can see only public resource on public groups
-        result = testInstance.getPublicResourcesSearch(-1, -1, testUtilsDao.getUser3(), null, null);
+        result = testInstance.getPublicResourcesSearch(-1, -1, testUtilsDao.getUser3(), null, null, null, null);
         assertResources(result, "1-1-1::pubPubPub", "5-5-5::privPubPub");
 
         // user4 is direct member of private group in private domain
-        result = testInstance.getPublicResourcesSearch(-1, -1, testUtilsDao.getUser4(), null, null);
+        result = testInstance.getPublicResourcesSearch(-1, -1, testUtilsDao.getUser4(), null, null, null, null);
         assertResources(result, "1-1-1::pubPubPub", "5-5-5::privPubPub", "7-7-7::privPrivPub");
 
         // user5 is direct member of private resource in  private group in private domain
-        result = testInstance.getPublicResourcesSearch(-1, -1, testUtilsDao.getUser5(), null, null);
+        result = testInstance.getPublicResourcesSearch(-1, -1, testUtilsDao.getUser5(), null, null, null, null);
         assertResources(result, "1-1-1::pubPubPub", "5-5-5::privPubPub", "7-7-7::privPrivPub", "8-8-8::privPrivPriv");
     }
 
-    public void assertResources(List<DBResource> result, String... resourceIdentifiers) {
-        List<String> resultIdentifiers = result.stream().map(val -> val.getIdentifierScheme() + "::" + val.getIdentifierValue()).collect(Collectors.toList());
+    public void assertResources(List<ResourceDao.DBResourceWrapper> result, String... resourceIdentifiers) {
+        List<String> resultIdentifiers = result.stream().map(val -> val.getDbResource().getIdentifierScheme() + "::" + val.getDbResource().getIdentifierValue()).collect(Collectors.toList());
         System.out.println(resultIdentifiers);
         assertArrayEquals(resourceIdentifiers, resultIdentifiers.stream().toArray());
     }
@@ -110,35 +110,35 @@ class ResourceDaoSearchTest extends AbstractBaseDao {
         assertEquals(8, allResources.size());
 
         // only one group is public -
-        Long result = testInstance.getPublicResourcesSearchCount(null, null, null);
+        Long result = testInstance.getPublicResourcesSearchCount(null, null, null, null, null);
         assertEquals(1, result.intValue());
 
         // user1 (admin) and user2 (viewer) are members of all resources
-        result = testInstance.getPublicResourcesSearchCount(testUtilsDao.getUser1(), null, null);
+        result = testInstance.getPublicResourcesSearchCount(testUtilsDao.getUser1(), null, null, null, null);
         assertEquals(8, result.intValue());
 
-        result = testInstance.getPublicResourcesSearchCount(testUtilsDao.getUser1(), null, "pubPub");
+        result = testInstance.getPublicResourcesSearchCount(testUtilsDao.getUser1(), null, "pubPub", null, null);
         assertEquals(2, result.intValue());
 
-        result = testInstance.getPublicResourcesSearchCount(testUtilsDao.getUser1(), "1-1", null);
+        result = testInstance.getPublicResourcesSearchCount(testUtilsDao.getUser1(), "1-1", null, null, null);
         assertEquals(1, result.intValue());
 
-        result = testInstance.getPublicResourcesSearchCount(testUtilsDao.getUser1(), "1-1", "priv");
+        result = testInstance.getPublicResourcesSearchCount(testUtilsDao.getUser1(), "1-1", "priv", null, null);
         assertEquals(0, result.intValue());
 
-        result = testInstance.getPublicResourcesSearchCount(testUtilsDao.getUser2(), null, null);
+        result = testInstance.getPublicResourcesSearchCount(testUtilsDao.getUser2(), null, null, null, null);
         assertEquals(8, result.intValue());
 
         // user3 is direct member of private domain - can see only public resource on public groups
-        result = testInstance.getPublicResourcesSearchCount(testUtilsDao.getUser3(), null, null);
+        result = testInstance.getPublicResourcesSearchCount(testUtilsDao.getUser3(), null, null, null, null);
         assertEquals(2, result.intValue());
 
         // user4 is direct member of private group in private domain
-        result = testInstance.getPublicResourcesSearchCount(testUtilsDao.getUser4(), null, null);
+        result = testInstance.getPublicResourcesSearchCount(testUtilsDao.getUser4(), null, null, null, null);
         assertEquals(3, result.intValue());
 
         // user5 is direct member of private resource in  private group in private domain
-        result = testInstance.getPublicResourcesSearchCount(testUtilsDao.getUser5(), null, null);
+        result = testInstance.getPublicResourcesSearchCount(testUtilsDao.getUser5(), null, null, null, null);
         assertEquals(4, result.intValue());
 
     }
diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/ResourceConstants.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/ResourceConstants.java
index 806dc4554729934e79bc17fce19f2a74e61d024d..9b06aa6109d3390bec5d374b04b4d2499aa9e6f5 100644
--- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/ResourceConstants.java
+++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/ResourceConstants.java
@@ -132,6 +132,7 @@ public class ResourceConstants {
     public static final String SUB_CONTEXT_PATH_EDIT_DOCUMENT_SUBRESOURCE_GENERATE =  SUB_CONTEXT_PATH_EDIT_DOCUMENT_GET_SUBRESOURCE +  URL_PATH_SEPARATOR + PATH_ACTION_GENERATE;
     // public
     public static final String CONTEXT_PATH_PUBLIC_SEARCH_PARTICIPANT = CONTEXT_PATH_PUBLIC + PATH_ACTION_SEARCH;
+    public static final String CONTEXT_PATH_PUBLIC_SEARCH_PARTICIPANT_METADATA = CONTEXT_PATH_PUBLIC_SEARCH_PARTICIPANT + "/metadata";
     public static final String CONTEXT_PATH_PUBLIC_DOMAIN = CONTEXT_PATH_PUBLIC + PATH_RESOURCE_TYPE_DOMAIN;
     public static final String CONTEXT_PATH_PUBLIC_APPLICATION = CONTEXT_PATH_PUBLIC + "application";
     public static final String CONTEXT_PATH_PUBLIC_USER = CONTEXT_PATH_PUBLIC + "user";
@@ -167,6 +168,7 @@ public class ResourceConstants {
     public static final String PARAM_QUERY_DOMAIN_CODE = "domainCode";
     public static final String PARAM_QUERY_USER = "user";
     public static final String PARAM_QUERY_PROPERTY = "property";
+    public static final String PARAM_QUERY_DOCUMENT_TYPE = "documentType";
 
     private ResourceConstants() {
     }
diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/external/SearchResource.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/external/SearchResource.java
index b53cddeacf4c9de485b77740a5fa6ff35384028b..6d514e10f224943306563b3aeb995bc2acc7bf59 100644
--- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/external/SearchResource.java
+++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/external/SearchResource.java
@@ -18,8 +18,8 @@
  */
 package eu.europa.ec.edelivery.smp.ui.external;
 
-
 import eu.europa.ec.edelivery.smp.data.dao.DomainDao;
+import eu.europa.ec.edelivery.smp.data.ui.ResourceFilterOptionsResult;
 import eu.europa.ec.edelivery.smp.data.ui.ServiceGroupSearchRO;
 import eu.europa.ec.edelivery.smp.data.ui.ServiceResult;
 import eu.europa.ec.edelivery.smp.logging.SMPLogger;
@@ -45,7 +45,7 @@ import static eu.europa.ec.edelivery.smp.ui.ResourceConstants.*;
  * @since 4.1
  */
 @RestController
-@RequestMapping(path = CONTEXT_PATH_PUBLIC_SEARCH_PARTICIPANT)
+@RequestMapping(produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
 public class SearchResource {
 
     private static final SMPLogger LOG = SMPLoggerFactory.getLogger(SearchResource.class);
@@ -58,7 +58,7 @@ public class SearchResource {
         this.domainDao = domainDao;
     }
 
-    @GetMapping(produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+    @GetMapping(path = CONTEXT_PATH_PUBLIC_SEARCH_PARTICIPANT)
     public ServiceResult<ServiceGroupSearchRO> getServiceGroupList(
             @RequestParam(value = PARAM_PAGINATION_PAGE, defaultValue = "0") int page,
             @RequestParam(value = PARAM_PAGINATION_PAGE_SIZE, defaultValue = "10") int pageSize,
@@ -66,24 +66,32 @@ public class SearchResource {
             @RequestParam(value = PARAM_PAGINATION_ORDER_TYPE, defaultValue = "asc", required = false) String orderType,
             @RequestParam(value = PARAM_QUERY_PARTC_ID, required = false) String participantIdentifier,
             @RequestParam(value = PARAM_QUERY_PARTC_SCHEME, required = false) String participantScheme,
-            @RequestParam(value = PARAM_QUERY_DOMAIN_CODE, required = false) String domainCode) {
+            @RequestParam(value = PARAM_QUERY_DOMAIN_CODE, required = false) String domainCode,
+            @RequestParam(value = PARAM_QUERY_DOCUMENT_TYPE, required = false) String documentType) {
 
         String participantIdentifierDecoded = decodeUrlToUTF8(participantIdentifier);
         String participantSchemeDecoded = decodeUrlToUTF8(participantScheme);
         String domainCodeDecoded = decodeUrlToUTF8(domainCode);
+        String documentTypeDecoded = decodeUrlToUTF8(documentType);
 
-        LOG.info("Search for page: {}, page size: {}, part. id: {}, part sch: {}, domain {}", page, pageSize, participantIdentifierDecoded,
-                participantSchemeDecoded, domainCodeDecoded);
+        LOG.info("Search for page: {}, page size: {}, part. id: {}, part sch: {}, domain: {}, document type: {}", page, pageSize, participantIdentifierDecoded,
+                participantSchemeDecoded, domainCodeDecoded, documentTypeDecoded);
 
         ResourceFilter sgf = new ResourceFilter();
         sgf.setIdentifierValueLike(participantIdentifierDecoded);
         sgf.setIdentifierSchemeLike(participantSchemeDecoded);
         // add domain search parameter
         sgf.setDomain(domainDao.validateDomainCode(domainCodeDecoded));
+        sgf.setDocumentType(documentTypeDecoded);
 
         return uiServiceGroupService.getTableList(page, pageSize, orderBy, orderType, sgf);
     }
 
+    @GetMapping(path = CONTEXT_PATH_PUBLIC_SEARCH_PARTICIPANT_METADATA)
+    public ResourceFilterOptionsResult serviceMetadataResultList() {
+        return uiServiceGroupService.getResourceMetadata();
+    }
+
     private String decodeUrlToUTF8(String value) {
         if (StringUtils.isBlank(value)) {
             return null;