Files
wehub-resource-sync 3a28426bf4
Lint and Format Check / lint-and-format (push) Failing after 0s
Check Migrations / Check for duplicate migration numbers (push) Failing after 1s
CI Pre-merge Check / CI Pre-merge Check (push) Failing after 2m17s
chore: import upstream snapshot with attribution
2026-07-13 12:23:40 +08:00

7.2 KiB

Insforge OSS Storage API Documentation

API Basics

Base URL: http://localhost:7130
Authentication:

  • Upload operations (PUT/POST/DELETE): Requires Authorization: Bearer <token> header
  • Download from public buckets: No authentication required
  • List/manage buckets: Requires authentication
  • API keys are for MCP testing (use tokens for production) System: Bucket-based storage with public/private access control

🔴 CRITICAL: URL Format

Storage returns ABSOLUTE URLs that are ready to use directly:

  • Response url field contains complete URL: http://localhost:7130/api/storage/buckets/{bucket}/objects/{filename}
  • DO NOT prepend host or modify the URL - use it exactly as returned
  • URLs work directly in <img src>, <video src>, or fetch requests
  • Example: "url": "http://localhost:7130/api/storage/buckets/avatars/objects/user123.jpg"

Bucket Operations (Use MCP Tools)

Available MCP Tools

  1. create-bucket - Create bucket (bucketName, isPublic: true by default)
  2. list-buckets - List all buckets
  3. delete-bucket - Delete bucket

Object Operations (Use REST API)

Base URL

/api/storage/buckets/:bucketName/objects/:objectKey

Upload Object with Specific Key

PUT /api/storage/buckets/:bucketName/objects/:objectKey

Send object as multipart/form-data:

const formData = new FormData();
formData.append('file', fileObject);

Returns:

{
  "bucket": "test-images",
  "key": "test.txt", 
  "size": 30,
  "mimeType": "text/plain",
  "uploadedAt": "2025-07-18T04:32:13.801Z",
  "url": "http://localhost:7130/api/storage/buckets/test-images/objects/test.txt"
}

Example curl:

# Windows PowerShell: use curl.exe
curl -X PUT http://localhost:7130/api/storage/buckets/avatars/objects/user123.jpg \
  -H "Authorization: Bearer YOUR_SESSION_TOKEN" \
  -F "file=@/path/to/image.jpg"

Upload Object with Auto-Generated Key

POST /api/storage/buckets/:bucketName/objects

Request:

# Windows PowerShell: use curl.exe
curl -X POST http://localhost:7130/api/storage/buckets/posts/objects \
  -H "Authorization: Bearer YOUR_SESSION_TOKEN" \
  -F "file=@/path/to/image.jpg"

Response:

{
  "bucket": "avatars",
  "key": "image-1737546841234-a3f2b1.jpg", 
  "size": 15234,
  "mimeType": "image/jpeg",
  "uploadedAt": "2025-07-18T04:32:13.801Z",
  "url": "http://localhost:7130/api/storage/buckets/avatars/objects/image-1737546841234-a3f2b1.jpg"
}

Download Object

GET /api/storage/buckets/:bucketName/objects/:objectKey

Returns the actual object content with appropriate content-type headers. Note: Public buckets allow downloads without authentication.

Example response: Raw object content (not JSON wrapped)

List Objects

GET /api/storage/buckets/:bucketName/objects

Query parameters:

  • prefix - Filter by key prefix
  • limit - Max results (default: 100)
  • offset - Pagination offset

Returns:

{
  "bucketName": "test-images",
  "prefix": null,
  "objects": [
    {
      "bucket": "test-images",
      "key": "test.txt",
      "size": 30,
      "mimeType": "text/plain",
      "uploadedAt": "2025-07-18T04:32:13.801Z",
      "url": "http://localhost:7130/api/storage/buckets/test-images/objects/test.txt"
    }
  ],
  "pagination": {
    "limit": 100,
    "offset": 0,
    "total": 1
  },
  "nextActions": "You can use PUT /api/storage/buckets/:bucketName/objects/:objectKey to upload with a specific key, or POST /api/storage/buckets/:bucketName/objects to upload with auto-generated key, and GET /api/storage/buckets/:bucketName/objects/:objectKey to download an object."
}

Pagination headers:

  • X-Total-Count: Total number of objects
  • X-Page: Current page number
  • X-Page-Size: Number of items per page

Example curl:

# Windows PowerShell: use curl.exe
curl -X GET "http://localhost:7130/api/storage/buckets/avatars/objects?limit=10&prefix=users/" \
  -H "Authorization: Bearer <token>"

Delete Object

DELETE /api/storage/buckets/:bucketName/objects/:objectKey

Returns:

{
  "message": "Object deleted successfully"
}

Example curl:

# Windows PowerShell: use curl.exe
curl -X DELETE http://localhost:7130/api/storage/buckets/avatars/objects/user123.jpg \
  -H "Authorization: Bearer <token>"

Update Bucket

PATCH /api/storage/buckets/:bucketName

Request body:

{ "isPublic": true }

Returns:

{
  "message": "Bucket visibility updated",
  "bucket": "test-images",
  "isPublic": false,
  "nextActions": "Bucket is now PRIVATE - authentication is required to access objects."
}

Example curl:

# Mac/Linux
curl -X PATCH http://localhost:7130/api/storage/buckets/avatars \
  -H 'Authorization: Bearer <token>' \
  -H 'Content-Type: application/json' \
  -d '{"isPublic": true}'

# Windows PowerShell (use curl.exe) - different quotes needed for nested JSON
curl.exe -X PATCH http://localhost:7130/api/storage/buckets/avatars \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{\"isPublic\": true}'

Database Integration

Option 1: Upload with Specific Key (PUT)

// Step 1: Upload object with known key
const formData = new FormData();
formData.append('file', file);
const upload = await fetch('/api/storage/buckets/images/objects/avatar.jpg', {
  method: 'PUT',
  headers: { 'Authorization': `Bearer ${token}` },
  body: formData
});

// Step 2: Store metadata
const records = [{
  userId: 'user123',
  image: await upload.json()  // Store object metadata
}];
await fetch('/api/database/profiles', {
  method: 'POST',
  headers: { 
    'Authorization': `Bearer ${token}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(records)
});

Option 2: Upload with Auto-Generated Key (POST)

// Step 1: Upload object with auto-generated key
const formData = new FormData();
formData.append('file', file);
const upload = await fetch('/api/storage/buckets/images/objects', {
  method: 'POST',
  headers: { 'Authorization': `Bearer ${token}` },
  body: formData
});
const fileData = await upload.json();

// Step 2: Store metadata with generated key
const records = [{
  userId: 'user123',
  image: fileData  // Contains auto-generated key
}];
await fetch('/api/database/profiles', {
  method: 'POST',
  headers: { 
    'Authorization': `Bearer ${token}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(records)
});

Error Response Format

All error responses follow this format:

{
  "error": "ERROR_CODE",
  "message": "Human-readable error message",
  "statusCode": 400,
  "nextActions": "Suggested action to resolve the error"
}

Example error:

{
  "error": "BUCKET_NOT_FOUND",
  "message": "Bucket 'nonexistent' does not exist",
  "statusCode": 404,
  "nextActions": "Create the bucket first"
}

Important Rules

  1. Object Operations

    • Upload uses multipart/form-data
    • Database stores metadata only
    • Use json column type for object metadata
  2. Bucket Names

    • Must be valid identifiers
    • Cannot start with underscore
  3. Remember

    • Bucket management uses MCP tools
    • Object operations use REST API
    • All operations need API key