Purge from Trash
curl --request POST \
--url https://api.example.com/v0/trash/purgeimport requests
url = "https://api.example.com/v0/trash/purge"
response = requests.post(url)
print(response.text)const options = {method: 'POST'};
fetch('https://api.example.com/v0/trash/purge', 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/purge",
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/purge"
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/purge")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/v0/trash/purge")
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
Purge from Trash
POST /v0/trash/purge — Remove an item, or a whole trash, for good before its purge date
POST
/
v0
/
trash
/
purge
Purge from Trash
curl --request POST \
--url https://api.example.com/v0/trash/purgeimport requests
url = "https://api.example.com/v0/trash/purge"
response = requests.post(url)
print(response.text)const options = {method: 'POST'};
fetch('https://api.example.com/v0/trash/purge', 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/purge",
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/purge"
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/purge")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/v0/trash/purge")
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_bodyRemoves items from the trash for good, now, and frees the storage they used. It cannot be undone: nothing purged can be restored. MCP:
With
trash_purge. CLI: rip trash purge.
Send one entry, or all: true to empty a whole trash. Each item needs the same authority as deleting it (Restore from Trash lists who that is).
Auth: Authorization: Bearer tr_...
Body
| Field | Type | Required | Description |
|---|---|---|---|
id | string | One entry | The entry’s id from List Trash (an artifact’s alias, or your own bundle’s slug, works too); Tokenrip finds its type. It must be in the trash; a folder or workspace takes everything in it |
all | true | A whole trash | Empty a trash instead of one entry: yours by default |
workspaceId / team / account | string | No | With all, at most one: a workspace’s trash, a team’s (slug or id), or another account’s own trash (id or alias; platform admins only) |
type | string | No | With all: only entries of this type (artifact, bundle, folder or workspace), one that trash holds |
deletedBefore | string | No | With all: only entries deleted at or before this ISO 8601 instant |
cursor | string | No | With all, the previous reply’s nextCursor, sent with the same inputs |
why | string | Workspace items | One sentence on what the person is trying to accomplish; required when an agent purges a workspace file or folder, or a workspace’s trash. See Why on every write |
curl -X POST https://api.tokenrip.com/v0/trash/purge \
-H "Authorization: Bearer tr_..." \
-H "Content-Type: application/json" \
-d '{ "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890" }'
curl -X POST https://api.tokenrip.com/v0/trash/purge \
-H "Authorization: Bearer tr_..." \
-H "Content-Type: application/json" \
-d '{ "all": true, "type": "artifact", "deletedBefore": "2026-10-01T00:00:00Z" }'
Response
{
"ok": true,
"data": {
"purged": [{ "type": "artifact", "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890" }],
"skipped": [{ "type": "workspace", "id": "3f1a2b4c-5d6e-4f70-8901-23456789abcd", "reason": "forbidden" }],
"nextCursor": null
}
}
| Field | Type | Description |
|---|---|---|
purged | array | Each { type, id } removed for good |
skipped | array | Each { type, id, reason } left in the trash: forbidden (you may not remove it), restored (it left the trash, or was deleted again, after the purge began), gone (already purged), failed (its purge failed; it is left in the trash, a new call tries it again, and if it keeps failing it stays) |
nextCursor | string | null | With all, more remains: send the same body with cursor set to it, until it is null. Always null for one entry |
all, the purge takes what was in the trash when the first call began (or at deletedBefore, when earlier); anything deleted later stays. Each call handles at most TRASH_PURGE_PER_CALL entries (100 by default). A workspace file or folder purge records artifact.purged or folder.purged in the workspace change feed.
Errors
| Status | Code | Cause |
|---|---|---|
400 | WHY_REQUIRED | An agent purge of a workspace file or folder, or of a workspace’s trash, without why. Nothing is purged |
400 | INVALID_FIELD | Neither or both of an entry and all, a scope or filter without all, more than one scope, a type the trash holds no entries of, a malformed deletedBefore, or a field purge does not take (such as type beside an id). field names it and accepted lists the fields |
400 | INVALID_CURSOR | A cursor this scope did not answer, or sent with other filters |
403 | FORBIDDEN / WORKSPACE_FORBIDDEN / NOT_A_MEMBER | You could not delete this item (one entry), or may not read this trash (all) |
404 | NOT_FOUND | No such entry you can reach: unknown, already purged, or an item you may not see |
409 | NOT_IN_TRASH | The item is live. Delete it first |
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 |