diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1f2271c70..327428138 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -94,6 +94,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
 - Captcha: Support native provider
 - Captcha: Enable by default
 - Mastodon API: Add support for `account_id` param to filter notifications by the account
+- Mastodon API: Add `emoji_reactions` property to Statuses
 - Configuration: `feed.logo` option for tag feed.
 - Tag feed: `/tags/:tag.rss` - list public statuses by hashtag.
 </details>
diff --git a/docs/API/differences_in_mastoapi_responses.md b/docs/API/differences_in_mastoapi_responses.md
index bb62ed5f2..50076cf98 100644
--- a/docs/API/differences_in_mastoapi_responses.md
+++ b/docs/API/differences_in_mastoapi_responses.md
@@ -29,6 +29,7 @@ Has these additional fields under the `pleroma` object:
 - `spoiler_text`: a map consisting of alternate representations of the `spoiler_text` property with the key being it's mimetype. Currently the only alternate representation supported is `text/plain`
 - `expires_at`: a datetime (iso8601) that states when the post will expire (be deleted automatically), or empty if the post won't expire
 - `thread_muted`: true if the thread the post belongs to is muted
+- `emoji_reactions`: An object with all the emoji reactions with count. Contains no information about the reacting users, for that use the `emoji_reactions_by` endpoint.
 
 ## Attachments
 
diff --git a/lib/pleroma/activity.ex b/lib/pleroma/activity.ex
index 510d3273c..896cbb3c5 100644
--- a/lib/pleroma/activity.ex
+++ b/lib/pleroma/activity.ex
@@ -312,9 +312,7 @@ def restrict_deactivated_users(query) do
       from(u in User.Query.build(deactivated: true), select: u.ap_id)
       |> Repo.all()
 
-    from(activity in query,
-      where: activity.actor not in ^deactivated_users
-    )
+    Activity.Queries.exclude_authors(query, deactivated_users)
   end
 
   defdelegate search(user, query, options \\ []), to: Pleroma.Activity.Search
diff --git a/lib/pleroma/activity/queries.ex b/lib/pleroma/activity/queries.ex
index 26bc1099d..79f305201 100644
--- a/lib/pleroma/activity/queries.ex
+++ b/lib/pleroma/activity/queries.ex
@@ -12,6 +12,7 @@ defmodule Pleroma.Activity.Queries do
   @type query :: Ecto.Queryable.t() | Activity.t()
 
   alias Pleroma.Activity
+  alias Pleroma.User
 
   @spec by_ap_id(query, String.t()) :: query
   def by_ap_id(query \\ Activity, ap_id) do
@@ -29,6 +30,11 @@ def by_actor(query \\ Activity, actor) do
     )
   end
 
+  @spec by_author(query, String.t()) :: query
+  def by_author(query \\ Activity, %User{ap_id: ap_id}) do
+    from(a in query, where: a.actor == ^ap_id)
+  end
+
   @spec by_object_id(query, String.t() | [String.t()]) :: query
   def by_object_id(query \\ Activity, object_id)
 
@@ -72,4 +78,8 @@ def exclude_type(query \\ Activity, activity_type) do
       where: fragment("(?)->>'type' != ?", activity.data, ^activity_type)
     )
   end
+
+  def exclude_authors(query \\ Activity, actors) do
+    from(activity in query, where: activity.actor not in ^actors)
+  end
 end
diff --git a/lib/pleroma/activity/search.ex b/lib/pleroma/activity/search.ex
index d30a5a6a5..f96e208da 100644
--- a/lib/pleroma/activity/search.ex
+++ b/lib/pleroma/activity/search.ex
@@ -26,18 +26,23 @@ def search(user, search_query, options \\ []) do
     |> query_with(index_type, search_query)
     |> maybe_restrict_local(user)
     |> maybe_restrict_author(author)
+    |> maybe_restrict_blocked(user)
     |> Pagination.fetch_paginated(%{"offset" => offset, "limit" => limit}, :offset)
     |> maybe_fetch(user, search_query)
   end
 
   def maybe_restrict_author(query, %User{} = author) do
-    from([a, o] in query,
-      where: a.actor == ^author.ap_id
-    )
+    Activity.Queries.by_author(query, author)
   end
 
   def maybe_restrict_author(query, _), do: query
 
+  def maybe_restrict_blocked(query, %User{} = user) do
+    Activity.Queries.exclude_authors(query, User.blocked_users_ap_ids(user))
+  end
+
+  def maybe_restrict_blocked(query, _), do: query
+
   defp restrict_public(q) do
     from([a, o] in q,
       where: fragment("?->>'type' = 'Create'", a.data),
diff --git a/lib/pleroma/web/mastodon_api/controllers/search_controller.ex b/lib/pleroma/web/mastodon_api/controllers/search_controller.ex
index 0a929f55b..5a5db8e00 100644
--- a/lib/pleroma/web/mastodon_api/controllers/search_controller.ex
+++ b/lib/pleroma/web/mastodon_api/controllers/search_controller.ex
@@ -43,7 +43,7 @@ defp do_search(version, %{assigns: %{user: user}} = conn, %{"q" => query} = para
     result =
       default_values
       |> Enum.map(fn {resource, default_value} ->
-        if params["type"] == nil or params["type"] == resource do
+        if params["type"] in [nil, resource] do
           {resource, fn -> resource_search(version, resource, query, options) end}
         else
           {resource, fn -> default_value end}
diff --git a/lib/pleroma/web/mastodon_api/views/status_view.ex b/lib/pleroma/web/mastodon_api/views/status_view.ex
index e9590224b..b59ac39bc 100644
--- a/lib/pleroma/web/mastodon_api/views/status_view.ex
+++ b/lib/pleroma/web/mastodon_api/views/status_view.ex
@@ -253,6 +253,16 @@ def render("show.json", %{activity: %{data: %{"object" => _object}} = activity}
           nil
       end
 
+    emoji_reactions =
+      with %{data: %{"reactions" => emoji_reactions}} <- object do
+        Enum.map(emoji_reactions, fn {emoji, users} ->
+          {emoji, length(users)}
+        end)
+        |> Enum.into(%{})
+      else
+        _ -> %{}
+      end
+
     %{
       id: to_string(activity.id),
       uri: object.data["id"],
@@ -293,7 +303,8 @@ def render("show.json", %{activity: %{data: %{"object" => _object}} = activity}
         spoiler_text: %{"text/plain" => summary_plaintext},
         expires_at: expires_at,
         direct_conversation_id: direct_conversation_id,
-        thread_muted: thread_muted?
+        thread_muted: thread_muted?,
+        emoji_reactions: emoji_reactions
       }
     }
   end
diff --git a/test/web/mastodon_api/controllers/search_controller_test.exs b/test/web/mastodon_api/controllers/search_controller_test.exs
index 7fedf42e5..effae130c 100644
--- a/test/web/mastodon_api/controllers/search_controller_test.exs
+++ b/test/web/mastodon_api/controllers/search_controller_test.exs
@@ -53,7 +53,8 @@ test "search", %{conn: conn} do
       {:ok, _} = CommonAPI.post(user_two, %{"status" => "This isn't"})
 
       results =
-        get(conn, "/api/v2/search", %{"q" => "2hu #private"})
+        conn
+        |> get("/api/v2/search", %{"q" => "2hu #private"})
         |> json_response(200)
 
       [account | _] = results["accounts"]
@@ -73,6 +74,30 @@ test "search", %{conn: conn} do
       [status] = results["statuses"]
       assert status["id"] == to_string(activity.id)
     end
+
+    test "excludes a blocked users from search results", %{conn: conn} do
+      user = insert(:user)
+      user_smith = insert(:user, %{nickname: "Agent", name: "I love 2hu"})
+      user_neo = insert(:user, %{nickname: "Agent Neo", name: "Agent"})
+
+      {:ok, act1} = CommonAPI.post(user, %{"status" => "This is about 2hu private 天子"})
+      {:ok, act2} = CommonAPI.post(user_smith, %{"status" => "Agent Smith"})
+      {:ok, act3} = CommonAPI.post(user_neo, %{"status" => "Agent Smith"})
+      Pleroma.User.block(user, user_smith)
+
+      results =
+        conn
+        |> assign(:user, user)
+        |> assign(:token, insert(:oauth_token, user: user, scopes: ["read"]))
+        |> get("/api/v2/search", %{"q" => "Agent"})
+        |> json_response(200)
+
+      status_ids = Enum.map(results["statuses"], fn g -> g["id"] end)
+
+      assert act3.id in status_ids
+      refute act2.id in status_ids
+      refute act1.id in status_ids
+    end
   end
 
   describe ".account_search" do
@@ -146,11 +171,10 @@ test "search", %{conn: conn} do
 
       {:ok, _} = CommonAPI.post(user_two, %{"status" => "This isn't"})
 
-      conn =
+      results =
         conn
         |> get("/api/v1/search", %{"q" => "2hu"})
-
-      assert results = json_response(conn, 200)
+        |> json_response(200)
 
       [account | _] = results["accounts"]
       assert account["id"] == to_string(user_three.id)
@@ -168,11 +192,10 @@ test "search fetches remote statuses and prefers them over other results", %{con
             "status" => "check out https://shitposter.club/notice/2827873"
           })
 
-        conn =
+        results =
           conn
           |> get("/api/v1/search", %{"q" => "https://shitposter.club/notice/2827873"})
-
-        assert results = json_response(conn, 200)
+          |> json_response(200)
 
         [status, %{"id" => ^activity_id}] = results["statuses"]
 
@@ -189,11 +212,10 @@ test "search doesn't show statuses that it shouldn't", %{conn: conn} do
         })
 
       capture_log(fn ->
-        conn =
+        results =
           conn
           |> get("/api/v1/search", %{"q" => Object.normalize(activity).data["id"]})
-
-        assert results = json_response(conn, 200)
+          |> json_response(200)
 
         [] = results["statuses"]
       end)
@@ -202,23 +224,23 @@ test "search doesn't show statuses that it shouldn't", %{conn: conn} do
     test "search fetches remote accounts", %{conn: conn} do
       user = insert(:user)
 
-      conn =
+      results =
         conn
         |> assign(:user, user)
         |> assign(:token, insert(:oauth_token, user: user, scopes: ["read"]))
         |> get("/api/v1/search", %{"q" => "mike@osada.macgirvin.com", "resolve" => "true"})
+        |> json_response(200)
 
-      assert results = json_response(conn, 200)
       [account] = results["accounts"]
       assert account["acct"] == "mike@osada.macgirvin.com"
     end
 
     test "search doesn't fetch remote accounts if resolve is false", %{conn: conn} do
-      conn =
+      results =
         conn
         |> get("/api/v1/search", %{"q" => "mike@osada.macgirvin.com", "resolve" => "false"})
+        |> json_response(200)
 
-      assert results = json_response(conn, 200)
       assert [] == results["accounts"]
     end
 
diff --git a/test/web/mastodon_api/views/status_view_test.exs b/test/web/mastodon_api/views/status_view_test.exs
index 17b6ebcbc..b54b19c0b 100644
--- a/test/web/mastodon_api/views/status_view_test.exs
+++ b/test/web/mastodon_api/views/status_view_test.exs
@@ -24,6 +24,22 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
     :ok
   end
 
+  test "has an emoji reaction list" do
+    user = insert(:user)
+    other_user = insert(:user)
+    third_user = insert(:user)
+    {:ok, activity} = CommonAPI.post(user, %{"status" => "dae cofe??"})
+
+    {:ok, _, _} = CommonAPI.react_with_emoji(activity.id, user, "☕")
+    {:ok, _, _} = CommonAPI.react_with_emoji(activity.id, other_user, "☕")
+    {:ok, _, _} = CommonAPI.react_with_emoji(activity.id, third_user, "🍵")
+    activity = Repo.get(Activity, activity.id)
+    status = StatusView.render("show.json", activity: activity)
+
+    assert status[:pleroma][:emoji_reactions]["🍵"] == 1
+    assert status[:pleroma][:emoji_reactions]["☕"] == 2
+  end
+
   test "loads and returns the direct conversation id when given the `with_direct_conversation_id` option" do
     user = insert(:user)
 
@@ -172,7 +188,8 @@ test "a note activity" do
         spoiler_text: %{"text/plain" => HTML.strip_tags(object_data["summary"])},
         expires_at: nil,
         direct_conversation_id: nil,
-        thread_muted: false
+        thread_muted: false,
+        emoji_reactions: %{}
       }
     }