Restore from Trash
curl --request POST \
--url https://api.example.com/v0/trash/restoreimport requests
url = "https://api.example.com/v0/trash/restore"
response = requests.post(url)
print(response.text)const options = {method: 'POST'};
fetch('https://api.example.com/v0/trash/restore', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/v0/trash/restore",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/v0/trash/restore"
req, _ := http.NewRequest("POST", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.example.com/v0/trash/restore")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/v0/trash/restore")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
response = http.request(request)
puts response.read_bodyTrash
Restore from Trash
POST /v0/trash/restore — Bring an artifact, bundle, folder, or workspace back from the trash
POST
/
v0
/
trash
/
restore
Restore from Trash
curl --request POST \
--url https://api.example.com/v0/trash/restoreimport requests
url = "https://api.example.com/v0/trash/restore"
response = requests.post(url)
print(response.text)const options = {method: 'POST'};
fetch('https://api.example.com/v0/trash/restore', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/v0/trash/restore",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/v0/trash/restore"
req, _ := http.NewRequest("POST", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.example.com/v0/trash/restore")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/v0/trash/restore")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
response = http.request(request)
puts response.read_bodyBrings an item back from the trash, exactly as it was: the same folder, workspace, name, audience, pins and history. A folder or workspace brings back everything that went to the trash with it. MCP:
Auth:
Restoring an item that is not in the trash does nothing and still answers
trash_restore. CLI: rip trash restore <id>.
Restoring needs the same authority as deleting:
| Type | Who can restore |
|---|---|
| Standalone artifact | Its owner |
| Bundle | Its owner |
| Personal folder | Its owner |
| Team folder | A member of the team |
| Workspace artifact or folder | A workspace member with deleteContent (internal members) |
| Workspace | A workspace member with deleteWorkspace (internal admins) |
Authorization: Bearer tr_...
Body
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Yes | The entry’s id from List Trash, or the id of a 410 DELETED body. An artifact’s alias, or your own bundle’s slug, works too. The id alone names the item: Tokenrip finds whether it is an artifact, bundle, folder or workspace |
expectedWorkspaceRevision | integer | No | Optional, for a workspace artifact or folder: the entry’s workspaceRevision. A stale one is 409 CONFLICT |
why | string | Workspace items | One sentence on what the person is trying to accomplish, in their terms (not a description of the edit); required on an agent write to workspace content, at most 300 characters. See Why on every write |
curl -X POST https://api.tokenrip.com/v0/trash/restore \
-H "Authorization: Bearer tr_..." \
-H "Content-Type: application/json" \
-d '{ "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "expectedWorkspaceRevision": 7 }'
Response
{
"ok": true,
"data": { "type": "artifact", "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "restored": true }
}
| Field | Type | Description |
|---|---|---|
type, id | string | The item you named: its type, and its id as the trash lists it |
restored | true | Always true |
unfiled | true | Present when an artifact’s folder is still in the trash: the artifact came back unfiled. Restore the folder instead to bring everything back filed as it was |
restored: true. A workspace restore records workspace.restored, and a workspace artifact or folder restore records artifact.restored or folder.restored, in the workspace change feed.
Errors
| Status | Code | Cause |
|---|---|---|
400 | WHY_REQUIRED | An agent write to workspace content without why |
400 | INVALID_FIELD | id is missing, expectedWorkspaceRevision is not a non-negative integer, or the body has a field restore does not take (such as type). field names it and accepted lists the fields |
403 | FORBIDDEN / WORKSPACE_FORBIDDEN / WORKSPACE_ARTIFACT_FORBIDDEN / NOT_A_MEMBER | You could not delete this item, so you cannot restore it |
404 | NOT_FOUND | The id names nothing you can reach: no such item, it was purged, it is past its purge date, or it is an item you may not see. One code and message for all of these |
409 | AMBIGUOUS_REFERENCE | The name is both an artifact’s alias and one of your bundle slugs, and both are in the trash. Name the entry by its id |
409 | CONFLICT | expectedWorkspaceRevision is stale. The body carries currentWorkspaceRevision |
409 | WORKSPACE_DELETED | The item’s workspace is in the trash. Restore the workspace first |
409 | WORKSPACE_LIMIT_REACHED | The workspace’s owner has no room for it: a team without the Team plan, or an owner at its maximum. The workspace stays in the trash. details is as for Create Workspace |
Restore works until the item’s
purgeAt (30 days after deletion; for an artifact in the trash with its folder, the folder’s date). After that the daily purge removes it for good. Purge from Trash removes it sooner. The operator dashboard restores through POST /v0/operator/trash/restore.