Skip to main content

Storage Buckets API

Complete API reference for managing storage buckets. Buckets are containers that organize and control access to your files.

Endpoints Overview​

All bucket endpoints are scoped to an app using {app_slug} in the URL path.

MethodEndpointDescription
GET/api/apps/{app_slug}/storage/buckets/List all buckets for an app
POST/api/apps/{app_slug}/storage/buckets/Create a new bucket
GET/api/apps/{app_slug}/storage/buckets/{slug}/Get bucket details
PATCH/api/apps/{app_slug}/storage/buckets/{slug}/Update bucket
DELETE/api/apps/{app_slug}/storage/buckets/{slug}/Delete bucket and all objects

Bucket Model​

Fields​

FieldTypeDescription
idintegerInternal database ID
uuidUUIDUnique identifier for API references
namestringHuman-readable bucket name
slugstringURL-safe identifier (auto-generated from name)
visibilitystringVisibility level: "private" or "public" (default: "private")
file_size_limitintegerMaximum file size in bytes (default: 50MB)
allowed_mime_typesarrayList of allowed MIME types (empty = all allowed)
app_categorystringApp category/purpose: "assets" or "attachments" (required for creation)
storage_providerstringStorage provider: "s3" or "sharepoint" (defaults to "s3", immutable after creation)
appintegerApp ID this bucket belongs to
object_countintegerNumber of objects in bucket (read-only)
created_atdatetimeCreation timestamp
updated_atdatetimeLast update timestamp
created_byintegerUser who created the bucket
modified_byintegerUser who last modified the bucket

Example Response​

{
"id": 1,
"uuid": "550e8400-e29b-41d4-a716-446655440000",
"name": "User Avatars",
"slug": "user-avatars",
"visibility": "public",
"file_size_limit": 5242880,
"allowed_mime_types": ["image/*"],
"app_category": "assets",
"storage_provider": "s3",
"app": 1,
"object_count": 42,
"created_at": "2025-01-15T10:00:00Z",
"updated_at": "2025-01-15T10:00:00Z",
"created_by": 1,
"modified_by": 1
}

List Buckets​

Get all buckets, with optional filtering and search.

GET /api/apps/{app_slug}/storage/buckets/
Authorization: Bearer YOUR_TOKEN

Using cURL:

curl https://your-api.com/api/apps/my-app/storage/buckets/ \
-H "Authorization: Bearer YOUR_TOKEN"

Query Parameters​

ParameterTypeDescription
searchstringSearch by name or slug
orderingstringOrder by field (prefix with - for descending)
visibilitystringFilter by visibility: "public" or "private"
app_categorystringFilter by app category: "assets" or "attachments"
pageintegerPage number for pagination
page_sizeintegerNumber of results per page

Note: Buckets are automatically filtered by app based on the {app_slug} in the URL path.

SharePoint provider: To create a SharePoint-backed bucket, send "storage_provider": "sharepoint". The provider must be enabled and the expected SharePoint site must already be resolvable; otherwise the request fails with Taruvi's standard error format and provider details in data.provider_error_code.

Examples​

Basic List

curl https://your-api.com/api/apps/my-app/storage/buckets/ \
-H "Authorization: Bearer YOUR_TOKEN"

Search by Name

curl "https://your-api.com/api/apps/my-app/storage/buckets/?search=avatar" \
-H "Authorization: Bearer YOUR_TOKEN"

Order by Creation Date

curl "https://your-api.com/api/apps/my-app/storage/buckets/?ordering=-created_at" \
-H "Authorization: Bearer YOUR_TOKEN"

Public Buckets Only

curl "https://your-api.com/api/apps/my-app/storage/buckets/?visibility=public" \
-H "Authorization: Bearer YOUR_TOKEN"

Filter by App Category

curl "https://your-api.com/api/apps/my-app/storage/buckets/?app_category=assets" \
-H "Authorization: Bearer YOUR_TOKEN"

Response​

{
"count": 3,
"next": null,
"previous": null,
"results": [
{
"id": 1,
"uuid": "550e8400-e29b-41d4-a716-446655440000",
"name": "User Avatars",
"slug": "user-avatars",
"visibility": "public",
"file_size_limit": 5242880,
"allowed_mime_types": ["image/*"],
"app": 1,
"object_count": 42,
"created_at": "2025-01-15T10:00:00Z",
"updated_at": "2025-01-15T10:00:00Z",
"created_by": 1,
"modified_by": 1
},
{
"id": 2,
"uuid": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"name": "Documents",
"slug": "documents",
"visibility": "private",
"file_size_limit": 52428800,
"allowed_mime_types": ["application/pdf", "application/msword", "text/*"],
"app": 1,
"object_count": 128,
"created_at": "2025-01-15T11:00:00Z",
"updated_at": "2025-01-15T11:00:00Z",
"created_by": 1,
"modified_by": 1
}
]
}

Create Bucket​

Create a new storage bucket with optional constraints.

POST /api/apps/{app_slug}/storage/buckets/
Authorization: Bearer YOUR_TOKEN
Content-Type: application/json

{
"name": "User Avatars",
"app_category": "assets",
"visibility": "public",
"file_size_limit": 5242880,
"allowed_mime_types": ["image/*"]
}

Using cURL:

curl -X POST https://your-api.com/api/apps/my-app/storage/buckets/ \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "User Avatars",
"app_category": "assets",
"visibility": "public",
"file_size_limit": 5242880,
"allowed_mime_types": ["image/*"]
}'

Request Body​

FieldTypeRequiredDescription
namestringYesHuman-readable bucket name
app_categorystringYesApp category/purpose: "assets" or "attachments"
visibilitystringNoVisibility level: "private" or "public" (default: "private")
storage_providerstringNoStorage backend: "s3" or "sharepoint" (default: "s3", immutable after creation)
file_size_limitintegerNoMax file size in bytes (default: 52428800 = 50MB)
allowed_mime_typesarrayNoAllowed MIME types (default: [] = all allowed)

Examples​

Basic Bucket

curl -X POST https://your-api.com/api/apps/my-app/storage/buckets/ \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "My Files",
"app_category": "assets"
}'

Public Image Bucket (5MB limit)

curl -X POST https://your-api.com/api/apps/my-app/storage/buckets/ \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "User Avatars",
"app_category": "assets",
"visibility": "public",
"file_size_limit": 5242880,
"allowed_mime_types": ["image/jpeg", "image/png", "image/gif"]
}'

Document Bucket (All Image Types)

curl -X POST https://your-api.com/api/apps/my-app/storage/buckets/ \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Documents",
"app_category": "attachments",
"visibility": "private",
"file_size_limit": 52428800,
"allowed_mime_types": ["image/*", "video/*"]
}'

Private Bucket (Any File Type, 100MB)

curl -X POST https://your-api.com/api/apps/my-app/storage/buckets/ \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Large Files",
"app_category": "attachments",
"visibility": "private",
"file_size_limit": 104857600,
"allowed_mime_types": []
}'

SharePoint-Backed Bucket (Office Documents)

curl -X POST https://your-api.com/api/apps/my-app/storage/buckets/ \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Team Documents",
"app_category": "assets",
"storage_provider": "sharepoint",
"visibility": "private",
"file_size_limit": 262144000,
"allowed_mime_types": [
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"application/vnd.openxmlformats-officedocument.presentationml.presentation",
"application/pdf"
]
}'
SharePoint Prerequisites

Creating a SharePoint-backed bucket requires:

  • SharePoint integration enabled on the platform (SHAREPOINT_ENABLED=True)
  • The Taruvi site's corresponding SharePoint site must be provisioned and resolvable via Microsoft Graph

SharePoint sites are provisioned automatically when a Taruvi site is created. If provisioning hasn't completed yet, bucket creation will fail with a 409 error.

Response (201 Created)​

{
"id": 1,
"uuid": "550e8400-e29b-41d4-a716-446655440000",
"name": "User Avatars",
"slug": "user-avatars",
"app_category": "assets",
"visibility": "public",
"file_size_limit": 5242880,
"allowed_mime_types": ["image/*"],
"storage_provider": "s3",
"app": 1,
"object_count": 0,
"created_at": "2025-01-15T10:00:00Z",
"updated_at": "2025-01-15T10:00:00Z",
"created_by": 1,
"modified_by": null
}

SharePoint Error Responses​

SharePoint Site Not Ready (409 Conflict)

Returned when the SharePoint site for this Taruvi site hasn't finished provisioning:

{
"status": "error",
"message": "The expected SharePoint site could not be resolved or is not ready.",
"code": "CONFLICT",
"data": {
"provider_error_code": "sharepoint_site_not_ready"
}
}

SharePoint Integration Disabled (503 Service Unavailable)

Returned when storage_provider: "sharepoint" is requested but the feature is disabled:

{
"status": "error",
"message": "SharePoint storage provider is not enabled.",
"code": "INTERNAL_ERROR"
}

Slug Generation​

The slug is auto-generated from the name:

  • Converted to lowercase
  • Spaces replaced with hyphens
  • Special characters removed

Examples:

  • "User Avatars" → user-avatars
  • "My Documents & Files" → my-documents-files
  • "Team Projects 2025" → team-projects-2025

App Categories​

The app_category field categorizes buckets by their purpose, enabling selective operations like app exports. This field is required when creating a bucket.

Available Types​

TypeValueDescriptionUse Cases
Assets"assets"App-related files that should be exported with the app• UI components
• App resources
• Static files
• Templates
Attachments"attachments"User-uploaded files that remain with the workspace• User documents
• Profile pictures
• Message attachments
• Form uploads

When to Use Each Type​

Use "assets" when:

  • Files are part of the app's functionality
  • Files should be exported when the app is exported
  • Files are created by app developers/designers
  • Files are shared across users

Use "attachments" when:

  • Files are uploaded by end users
  • Files should stay in the workspace when exporting apps
  • Files are user-specific or session-specific
  • Files are dynamic user content

Example Scenario: App Export​

When exporting an app for transfer or backup:

# Get all asset buckets to export
GET /api/apps/{app_slug}/storage/buckets/?app_category=assets

# These buckets and their files will be included in the app export

The attachments buckets are intentionally excluded, keeping user data separate from app structure.

Get Bucket​

Retrieve details of a specific bucket.

Request​

GET /api/apps/{app_slug}/storage/buckets/{slug}/
Authorization: Bearer YOUR_TOKEN

Example​

curl https://your-api.com/api/apps/my-app/storage/buckets/user-avatars/ \
-H "Authorization: Bearer YOUR_TOKEN"

Response (200 OK)​

{
"id": 1,
"uuid": "550e8400-e29b-41d4-a716-446655440000",
"name": "User Avatars",
"slug": "user-avatars",
"visibility": "public",
"file_size_limit": 5242880,
"allowed_mime_types": ["image/*"],
"app_category": "assets",
"app": 1,
"object_count": 42,
"created_at": "2025-01-15T10:00:00Z",
"updated_at": "2025-01-15T10:00:00Z",
"created_by": 1,
"modified_by": 1
}

Update Bucket​

Partially update a bucket's configuration. Only PATCH is supported (not PUT).

PATCH /api/apps/{app_slug}/storage/buckets/{slug}/
Authorization: Bearer YOUR_TOKEN
Content-Type: application/json

{
"visibility": "private",
"file_size_limit": 10485760
}

Using cURL:

curl -X PATCH https://your-api.com/api/apps/my-app/storage/buckets/user-avatars/ \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"visibility": "private", "file_size_limit": 10485760}'

Updatable Fields​

FieldTypeDescription
namestringBucket display name
app_categorystringApp category/purpose: "assets" or "attachments"
visibilitystringVisibility level: "private" or "public"
file_size_limitintegerMax file size in bytes
allowed_mime_typesarrayAllowed MIME types

Note: slug, app, uuid, storage_provider cannot be changed after creation.

Examples​

Make Bucket Private

curl -X PATCH https://your-api.com/api/apps/my-app/storage/buckets/user-avatars/ \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"visibility": "private"}'

Increase Size Limit to 10MB

curl -X PATCH https://your-api.com/api/apps/my-app/storage/buckets/user-avatars/ \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"file_size_limit": 10485760}'

Update Allowed MIME Types

curl -X PATCH https://your-api.com/api/apps/my-app/storage/buckets/documents/ \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"allowed_mime_types": [
"application/pdf",
"application/msword",
"application/vnd.openxmlformats-officedocument.wordprocessingml.document"
]
}'

Rename Bucket

curl -X PATCH https://your-api.com/api/apps/my-app/storage/buckets/user-avatars/ \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "Profile Pictures"}'

Response (200 OK)​

{
"id": 1,
"uuid": "550e8400-e29b-41d4-a716-446655440000",
"name": "User Avatars",
"slug": "user-avatars",
"visibility": "private",
"file_size_limit": 10485760,
"allowed_mime_types": ["image/*"],
"app_category": "assets",
"app": 1,
"object_count": 42,
"created_at": "2025-01-15T10:00:00Z",
"updated_at": "2025-01-15T12:30:00Z",
"created_by": 1,
"modified_by": 1
}

Delete Bucket​

Delete a bucket and all its objects. This operation is irreversible.

DELETE /api/apps/{app_slug}/storage/buckets/{slug}/
Authorization: Bearer YOUR_TOKEN

Using cURL:

curl -X DELETE https://your-api.com/api/apps/my-app/storage/buckets/user-avatars/ \
-H "Authorization: Bearer YOUR_TOKEN"

Behavior​

  1. Deletes all files from cloud storage (batch operation)
  2. Deletes all object records from database (cascade)
  3. Deletes the bucket record

Response (204 No Content)​

{
"success": true,
"message": "Bucket \"User Avatars\" and all objects deleted successfully",
"status_code": 204
}

Error Response (500 Internal Server Error)​

If deletion fails (e.g., storage unavailable):

{
"success": false,
"message": "Failed to delete bucket \"User Avatars\"",
"status_code": 500
}

MIME Type Patterns​

The allowed_mime_types field supports exact matches and wildcards.

Exact Match​

{
"allowed_mime_types": [
"image/jpeg",
"image/png",
"image/gif"
]
}

Only these specific types are allowed.

Wildcard Match​

{
"allowed_mime_types": [
"image/*",
"video/*"
]
}

Allows all image and video types:

  • image/jpeg ✓
  • image/png ✓
  • image/svg+xml ✓
  • video/mp4 ✓
  • application/pdf ✗

Common Patterns​

Images Only

{"allowed_mime_types": ["image/*"]}

Documents

{
"allowed_mime_types": [
"application/pdf",
"application/msword",
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"application/vnd.ms-excel",
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
]
}

Media Files

{"allowed_mime_types": ["image/*", "video/*", "audio/*"]}

Text Files

{"allowed_mime_types": ["text/*"]}

No Restrictions

{"allowed_mime_types": []}

Validation Rules​

When creating or updating a bucket, the allowed_mime_types field is validated to ensure only valid MIME type patterns are stored.

Valid Formats​

Each MIME type entry must follow one of these patterns:

  1. Exact type: type/subtype (e.g., image/png, application/pdf)
  2. Wildcard type: type/* (e.g., image/*, video/*)
  3. Universal: */* (allows all types)

The validation follows RFC 6838 MIME type conventions with the following rules:

  • Type and subtype must start with an alphanumeric character
  • Type and subtype can contain letters, numbers, hyphens, plus signs, and dots
  • Must include a forward slash (/) separator
  • Wildcards (*) are only allowed in the subtype position

Valid Examples​

✅ These will pass validation:

{
"allowed_mime_types": [
"image/png",
"image/jpeg",
"application/pdf",
"image/*",
"video/*",
"text/plain",
"application/vnd.openxmlformats-officedocument.wordprocessingml.document"
]
}

❌ These will be rejected:

{
"allowed_mime_types": [
"image/", // Missing subtype
"image", // Missing slash and subtype
"*/png", // Wildcard only allowed in subtype position
"", // Empty string
"/png", // Missing type
"image/*pdf" // Invalid format after wildcard
]
}

Error Messages​

If validation fails, you'll receive a clear error message:

{
"allowed_mime_types": [
"Invalid MIME type format: ['image/', 'image']. Valid formats: 'image/png', 'image/*', 'application/pdf', etc."
]
}

Best Practices​

  1. Use wildcards for flexibility: ["image/*"] instead of listing every image format
  2. Combine exact and wildcards: ["image/*", "application/pdf"] for images + PDFs
  3. Empty list for no restrictions: [] allows all MIME types
  4. Validate before upload: Invalid patterns will be rejected at bucket creation/update time
  5. Test your patterns: Ensure your MIME type patterns match the files you intend to upload

File Size Limits​

Recommended limits based on use case:

Use CaseLimitBytes
Avatars/Icons2 MB2097152
Photos5 MB5242880
Documents10 MB10485760
High-res Images25 MB26214400
General Files50 MB52428800
Large Files100 MB104857600

For files >100MB, increase the bucket's file_size_limit when creating the bucket. Note that very large files may be subject to server memory constraints.

Authentication & Permissions​

All bucket operations require authentication:

  • JWT Token Required: Include Authorization: Bearer YOUR_TOKEN header in all requests
  • App-Scoped: Buckets are associated with your app
  • Secure Access: Private buckets require authentication for all operations
  • Public Buckets: When marked as public, files can be accessed without authentication

Best Practices​

Naming Conventions​

Good Names:

  • User Avatars → user-avatars
  • Project Documents → project-documents
  • Team Photos 2025 → team-photos-2025

Avoid:

  • Generic names: "Files", "Data"
  • Special characters: "My@Files", "Docs#1"
  • Very long names (keep under 50 characters)

Bucket Organization​

By Purpose:

  • avatars - User profile pictures
  • documents - User documents
  • media - Photos, videos
  • exports - Generated reports

By Visibility:

  • public-assets - Publicly accessible files
  • private-files - Authenticated access only

By Type:

  • images - All image files
  • videos - All video files
  • audio - All audio files

By App Category:

  • Use app_category: "assets" for app-related files (UI components, templates, static resources)
  • Use app_category: "attachments" for user-uploaded content (documents, photos, form uploads)
  • This distinction is crucial for app export functionality - assets are exported with the app, attachments remain in the workspace

Security​

  1. Use Private Buckets by Default

    • Only make buckets public if necessary
    • Consider signed URLs for temporary access
  2. Set Appropriate Size Limits

    • Prevents abuse and excessive storage costs
    • Match limits to expected file types
  3. Restrict MIME Types

    • Prevent unexpected file uploads
    • Reduce security risks
  4. Regular Audits

    • Review bucket configurations
    • Monitor storage usage
    • Check for unused buckets

Visibility & Access Control​

Overview​

The visibility field controls who can access objects in a bucket. Each bucket has a default visibility level that objects inherit, but individual objects can override this setting for fine-grained control.

Visibility Levels​

LevelValueDescriptionAccess Rules
Private"private"Default visibility• Requires authentication
• Only file owner or staff can access
• Most secure option
Public"public"Publicly accessible• No authentication required for downloads
• Anyone with the URL can access
• Upload/delete still requires authentication

How It Works​

Bucket-Level Visibility (Default)​

When you create a bucket, its visibility setting determines the default access level for all objects:

# Create a public bucket
POST /api/apps/{app_slug}/storage/buckets/
{
"name": "Public Images",
"visibility": "public" # All objects will be public by default
}

Object-Level Overrides​

Individual objects can override the bucket's default visibility. See Object Visibility for details.

Example Scenario:

Bucket: "marketing-assets" (visibility: "public")
├─ logo.png (visibility: null) → Effective: public (inherits)
├─ banner.jpg (visibility: null) → Effective: public (inherits)
└─ draft-logo.png (visibility: "private") → Effective: private (overrides!)

In this example:

  • The bucket is public, so most assets are publicly accessible
  • But draft-logo.png overrides with visibility: "private" to keep it restricted
  • This solves the problem of one private file in an otherwise public bucket

Access Control Rules​

Public Objects​

  • ✅ GET/Download: Anyone with the URL (no auth required)
  • ❌ POST/Upload: Requires authentication + ownership
  • ❌ DELETE: Requires authentication + ownership
  • ❌ PATCH/Update: Requires authentication + ownership

Private Objects​

  • ✅ GET/Download: Owner or staff only (requires auth)
  • ✅ POST/Upload: Owner only (requires auth)
  • ✅ DELETE: Owner only (requires auth)
  • ✅ PATCH/Update: Owner only (requires auth)

Examples​

Public Bucket for Website Assets​

POST /api/apps/{app_slug}/storage/buckets/
{
"name": "Website Assets",
"visibility": "public",
"allowed_mime_types": ["image/*", "video/*"]
}

Use case: Product images, logos, marketing materials that anyone can view.

Private Bucket for User Documents​

POST /api/apps/{app_slug}/storage/buckets/
{
"name": "User Documents",
"visibility": "private",
"file_size_limit": 104857600 # 100MB
}

Use case: Tax documents, contracts, personal files that require authentication.

Mixed Visibility (Public Bucket with Private Exceptions)​

# 1. Create public bucket
POST /api/apps/{app_slug}/storage/buckets/
{
"name": "Product Images",
"visibility": "public"
}

# 2. Upload public image (inherits bucket visibility)
PUT /api/apps/{app_slug}/storage/buckets/product-images/objects/released/product-1.jpg
Content-Type: image/jpeg
<binary data>

# 3. Upload private image (overrides bucket visibility)
PUT /api/apps/{app_slug}/storage/buckets/product-images/objects/unreleased/secret-product.jpg
Content-Type: multipart/form-data

file=<binary>
visibility="private" # This object will be private despite public bucket

Security Best Practices​

  1. Default to Private: Use "visibility": "private" unless you have a specific reason for public access
  2. Audit Public Buckets: Regularly review public buckets to ensure no sensitive data is exposed
  3. Use Object Overrides: For mostly-public buckets, use object-level visibility: "private" for exceptions
  4. Combine with MIME Types: Restrict allowed_mime_types for public buckets to prevent unwanted file types
  5. Monitor Access: Track who uploads to public buckets using the created_by field

Changing Visibility​

You can change a bucket's visibility at any time:

# Make a public bucket private
PATCH /api/apps/{app_slug}/storage/buckets/website-assets/
{
"visibility": "private"
}

⚠️ Important: Changing bucket visibility affects all objects that inherit from it. Objects with explicit visibility settings are not affected.