← Back to docs

Storage API

Storage API

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.

Using the file manager

Open:

/storage

You can:

  • upload files
  • search and filter
  • display images as cards, gallery or list
  • choose whether previews contain the whole image or cover the preview area
  • edit title, description, alt text, tags and notes
  • choose whether a file is private, unlisted or public
  • delete and restore files
  • bulk-delete selected files
  • check whether registered file locations still exist
  • request AI image analysis
  • create a new image from a stored reference image

Original files are retained. Image uploads can also receive smaller derivatives for faster previews.

Visibility and public files

Each file has a visibility level:

  • private - only the owner, administrators and correctly scoped StorageAPI clients can access it
  • unlisted - the file has a stable public UUID link but is not shown in the public browser
  • public - the file has a stable public UUID link and can also appear in the public browser

The 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.

Search and sorting

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.

File locations

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 exist
  • missing - the file is missing at that location
  • error - the location check failed
  • unknown - the location has not been checked
  • unresolved - the location is a legacy hint that cannot yet be checked directly

A replacement URL can be added to a file. "Check locations" tests the registered candidates again.

AI descriptions for images

Administrators get an AI description button directly below images.

When used:

  1. the image is analyzed through the existing ToolsAPI AI service on request
  2. the suggested text is placed in the description field in the UI
  3. it is not saved automatically
  4. review it and choose Save metadata if you want to keep it

The general analyzer also supports description, alt text, tags, title and visible-text extraction. AI never automatically overwrites human-edited metadata.

Generate a new image from a stored image

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.

API for remote sites and applications

Remote sites can use Storage API to store files under an existing ToolsAPI user account.

Token and ownership

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.

Permissions / scopes

Grant only the scopes the remote site needs:

  • storage.read - list metadata and download files owned by the token user
  • storage.write - upload files and edit metadata
  • storage.delete - delete, bulk-delete and restore files
  • storage.locations - add and check file locations
  • storage.ai.analyze - request image analysis
  • storage.ai.generate - create images from stored references
  • storage.api - full Storage API access when all permissions are intentionally required

A valid token without the required scope is rejected.

Base URL

https://tools.tornevall.net/api/storage/v1

List files

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"

Upload

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.

Read one file record

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.

Download file content

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.

Update metadata

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 and restore

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.

Add a replacement URL

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

AI analysis

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.

Generate an image from a stored reference

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.

Errors and upload safety

Remote clients should handle normal HTTP errors:

  • 401 - token is missing, invalid or lacks the required scope
  • 403 - the user cannot manage the requested file
  • 404 - file or resource was not found
  • 422 - validation or the requested operation failed

Uploads are MIME-checked and virus-scanned server-side before permanent acceptance.