diff --git a/lib/pleroma/notification.ex b/lib/pleroma/notification.ex
index 00a382f31..039cc7312 100644
--- a/lib/pleroma/notification.ex
+++ b/lib/pleroma/notification.ex
@@ -36,6 +36,37 @@ def for_user(user, opts \\ %{}) do
     Repo.all(query)
   end
 
+  def get(%{id: user_id} = _user, id) do
+    query = from n in Notification,
+      where: n.id == ^id,
+      preload: [:activity]
+
+    notification = Repo.one(query)
+    case notification do
+      %{user_id: ^user_id} ->
+        {:ok, notification}
+      _ ->
+        {:error, "Cannot get notification"}
+    end
+  end
+
+  def clear(user) do
+    query = from n in Notification,
+      where: n.user_id == ^user.id
+
+    Repo.delete_all(query)
+  end
+
+  def dismiss(%{id: user_id} = _user, id) do
+    notification = Repo.get(Notification, id)
+    case notification do
+      %{user_id: ^user_id} ->
+        Repo.delete(notification)
+      _ ->
+        {:error, "Cannot dismiss notification"}
+    end
+  end
+
   def create_notifications(%Activity{id: id, data: %{"to" => to, "type" => type}} = activity) when type in ["Create", "Like", "Announce", "Follow"] do
     users = User.get_notified_from_activity(activity)
 
diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex
index fb06d55c1..9f50dc596 100644
--- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex
+++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex
@@ -244,23 +244,8 @@ def unfav_status(%{assigns: %{user: user}} = conn, %{"id" => ap_id_or_id}) do
 
   def notifications(%{assigns: %{user: user}} = conn, params) do
     notifications = Notification.for_user(user, params)
-    result = Enum.map(notifications, fn (%{id: id, activity: activity, inserted_at: created_at}) ->
-      actor = User.get_cached_by_ap_id(activity.data["actor"])
-      created_at = NaiveDateTime.to_iso8601(created_at)
-      |> String.replace(~r/(\.\d+)?$/, ".000Z", global: false)
-      case activity.data["type"] do
-        "Create" ->
-          %{id: id, type: "mention", created_at: created_at, account: AccountView.render("account.json", %{user: actor}), status: StatusView.render("status.json", %{activity: activity, for: user})}
-        "Like" ->
-          liked_activity = Activity.get_create_activity_by_object_ap_id(activity.data["object"])
-          %{id: id, type: "favourite", created_at: created_at, account: AccountView.render("account.json", %{user: actor}), status: StatusView.render("status.json", %{activity: liked_activity, for: user})}
-        "Announce" ->
-          announced_activity = Activity.get_create_activity_by_object_ap_id(activity.data["object"])
-          %{id: id, type: "reblog", created_at: created_at, account: AccountView.render("account.json", %{user: actor}), status: StatusView.render("status.json", %{activity: announced_activity, for: user})}
-        "Follow" ->
-          %{id: id, type: "follow", created_at: created_at, account: AccountView.render("account.json", %{user: actor})}
-        _ -> nil
-      end
+    result = Enum.map(notifications, fn x ->
+      render_notification(user, x)
     end)
     |> Enum.filter(&(&1))
 
@@ -269,6 +254,33 @@ def notifications(%{assigns: %{user: user}} = conn, params) do
     |> json(result)
   end
 
+  def get_notification(%{assigns: %{user: user}} = conn, %{"id" => id} = _params) do
+    with {:ok, notification} <- Notification.get(user, id) do
+      json(conn, render_notification(user, notification))
+    else
+      {:error, reason} ->
+        conn
+        |> put_resp_content_type("application/json")
+        |> send_resp(403, Poison.encode!(%{"error" => reason}))
+    end
+  end
+
+  def clear_notifications(%{assigns: %{user: user}} = conn, _params) do
+    Notification.clear(user)
+    json(conn, %{})
+  end
+
+  def dismiss_notification(%{assigns: %{user: user}} = conn, %{"id" => id} = _params) do
+    with {:ok, _notif} <- Notification.dismiss(user, id) do
+      json(conn, %{})
+    else
+      {:error, reason} ->
+        conn
+        |> put_resp_content_type("application/json")
+        |> send_resp(403, Poison.encode!(%{"error" => reason}))
+    end
+  end
+
   def relationships(%{assigns: %{user: user}} = conn, %{"id" => id}) do
     id = List.wrap(id)
     q = from u in User,
@@ -467,4 +479,23 @@ def empty_array(conn, _) do
     Logger.debug("Unimplemented, returning an empty array")
     json(conn, [])
   end
+
+  defp render_notification(user, %{id: id, activity: activity, inserted_at: created_at} = _params) do
+    actor = User.get_cached_by_ap_id(activity.data["actor"])
+    created_at = NaiveDateTime.to_iso8601(created_at)
+    |> String.replace(~r/(\.\d+)?$/, ".000Z", global: false)
+    case activity.data["type"] do
+      "Create" ->
+        %{id: id, type: "mention", created_at: created_at, account: AccountView.render("account.json", %{user: actor}), status: StatusView.render("status.json", %{activity: activity, for: user})}
+      "Like" ->
+        liked_activity = Activity.get_create_activity_by_object_ap_id(activity.data["object"])
+        %{id: id, type: "favourite", created_at: created_at, account: AccountView.render("account.json", %{user: actor}), status: StatusView.render("status.json", %{activity: liked_activity, for: user})}
+      "Announce" ->
+        announced_activity = Activity.get_create_activity_by_object_ap_id(activity.data["object"])
+        %{id: id, type: "reblog", created_at: created_at, account: AccountView.render("account.json", %{user: actor}), status: StatusView.render("status.json", %{activity: announced_activity, for: user})}
+      "Follow" ->
+        %{id: id, type: "follow", created_at: created_at, account: AccountView.render("account.json", %{user: actor})}
+      _ -> nil
+    end
+  end
 end
diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex
index 4c74736e2..637c300c8 100644
--- a/lib/pleroma/web/router.ex
+++ b/lib/pleroma/web/router.ex
@@ -83,7 +83,10 @@ def user_fetcher(username) do
     post "/statuses/:id/favourite", MastodonAPIController, :fav_status
     post "/statuses/:id/unfavourite", MastodonAPIController, :unfav_status
 
+    post "/notifications/clear", MastodonAPIController, :clear_notifications
+    post "/notifications/dismiss", MastodonAPIController, :dismiss_notification
     get "/notifications", MastodonAPIController, :notifications
+    get "/notifications/:id", MastodonAPIController, :get_notification
 
     post "/media", MastodonAPIController, :upload
   end
diff --git a/test/notification_test.exs b/test/notification_test.exs
index 77fdb532f..eee1c9fa3 100644
--- a/test/notification_test.exs
+++ b/test/notification_test.exs
@@ -31,4 +31,65 @@ test "it doesn't create a notification for user if the user blocks the activity
       assert nil == Notification.create_notification(activity, user)
     end
   end
+
+  describe "get notification" do
+    test "it gets a notification that belongs to the user" do
+      user = insert(:user)
+      other_user = insert(:user)
+
+      {:ok, activity} = TwitterAPI.create_status(user, %{"status" => "hey @#{other_user.nickname}"})
+      {:ok, [notification]} = Notification.create_notifications(activity)
+      {:ok, notification} = Notification.get(other_user, notification.id)
+
+      assert notification.user_id == other_user.id
+    end
+
+    test "it returns error if the notification doesn't belong to the user" do
+      user = insert(:user)
+      other_user = insert(:user)
+
+      {:ok, activity} = TwitterAPI.create_status(user, %{"status" => "hey @#{other_user.nickname}"})
+      {:ok, [notification]} = Notification.create_notifications(activity)
+      {:error, notification} = Notification.get(user, notification.id)
+    end
+  end
+
+  describe "dismiss notification" do
+    test "it dismisses a notification that belongs to the user" do
+      user = insert(:user)
+      other_user = insert(:user)
+
+      {:ok, activity} = TwitterAPI.create_status(user, %{"status" => "hey @#{other_user.nickname}"})
+      {:ok, [notification]} = Notification.create_notifications(activity)
+      {:ok, notification} = Notification.dismiss(other_user, notification.id)
+
+      assert notification.user_id == other_user.id
+    end
+
+    test "it returns error if the notification doesn't belong to the user" do
+      user = insert(:user)
+      other_user = insert(:user)
+
+      {:ok, activity} = TwitterAPI.create_status(user, %{"status" => "hey @#{other_user.nickname}"})
+      {:ok, [notification]} = Notification.create_notifications(activity)
+      {:error, notification} = Notification.dismiss(user, notification.id)
+    end
+  end
+
+  describe "clear notification" do
+    test "it clears all notifications belonging to the user" do
+      user = insert(:user)
+      other_user = insert(:user)
+      third_user = insert(:user)
+
+      {:ok, activity} = TwitterAPI.create_status(user, %{"status" => "hey @#{other_user.nickname} and @#{third_user.nickname} !"})
+      {:ok, _notifs} = Notification.create_notifications(activity)
+      {:ok, activity} = TwitterAPI.create_status(user, %{"status" => "hey again @#{other_user.nickname} and @#{third_user.nickname} !"})
+      {:ok, _notifs} = Notification.create_notifications(activity)
+      Notification.clear(other_user)
+
+      assert Notification.for_user(other_user) == []
+      assert Notification.for_user(third_user) != []
+    end
+  end
 end
diff --git a/test/web/mastodon_api/mastodon_api_controller_test.exs b/test/web/mastodon_api/mastodon_api_controller_test.exs
index cf60b4a51..f506d56a1 100644
--- a/test/web/mastodon_api/mastodon_api_controller_test.exs
+++ b/test/web/mastodon_api/mastodon_api_controller_test.exs
@@ -2,7 +2,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
   use Pleroma.Web.ConnCase
 
   alias Pleroma.Web.TwitterAPI.TwitterAPI
-  alias Pleroma.{Repo, User, Activity}
+  alias Pleroma.{Repo, User, Activity, Notification}
   alias Pleroma.Web.{OStatus, CommonAPI}
 
   import Pleroma.Factory
@@ -122,6 +122,75 @@ test "when you didn't create it", %{conn: conn} do
     end
   end
 
+  describe "notifications" do
+    test "list of notifications", %{conn: conn} do
+      user = insert(:user)
+      other_user = insert(:user)
+
+      {:ok, activity} = TwitterAPI.create_status(other_user, %{"status" => "hi @#{user.nickname}"})
+      {:ok, [notification]} = Notification.create_notifications(activity)
+
+      conn = conn
+      |> assign(:user, user)
+      |> get("/api/v1/notifications")
+
+      expected_response = "hi <a href=\"#{user.ap_id}\">@#{user.nickname}</a>"
+      assert [%{"status" => %{"content" => response}} | _rest] = json_response(conn, 200)
+      assert response == expected_response
+    end
+
+    test "getting a single notification", %{conn: conn} do
+      user = insert(:user)
+      other_user = insert(:user)
+
+      {:ok, activity} = TwitterAPI.create_status(other_user, %{"status" => "hi @#{user.nickname}"})
+      {:ok, [notification]} = Notification.create_notifications(activity)
+
+      conn = conn
+      |> assign(:user, user)
+      |> get("/api/v1/notifications/#{notification.id}")
+
+      expected_response = "hi <a href=\"#{user.ap_id}\">@#{user.nickname}</a>"
+      assert %{"status" => %{"content" => response}} = json_response(conn, 200)
+      assert response == expected_response
+    end
+
+    test "dismissing a single notification", %{conn: conn} do
+      user = insert(:user)
+      other_user = insert(:user)
+
+      {:ok, activity} = TwitterAPI.create_status(other_user, %{"status" => "hi @#{user.nickname}"})
+      {:ok, [notification]} = Notification.create_notifications(activity)
+
+      conn = conn
+      |> assign(:user, user)
+      |> post("/api/v1/notifications/dismiss", %{"id" => notification.id})
+
+      assert %{} = json_response(conn, 200)
+    end
+
+    test "clearing all notifications", %{conn: conn} do
+      user = insert(:user)
+      other_user = insert(:user)
+
+      {:ok, activity} = TwitterAPI.create_status(other_user, %{"status" => "hi @#{user.nickname}"})
+      {:ok, [notification]} = Notification.create_notifications(activity)
+
+      conn = conn
+      |> assign(:user, user)
+      |> post("/api/v1/notifications/clear")
+
+      assert %{} = json_response(conn, 200)
+
+      conn = build_conn()
+      |> assign(:user, user)
+      |> get("/api/v1/notifications")
+
+      assert all = json_response(conn, 200)
+      assert all == []
+    end
+  end
+
   describe "reblogging" do
     test "reblogs and returns the reblogged status", %{conn: conn} do
       activity = insert(:note_activity)