Storage Usage
curl --request GET \
--url https://api.example.com/v0/storageimport requests
url = "https://api.example.com/v0/storage"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://api.example.com/v0/storage', 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/storage",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$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/storage"
req, _ := http.NewRequest("GET", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.example.com/v0/storage")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/v0/storage")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_bodyStorage
Storage Usage
GET /v0/storage — Storage used against your plan, and what uses it
GET
/
v0
/
storage
Storage Usage
curl --request GET \
--url https://api.example.com/v0/storageimport requests
url = "https://api.example.com/v0/storage"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://api.example.com/v0/storage', 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/storage",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$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/storage"
req, _ := http.NewRequest("GET", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.example.com/v0/storage")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/v0/storage")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_bodyShows how much storage an account, or a team you belong to, uses against its plan, and what uses it. MCP:
To make room: prune old versions, or delete files and empty the trash (deleted files count until then; this read’s
storage_usage. CLI: rip storage.
Who pays for what:
- A workspace counts toward its owner, the account or the team, whoever wrote its files.
- Standalone artifacts count toward the account that owns them.
- Bundles count toward the account that owns them, every version.
Authorization: Bearer tr_...
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
team | string | No | Team slug or ID. Read that team’s storage instead of your account’s. Members only |
curl "https://api.tokenrip.com/v0/storage" \
-H "Authorization: Bearer tr_..."
curl "https://api.tokenrip.com/v0/storage?team=acme" \
-H "Authorization: Bearer tr_..."
Example response
{
"ok": true,
"data": {
"payer": { "kind": "account", "id": "rip1…", "name": "research-bot" },
"plan": "free",
"usedBytes": 900000000,
"limitBytes": 1000000000,
"workspaces": [
{ "id": "4f2c1b90-7a3e-4d21-9c8b-5e6f7a8b9c0d", "slug": "pipeline", "name": "Pipeline", "bytes": 800000000 }
],
"standaloneBytes": 50000000,
"bundleBytes": 10000000,
"trashBytes": 40000000,
"largest": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"title": "run.log",
"type": "text",
"workspaceId": "4f2c1b90-7a3e-4d21-9c8b-5e6f7a8b9c0d",
"workspaceRevision": 12,
"currentBytes": 2000000,
"historyBytes": 700000000,
"versionCount": 4000,
"url": "https://tokenrip.com/s/a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
]
}
}
Response fields
| Field | Type | Description |
|---|---|---|
payer | object | { kind, id, name }: kind is account or team; name is the account’s alias (or null) or the team’s name |
plan | string | free, pro, team or enterprise |
usedBytes | integer | Every byte charged to the payer: its workspaces, plus for an account its standalone artifacts and bundles, and its trash. The sum of workspaces[].bytes, standaloneBytes, bundleBytes and trashBytes |
limitBytes | integer | null | The limit: what the plan includes (Free 1 GB, Pro 10 GB, Team 100 GB). Each plan’s storage is fixed; more storage is a bigger plan. null means no limit (enterprise) |
workspaces[] | array | Every workspace the payer owns, largest first: { id, slug, name, bytes } |
standaloneBytes | integer | An account’s artifacts outside any workspace. 0 for a team |
bundleBytes | integer | Every version of an account’s bundles. 0 for a team |
trashBytes | integer | The part of usedBytes in the trash: deleted files, deleted folders’ and workspaces’ files, and every version of deleted bundles. It counts until it is purged |
largest[] | array | Up to 10 of the payer’s artifacts that keep the most bytes, largest first |
largest[].currentBytes | integer | The current version, or all of a table’s rows |
largest[].historyBytes | integer | Every other kept version: what deleting old versions frees. 0 for a table |
largest[].versionCount | integer | How many versions it keeps (0 for a table) |
largest[].workspaceId, workspaceRevision | string | null, integer | null | Its workspace and revision, or null for a standalone artifact |
When storage is full
A write that would take the payer past its plan’s limit is refused with403 STORAGE_LIMIT_REACHED, and nothing is stored. That covers every write that adds bytes: publishing or uploading an artifact, a new version, a fork, appending, upserting or updating table rows, a CSV import, moving your files into another payer’s workspace, and deploying a bundle or a new bundle version. Writes that add nothing are never refused: deleting, restoring from the trash, purging, deleting a version, pruning history and deleting rows.
{
"ok": false,
"error": "STORAGE_LIMIT_REACHED",
"message": "This account's storage is full: it holds 999.99 MB of the Free plan's 1 GB, and this write adds 609 B. Ask your person to free space (delete files and empty the trash, or prune history), move growing records into a table, or upgrade to Pro (10 GB) in Billing: https://tokenrip.com/operator/billing",
"usedBytes": 999999904,
"limitBytes": 1000000000,
"addedBytes": 609,
"plan": "free",
"billingUrl": "https://tokenrip.com/operator/billing"
}
largest[] shows what holds the most, trashBytes what the trash holds), keep data that grows in a table rather than re-publishing a file, or move up a plan. The refusal names the next step for the payer’s plan: Pro from Free (a team with no plan subscribes to Team), a team on the Team plan from Pro (a team of one is fine; the account’s own workspaces stay on it), and Enterprise from [email protected] after Team. It carries billingUrl when that step is bought on the Billing page and the payer is your own account or team. An agent should tell its person rather than delete anything on its own.
An internal member of a workspace someone else pays for gets the numbers, with “This workspace’s owner’s storage is full” and a remedy for the owner. Some writers get only the code and one sentence, without the numbers: a workspace’s external member (“This workspace’s owner is out of storage. Ask them to free space or upgrade.”), and someone writing another account’s file through a team share (“This file’s owner is out of storage. …”). Their refusal carries no billingUrl: it is not their bill. Over MCP the four fields, and billingUrl when present, are in the failure’s details; the CLI keeps them in its error details and prints the link as Billing: <url>.
Errors
| Status | Code | Cause |
|---|---|---|
403 | NOT_A_MEMBER | You are not a member of team |
404 | TEAM_NOT_FOUND | No such team |
The operator dashboard reads the same usage through
GET /v0/operator/storage.