diff --git a/SearchEndpoint/AbstractSearchEndpoint.php b/SearchEndpoint/AbstractSearchEndpoint.php
new file mode 100644
index 0000000000000000000000000000000000000000..4effbf8ce55b4440ee2782279e3803b9eff5bd37
--- /dev/null
+++ b/SearchEndpoint/AbstractSearchEndpoint.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the ONGR package.
+ *
+ * (c) NFQ Technologies UAB <info@nfq.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace ONGR\ElasticsearchBundle\DSL\SearchEndpoint;
+
+use ONGR\ElasticsearchBundle\Serializer\Normalizer\AbstractNormalizable;
+
+/**
+ * Abstract class used to define search endpoint with references.
+ */
+abstract class AbstractSearchEndpoint extends AbstractNormalizable implements SearchEndpointInterface
+{
+}
diff --git a/SearchEndpoint/AggregationsEndpoint.php b/SearchEndpoint/AggregationsEndpoint.php
new file mode 100644
index 0000000000000000000000000000000000000000..6418de39397706e79afe79fbd32d4da1321a8e68
--- /dev/null
+++ b/SearchEndpoint/AggregationsEndpoint.php
@@ -0,0 +1,65 @@
+<?php
+
+/*
+ * This file is part of the ONGR package.
+ *
+ * (c) NFQ Technologies UAB <info@nfq.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace ONGR\ElasticsearchBundle\DSL\SearchEndpoint;
+
+use ONGR\ElasticsearchBundle\DSL\BuilderInterface;
+use ONGR\ElasticsearchBundle\DSL\NamedBuilderBag;
+use ONGR\ElasticsearchBundle\DSL\NamedBuilderInterface;
+use ONGR\ElasticsearchBundle\DSL\ParametersTrait;
+use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
+
+/**
+ * Search aggregations dsl endpoint.
+ */
+class AggregationsEndpoint implements SearchEndpointInterface
+{
+    /**
+     * @var NamedBuilderBag
+     */
+    private $bag;
+
+    /**
+     * Initialized aggregations bag.
+     */
+    public function __construct()
+    {
+        $this->bag = new NamedBuilderBag();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function normalize(NormalizerInterface $normalizer, $format = null, array $context = [])
+    {
+        if (!empty($this->bag->all())) {
+            return $this->bag->toArray();
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function addBuilder(BuilderInterface $builder, $parameters = [])
+    {
+        if ($builder instanceof NamedBuilderInterface) {
+            $this->bag->add($builder);
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getBuilder()
+    {
+        return $this->bag->all();
+    }
+}
diff --git a/SearchEndpoint/FilterEndpoint.php b/SearchEndpoint/FilterEndpoint.php
new file mode 100644
index 0000000000000000000000000000000000000000..45e572b9efe92cdd7b74d4d0d916264d9cf66fd8
--- /dev/null
+++ b/SearchEndpoint/FilterEndpoint.php
@@ -0,0 +1,42 @@
+<?php
+
+/*
+ * This file is part of the ONGR package.
+ *
+ * (c) NFQ Technologies UAB <info@nfq.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace ONGR\ElasticsearchBundle\DSL\SearchEndpoint;
+
+use ONGR\ElasticsearchBundle\DSL\Query\FilteredQuery;
+use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
+
+/**
+ * Search filter dsl endpoint.
+ */
+class FilterEndpoint extends QueryEndpoint
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function normalize(NormalizerInterface $normalizer, $format = null, array $context = [])
+    {
+        if ($this->getBuilder()) {
+            $query = new FilteredQuery();
+            $query->setBoolParameters($this->getParameters());
+            $query->setFilter($this->getBuilder());
+            $this->addReference('filtered_query', $query);
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getOrder()
+    {
+        return 1;
+    }
+}
diff --git a/SearchEndpoint/HighlightEndpoint.php b/SearchEndpoint/HighlightEndpoint.php
new file mode 100644
index 0000000000000000000000000000000000000000..5a2afbd0164cbf410aee611c5acecc8a37e397f9
--- /dev/null
+++ b/SearchEndpoint/HighlightEndpoint.php
@@ -0,0 +1,52 @@
+<?php
+
+/*
+ * This file is part of the ONGR package.
+ *
+ * (c) NFQ Technologies UAB <info@nfq.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace ONGR\ElasticsearchBundle\DSL\SearchEndpoint;
+
+use ONGR\ElasticsearchBundle\DSL\BuilderInterface;
+use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
+
+/**
+ * Search highlight dsl endpoint.
+ */
+class HighlightEndpoint implements SearchEndpointInterface
+{
+    /**
+     * @var BuilderInterface
+     */
+    private $highlight;
+
+    /**
+     * {@inheritdoc}
+     */
+    public function normalize(NormalizerInterface $normalizer, $format = null, array $context = [])
+    {
+        if ($this->getBuilder()) {
+            return $this->getBuilder()->toArray();
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function addBuilder(BuilderInterface $builder, $parameters = [])
+    {
+        $this->highlight = $builder;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getBuilder()
+    {
+        return $this->highlight;
+    }
+}
diff --git a/SearchEndpoint/PostFilterEndpoint.php b/SearchEndpoint/PostFilterEndpoint.php
new file mode 100644
index 0000000000000000000000000000000000000000..acd0967a68e32fdfd636e84e5b00ad40a73aa9af
--- /dev/null
+++ b/SearchEndpoint/PostFilterEndpoint.php
@@ -0,0 +1,37 @@
+<?php
+
+/*
+ * This file is part of the ONGR package.
+ *
+ * (c) NFQ Technologies UAB <info@nfq.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace ONGR\ElasticsearchBundle\DSL\SearchEndpoint;
+
+use ONGR\ElasticsearchBundle\DSL\Filter\PostFilter;
+use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
+
+/**
+ * Search post filter dsl endpoint.
+ */
+class PostFilterEndpoint extends QueryEndpoint
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function normalize(NormalizerInterface $normalizer, $format = null, array $context = [])
+    {
+        if ($this->getBuilder()) {
+            $postFilter = new PostFilter();
+            $postFilter->setBoolParameters($this->getParameters());
+            $postFilter->setFilter($this->getBuilder());
+
+            return $postFilter->toArray();
+        }
+
+        return null;
+    }
+}
diff --git a/SearchEndpoint/QueryEndpoint.php b/SearchEndpoint/QueryEndpoint.php
new file mode 100644
index 0000000000000000000000000000000000000000..ddf4ec414e4d8e50cad1c5a6e922fa3b704a23a8
--- /dev/null
+++ b/SearchEndpoint/QueryEndpoint.php
@@ -0,0 +1,143 @@
+<?php
+
+/*
+ * This file is part of the ONGR package.
+ *
+ * (c) NFQ Technologies UAB <info@nfq.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace ONGR\ElasticsearchBundle\DSL\SearchEndpoint;
+
+use ONGR\ElasticsearchBundle\DSL\Bool\Bool;
+use ONGR\ElasticsearchBundle\DSL\BuilderInterface;
+use ONGR\ElasticsearchBundle\DSL\ParametersTrait;
+use ONGR\ElasticsearchBundle\DSL\Query\FilteredQuery;
+use ONGR\ElasticsearchBundle\Serializer\Normalizer\OrderedNormalizerInterface;
+use Symfony\Component\OptionsResolver\OptionsResolver;
+use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
+
+/**
+ * Search query dsl endpoint.
+ */
+class QueryEndpoint extends AbstractSearchEndpoint implements OrderedNormalizerInterface
+{
+    use ParametersTrait;
+
+    /**
+     * @var BuilderInterface|Bool
+     */
+    private $query;
+
+    /**
+     * @var OptionsResolver
+     */
+    private $resolver;
+
+    /**
+     * Instantiates resolver.
+     */
+    public function __construct()
+    {
+        $this->resolver = new OptionsResolver();
+        $this->configureResolver($this->resolver);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function addBuilder(BuilderInterface $builder, $parameters = [])
+    {
+        if (!$this->query && !(array_key_exists('bool_type', $parameters) && !empty($parameters['bool_type']))) {
+            $this->setBuilder($builder);
+        } else {
+            $parameters = $this->resolver->resolve(array_filter($parameters));
+            $this->query instanceof Bool ? : $this->convertToBool();
+            $this->query->addToBool($builder, $parameters['bool_type']);
+        }
+
+        return $this;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function normalize(NormalizerInterface $normalizer, $format = null, array $context = [])
+    {
+        $isRelevant = false;
+
+        if ($this->hasReference('filtered_query')) {
+            /** @var FilteredQuery $query */
+            $query = $this->getReference('filtered_query');
+            $this->addBuilder($query);
+            $isRelevant = true;
+        }
+
+        if ($this->getBuilder()) {
+            if (method_exists($this->getBuilder(), 'setParameters') && count($this->getParameters()) > 0) {
+                $this
+                    ->getBuilder()
+                    ->setParameters($this->processArray($this->getBuilder()->getParameters()));
+            }
+
+            $isRelevant = true;
+        }
+
+        return $isRelevant ? [$this->getBuilder()->getType() => $this->getBuilder()->toArray()] : null;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getOrder()
+    {
+        return 2;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getBuilder()
+    {
+        return $this->query;
+    }
+
+    /**
+     * Sets builder.
+     *
+     * @param BuilderInterface $builder
+     */
+    protected function setBuilder(BuilderInterface $builder)
+    {
+        $this->query = $builder;
+    }
+
+    /**
+     * Default properties for query.
+     *
+     * @param OptionsResolver $resolver
+     */
+    protected function configureResolver(OptionsResolver $resolver)
+    {
+        $resolver
+            ->setDefaults(
+                ['bool_type' => Bool::MUST]
+            );
+    }
+
+    /**
+     * Converts query to bool.
+     */
+    private function convertToBool()
+    {
+        $bool = new Bool();
+
+        if ($this->query !== null) {
+            $bool->addToBool($this->query);
+        }
+
+        $this->query = $bool;
+    }
+}
diff --git a/SearchEndpoint/SearchEndpointFactory.php b/SearchEndpoint/SearchEndpointFactory.php
new file mode 100644
index 0000000000000000000000000000000000000000..1340ab67d3424f91913c23ac914edee17f048dcc
--- /dev/null
+++ b/SearchEndpoint/SearchEndpointFactory.php
@@ -0,0 +1,55 @@
+<?php
+
+/*
+ * This file is part of the ONGR package.
+ *
+ * (c) NFQ Technologies UAB <info@nfq.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace ONGR\ElasticsearchBundle\DSL\SearchEndpoint;
+
+/**
+ * Factory for search endpoints.
+ */
+class SearchEndpointFactory
+{
+    /**
+     * @var array Holds namespaces for endpoints.
+     */
+    private static $endpoints = [
+        'query' => 'ONGR\ElasticsearchBundle\DSL\SearchEndpoint\QueryEndpoint',
+        'filter' => 'ONGR\ElasticsearchBundle\DSL\SearchEndpoint\FilterEndpoint',
+        'post_filter' => 'ONGR\ElasticsearchBundle\DSL\SearchEndpoint\PostFilterEndpoint',
+        'sort' => 'ONGR\ElasticsearchBundle\DSL\SearchEndpoint\SortEndpoint',
+        'highlight' => 'ONGR\ElasticsearchBundle\DSL\SearchEndpoint\HighlightEndpoint',
+        'aggregations' => 'ONGR\ElasticsearchBundle\DSL\SearchEndpoint\AggregationsEndpoint',
+        'suggest' => 'ONGR\ElasticsearchBundle\DSL\SearchEndpoint\SuggestEndpoint',
+    ];
+
+    /**
+     * Returns a search endpoint instance.
+     *
+     * @param string $type Type of endpoint.
+     *
+     * @return SearchEndpointInterface
+     *
+     * @throws \RuntimeException Endpoint does not exist.
+     * @throws \DomainException  Endpoint is not implementing SearchEndpointInterface
+     */
+    public static function get($type)
+    {
+        if (!array_key_exists($type, self::$endpoints)) {
+            throw new \RuntimeException();
+        }
+        $endpoint = new self::$endpoints[$type]();
+
+        if ($endpoint instanceof SearchEndpointInterface) {
+            return $endpoint;
+        }
+
+        throw new \DomainException();
+    }
+}
diff --git a/SearchEndpoint/SearchEndpointInterface.php b/SearchEndpoint/SearchEndpointInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..83139eb9dda78819dbfdfff81f2d1c03c36d422c
--- /dev/null
+++ b/SearchEndpoint/SearchEndpointInterface.php
@@ -0,0 +1,39 @@
+<?php
+
+/*
+ * This file is part of the ONGR package.
+ *
+ * (c) NFQ Technologies UAB <info@nfq.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace ONGR\ElasticsearchBundle\DSL\SearchEndpoint;
+
+use ONGR\ElasticsearchBundle\DSL\BuilderInterface;
+use ONGR\ElasticsearchBundle\DSL\ParametersTrait;
+use Symfony\Component\Serializer\Normalizer\NormalizableInterface;
+
+/**
+ * Interface used to define search endpoint.
+ */
+interface SearchEndpointInterface extends NormalizableInterface
+{
+    /**
+     * Adds builder to search endpoint.
+     *
+     * @param BuilderInterface $builder    Builder to add.
+     * @param array            $parameters Additional parameters relevant to builder.
+     *
+     * @return SearchEndpointInterface
+     */
+    public function addBuilder(BuilderInterface $builder, $parameters = []);
+
+    /**
+     * Returns currectly contained builder.
+     *
+     * @return BuilderInterface|BuilderInterface[]
+     */
+    public function getBuilder();
+}
diff --git a/SearchEndpoint/SortEndpoint.php b/SearchEndpoint/SortEndpoint.php
new file mode 100644
index 0000000000000000000000000000000000000000..a05f89778341040675c1b63a366dffced318d174
--- /dev/null
+++ b/SearchEndpoint/SortEndpoint.php
@@ -0,0 +1,61 @@
+<?php
+
+/*
+ * This file is part of the ONGR package.
+ *
+ * (c) NFQ Technologies UAB <info@nfq.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace ONGR\ElasticsearchBundle\DSL\SearchEndpoint;
+
+use ONGR\ElasticsearchBundle\DSL\BuilderInterface;
+use ONGR\ElasticsearchBundle\DSL\Sort\Sorts;
+use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
+
+/**
+ * Search sort dsl endpoint.
+ */
+class SortEndpoint implements SearchEndpointInterface
+{
+    /**
+     * @var Sorts
+     */
+    protected $sorts;
+
+    /**
+     * Initializes Sorts object.
+     */
+    public function __construct()
+    {
+        $this->sorts = new Sorts();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function normalize(NormalizerInterface $normalizer, $format = null, array $context = [])
+    {
+        if ($this->sorts->isRelevant()) {
+            return $this->sorts->toArray();
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function addBuilder(BuilderInterface $builder, $parameters = [])
+    {
+        $this->sorts->addSort($builder);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getBuilder()
+    {
+        return $this->sorts;
+    }
+}
diff --git a/SearchEndpoint/SuggestEndpoint.php b/SearchEndpoint/SuggestEndpoint.php
new file mode 100644
index 0000000000000000000000000000000000000000..c40b5f070b94376d49c07c9c841926afb215a905
--- /dev/null
+++ b/SearchEndpoint/SuggestEndpoint.php
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ * This file is part of the ONGR package.
+ *
+ * (c) NFQ Technologies UAB <info@nfq.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace ONGR\ElasticsearchBundle\DSL\SearchEndpoint;
+
+use ONGR\ElasticsearchBundle\DSL\BuilderInterface;
+use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
+
+/**
+ * Search suggesters dsl endpoint.
+ */
+class SuggestEndpoint extends AggregationsEndpoint
+{
+}