diff --git a/Gemfile.lock b/Gemfile.lock
index 069dde9b..7bedbcff 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -167,7 +167,7 @@ GEM
     devise_invitable (2.0.9)
       actionmailer (>= 5.0)
       devise (>= 4.6)
-    distributed-press-api-client (0.4.0rc3)
+    distributed-press-api-client (0.4.0)
       addressable (~> 2.3, >= 2.3.0)
       climate_control
       dry-schema
@@ -627,7 +627,7 @@ DEPENDENCIES
   devise
   devise-i18n
   devise_invitable
-  distributed-press-api-client (~> 0.4.0rc3)
+  distributed-press-api-client (~> 0.4.0)
   dotenv-rails
   down
   ed25519
diff --git a/app/controllers/activity_pubs_controller.rb b/app/controllers/activity_pubs_controller.rb
index 1efe2b89..edece8f8 100644
--- a/app/controllers/activity_pubs_controller.rb
+++ b/app/controllers/activity_pubs_controller.rb
@@ -27,7 +27,7 @@ class ActivityPubsController < ApplicationController
     authorize activity_pubs
 
     action = params[:activity_pub_action].to_sym
-    method = :"#{action}!"
+    method = :"#{action}_all!"
     may    = :"may_#{action}?"
 
     redirect_to_moderation_queue!
@@ -35,36 +35,25 @@ class ActivityPubsController < ApplicationController
     return unless ActivityPub.events.include? action
 
     # Crear una sola remote flag por autore
-    if action == :report
-      message = remote_flag_params(activity_pubs.first).dig(:remote_flag_attributes, :message)
-
-      activity_pubs.distinct.pluck(:actor_id).each do |actor_id|
-        remote_flag = ActivityPub::RemoteFlag.find_or_initialize_by(actor_id: actor_id, site_id: site.id)
-        remote_flag.message = message
-        # Lo estamos actualizando, con lo que lo vamos a volver a enviar
-        remote_flag.requeue if remote_flag.persisted?
-        remote_flag.save
-        # XXX: Idealmente todas las ActivityPub que enviamos pueden
-        # cambiar de estado, pero chequeamos de todas formas.
-        remote_flag.activity_pubs << (activity_pubs.where(actor_id: actor_id).to_a.select { |a| a.public_send(may) })
-      end
-    end
-
     ActivityPub.transaction do
-      activity_pubs.find_each do |activity_pub|
-        next unless activity_pub.public_send(may)
+      if action == :report
+        message = remote_flag_params(activity_pubs.first).dig(:remote_flag_attributes, :message)
 
-        activity_pub.public_send(method)
-
-        flash[:success] = I18n.t('activity_pubs.action_on_several.success')
-      rescue Exception => e
-        ExceptionNotifier.notify_exception(e,
-                                           data: { site: site.name, params: params.permit!.to_h,
-                                                   activity_pub: activity_pub.id })
-
-        flash.delete(:success)
-        flash[:error] = I18n.t('activity_pubs.action_on_several.error')
+        activity_pubs.distinct.pluck(:actor_id).each do |actor_id|
+          remote_flag = ActivityPub::RemoteFlag.find_or_initialize_by(actor_id: actor_id, site_id: site.id)
+          remote_flag.message = message
+          # Lo estamos actualizando, con lo que lo vamos a volver a enviar
+          remote_flag.requeue if remote_flag.persisted?
+          remote_flag.save
+          # XXX: Idealmente todas las ActivityPub que enviamos pueden
+          # cambiar de estado, pero chequeamos de todas formas.
+          remote_flag.activity_pubs << (activity_pubs.where(actor_id: actor_id).to_a.select { |a| a.public_send(may) })
+        end
       end
+
+      message = activity_pubs.public_send(method) ? :success : :error
+
+      flash[message] = I18n.t("activity_pubs.action_on_several.#{message}")
     end
   end
 
diff --git a/app/controllers/actor_moderations_controller.rb b/app/controllers/actor_moderations_controller.rb
index 7c2c3d82..bc4a059b 100644
--- a/app/controllers/actor_moderations_controller.rb
+++ b/app/controllers/actor_moderations_controller.rb
@@ -37,7 +37,7 @@ class ActorModerationsController < ApplicationController
     authorize actor_moderations
 
     action = params[:actor_moderation_action].to_sym
-    method = :"#{action}!"
+    method = :"#{action}_all!"
     may    = :"may_#{action}?"
 
     redirect_to_moderation_queue!
@@ -45,20 +45,17 @@ class ActorModerationsController < ApplicationController
     return unless ActorModeration.events.include? action
 
     ActorModeration.transaction do
-      actor_moderations.find_each do |actor_moderation|
-        next unless actor_moderation.public_send(may)
+      if action == :report
+        actor_moderations.find_each do |actor_moderation|
+          next unless actor_moderation.public_send(may)
 
-        actor_moderation.update(actor_moderation_params(actor_moderation)) if action == :report
-
-        actor_moderation.public_send(method)
-
-        flash[:success] = I18n.t('actor_moderations.action_on_several.success')
-      rescue Exception => e
-        ExceptionNotifier.notify_exception(e, data: { site: site.name, params: params.permit!.to_h })
-
-        flash.delete(:success)
-        flash[:error] = I18n.t('actor_moderations.action_on_several.error')
+          actor_moderation.update(actor_moderation_params(actor_moderation))
+        end
       end
+
+      message = actor_moderation.public_send(method) ? :success : :error
+
+      flash[message] = I18n.t("actor_moderations.action_on_several.#{message}")
     end
   end
 
diff --git a/app/controllers/instance_moderations_controller.rb b/app/controllers/instance_moderations_controller.rb
index 270f0588..06f5cfc1 100644
--- a/app/controllers/instance_moderations_controller.rb
+++ b/app/controllers/instance_moderations_controller.rb
@@ -10,6 +10,12 @@ class InstanceModerationsController < ApplicationController
 
       instance_moderation.public_send(:"#{event}!") if instance_moderation.public_send(:"may_#{event}?")
 
+      flash[:success] = I18n.t("instance_moderations.#{event}.success")
+    rescue Exception => e
+      ExceptionNotifier.notify_exception(e, data: { site: site.name, params: params.permit!.to_h })
+
+      flash[:error] = I18n.t("instance_moderations.#{event}.error")
+    ensure
       redirect_to_moderation_queue!
     end
   end
@@ -20,17 +26,16 @@ class InstanceModerationsController < ApplicationController
     authorize instance_moderations
 
     action = params[:instance_moderation_action].to_sym
-    method = :"#{action}!"
-    may    = :"may_#{action}?"
+    method = :"#{action}_all!"
 
     redirect_to_moderation_queue!
 
     return unless InstanceModeration.events.include? action
 
     InstanceModeration.transaction do
-      instance_moderations.find_each do |instance_moderation|
-        instance_moderation.public_send(method) if instance_moderation.public_send(may)
-      end
+      message = instance_moderations.public_send(method) ? :success : :error
+
+      flash[:message] = I18n.t("instance_moderations.action_on_several.#{message}")
     end
   end
 
diff --git a/app/jobs/activity_pub/instance_moderation_job.rb b/app/jobs/activity_pub/instance_moderation_job.rb
index 17def46e..e28be84e 100644
--- a/app/jobs/activity_pub/instance_moderation_job.rb
+++ b/app/jobs/activity_pub/instance_moderation_job.rb
@@ -14,7 +14,6 @@ class ActivityPub
       end
 
       instances = ActivityPub::Instance.where(hostname: hostnames)
-      success = true
 
       Site.transaction do
         # Crea todas las moderaciones de instancia con un estado por
@@ -22,17 +21,11 @@ class ActivityPub
         instances.find_each do |instance|
           # Esto bloquea cada una individualmente en la Social Inbox,
           # idealmente son pocas instancias las que aparecen.
-          site.instance_moderations.find_or_create_by(instance: instance).tap do |instance_moderation|
-            instance_moderation.block! if instance_moderation.may_block?
-          # Notificar todos los errores sin detener la ejecución
-          rescue Exception => e
-            ExceptionNotifier.notify_exception(e, data: { site: site.name, instance_moderation: instance_moderation.id })
-            success = false
-          end
+          site.instance_moderations.find_or_create_by(instance: instance)
         end
-      end
 
-      success
+        site.instance_moderations.where(instance_id: instances.ids).block_all!
+      end
     end
   end
 end
diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb
index 33cd4d45..61120a58 100644
--- a/app/models/activity_pub.rb
+++ b/app/models/activity_pub.rb
@@ -8,12 +8,12 @@
 #
 # @see {https://www.w3.org/TR/activitypub/#client-to-server-interactions}
 class ActivityPub < ApplicationRecord
-  include AASM
-  include AasmEventsConcern
-
   IGNORED_EVENTS = %i[remove]
   IGNORED_STATES = %i[removed]
 
+  include AASM
+  include AasmEventsConcern
+
   belongs_to :instance
   belongs_to :site
   belongs_to :object, polymorphic: true
@@ -68,7 +68,7 @@ class ActivityPub < ApplicationRecord
       transitions from: %i[paused], to: :approved
 
       before do
-        raise unless site.social_inbox.inbox.accept(id: object.uri).ok?
+        allow_remotely!
       end
     end
 
@@ -77,7 +77,7 @@ class ActivityPub < ApplicationRecord
       transitions from: %i[paused approved], to: :rejected
 
       before do
-        raise unless site.social_inbox.inbox.reject(id: object.uri).ok?
+        reject_remotely!
       end
     end
 
@@ -90,4 +90,12 @@ class ActivityPub < ApplicationRecord
       end
     end
   end
+
+  def reject_remotely!
+    raise unless site.social_inbox.inbox.reject(id: object.uri).ok?
+  end
+
+  def allow_remotely!
+    raise unless site.social_inbox.inbox.accept(id: object.uri).ok?
+  end
 end
diff --git a/app/models/actor_moderation.rb b/app/models/actor_moderation.rb
index 01613f72..783160c7 100644
--- a/app/models/actor_moderation.rb
+++ b/app/models/actor_moderation.rb
@@ -2,31 +2,18 @@
 
 # Mantiene la relación entre Site y Actor
 class ActorModeration < ApplicationRecord
-  include AASM
-  include AasmEventsConcern
-
   IGNORED_EVENTS = %i[remove]
   IGNORED_STATES = %i[removed]
 
+  include AASM
+  include AasmEventsConcern
+
   belongs_to :site
   belongs_to :remote_flag, optional: true, class_name: 'ActivityPub::RemoteFlag'
   belongs_to :actor, class_name: 'ActivityPub::Actor'
 
   accepts_nested_attributes_for :remote_flag
 
-  # Bloquea todes les Actores bloqueables
-  def self.block_all!
-    self.update_all(aasm_state: 'blocked', updated_at: Time.now)
-  end
-
-  def self.pause_all!
-    self.update_all(aasm_state: 'paused', updated_at: Time.now)
-  end
-
-  def self.remove_all!
-    self.update_all(aasm_state: 'removed', updated_at: Time.now)
-  end
-
   aasm do
     state :paused, initial: true
     state :allowed
@@ -42,19 +29,27 @@ class ActorModeration < ApplicationRecord
       end
     end
 
+    # Al permitir una cuenta se permiten todos los comentarios
+    # pendientes de moderación que ya hizo.
     event :allow do
       transitions from: %i[paused blocked reported], to: :allowed
 
       before do
         allow_remotely!
+
+        site.activity_pubs.paused.where(actor_id: self.actor_id).allow_all!
       end
     end
 
+    # Al bloquear una cuenta se bloquean todos los comentarios
+    # pendientes de moderación que hizo.
     event :block do
       transitions from: %i[paused allowed], to: :blocked
 
       before do
         block_remotely!
+
+        site.activity_pubs.paused.where(actor_id: self.actor_id).reject_all!
       end
     end
 
@@ -72,6 +67,10 @@ class ActorModeration < ApplicationRecord
     # mostrarlo y todas sus actividades.
     event :remove do
       transitions to: :removed
+
+      before do
+        site.activity_pubs.where(actor_id: self.actor_id).remove_all!
+      end
     end
   end
 
diff --git a/app/models/concerns/aasm_events_concern.rb b/app/models/concerns/aasm_events_concern.rb
index 418368d8..967a61b3 100644
--- a/app/models/concerns/aasm_events_concern.rb
+++ b/app/models/concerns/aasm_events_concern.rb
@@ -27,5 +27,33 @@ module AasmEventsConcern
     def self.states
       aasm.states.map(&:name) - self::IGNORED_STATES
     end
+
+    # Define un método que cambia el estado para todos los objetos del
+    # scope actual.
+    #
+    # @return [Bool] Si hubo al menos un error, devuelve false.
+    self.events.each do |event|
+      define_singleton_method(:"#{event}_all!") do
+        success = true
+
+        self.find_each do |object|
+          object.public_send(:"#{event}!") if object.public_send(:"may_#{event}?")
+        rescue Exception => e
+          success = false
+
+          notify_exception! e, object
+        end
+
+        success
+      end
+    end
+
+    # Envía notificación de errores
+    #
+    # @param exception [Exception]
+    # @param record [ApplicationRecord]
+    def notify_exception!(exception, record)
+      ExceptionNotifier.notify_exception(exception, data: { site: site.name, record_type: record.class.name, record_id: record.id })
+    end
   end
 end
diff --git a/app/models/fediblock_state.rb b/app/models/fediblock_state.rb
index e50abaef..dfdc4e34 100644
--- a/app/models/fediblock_state.rb
+++ b/app/models/fediblock_state.rb
@@ -39,12 +39,6 @@ class FediblockState < ApplicationRecord
         # Luego esta tarea crea las que falten e ignora las que ya se
         # bloquearon.
         ActivityPub::InstanceModerationJob.perform_now(site: site, hostnames: fediblock.hostnames)
-
-        # Bloquear a todes les Actores de las instancias bloqueadas para
-        # indicarle a le usuarie que les tiene que desbloquear
-        # manualmente.
-        actor_ids = ActivityPub::Actor.where(instance_id: instance_ids).ids
-        ActorModeration.where(actor_id: actor_ids).paused.block_all!
       end
     end
 
@@ -66,12 +60,6 @@ class FediblockState < ApplicationRecord
         # bloqueadas por otros fediblocks.
         instance_ids = ActivityPub::Instance.where(hostname: unique_hostnames).ids
         site.instance_moderations.where(instance_id: instance_ids).pause_all!
-
-        # Volver a pausar todes les actores de esta instancia que fueron
-        # bloqueades, a menos que hayan sido bloqueades por otro
-        # fediblock.
-        actor_ids = ActivityPub::Actor.where(instance_id: instance_ids).ids
-        ActorModeration.where(actor_id: actor_ids).blocked.pause_all!
       end
     end
   end
diff --git a/app/models/instance_moderation.rb b/app/models/instance_moderation.rb
index ef04b7ff..1ed7d2c0 100644
--- a/app/models/instance_moderation.rb
+++ b/app/models/instance_moderation.rb
@@ -2,35 +2,22 @@
 
 # Mantiene el registro de relaciones entre sitios e instancias
 class InstanceModeration < ApplicationRecord
-  include AASM
-  include AasmEventsConcern
-
   IGNORED_EVENTS = []
   IGNORED_STATES = []
 
+  include AASM
+  include AasmEventsConcern
+
   belongs_to :site
   belongs_to :instance, class_name: 'ActivityPub::Instance'
 
-  # Traer todas las instancias bloqueables, según la máquina de estados,
-  # todas las que no estén bloqueadas ya.
-  scope :may_block, -> { where.not(aasm_state: 'blocked') }
-  scope :may_pause, -> { where.not(aasm_state: 'paused') }
-
-  # Bloquear instancias en masa
-  def self.block_all!
-    self.may_block.update_all(aasm_state: 'blocked', updated_at: Time.now)
-  end
-
-  # Pausar instancias en masa
-  def self.pause_all!
-    self.may_pause.update_all(aasm_state: 'paused', updated_at: Time.now)
-  end
-
   aasm do
     state :paused, initial: true
     state :allowed
     state :blocked
 
+    # Al volver la instancia a pausa no cambiamos el estado de
+    # moderación de actores pre-existente.
     event :pause do
       transitions from: %i[allowed blocked], to: :paused
 
@@ -39,23 +26,36 @@ class InstanceModeration < ApplicationRecord
       end
     end
 
+    # Al permitir, también permitimos todes les actores que no hayan
+    # tenido acciones de moderación.
     event :allow do
       transitions from: %i[paused blocked], to: :allowed
 
       before do
         allow_remotely!
+
+        site.actor_moderations.paused.where(actor_id: actor_ids).allow_all!
       end
     end
 
+    # Al bloquear, también bloqueamos a todes les actores que no hayan
+    # tenido acciones de moderación.
     event :block do
       transitions from: %i[paused allowed], to: :blocked
 
       before do
         block_remotely!
+
+        site.actor_moderations.paused.where(actor_id: actor_ids).block_all!
       end
     end
   end
 
+  # @return [Array<String>]
+  def actor_ids
+    ActivityPub::Actor.where(instance_id: self.instance_id).ids
+  end
+
   # Elimina la instancia de todas las listas
   #
   # @return [Boolean]
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 53ce747e..66941412 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -138,14 +138,27 @@ en:
       success: "Account paused. All of their comments will need to be moderated individually on the Comments section."
       error: "There was an error while pausing the account. We received a report and will be acting on it soon."
     allow:
-      success: "Account allowed. All of their comments will be approved automatically."
+      success: "Account allowed. All of their comments will be approved automatically. Any pending comments have been approved."
       error: "There was an error while allowing the account. We received a report and will be acting on it soon."
     block:
-      success: "Account blocked. All of their comments will be rejected automatically. If you want to report it to their instance, please use the Report button."
+      success: "Account blocked. All of their comments will be rejected automatically. Any pending comments have been rejected. If you want to report it to their instance, please use the Report button."
       error: "There was an error while blocking the account. We received a report and will be acting on it soon."
     report:
       success: "Account reported."
       error: "There was an error while reporting the account. We received a report and will be acting on it soon."
+  instance_moderations:
+    action_on_several:
+      success: "Several instances have changed moderation state. You can find them using the filters on the Instances section."
+      error: "There was an error while changing moderation state. We received a report and will be acting on it soon."
+    pause:
+      success: "Instance paused. All of their comments and accounts will need to be moderated individually."
+      error: "There was an error while pausing the instance. We received a report and will be acting on it soon."
+    allow:
+      success: "Instance allowed. All of their comments and accounts will be approved automatically. Any pending comments and accounts have been also approved."
+      error: "There was an error while allowing the instance. We received a report and will be acting on it soon."
+    block:
+      success: "Instance blocked. All of their comments and accounts will be rejected automatically. Any pending comments and accounts have been also rejected."
+      error: "There was an error while blocking the instance. We received a report and will be acting on it soon."
   fediblock_states:
     action_on_several:
       success: "Blocklists have been enabled, you can find their instances by filtering by Blocked. Any pending account from these instances has also been blocked. You can approve them individually on the Accounts section."
diff --git a/config/locales/es.yml b/config/locales/es.yml
index 6f51c6bd..5e50e831 100644
--- a/config/locales/es.yml
+++ b/config/locales/es.yml
@@ -137,14 +137,27 @@ es:
       success: "Cuenta pausada. Todos los comentarios que haga necesitan ser aprobados manualmente en la sección Comentarios."
       error: "No se pudo pausar la cuenta. Hemos recibido el reporte y lo estaremos verificando."
     allow:
-      success: "Cuenta permitida. Todos los comentarios que haga serán aprobados inmediatamente."
+      success: "Cuenta permitida. Todos los comentarios que haga serán aprobados inmediatamente. Todos los comentarios pendientes de moderación fueron aprobados."
       error: "No se pudo permitir la cuenta. Hemos recibido el reporte y lo estaremos verificando."
     block:
-      success: "Cuenta bloqueada. Todos los comentarios que haga serán rechazados inmediatamente. Si querés reportarla a su instancia, podés usar el botón Reportar."
+      success: "Cuenta bloqueada. Todos los comentarios que haga serán rechazados inmediatamente. Todos los comentarios pendientes de moderación fueron rechazados. Si querés reportarla a su instancia, podés usar el botón Reportar."
       error: "No se pudo bloquear la cuenta. Hemos recibido el reporte y lo estaremos verificando."
     report:
       success: "Cuenta reportada a su instancia."
       error: "No se pudo reportar la cuenta. Hemos recibido el reporte y lo estaremos verificando."
+  instance_moderations:
+    action_on_several:
+      success: "Se ha modificado el estado de moderación de varias instancias. Podés encontrarlas usando los filtros en la sección Instancias."
+      error: "Hubo un error al modificar el estado de moderación de varias instancias. Hemos recibido el reporte y lo estaremos verificando."
+    pause:
+      success: "Instancia pausada. Todos los comentarios y cuentas de esta instancia necesitan ser aprobados manualmente. No se ha modificado el estado de moderación de cuentas y comentarios pre-existentes."
+      error: "No se pudo pausar la instancia. Hemos recibido el reporte y lo estaremos verificando."
+    allow:
+      success: "Instancia permitida. Todos los comentarios y cuentas pendientes de moderación fueron aprobados y los próximos serán aprobados inmediatamente."
+      error: "No se pudo permitir la instancia. Hemos recibido el reporte y lo estaremos verificando."
+    block:
+      success: "Instancia bloqueada. Todos los comentarios y cuentas serán rechazados inmediatamente. Todos los comentarios y cuentas pendientes de moderación fueron rechazados."
+      error: "No se pudo bloquear la instancia. Hemos recibido el reporte y lo estaremos verificando."
   fediblock_states:
     action_on_several:
       success: "Se habilitaron las listas de bloqueo, podés encontrar las instancias filtrando por Bloqueadas. Todas las cuentas de estas instancias pendientes de moderación han sido bloqueadas. Podés activarlas individualmente en la sección Cuentas."