Beam Help
Get help now

How-to · Zoho DESK

How to delete a ticket attachment in Zoho Desk

Remove a file or attachment from a support ticket.

Deleting a ticket attachment in Zoho Desk is done via a DELETE API call that targets the specific attachment by its ID within a given ticket. Depending on where the attachment lives — on the ticket itself, on a thread, or on a transition draft — you'll use a slightly different endpoint.


Why this matters


Attachments on support tickets can contain sensitive customer data, outdated files, or simply clutter that makes triage harder. Being able to remove them programmatically is essential for automated cleanup workflows, compliance-driven data retention policies, or any integration that manages ticket content at scale. As independent expert support for Zoho (not official Zoho support), Beam Help walks you through every variant of this operation.


Step-by-step


Step 1. Confirm your OAuth scopes are in place.

Before making any destructive API call, verify that your connected app has been granted the Desk.tickets.DELETE scope (and Desk.tickets.ALL if you want full ticket permissions). Without these scopes the request will be rejected at the authorization layer. [6]


Step 2. Identify which attachment you want to remove.

You need two IDs: the ticketId of the parent ticket and the attachmentId of the file you want to remove. If you are unsure of the attachmentId, retrieve it first with a GET request to /api/v1/tickets/{ticketId}/attachments/{attachmentId} to confirm you have the right record before deleting. [8]


Step 3. Delete a top-level ticket attachment.

Send a DELETE request to the following endpoint, substituting your real IDs:


DELETE /api/v1/tickets/{ticketId}/attachments/{attachmentId}

In Python this looks like:


response = client.delete_ticket_attachment(
    ticketId="your_ticket_id",
    attachmentId="your_attachment_id"
)

A successful call removes the attachment from the ticket record entirely. [1]


Step 4. (Alternative) Delete an attachment on a ticket thread.

If the file was uploaded as part of a reply or note thread rather than directly on the ticket, you must include the thread_id in the path. Use this endpoint instead:


DELETE /api/v1/tickets/{ticket_id}/threads/{thread_id}/attachments/{attachment_id}

In Python:


response = client.delete_attachment(
    ticket_id="your_ticket_id",
    thread_id="your_thread_id",
    attachment_id="your_attachment_id"
)

This variant requires three path parameters rather than two, so make sure you have the correct thread_id before calling it. [3]


Step 5. (Alternative) Delete an attachment from a transition draft.

If your workflow uses ticket transitions and an attachment was added to a transition draft, a separate endpoint handles that case:


DELETE /api/v1/tickets/{ticketId}/transitions/{transitionId}/attachments/{attachmentId}

In Python:


response = client.op_16_delete_attachment_of_transition(
    ticketId="your_ticket_id",
    transitionId="your_transition_id",
    attachmentId="your_attachment_id"
)

This is specifically scoped to transition draft attachments and will not affect attachments stored directly on the ticket or its threads. [4]


---


Common pitfalls


  • Wrong endpoint for the attachment type. The Zoho Desk API exposes distinct routes for ticket-level attachments, thread-level attachments, and transition-draft attachments. Using the ticket-level endpoint (/tickets/{ticketId}/attachments/{attachmentId}) when the file actually belongs to a thread will return an error or a "not found" response. Always confirm where the attachment was originally uploaded. [1][3]

  • Missing or incorrect scope. The Desk.tickets.DELETE scope must be explicitly included in your OAuth token request. Having only Desk.tickets.READ or Desk.tickets.WRITE is not sufficient for deletion. Review your scope configuration and re-authorise if needed. [6]

  • Confusing ticket attachments with account attachments. If you are working in a context that also manages account records, note that account-level attachments use a completely different path (/api/v1/accounts/{accountId}/attachments/{attachmentId}) and should not be mixed up with ticket attachment endpoints. [7]

  • Irreversible operation. A DELETE call on an attachment is permanent. There is no recycle bin or undo. Always use the GET endpoint to verify the correct attachmentId before issuing the delete. [8]

---


What to check


  • Confirm the attachment is gone by calling GET /api/v1/tickets/{ticketId}/attachments/{attachmentId} after deletion — it should return a 404 or empty response, indicating the file has been removed. [8]
  • Verify scope coverage in your OAuth client settings to ensure Desk.tickets.DELETE (or Desk.tickets.ALL) is present and the token has been refreshed since the scope was added. [6]
  • Check the correct path variant was used — ticket-level, thread-level, or transition-level — to ensure the right attachment was targeted and no unintended files were affected. [1][3][4]

Sources cited

  1. [1] DELETE /api/v1/tickets/{ticketId}/attachments/{attachmentId}
  2. [2] DELETE /api/v1/tickets/{ticket_id}/attachments/{attachment_id}
  3. [3] DELETE /api/v1/tickets/{ticket_id}/threads/{thread_id}/attachments/{attachment_id}
  4. [4] DELETE /api/v1/tickets/{ticketId}/transitions/{transitionId}/attachments/{attachmentId}
  5. [5] server.py: build_zoho_links
  6. [6] config.py
  7. [7] DELETE /api/v1/accounts/{accountId}/attachments/{attachmentId}
  8. [8] GET /api/v1/tickets/{ticketId}/attachments/{attachmentId}
Delete Ticket Attachment | Beam Help — Beam Help