Skip to content

HTTP API Reference

Stowry provides a REST API for object storage operations. All endpoints support presigned URL authentication.

http://localhost:5708

Requests require presigned URL authentication unless public_read or public_write is enabled. See Authentication for details.

List objects with optional prefix filtering and pagination.

GET /

Query Parameters:

ParameterTypeDefaultDescription
prefixstring-Filter objects by path prefix
limitint100Maximum objects per page (1-1000)
cursorstring-Pagination cursor from previous response

Response: 200 OK

{
"items": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"path": "photos/vacation.jpg",
"content_type": "image/jpeg",
"etag": "a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e",
"file_size_bytes": 1048576,
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T10:30:00Z"
}
],
"next_cursor": "MjAyNC0wMS0xNVQxMDozMDowMFp8cGhvdG9zL3ZhY2F0aW9uLmpwZw=="
}

Example:

Terminal window
# List all objects
curl "http://localhost:5708/"
# List with prefix
curl "http://localhost:5708/?prefix=photos/"
# Paginate
curl "http://localhost:5708/?limit=10&cursor=MjAyNC0wMS0..."

Download an object by path.

GET /{path}

Path Parameters:

ParameterDescription
pathObject path (e.g., photos/vacation.jpg)

Response Headers:

HeaderDescription
Content-TypeMIME type of the object
ETagObject hash (SHA256)
Content-LengthObject size in bytes
Last-ModifiedLast modification time

Response: 200 OK with file content

Errors:

StatusError CodeDescription
400invalid_pathInvalid path format
404not_foundObject not found

Example:

Terminal window
# Download object
curl -O http://localhost:5708/photos/vacation.jpg
# Get with headers
curl -I http://localhost:5708/photos/vacation.jpg

Server Mode Behavior:

  • Store: Returns exact path or 404
  • Static: Falls back to {path}/index.html if path not found
  • SPA: Falls back to /index.html for client-side routing

Upload or overwrite an object.

PUT /{path}

Path Parameters:

ParameterDescription
pathObject path (e.g., photos/vacation.jpg)

Request Headers:

HeaderRequiredDescription
Content-TypeNoMIME type (auto-detected if not provided)
If-MatchNoConditional update (ETag must match)

Request Body: Raw file content

Response: 200 OK

{
"id": "550e8400-e29b-41d4-a716-446655440000",
"path": "photos/vacation.jpg",
"content_type": "image/jpeg",
"etag": "a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e",
"file_size_bytes": 1048576,
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T10:30:00Z"
}

Errors:

StatusError CodeDescription
400invalid_pathInvalid path format
412precondition_failedETag mismatch (If-Match)
500internal_errorServer error

Example:

Terminal window
# Upload file
curl -X PUT \
-H "Content-Type: image/jpeg" \
--data-binary @vacation.jpg \
http://localhost:5708/photos/vacation.jpg
# Conditional update
curl -X PUT \
-H "If-Match: a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e" \
--data-binary @vacation.jpg \
http://localhost:5708/photos/vacation.jpg

Soft delete an object (marks for deletion but doesn’t remove immediately).

DELETE /{path}

Path Parameters:

ParameterDescription
pathObject path (e.g., photos/vacation.jpg)

Response: 204 No Content

Errors:

StatusError CodeDescription
400invalid_pathInvalid path format
404not_foundObject not found

Example:

Terminal window
curl -X DELETE http://localhost:5708/photos/vacation.jpg

Note: Deleted objects remain in storage until stowry cleanup is run.


All errors return JSON:

{
"error": "error_code",
"message": "Human-readable error message"
}

Valid paths must:

  • Be relative (no leading /)
  • Contain no path traversal (..)
  • Contain no empty segments (//)
  • Contain no invalid characters (\ ? # ~)
  • Be valid UTF-8
  • Have no trailing slashes

Valid paths:

  • file.txt
  • photos/vacation.jpg
  • data/2024/01/report.pdf

Invalid paths:

  • /file.txt (leading slash)
  • ../secret.txt (path traversal)
  • folder//file.txt (empty segment)
  • file?.txt (invalid character)

If Content-Type header is not provided on upload, Stowry detects it from the file extension:

ExtensionContent Type
.htmltext/html
.csstext/css
.jsapplication/javascript
.jsonapplication/json
.pngimage/png
.jpg, .jpegimage/jpeg
.gifimage/gif
.svgimage/svg+xml
.pdfapplication/pdf
(unknown)application/octet-stream

List responses use cursor-based pagination:

  1. Make initial request: GET /?limit=10
  2. If next_cursor is present in response, there are more results
  3. Request next page: GET /?limit=10&cursor={next_cursor}
  4. Repeat until next_cursor is empty or null

Benefits:

  • Consistent results during concurrent modifications
  • Efficient for large datasets
  • No offset skipping issues