API - Delete attachment from article

is it possible to delete attachments using the APIs?
I need, if possible, to develop a procedure that, by calling an API, deletes attachments from a closed ticket, since attachments may contain sensitive data.

Hi @microdesign. You could delete articles via REST API.

Hi @microdesign ,

you could solve this by the following changes:

  1. Create a new route to delete ticket attachments (config/routes/ticket.rb)
  2. Add a new instance function to delete all attachments of the ticket (app/model/ticket.rb)
  3. Add a controller function for your route to handle the ticket delete request (app/controller/tickets_controller.rb)
  4. Restrict the access to the admins for the new controller function (app/policies/controllers/tickets_controller_policy.rb)

Here some example code:

diff --git a/app/controllers/tickets_controller.rb b/app/controllers/tickets_controller.rb
index d796909ecf..8f2ce8dc5a 100644
--- a/app/controllers/tickets_controller.rb
+++ b/app/controllers/tickets_controller.rb
@@ -662,6 +662,12 @@ class TicketsController < ApplicationController
     render json: result, status: :ok
+  def delete_attachments
+    Ticket.find(params[:id]).delete_attachments
+    render json: {}, status: :ok
+  end
   def ticket_all(ticket)
diff --git a/app/models/ticket.rb b/app/models/ticket.rb
index 36d5ddb03b..a2e1898956 100644
--- a/app/models/ticket.rb
+++ b/app/models/ticket.rb
@@ -627,6 +627,19 @@ returns a hex color code
+  def delete_attachments
+  	articles.each do |article|
+      next if article.attachments.blank?
+      Store.remove(
+        object: 'Ticket::Article',
+        o_id: article.id,
+      )
+      article.update(preferences: article.preferences.merge(attachments_deleted_at: Time.zone.now))
+    end
+  end
   def check_generate
diff --git a/app/policies/controllers/tickets_controller_policy.rb b/app/policies/controllers/tickets_controller_policy.rb
index f22c01e04d..63996902a9 100644
--- a/app/policies/controllers/tickets_controller_policy.rb
+++ b/app/policies/controllers/tickets_controller_policy.rb
@@ -1,7 +1,7 @@
 # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
 class Controllers::TicketsControllerPolicy < Controllers::ApplicationControllerPolicy
-  permit! %i[import_example import_start], to: 'admin'
+  permit! %i[import_example import_start delete_attachments], to: 'admin'
   permit! %i[ticket_customer ticket_history ticket_related ticket_recent ticket_merge ticket_split], to: 'ticket.agent'
   permit! %i[ticket_create create], to: ['ticket.agent', 'ticket.customer']
diff --git a/config/routes/ticket.rb b/config/routes/ticket.rb
index 346952c7e5..f160cd1d57 100644
--- a/config/routes/ticket.rb
+++ b/config/routes/ticket.rb
@@ -38,6 +38,7 @@ Zammad::Application.routes.draw do
   match api_path + '/ticket_recent',                                 to: 'tickets#ticket_recent',     via: :get
   match api_path + '/ticket_merge/:source_ticket_id/:target_ticket_number', to: 'tickets#ticket_merge', via: :put
   match api_path + '/ticket_stats',                                  to: 'tickets#stats',             via: %i[get post]
+  match api_path + '/ticket_attachment/:id',                         to: 'tickets#delete_attachments', via: :delete
   # ticket overviews
   match api_path + '/ticket_overview',                               to: 'ticket_overviews#data',     via: :get

If you want to learn some more about packaging, feel free to take a look at Packages Tutorial

Ah I forgot, here the example cur api request for the ticket delete :wink:

curl -XDELETE -u"admin@example.com:test"