API reference · Platform

Storage

Your reference bucket: uploaded files, private folders, one shared quota.

GETPOSTPATCHDELETE/v1/uploadsFree · counts against the shared bucket quota

The workspace's reference bank — the files behind /studio/storage. They live in the eroq Store bucket under workspaces/{workspace_id}/uploads/ (single-level folders are prefixes of the key), share the quota with the library (5 GB free, more on every plan), cost no credits, and are NEVER public: every read is a short-lived signed URL, so nothing can hotlink your references off-site. Character and element reference photos live in the same bucket under workspaces/{ws}/references/{characters|elements}/{id}/ and count against the same quota (uploadsBytes in the meter).

There is no metadata database — the key IS the record: workspaces/{ws}/uploads/{folder?}/{id}-{Name}.ext. The id prefix survives renames and moves, so a reference keeps working even while you reorganize. File names double as @-mention handles (@Red Jacket in a prompt, matched case-insensitively). Root folders are capped at 20 per workspace (409 folder_limit), and folder deletion is a single native recursive directory delete — children AND the directory object itself go.

The bucket takes images and videos only — a reference is a face, a place, a prop or a clip, so anything else answers 415 type_not_accepted. Access follows the workspace role ladder: storage:read to browse, storage:upload (Creator and above by default) to add or organise, storage:delete (Developer and above) to remove; a key acts with its owner's role.

POST /v1/uploads takes multipart file plus optional folder and name; over the bucket ceiling it answers 409 storage_full (free space or upgrade — generations still work, they just stop auto-saving). PATCH /v1/uploads/{id} renames and/or moves. PATCH /v1/uploads/folders/{name} and DELETE /v1/uploads/folders/{name} rezone or remove a whole folder. Reference an upload in any generation's elements array as upload:<id> — its photo joins the numbered references slots.

GET /v1/uploads/usage returns just the meter ({ usage: { bucketBytes, limitBytes, over } }) — cheap enough to consult before every render.

Endpoints

Select a verb to load its request, playground and response.

GET/v1/uploadsshown

List every reference (files + folders + the shared-bucket usage).

POST/v1/uploads

Upload a reference file (multipart file, optional folder, name). A new folder beyond the 20-folder cap answers 409 folder_limit.

PATCH/v1/uploads/{id}

Rename and/or move a file.

DELETE/v1/uploads/{id}

Remove a file from the bucket.

PATCH/v1/uploads/folders/{name}

Rename a folder — every child is rezoned (each keeps its mention-stable id), then the emptied old directory is deleted.

DELETE/v1/uploads/folders/{name}

Delete a folder and everything in it — one native recursive delete, the directory object included.

curl https://eroq.ai/v1/uploads \
  -H "Authorization: Bearer $EROQ_API_KEY"
/v1/uploads
→ GET /v1/uploads
Press run — this replays a real exchange from the docs' own data. No key, no request, no charge.

Response

200 · application/json
{
  "files": [{
    "id": "0b52a91f-3c", "name": "Red Jacket", "folder": "Wardrobe",
    "file": "0b52a91f-3c-Red_Jacket.webp", "ext": "webp",
    "bytes": 184320, "lastModified": "2026-09-21T10:11:12.000",
    "key": "workspaces/1f0c…/uploads/Wardrobe/0b52a91f-3c-Red_Jacket.webp",
    "url": "https://store.eroq.ai/workspaces/1f0c…/uploads/Wardrobe/0b52a91f-3c-Red_Jacket.webp?token=…"
  }],
  "folders": ["Wardrobe"],
  "folderLimit": 20,
  "usage": { "totalBytes": 1480000000, "publishedBytes": 0, "libraryBytes": 220000000,
    "uploadsBytes": 640000, "bucketBytes": 220640000, "limitBytes": 5368709120, "over": false }
}