Storage API is the ToolsAPI file archive for new and legacy files. Normal users work with their own files. Legacy forum files can also appear as owned files when the vBulletin account is linked to the Tools account.
Open:
/storage
You can:
Original files are retained. Image uploads can also receive smaller derivatives for faster previews.
Each file has a visibility level:
private - only the owner, administrators and correctly scoped StorageAPI clients can access itunlisted - the file has a stable public UUID link but is not shown in the public browserpublic - the file has a stable public UUID link and can also appear in the public browserThe public file browser is available at:
/storage/public
Only active files with visibility=public are listed there. Unlisted files remain reachable through their direct UUID URL.
Administrators can open the complete StorageAPI manager at:
/admin/storage
It uses the same manager as /storage, while administrator access can cover the full archive, legacy locations, missing-file repair, metadata and AI actions.
Filters include file type, active/deleted status, location availability and AI-analysis status.
Administrators can also filter and sort by the imported legacy storagepath. This is useful when a group of old files came from the same location, such as /filestore01 or /images/bilder/tornevall_storage, and needs to be repaired or moved together.
One file can have several possible locations. A broken legacy URL therefore does not require replacing or deleting the file record.
Location states are:
available - the location responds and the file appears to existmissing - the file is missing at that locationerror - the location check failedunknown - the location has not been checkedunresolved - the location is a legacy hint that cannot yet be checked directlyA replacement URL can be added to a file. "Check locations" tests the registered candidates again.
Administrators get an AI description button directly below images.
When used:
The general analyzer also supports description, alt text, tags, title and visible-text extraction. AI never automatically overwrites human-edited metadata.
Use Generate on an image and describe the new result. The selected Storage API file is used as the reference by the existing ToolsAPI image generator.
A successful result is registered as a new Storage API file. The source image is not changed.
Remote sites can use Storage API to store files under an existing ToolsAPI user account.
Create and manage tokens in ToolsAPI My API Keys. A token belongs to a normal Tools user and its users.id.
The storage database does not contain separate end-user credentials or API tokens. It stores file data and owner_user_id as a reference to the Tools user.
A normal user can create and own a token. Storage permissions are assigned through the existing ToolsAPI API-key administration. Regular users cannot grant new scopes to their own tokens. This lets a remote site receive only the storage permissions intended by the administrator without introducing a second permissions system in the storage database.
Send the token with:
Authorization: Bearer YOUR_TOKEN
or:
X-Api-Key: YOUR_TOKEN
Avoid query-string tokens when possible.
Grant only the scopes the remote site needs:
storage.read - list metadata and download files owned by the token userstorage.write - upload files and edit metadatastorage.delete - delete, bulk-delete and restore filesstorage.locations - add and check file locationsstorage.ai.analyze - request image analysisstorage.ai.generate - create images from stored referencesstorage.api - full Storage API access when all permissions are intentionally requiredA valid token without the required scope is rejected.
https://tools.tornevall.net/api/storage/v1
GET /api/storage/v1/files
Common query parameters:
q=logo
status=active
mime=image/
availability=available
storagepath=/filestore01
sort=storagepath
direction=asc
per_page=50
storagepath filtering and sorting use imported legacy path data.
Example:
curl -H "Authorization: Bearer $TOKEN" \
"https://tools.tornevall.net/api/storage/v1/files?mime=image/&sort=created&direction=desc"
POST /api/storage/v1/files
Content-Type: multipart/form-data
Example:
curl -X POST \
-H "Authorization: Bearer $TOKEN" \
-F "file=@image.jpg" \
-F "visibility=private" \
https://tools.tornevall.net/api/storage/v1/files
Visibility can be private, unlisted or public.
GET /api/storage/v1/files/{id}
The response includes file ID, UUID, filename, MIME, size, hashes, metadata, visibility, locations, a content_url and legacy data when applicable.
Private files are downloaded through the token-protected content endpoint:
GET /api/storage/v1/files/{id}/content
It requires storage.read and works even when the file has visibility=private. File metadata responses include a content_url pointing to this endpoint.
Files with public or unlisted visibility can additionally expose a stable UUID URL in public_url.
PATCH /api/storage/v1/files/{id}
Content-Type: application/json
Example:
{
"title": "Product image",
"description": "Front view of the product",
"alt_text": "Black product photographed from the front",
"tags": ["product", "black"],
"visibility": "public"
}
DELETE /api/storage/v1/files/{id}
POST /api/storage/v1/files/{id}/restore
POST /api/storage/v1/files/mass-delete
Bulk-delete body:
{
"fileids": [12, 13, 14]
}
Deletion is a logical/soft delete in the Storage API model.
POST /api/storage/v1/files/{id}/locations
Content-Type: application/json
{
"location_type": "url",
"location": "https://cdn.example.com/images/file.jpg",
"is_primary": true
}
Check all locations for the file:
POST /api/storage/v1/files/{id}/locations/check
POST /api/storage/v1/files/{id}/analyze
Content-Type: application/json
{
"analysis_type": "describe"
}
Initial modes are describe, alt_text, tags, title and text. A custom prompt can also be supplied.
AI only runs when requested.
POST /api/storage/v1/files/{id}/generate
Content-Type: application/json
{
"prompt": "Create a wide banner based on this image"
}
The generated result becomes a new Storage API file and keeps provenance back to the source file.
Remote clients should handle normal HTTP errors:
401 - token is missing, invalid or lacks the required scope403 - the user cannot manage the requested file404 - file or resource was not found422 - validation or the requested operation failedUploads are MIME-checked and virus-scanned server-side before permanent acceptance.