Background: I'm adding hard deletes to the Salesforce destination in StreamSets Data Collector. Adding the ability to do hard deletes via the Bulk API is trivial - just specify hardDelete instead of delete as the operation for the job. Where I'm hitting a problem is in testing that a hard delete did, in fact, happen, rather than a soft delete.

As has been discussed in answers to questions such as The netherworld of deleted records not in recycle bin, explicitly hard-deleted records, and records emptied out of the recycle bin, still show up in queries for deleted records alongside the contents of the recycle bin. The final section of the article Recover records and data in Salesforce explains the record deletion deathcycle that causes this behavior - the period of time between records being marked for deletion and actually deleted.

And so we come to the question: is there a way to retrieve the contents of the recycle bin via API (I'm not aware of one!), or a way to determine whether a given record is in the recycle bin or not, short of trying to undelete the record.

I have verified that, as expected, I can undelete a soft-deleted record, and that trying to delete a hard-deleted record located via a SOQL query in Apex does indeed fail:

Account[] a = [SELECT Id, Name FROM Account WHERE Name = 'deleteme' ALL ROWS];


undelete a;

Trying the above after hard-deleting the Account 'deleteme' gives:

System.DmlException: Undelete failed. First exception on row 0 with id 0011R00002iWH24QAG; first error: UNDELETE_FAILED, Entity is not in the recycle bin: []

I can try to undelete the record and test for the exceptions, but I'd like a more... elegant approach.

  • I do believe trying to undelete is your only option. Did you run that query with the given Id after it was hard deleted and it still returned rows? I would have assumed that query would not find the record any more, giving you a DML-free option.
    – Adrian Larson
    Oct 4, 2021 at 21:35
  • Yes - running that query after hard-deletion still returns the record, since at that point it's only marked for deletion, and it will be physically deleted some time later.
    – metadaddy
    Oct 4, 2021 at 21:45

1 Answer 1


I believe what you're looking for is this query:

Boolean isRecordInRecycleBin = [SELECT COUNT() FROM DeleteEvent WHERE Record = '0011R00002iWH24QAG'] == 1;

Note: This query also returns true for records that are not deleted at all so you'll need to run IsDeleted = TRUE ALL ROWS query first to get all deleted records and then use the ids in the query above to determine if the records are soft or hard deleted

Here's a recycle bin URL in it you can see that the object used is DeleteEvent: https://connect-computing-2597-dev-ed.lightning.force.com/lightning/o/DeleteEvent/list?filterName=00B3F000009ovJvUAI

Reference: https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_deleteevent.htm

  • Was removed in API Version 50, according to the docs.
    – Adrian Larson
    Oct 4, 2021 at 22:26
  • 2
    @AdrianLarson Ya that's a vague documentation. They mean 'search' as in SOSL not SOQL. System.QueryException: entity type DeleteEvent does not support search. SOQL still works in v52.0 Oct 4, 2021 at 22:47
  • 1
    Perfect - thanks so much! I have the Id of the deleted record in question, so I just need to run this SOQL and see if the DeleteEvent is there or not.
    – metadaddy
    Oct 4, 2021 at 22:58

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .