Skip to main content

Overview

The Storage API provides bucket-based file storage similar to S3. Upload, download, and manage files with support for both local and S3-compatible storage backends.

Headers

For authenticated function invocations:
Authorization: Bearer your-jwt-token-or-anon-key
Content-Type: application/json
For admin endpoints:
Authorization: Bearer admin-jwt-token-Or-API-Key
Content-Type: application/json

Upload Object with upload strategy

InsForge supports two types of storage backends:
  1. Local Storage: Files are stored on the local filesystem. Use for development or low-volume production.
  2. S3-Compatible: Files are stored on S3-compatible object storage. Use for high-volume production.
The steps to upload a file are:
  1. Get upload strategy
  2. Upload file
  3. Confirm upload (S3 only)

Step 1: Get Upload Strategy

Get the optimal upload strategy (direct or presigned URL) based on storage backend. The upload strategy API returns the optimal upload method based on the storage backend:
  • Local Storage: Direct upload to InsForge API
  • S3-Compatible: Presigned URL for direct upload to S3
POST /api/storage/buckets/{bucketName}/upload-strategy

Request Body

FieldTypeRequiredDescription
filenamestringYesOriginal filename
contentTypestringNoMIME type of the file
sizeintegerNoFile size in bytes

Example

curl -X POST "https://your-app.insforge.app/api/storage/buckets/avatars/upload-strategy" \
  -H "Authorization: Bearer your-jwt-token" \
  -H "Content-Type: application/json" \
  -d '{
    "filename": "profile-photo.jpg",
    "contentType": "image/jpeg",
    "size": 102400
  }'

Response (S3 Backend)

{
  "method": "presigned",
  "uploadUrl": "https://s3-bucket.amazonaws.com/",
  "fields": {
    "bucket": "my-s3-bucket",
    "key": "app-key/avatars/profile-photo-1234567890-abc123.jpg",
    "X-Amz-Algorithm": "AWS4-HMAC-SHA256",
    "X-Amz-Credential": "...",
    "Policy": "...",
    "X-Amz-Signature": "..."
  },
  "key": "profile-photo-1234567890-abc123.jpg",
  "confirmRequired": true,
  "confirmUrl": "/api/storage/buckets/avatars/objects/profile-photo-1234567890-abc123.jpg/confirm-upload",
  "expiresAt": "2025-09-05T01:00:00Z"
}

Response (Local Storage)

{
  "method": "direct",
  "uploadUrl": "/api/storage/buckets/avatars/objects/profile-photo-1234567890-abc123.jpg",
  "key": "profile-photo-1234567890-abc123.jpg",
  "confirmRequired": false
}

Step 2: Upload File

Upload the file to the specified URL using the provided method.
  • Local Storage: Use a PUT request to uploadUrl with multipart/form-data and a file field.
  • S3-Compatible: Use a POST request to uploadUrl with multipart/form-data and a file field. Include all fields from the fields object in the request.

Step 3: Confirm Presigned Upload (S3 Only)

Confirm that a file was successfully uploaded to S3 using presigned URL.
POST /api/storage/buckets/{bucketName}/objects/{objectKey}/confirm-upload

Request Body

FieldTypeRequiredDescription
sizeintegerYesFile size in bytes
contentTypestringNoMIME type of the file
etagstringNoS3 ETag of the uploaded object

Example

curl -X POST "https://your-app.insforge.app/api/storage/buckets/avatars/objects/profile-photo-123.jpg/confirm-upload" \
  -H "Authorization: Bearer your-jwt-token" \
  -H "Content-Type: application/json" \
  -d '{
    "size": 102400,
    "contentType": "image/jpeg"
  }'

Response

{
  "bucket": "avatars",
  "key": "profile-photo-123.jpg",
  "size": 102400,
  "mimeType": "image/jpeg",
  "uploadedAt": "2024-01-21T10:30:00Z",
  "url": "/api/storage/buckets/avatars/objects/profile-photo-123.jpg"
}

Upload Object (Deprecated)

Upload a file to a bucket with a specific key.
PUT /api/storage/buckets/{bucketName}/objects/{objectKey}

Path Parameters

ParameterTypeDescription
bucketNamestringName of the bucket
objectKeystringObject key (can include / for pseudo-folders)

Request Body

multipart/form-data with a file field.

Example

curl -X PUT "https://your-app.insforge.app/api/storage/buckets/avatars/objects/users/profile.jpg" \
  -H "Authorization: Bearer your-jwt-token" \
  -F "file=@/path/to/image.jpg"

Response

{
  "bucket": "avatars",
  "key": "users/profile.jpg",
  "size": 102400,
  "mimeType": "image/jpeg",
  "uploadedAt": "2024-01-15T10:30:00Z",
  "url": "/api/storage/buckets/avatars/objects/users/profile.jpg"
}

Upload with Auto-Generated Key (Deprecated)

Upload a file with an auto-generated unique key.
POST /api/storage/buckets/{bucketName}/objects

Example

curl -X POST "https://your-app.insforge.app/api/storage/buckets/uploads/objects" \
  -H "Authorization: Bearer your-jwt-token" \
  -F "file=@/path/to/document.pdf"

Response

{
  "bucket": "uploads",
  "key": "document-1737546841234-a3f2b1.pdf",
  "size": 204800,
  "mimeType": "application/pdf",
  "uploadedAt": "2024-01-21T10:30:00Z",
  "url": "/api/storage/buckets/uploads/objects/document-1737546841234-a3f2b1.pdf"
}

Download Object with download strategy

InsForge supports two types of storage backends:
  1. Local Storage: Files are stored on the local filesystem. Use for development or low-volume production.
  2. S3-Compatible: Files are stored on S3-compatible object storage. Use for high-volume production.
The steps to download a file are:
  1. Get download strategy
  2. Download file from returned URL

Step 1: Get Download Strategy

Get the optimal download strategy (direct URL or presigned URL) based on storage backend and bucket visibility. The download strategy API returns the optimal download method based on the storage backend and bucket visibility:
  • Local Storage: Direct download from InsForge API
  • S3-Compatible: Presigned URL for S3.
POST /api/storage/buckets/{bucketName}/objects/{objectKey}/download-strategy

Request Body

FieldTypeRequiredDescription
expiresInintegerNoURL expiration in seconds (default: 3600)

Example

curl -X POST "https://your-app.insforge.app/api/storage/buckets/avatars/objects/profile.jpg/download-strategy" \
  -H "Authorization: Bearer your-jwt-token" \
  -H "Content-Type: application/json" \
  -d '{"expiresIn": 3600}'

Response (S3 Public Bucket)

{
  "method": "direct",
  "url": "https://s3-bucket.s3.us-east-2.amazonaws.com/app-key/avatars/profile.jpg"
}

Response (S3 Private Bucket)

{
  "method": "presigned",
  "url": "https://s3-bucket.s3.us-east-2.amazonaws.com/app-key/avatars/profile.jpg?X-Amz-Algorithm=...",
  "expiresAt": "2025-09-05T01:00:00Z"
}

Step 2: Download File

Download the file from the returned URL, using the appropriate method.

Download Object (Deprecated)

Download a file from a bucket.
GET /api/storage/buckets/{bucketName}/objects/{objectKey}

Example

curl "https://your-app.insforge.app/api/storage/buckets/avatars/objects/users/profile.jpg" \
  -H "Authorization: Bearer your-jwt-token" \
  -o profile.jpg

Response

Binary file content with appropriate Content-Type and Content-Length headers.

Delete Object

Delete a file from a bucket.
DELETE /api/storage/buckets/{bucketName}/objects/{objectKey}

Example

curl -X DELETE "https://your-app.insforge.app/api/storage/buckets/avatars/objects/users/profile.jpg" \
  -H "Authorization: Bearer your-jwt-token"

Response

{
  "message": "Object deleted successfully"
}

List Objects in Bucket

List all objects in a bucket with optional filtering.
GET /api/storage/buckets/{bucketName}/objects

Query Parameters

ParameterTypeDescription
prefixstringFilter by key prefix (e.g., users/)
searchstringSearch objects by key (partial match)
limitintegerMaximum objects to return (1-1000, default: 100)
offsetintegerNumber of objects to skip

Example

# Filter by prefix
curl "https://your-app.insforge.app/api/storage/buckets/avatars/objects?prefix=users/&limit=50" \
  -H "Authorization: Bearer your-jwt-token"

# Search by key
curl "https://your-app.insforge.app/api/storage/buckets/avatars/objects?search=profile" \
  -H "Authorization: Bearer your-jwt-token"

Response

{
  "data": [
    {
      "bucket": "avatars",
      "key": "users/user123.jpg",
      "size": 102400,
      "mimeType": "image/jpeg",
      "uploadedAt": "2024-01-15T10:30:00Z",
      "url": "/api/storage/buckets/avatars/objects/users/user123.jpg"
    },
    {
      "bucket": "avatars",
      "key": "users/user456.png",
      "size": 204800,
      "mimeType": "image/png",
      "uploadedAt": "2024-01-16T11:00:00Z",
      "url": "/api/storage/buckets/avatars/objects/users/user456.png"
    }
  ],
  "pagination": {
    "offset": 0,
    "limit": 100,
    "total": 2
  }
}

Bucket Management (Admin)

List All Buckets

GET /api/storage/buckets

Example

curl "https://your-app.insforge.app/api/storage/buckets" \
  -H "Authorization: Bearer admin-jwt-token"

Response

{
  "buckets": ["avatars", "documents", "uploads", "public"]
}

Create Bucket

POST /api/storage/buckets

Request Body

FieldTypeRequiredDescription
bucketNamestringYesBucket name (alphanumeric, underscore, hyphen)
isPublicbooleanNoWhether bucket is publicly accessible (default: true)

Example

curl -X POST "https://your-app.insforge.app/api/storage/buckets" \
  -H "Authorization: Bearer admin-jwt-token" \
  -H "Content-Type: application/json" \
  -d '{
    "bucketName": "user-uploads",
    "isPublic": false
  }'

Response

{
  "message": "Bucket created successfully",
  "bucket": "user-uploads"
}

Update Bucket

PATCH /api/storage/buckets/{bucketName}

Request Body

FieldTypeRequiredDescription
isPublicbooleanYesWhether bucket is publicly accessible

Example

curl -X PATCH "https://your-app.insforge.app/api/storage/buckets/user-uploads" \
  -H "Authorization: Bearer admin-jwt-token" \
  -H "Content-Type: application/json" \
  -d '{"isPublic": true}'

Response

{
  "message": "Bucket visibility updated",
  "bucket": "user-uploads",
  "isPublic": true
}

Delete Bucket

DELETE /api/storage/buckets/{bucketName}

Example

curl -X DELETE "https://your-app.insforge.app/api/storage/buckets/old-uploads" \
  -H "Authorization: Bearer admin-jwt-token"

Response

{
  "message": "Bucket deleted successfully"
}

Error Responses

Bucket Not Found (404)

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

Object Not Found (404)

{
  "error": "OBJECT_NOT_FOUND",
  "message": "Object 'missing.jpg' not found in bucket 'avatars'",
  "statusCode": 404,
  "nextActions": "Check the bucket and key combination"
}

Invalid File (400)

{
  "error": "INVALID_FILE",
  "message": "No file provided in the request",
  "statusCode": 400,
  "nextActions": "Include a file in the multipart form data"
}

Bucket Already Exists (409)

{
  "error": "BUCKET_EXISTS",
  "message": "Bucket 'avatars' already exists",
  "statusCode": 409,
  "nextActions": "Choose a different bucket name"
}