How to restore accidentally deleted documents from Sanity dataset

32 replies
Last updated: Jun 25, 2020
Is there a way to restore docs from a dataset in sanity, I accidentally wiped all my products.
AI Update

I'm really sorry to hear you accidentally wiped your products! The good news is that yes, you can restore deleted documents in Sanity if they were deleted within your plan's history retention period.

Quick Recovery Options

1. Restore via Studio UI (Easiest)

If you still have the document IDs, you can restore individual documents directly through the Studio:

  • Navigate to https://YOUR-PROJECT.sanity.studio/YOUR-DATASET/YOUR-DOC-TYPE/YOUR-DOC-ID
  • Even though the document is deleted, you can access its history and restore it using the history interface

2. Use the History API (For Bulk Restoration)

For restoring multiple products programmatically, you'll need to use the History API. Here's the approach based on a successful community recovery:

Step 1: Get the transaction ID of the deletion event

GET https://YOUR-PROJECT.api.sanity.io/v1/data/history/YOUR-DATASET/transactions

Step 2: Find the documents that were deleted in that transaction

GET https://YOUR-PROJECT.api.sanity.io/v1/data/history/YOUR-DATASET/transactions/TRANSACTION-ID?excludeContent=true&reverse=true

Step 3: For each deleted document, get its last revision before the deletion. The key insight is that you need to query the transaction before the deletion transaction to get the actual document content.

Step 4: Use the JavaScript client's createOrReplace() method to restore each document with the retrieved content.

A community member successfully restored 400 accidentally deleted documents using this exact approach. The tricky part is that querying the deletion transaction itself returns empty documents, so you need to get the previous transaction for each document.

Important Caveats

History retention depends on your plan (as detailed in the history documentation):

  • Free: 3 days
  • Growth: 90 days
  • Enterprise: 365 days (customizable)

If your deletion happened outside your retention window, the history is permanently gone.

Prevention for Next Time

Before making bulk changes, always export your dataset as a backup using the CLI export command:

sanity dataset export production backup-before-changes.tar.gz

You can then restore if something goes wrong:

sanity dataset import backup-before-changes.tar.gz production

Consider setting up automated backups using GitHub Actions or scheduled scripts, especially for production environments, since Sanity doesn't provide built-in backup storage.

Good luck with the recovery! If you're within your retention period, you should be able to get everything back.

Show original thread
32 replies
We're desperately needing help here. We accidentally deleted around 400 documents and re-created new ones with the same IDs. Unfortunately, we did not export the dataset in-between.
We're needing to restore the old versions of all these documents but can't quite piece together how to accomplish this from the docs on the History API. We can get the transactions, but that only takes us so far (especially considering we can't get the old content due to
excludeContent: true
being required.
Update: It seems like we have an ID of the transaction where all of these were deleted. What we can't figure out is how to "undo" that transaction.
user M
This is pretty urgent, any help here?
Hi both, that sounds worrying, sorry to hear. Could you DM me your project ID?
Also, just in case, could you share the transaction ID?
The one that we accidentally deleted all the products correct?
You want it in here or DM?
DM is fine šŸ™‚
Are you seeing the relevant transaction in the newly created documents’ history btw (considering they have the same IDs as the old docs)?
Yes, we are. We can see history for the documents that exist now.
We were going to try reverting a couple individual documents via the studio UI and reverse-engineer the request it sends.
That’s creative šŸ˜‰ And one way to get things back I guess, if the former product IDs are matched 1:1 with the new ones. But would be good to have an undo for the transaction itself. I’ve asked the team but it might take a moment to investigate this.
okay thank you so much šŸ˜„
user M
Would you advise against doing what we were going to do for any reason? Should we wait until you've investigated before restoring any individual documents?
If you feel comfortable moving ahead that way, it’s likely to be faster in this case, so feel free to do so šŸ™‚ Just keep us posted!
I’ll let you know if I get an update on the transaction question in the meantime. We won’t take action without informing you.
Okay. If there's still a way to do some kind of mass-restore, we'd definitely still be interested. Just wanted to make sure restoring individual documents at this point wouldn't hinder that effort in any way.
[It shouldn’t] šŸ‘
Ok, so here’s some practical input šŸ™‚
Step 1: Get all the documents involved in this transaction usingĀ 
GET /transactions
Ā API.
Step 2: Use history API’sĀ 
GET /history/documents
Ā endpoint to build all the documents as they looked during that transaction.
Step 3: Submit Create mutation to recreate these documents.
So I tried that, and used the exact time stamp of the deletion and it doesn’t seem to return the data we need
For example:
<https://c3g4r239.api.sanity.io/v1/data/history/dev/documents/2-FMT-2?revision=IT2L0aqWToOorOcvdRoqsD>

This is the deletion transaction id

doing a get request for that just returns:

{
    "documents": []
}
That’s not a very useful response indeed. We’ll check but will take around half an hour until someone can look at it - in case you’re in a hurry šŸ™‚
that’s fine! Thank you!
Is it because the documents that were deleted didn't exist as of the transaction that deleted them?
So we need to somehow programmatically get the most recent transaction ID before that one for each document? (It could be different for each document since they were all edited at different points before the accidental mass-delete).
That took a bit longer than expected. There’s still no straightforward way but this should provide one method. Whether it’s easier than what you’re already carrying out with the individual docs depends:

<https://c3g4r239.api.sanity.io/v1/data/history/dev/transactions/2-FMT-2?excludeContent=true&reverse=true>

The above API call also returns all the docs involved in the delete transaction, loop through them to get all 400 doc ids. Call the same API to get one-before-delete transaction for the all the documents. CallĀ 
/history/documents
Ā API on all these documents with revision id (transaction id) to get the snapshot.
Yep, this is exactly what I am in the process of doing.
Appreciate all the help! It's good to have confirmation that this approach is the correct way.
Haha thank you though Peter! We will keep you updated!
That’s great, you found the way before we could show it - next time I’ll ask you instead šŸ˜„ Hope things will settle this way!
user M
Looks like we have got it working!
user K
ran his script and it seemed to revert all the docs to the prev transaction before the delete.
That’s awesome, well done! Must have taken some detective work to get everything lined up correctly for the script to run. We’ll work on improving the docs around recovery as you’re surely not the first to run into this šŸ™‚
That'd be great! Thanks again for the help today!

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?