diff --git a/app/graphql/mutations/achievements/delete.rb b/app/graphql/mutations/achievements/delete.rb
new file mode 100644
index 0000000000000000000000000000000000000000..0b510b44b4ef37d89ce9fb79e5bf9b1ccd69592b
--- /dev/null
+++ b/app/graphql/mutations/achievements/delete.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+module Mutations
+  module Achievements
+    class Delete < BaseMutation
+      graphql_name 'AchievementsDelete'
+
+      include Gitlab::Graphql::Authorize::AuthorizeResource
+
+      field :achievement,
+        ::Types::Achievements::AchievementType,
+        null: true,
+        description: 'Achievement.'
+
+      argument :achievement_id, ::Types::GlobalIDType[::Achievements::Achievement],
+        required: true,
+        description: 'Global ID of the achievement being deleted.'
+
+      authorize :admin_achievement
+
+      def resolve(args)
+        achievement = authorized_find!(id: args[:achievement_id])
+
+        result = ::Achievements::DestroyService.new(current_user, achievement).execute
+        { achievement: result.payload, errors: result.errors }
+      end
+
+      def find_object(id:)
+        GitlabSchema.object_from_id(id, expected_type: ::Achievements::Achievement)
+      end
+    end
+  end
+end
diff --git a/app/graphql/types/mutation_type.rb b/app/graphql/types/mutation_type.rb
index 9bdbdad43861d0046894dab218ba88ecb164f7a6..43ca4f9643d2d5d856a2c132a5b319afb8975463 100644
--- a/app/graphql/types/mutation_type.rb
+++ b/app/graphql/types/mutation_type.rb
@@ -8,6 +8,7 @@ class MutationType < BaseObject
 
     mount_mutation Mutations::Achievements::Award, alpha: { milestone: '15.10' }
     mount_mutation Mutations::Achievements::Create, alpha: { milestone: '15.8' }
+    mount_mutation Mutations::Achievements::Delete, alpha: { milestone: '15.11' }
     mount_mutation Mutations::Achievements::Revoke, alpha: { milestone: '15.10' }
     mount_mutation Mutations::Admin::SidekiqQueues::DeleteJobs
     mount_mutation Mutations::AlertManagement::CreateAlertIssue
diff --git a/app/services/achievements/destroy_service.rb b/app/services/achievements/destroy_service.rb
new file mode 100644
index 0000000000000000000000000000000000000000..3204adb8e891596c052a9a7b7f10d9080378925b
--- /dev/null
+++ b/app/services/achievements/destroy_service.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+module Achievements
+  class DestroyService
+    attr_reader :current_user, :achievement
+
+    def initialize(current_user, achievement)
+      @current_user = current_user
+      @achievement = achievement
+    end
+
+    def execute
+      return error_no_permissions unless allowed?
+
+      achievement.delete
+      ServiceResponse.success(payload: achievement)
+    end
+
+    private
+
+    def allowed?
+      current_user&.can?(:admin_achievement, achievement)
+    end
+
+    def error_no_permissions
+      error('You have insufficient permissions to delete this achievement')
+    end
+
+    def error(message)
+      ServiceResponse.error(message: Array(message))
+    end
+  end
+end
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index 27da9f2b653493120833d7b02047d54c6e1d09b1..312e8894071c6380c6bf985b2b433d3665da5f75 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -795,6 +795,29 @@ Input type: `AchievementsCreateInput`
 | <a id="mutationachievementscreateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
 | <a id="mutationachievementscreateerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
 
+### `Mutation.achievementsDelete`
+
+WARNING:
+**Introduced** in 15.11.
+This feature is in Alpha. It can be changed or removed at any time.
+
+Input type: `AchievementsDeleteInput`
+
+#### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mutationachievementsdeleteachievementid"></a>`achievementId` | [`AchievementsAchievementID!`](#achievementsachievementid) | Global ID of the achievement being deleted. |
+| <a id="mutationachievementsdeleteclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mutationachievementsdeleteachievement"></a>`achievement` | [`Achievement`](#achievement) | Achievement. |
+| <a id="mutationachievementsdeleteclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationachievementsdeleteerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
+
 ### `Mutation.achievementsRevoke`
 
 WARNING:
diff --git a/spec/graphql/mutations/achievements/delete_spec.rb b/spec/graphql/mutations/achievements/delete_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..0eb6f5a2e6f9b29952473432f4b9dd5cdab925ef
--- /dev/null
+++ b/spec/graphql/mutations/achievements/delete_spec.rb
@@ -0,0 +1,56 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Mutations::Achievements::Delete, feature_category: :user_profile do
+  include GraphqlHelpers
+
+  let_it_be(:developer) { create(:user) }
+  let_it_be(:maintainer) { create(:user) }
+  let_it_be(:recipient) { create(:user) }
+  let_it_be(:group) { create(:group) }
+
+  let(:achievement) { create(:achievement, namespace: group) }
+
+  describe '#resolve' do
+    subject(:resolve_mutation) do
+      described_class.new(object: nil, context: { current_user: current_user }, field: nil).resolve(
+        achievement_id: achievement&.to_global_id
+      )
+    end
+
+    before_all do
+      group.add_developer(developer)
+      group.add_maintainer(maintainer)
+    end
+
+    context 'when the user does not have permission' do
+      let(:current_user) { developer }
+
+      it 'raises an error' do
+        expect { resolve_mutation }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+          .with_message(Gitlab::Graphql::Authorize::AuthorizeResource::RESOURCE_ACCESS_ERROR)
+      end
+    end
+
+    context 'when the user has permission' do
+      let(:current_user) { maintainer }
+
+      context 'when the params are invalid' do
+        let(:achievement) { nil }
+
+        it 'returns the validation error' do
+          expect { resolve_mutation }.to raise_error { Gitlab::Graphql::Errors::ArgumentError }
+        end
+      end
+
+      it 'deletes the achievement' do
+        resolve_mutation
+
+        expect(Achievements::Achievement.find_by(id: achievement.id)).to be_nil
+      end
+    end
+  end
+
+  specify { expect(described_class).to require_graphql_authorizations(:admin_achievement) }
+end
diff --git a/spec/requests/api/graphql/mutations/achievements/delete_spec.rb b/spec/requests/api/graphql/mutations/achievements/delete_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..276da4f46a8158bdf00519a32ee51b17aaa6072c
--- /dev/null
+++ b/spec/requests/api/graphql/mutations/achievements/delete_spec.rb
@@ -0,0 +1,79 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Mutations::Achievements::Delete, feature_category: :user_profile do
+  include GraphqlHelpers
+
+  let_it_be(:developer) { create(:user) }
+  let_it_be(:maintainer) { create(:user) }
+  let_it_be(:group) { create(:group) }
+
+  let!(:achievement) { create(:achievement, namespace: group) }
+  let(:mutation) { graphql_mutation(:achievements_delete, params) }
+  let(:achievement_id) { achievement&.to_global_id }
+  let(:params) { { achievement_id: achievement_id } }
+
+  subject { post_graphql_mutation(mutation, current_user: current_user) }
+
+  def mutation_response
+    graphql_mutation_response(:achievements_delete)
+  end
+
+  before_all do
+    group.add_developer(developer)
+    group.add_maintainer(maintainer)
+  end
+
+  context 'when the user does not have permission' do
+    let(:current_user) { developer }
+
+    it_behaves_like 'a mutation that returns a top-level access error'
+
+    it 'does not revoke any achievements' do
+      expect { subject }.not_to change { Achievements::Achievement.count }
+    end
+  end
+
+  context 'when the user has permission' do
+    let(:current_user) { maintainer }
+
+    context 'when the params are invalid' do
+      let(:achievement) { nil }
+
+      it 'returns the validation error' do
+        subject
+
+        expect(graphql_errors.to_s).to include('invalid value for achievementId (Expected value to not be null)')
+      end
+    end
+
+    context 'when the achievement_id is invalid' do
+      let(:achievement_id) { "gid://gitlab/Achievements::Achievement/#{non_existing_record_id}" }
+
+      it 'returns the validation error' do
+        subject
+
+        expect(graphql_errors.to_s)
+          .to include("The resource that you are attempting to access does not exist or you don't have permission")
+      end
+    end
+
+    context 'when the feature flag is disabled' do
+      before do
+        stub_feature_flags(achievements: false)
+      end
+
+      it 'returns the relevant error' do
+        subject
+
+        expect(graphql_errors.to_s)
+          .to include("The resource that you are attempting to access does not exist or you don't have permission")
+      end
+    end
+
+    it 'deletes the achievement' do
+      expect { subject }.to change { Achievements::Achievement.count }.by(-1)
+    end
+  end
+end
diff --git a/spec/services/achievements/destroy_service_spec.rb b/spec/services/achievements/destroy_service_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..7af10ceec6af97827a9fe0beccc6a0bcec72bed2
--- /dev/null
+++ b/spec/services/achievements/destroy_service_spec.rb
@@ -0,0 +1,39 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Achievements::DestroyService, feature_category: :user_profile do
+  describe '#execute' do
+    let_it_be(:developer) { create(:user) }
+    let_it_be(:maintainer) { create(:user) }
+    let_it_be(:group) { create(:group) }
+
+    let(:achievement) { create(:achievement, namespace: group) }
+
+    subject(:response) { described_class.new(current_user, achievement).execute }
+
+    before_all do
+      group.add_developer(developer)
+      group.add_maintainer(maintainer)
+    end
+
+    context 'when user does not have permission' do
+      let(:current_user) { developer }
+
+      it 'returns an error' do
+        expect(response).to be_error
+        expect(response.message).to match_array(
+          ['You have insufficient permissions to delete this achievement'])
+      end
+    end
+
+    context 'when user has permission' do
+      let(:current_user) { maintainer }
+
+      it 'deletes the achievement' do
+        expect(response).to be_success
+        expect(Achievements::Achievement.find_by(id: achievement.id)).to be_nil
+      end
+    end
+  end
+end