diff --git a/.code-samples.meilisearch.yaml b/.code-samples.meilisearch.yaml
index 7d96cf6c..8a7feb5a 100644
--- a/.code-samples.meilisearch.yaml
+++ b/.code-samples.meilisearch.yaml
@@ -1626,6 +1626,21 @@ reset_proximity_precision_settings_1: |-
     .reset_proximity_precision()
     .await
     .unwrap();
+facet_search_1: |-
+  let client = client::new("http://localhost:7700", Some("apiKey"));
+  let res = client.index("books")
+    .facet_search("genres")
+    .with_facet_query("fiction")
+    .with_filter("rating > 3")
+    .execute()
+    .await
+    .unwrap();
+facet_search_3: |-
+  let client = client::new("http://localhost:7700", Some("apiKey"));
+  let res = client.index("books")
+    .facet_search("genres")
+    .with_facet_query("c")
+    .execute()
 create_snapshot_1: |-
   client
     .create_snapshot()
diff --git a/src/indexes.rs b/src/indexes.rs
index 05c728f1..1f4285bd 100644
--- a/src/indexes.rs
+++ b/src/indexes.rs
@@ -279,6 +279,56 @@ impl<Http: HttpClient> Index<Http> {
         SearchQuery::new(self)
     }
 
+    /// Returns the facet stats matching a specific query in the index.
+    ///
+    /// See also [`Index::facet_search`].
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// # use serde::{Serialize, Deserialize};
+    /// # use meilisearch_sdk::{client::*, indexes::*, search::*};
+    /// #
+    /// # let MEILISEARCH_URL = option_env!("MEILISEARCH_URL").unwrap_or("http://localhost:7700");
+    /// # let MEILISEARCH_API_KEY = option_env!("MEILISEARCH_API_KEY").unwrap_or("masterKey");
+    /// #
+    /// #[derive(Serialize, Deserialize, Debug)]
+    /// struct Movie {
+    ///     name: String,
+    ///     genre: String,
+    /// }
+    /// # futures::executor::block_on(async move {
+    /// # let client = Client::new(MEILISEARCH_URL, Some(MEILISEARCH_API_KEY));
+    /// let movies = client.index("execute_query");
+    ///
+    /// // add some documents
+    /// # movies.add_or_replace(&[Movie{name:String::from("Interstellar"), genre:String::from("scifi")},Movie{name:String::from("Inception"), genre:String::from("drama")}], Some("name")).await.unwrap().wait_for_completion(&client, None, None).await.unwrap();
+    /// # movies.set_filterable_attributes(["genre"]).await.unwrap().wait_for_completion(&client, None, None).await.unwrap();
+    ///
+    /// let query = FacetSearchQuery::new(&movies, "genre").with_facet_query("scifi").build();
+    /// let res = movies.execute_facet_query(&query).await.unwrap();
+    ///
+    /// assert!(res.facet_hits.len() > 0);
+    /// # movies.delete().await.unwrap().wait_for_completion(&client, None, None).await.unwrap();
+    /// # });
+    /// ```
+    pub async fn execute_facet_query(
+        &self,
+        body: &FacetSearchQuery<'_>,
+    ) -> Result<FacetSearchResponse, Error> {
+        request::<(), &FacetSearchQuery, FacetSearchResponse>(
+            &format!("{}/indexes/{}/facet-search", self.client.host, self.uid),
+            self.client.get_api_key(),
+            Method::Post { body, query: () },
+            200,
+        )
+        .await
+    }
+
+    pub fn facet_search<'a>(&'a self, facet_name: &'a str) -> FacetSearchQuery<'a> {
+        FacetSearchQuery::new(self, facet_name)
+    }
+
     /// Get one document using its unique id.
     ///
     /// Serde is needed. Add `serde = {version="1.0", features=["derive"]}` in the dependencies section of your Cargo.toml.
diff --git a/src/search.rs b/src/search.rs
index ec96d9d7..50f2324b 100644
--- a/src/search.rs
+++ b/src/search.rs
@@ -601,6 +601,153 @@ pub struct MultiSearchResponse<T> {
     pub results: Vec<SearchResults<T>>,
 }
 
+/// A struct representing a facet-search query.
+///
+/// You can add search parameters using the builder syntax.
+///
+/// See [this page](https://www.meilisearch.com/docs/reference/api/facet_search) for the official list and description of all parameters.
+///
+/// # Examples
+///
+/// ```
+/// # use serde::{Serialize, Deserialize};
+/// # use meilisearch_sdk::{client::*, indexes::*, search::*};
+/// #
+/// # let MEILISEARCH_URL = option_env!("MEILISEARCH_URL").unwrap_or("http://localhost:7700");
+/// # let MEILISEARCH_API_KEY = option_env!("MEILISEARCH_API_KEY").unwrap_or("masterKey");
+/// #
+/// #[derive(Serialize)]
+/// struct Movie {
+///     name: String,
+///     genre: String,
+/// }
+/// # futures::executor::block_on(async move {
+/// # let client = Client::new(MEILISEARCH_URL, Some(MEILISEARCH_API_KEY));
+/// let movies = client.index("execute_query");
+///
+/// // add some documents
+/// # movies.add_or_replace(&[Movie{name:String::from("Interstellar"), genre:String::from("scifi")},Movie{name:String::from("Inception"), genre:String::from("drama")}], Some("name")).await.unwrap().wait_for_completion(&client, None, None).await.unwrap();
+/// # movies.set_filterable_attributes(["genre"]).await.unwrap().wait_for_completion(&client, None, None).await.unwrap();
+///
+/// let query = FacetSearchQuery::new(&movies, "genre").with_facet_query("scifi").build();
+/// let res = movies.execute_facet_query(&query).await.unwrap();
+///
+/// assert!(res.facet_hits.len() > 0);
+/// # movies.delete().await.unwrap().wait_for_completion(&client, None, None).await.unwrap();
+/// # });
+/// ```
+///
+/// ```
+/// # use meilisearch_sdk::{Client, SearchQuery, Index};
+/// #
+/// # let MEILISEARCH_URL = option_env!("MEILISEARCH_URL").unwrap_or("http://localhost:7700");
+/// # let MEILISEARCH_API_KEY = option_env!("MEILISEARCH_API_KEY").unwrap_or("masterKey");
+/// #
+/// # let client = Client::new(MEILISEARCH_URL, Some(MEILISEARCH_API_KEY));
+/// # let index = client.index("facet_search_query_builder_build");
+/// let query = index.facet_search("kind")
+///     .with_facet_query("space")
+///     .build(); // you can also execute() instead of build()
+/// ```
+
+#[derive(Debug, Serialize, Clone)]
+#[serde(rename_all = "camelCase")]
+pub struct FacetSearchQuery<'a> {
+    #[serde(skip_serializing)]
+    index: &'a Index,
+    /// The facet name to search values on.
+    pub facet_name: &'a str,
+    /// The search query for the facet values.
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub facet_query: Option<&'a str>,
+    /// The text that will be searched for among the documents.
+    #[serde(skip_serializing_if = "Option::is_none")]
+    #[serde(rename = "q")]
+    pub search_query: Option<&'a str>,
+    /// Filter applied to documents.
+    ///
+    /// Read the [dedicated guide](https://www.meilisearch.com/docs/learn/advanced/filtering) to learn the syntax.
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub filter: Option<Filter<'a>>,
+    /// Defines the strategy on how to handle search queries containing multiple words.
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub matching_strategy: Option<MatchingStrategies>,
+}
+
+#[allow(missing_docs)]
+impl<'a> FacetSearchQuery<'a> {
+    pub fn new(index: &'a Index, facet_name: &'a str) -> FacetSearchQuery<'a> {
+        FacetSearchQuery {
+            index,
+            facet_name,
+            facet_query: None,
+            search_query: None,
+            filter: None,
+            matching_strategy: None,
+        }
+    }
+
+    pub fn with_facet_query<'b>(
+        &'b mut self,
+        facet_query: &'a str,
+    ) -> &'b mut FacetSearchQuery<'a> {
+        self.facet_query = Some(facet_query);
+        self
+    }
+
+    pub fn with_search_query<'b>(
+        &'b mut self,
+        search_query: &'a str,
+    ) -> &'b mut FacetSearchQuery<'a> {
+        self.search_query = Some(search_query);
+        self
+    }
+
+    pub fn with_filter<'b>(&'b mut self, filter: &'a str) -> &'b mut FacetSearchQuery<'a> {
+        self.filter = Some(Filter::new(Either::Left(filter)));
+        self
+    }
+
+    pub fn with_array_filter<'b>(
+        &'b mut self,
+        filter: Vec<&'a str>,
+    ) -> &'b mut FacetSearchQuery<'a> {
+        self.filter = Some(Filter::new(Either::Right(filter)));
+        self
+    }
+
+    pub fn with_matching_strategy<'b>(
+        &'b mut self,
+        matching_strategy: MatchingStrategies,
+    ) -> &'b mut FacetSearchQuery<'a> {
+        self.matching_strategy = Some(matching_strategy);
+        self
+    }
+
+    pub fn build(&mut self) -> FacetSearchQuery<'a> {
+        self.clone()
+    }
+
+    pub async fn execute(&'a self) -> Result<FacetSearchResponse, Error> {
+        self.index.execute_facet_query(self).await
+    }
+}
+
+#[derive(Debug, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct FacetHit {
+    pub value: String,
+    pub count: usize,
+}
+
+#[derive(Debug, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct FacetSearchResponse {
+    pub facet_hits: Vec<FacetHit>,
+    pub facet_query: Option<String>,
+    pub processing_time_ms: usize,
+}
+
 #[cfg(test)]
 mod tests {
     use crate::{
@@ -1174,4 +1321,118 @@ mod tests {
 
         Ok(())
     }
+
+    #[meilisearch_test]
+    async fn test_facet_search_base(client: Client, index: Index) -> Result<(), Error> {
+        setup_test_index(&client, &index).await?;
+        let res = index.facet_search("kind").execute().await?;
+        assert_eq!(res.facet_hits.len(), 2);
+        Ok(())
+    }
+
+    #[meilisearch_test]
+    async fn test_facet_search_with_facet_query(client: Client, index: Index) -> Result<(), Error> {
+        setup_test_index(&client, &index).await?;
+        let res = index
+            .facet_search("kind")
+            .with_facet_query("title")
+            .execute()
+            .await?;
+        assert_eq!(res.facet_hits.len(), 1);
+        assert_eq!(res.facet_hits[0].value, "title");
+        assert_eq!(res.facet_hits[0].count, 8);
+        Ok(())
+    }
+
+    #[meilisearch_test]
+    async fn test_facet_search_with_search_query(
+        client: Client,
+        index: Index,
+    ) -> Result<(), Error> {
+        setup_test_index(&client, &index).await?;
+        let res = index
+            .facet_search("kind")
+            .with_search_query("Harry Potter")
+            .execute()
+            .await?;
+        assert_eq!(res.facet_hits.len(), 1);
+        assert_eq!(res.facet_hits[0].value, "title");
+        assert_eq!(res.facet_hits[0].count, 7);
+        Ok(())
+    }
+
+    #[meilisearch_test]
+    async fn test_facet_search_with_filter(client: Client, index: Index) -> Result<(), Error> {
+        setup_test_index(&client, &index).await?;
+        let res = index
+            .facet_search("kind")
+            .with_filter("value = \"The Social Network\"")
+            .execute()
+            .await?;
+        assert_eq!(res.facet_hits.len(), 1);
+        assert_eq!(res.facet_hits[0].value, "title");
+        assert_eq!(res.facet_hits[0].count, 1);
+
+        let res = index
+            .facet_search("kind")
+            .with_filter("NOT value = \"The Social Network\"")
+            .execute()
+            .await?;
+        assert_eq!(res.facet_hits.len(), 2);
+        Ok(())
+    }
+
+    #[meilisearch_test]
+    async fn test_facet_search_with_array_filter(
+        client: Client,
+        index: Index,
+    ) -> Result<(), Error> {
+        setup_test_index(&client, &index).await?;
+        let res = index
+            .facet_search("kind")
+            .with_array_filter(vec![
+                "value = \"The Social Network\"",
+                "value = \"The Social Network\"",
+            ])
+            .execute()
+            .await?;
+        assert_eq!(res.facet_hits.len(), 1);
+        assert_eq!(res.facet_hits[0].value, "title");
+        assert_eq!(res.facet_hits[0].count, 1);
+        Ok(())
+    }
+
+    #[meilisearch_test]
+    async fn test_facet_search_with_matching_strategy_all(
+        client: Client,
+        index: Index,
+    ) -> Result<(), Error> {
+        setup_test_index(&client, &index).await?;
+        let res = index
+            .facet_search("kind")
+            .with_search_query("Harry Styles")
+            .with_matching_strategy(MatchingStrategies::ALL)
+            .execute()
+            .await?;
+        assert_eq!(res.facet_hits.len(), 0);
+        Ok(())
+    }
+
+    #[meilisearch_test]
+    async fn test_facet_search_with_matching_strategy_last(
+        client: Client,
+        index: Index,
+    ) -> Result<(), Error> {
+        setup_test_index(&client, &index).await?;
+        let res = index
+            .facet_search("kind")
+            .with_search_query("Harry Styles")
+            .with_matching_strategy(MatchingStrategies::LAST)
+            .execute()
+            .await?;
+        assert_eq!(res.facet_hits.len(), 1);
+        assert_eq!(res.facet_hits[0].value, "title");
+        assert_eq!(res.facet_hits[0].count, 7);
+        Ok(())
+    }
 }