SpiderMedia Storage
SpiderMedia provides per-client media isolation - each client gets their own dedicated storage for files and videos. This ensures complete data separation and enables client-specific media management.
Overview
When you register as a SpiderIQ client, you automatically receive:
SeaweedFS Bucket
Dedicated S3-compatible bucket for files, images, and logos
PeerTube Channel
Private channel for video imports and hosting
How It Works
Automatic Provisioning
When you register via POST /api/v1/clients/register, SpiderMedia automatically:
- Creates a SeaweedFS bucket named
client-{your_client_id} - Creates a PeerTube channel for video storage
- Stores credentials securely in your client record
- Returns media info in the registration response
{
"client_id": "cli_abc123",
"media_bucket_name": "client-cli-abc123",
"media_public_url": "https://media.spideriq.ai/client-cli-abc123",
"media_peertube_channel_name": "client_cli_abc123",
"media_created": true
}
File Storage
SpiderMedia provides three upload methods depending on your use case:
Image Upload (v2.28.8)
Best for: Validated image uploads
POST /api/v1/media/images/upload
Magic byte validation + auto-correction
Multipart Upload
Best for: cURL, Postman, direct file uploads
POST /api/v1/media/files/upload
Uses multipart/form-data with actual file bytes
Base64 Upload
Best for: Xano, N8N, Make, automation tools
POST /api/v1/media/files/upload-base64
Uses JSON with base64-encoded file content
New in v2.28.8: The Image Upload endpoint validates images using magic byte detection and auto-corrects filename extensions. Use this for guaranteed image validation.
Automation tools (Xano, N8N, Make) typically don't support multipart/form-data. Use the base64 endpoint instead.
Option 1: Image Upload with Validation (v2.28.8)
For images that need format validation and auto-correction:
curl -X POST "https://spideriq.ai/api/v1/media/images/upload" \
-H "Authorization: Bearer $CLIENT_TOKEN" \
-F "file=@company-logo.png" \
-F "folder=logos"
Response includes validation info:
{
"success": true,
"url": "https://media.spideriq.ai/client-cli-abc123/logos/company-logo.png",
"detected_format": "PNG",
"original_filename": "company-logo.jpg",
"corrected_filename": "company-logo.png",
"format_corrected": true
}
When to use image upload:
- You need guaranteed image validation
- Files may have wrong extensions (e.g., PNG saved as .jpg)
- You want auto-correction of filename extensions
Option 2: Multipart Upload (cURL/Postman)
curl -X POST "https://spideriq.ai/api/v1/media/files/upload" \
-H "Authorization: Bearer $CLIENT_TOKEN" \
-F "file=@company-logo.png" \
-F "folder=logos"
Option 2: Base64 Upload (Xano/N8N)
curl -X POST "https://spideriq.ai/api/v1/media/files/upload-base64" \
-H "Authorization: Bearer $CLIENT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"file_data": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR...",
"filename": "company-logo.png",
"folder": "logos"
}'
Response (both methods):
{
"success": true,
"url": "https://media.spideriq.ai/client-cli-abc123/logos/company-logo.png",
"key": "logos/company-logo.png",
"content_type": "image/png",
"size": 15234
}
Video Import
Import videos to your private PeerTube channel:
curl -X POST "https://spideriq.ai/api/v1/media/videos/import" \
-H "Authorization: Bearer $CLIENT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/product-demo.mp4",
"title": "Product Demo",
"privacy": 2
}'
Privacy Options:
1= Public (visible to everyone)2= Unlisted (accessible via link only, default)3= Private (only you can view)
Video Status & Direct URLs
After importing a video, use the status endpoint to check processing progress and get direct .mp4 URLs:
curl "https://spideriq.ai/api/v1/media/videos/{video_id}/status" \
-H "Authorization: Bearer $CLIENT_TOKEN"
Response when processing:
{
"success": true,
"video_id": "123",
"status": "transcoding",
"file_url": null,
"download_url": null
}
Response when ready:
{
"success": true,
"video_id": "123",
"status": "ready",
"file_url": "https://videos.spideriq.ai/static/web-videos/abc123-720.mp4",
"download_url": "https://videos.spideriq.ai/download/web-videos/abc123-720.mp4",
"duration": 180,
"views": 42
}
For automation workflows: Poll this endpoint after import. When status becomes ready, use file_url to download or process the video directly.
Worker Integration
SpiderIQ workers automatically use your client-specific storage when processing jobs. For example, when SpiderSite extracts a company logo:
- Worker receives job with your
client_id - Worker fetches your media credentials via internal API
- Logo is uploaded to your bucket, not a shared one
- Result includes URL pointing to your isolated storage
{
"extracted_logo": {
"url": "https://media.spideriq.ai/client-cli-abc123/logo_example-com_abc123.png",
"mime_type": "image/png"
}
}
API Endpoints
File Operations
| Endpoint | Method | Description | Content-Type |
|---|---|---|---|
/media/images/upload | POST | Upload image with validation (v2.28.8) | multipart/form-data |
/media/files/upload | POST | Upload file (multipart) | multipart/form-data |
/media/files/upload-base64 | POST | Upload file (base64) | application/json |
/media/files/list | GET | List files in bucket | - |
/media/files/delete | DELETE | Delete files | application/json |
/media/stats | GET | Get storage stats | - |
Video Operations
| Endpoint | Method | Description | Content-Type |
|---|---|---|---|
/media/videos/import | POST | Import video from URL | application/json |
/media/videos/list | GET | List videos in channel | - |
/media/videos/{id}/status | GET | Get video status & URLs | - |
Key difference: File uploads have two endpoints (multipart vs base64). Video import only needs JSON since it downloads from a URL - no file bytes required.
Examples
Upload Company Logo
# Upload logo
curl -X POST "https://spideriq.ai/api/v1/media/files/upload" \
-H "Authorization: Bearer $CLIENT_TOKEN" \
-F "file=@logo.png" \
-F "folder=branding"
# Response
{
"success": true,
"url": "https://media.spideriq.ai/client-cli-abc123/branding/img/logo.png"
}
List All Files
curl "https://spideriq.ai/api/v1/media/files" \
-H "Authorization: Bearer $CLIENT_TOKEN"
# Response
{
"success": true,
"files": [
{
"key": "logos/company-logo.png",
"size": 15234,
"last_modified": "2026-01-08T20:30:00Z",
"url": "https://media.spideriq.ai/client-cli-abc123/logos/company-logo.png"
}
],
"total": 1
}
Import Product Video
curl -X POST "https://spideriq.ai/api/v1/media/videos/import" \
-H "Authorization: Bearer $CLIENT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"url": "https://youtube.com/watch?v=example",
"title": "Product Overview",
"description": "Our product demonstration video",
"privacy": 2
}'
# Response
{
"success": true,
"video_id": 123,
"title": "Product Overview",
"watch_url": "https://videos.spideriq.ai/w/abc123",
"embed_url": "https://videos.spideriq.ai/videos/embed/abc123"
}
Get Storage Stats
curl "https://spideriq.ai/api/v1/media/stats" \
-H "Authorization: Bearer $CLIENT_TOKEN"
# Response
{
"success": true,
"storage": {
"total_files": 42,
"total_size_bytes": 15728640,
"total_size_mb": 15.0
},
"videos": {
"total_videos": 3,
"total_duration_seconds": 1800
}
}
Public URLs
All files in your bucket are publicly accessible via:
https://media.spideriq.ai/{bucket_name}/{key}
For example:
https://media.spideriq.ai/client-cli-abc123/logos/img/logo.pnghttps://media.spideriq.ai/client-cli-abc123/images/product.jpg
Files are publicly accessible by URL but your bucket name is unique to your client_id, providing effective isolation.
Best Practices
Organize with Folders
Use folders to organize your files:
logos/- Company logosimages/- Product imagesdocuments/- PDFs and documents
Use Descriptive Names
Name files descriptively:
- Good:
company-logo-2026.png - Bad:
image1.png
Clean Up Unused Files
Periodically delete files you no longer need to manage storage costs.
Xano Integration
Xano doesn't support multipart/form-data uploads natively. Use the base64 endpoint instead.
Upload File in Xano
- Create External API Request
- Configure:
- Method:
POST - URL:
https://spideriq.ai/api/v1/media/files/upload-base64 - Headers:
Authorization:Bearer {your_client_token}Content-Type:application/json
- Body (JSON):
{
"file_data": "{base64_encoded_content}",
"filename": "image.jpg",
"folder": "uploads"
}
- Method:
In Xano, use base64_encode() function to convert file content to base64 before sending.
Import Video in Xano
Video import is simpler - just send JSON with the video URL:
- Create External API Request
- Configure:
- Method:
POST - URL:
https://spideriq.ai/api/v1/media/videos/import - Headers:
Authorization:Bearer {your_client_token}Content-Type:application/json
- Body:
{
"url": "https://instagram.com/reel/ABC123",
"title": "My Video",
"privacy": 2
}
- Method:
Poll Video Status in Xano
After importing, poll the status endpoint until status is ready:
- Method:
GET - URL:
https://spideriq.ai/api/v1/media/videos/{video_id}/status - When
status === "ready", usefile_urlfor the direct .mp4 link
N8N Integration
Upload File in N8N
Use the HTTP Request node:
- Method: POST
- URL:
https://spideriq.ai/api/v1/media/files/upload-base64 - Authentication: Header Auth
- Name:
Authorization - Value:
Bearer {your_client_token}
- Name:
- Body Content Type: JSON
- Body Parameters:
file_data:{{ $binary.data.data }}(for binary input)filename:image.jpgfolder:n8n-uploads
Import Video in N8N
- Method: POST
- URL:
https://spideriq.ai/api/v1/media/videos/import - Body Content Type: JSON
- Body:
{
"url": "{{ $json.video_url }}",
"title": "{{ $json.title }}",
"privacy": 2
}
Troubleshooting
422 Unprocessable Entity on file upload
Cause: You're sending JSON to the multipart endpoint.
Solution: Use /media/files/upload-base64 for JSON/base64 uploads, or use proper multipart/form-data with the original endpoint.
Media not provisioned
If media_created: false in your client info, your media resources weren't created during registration. Contact support or use the admin provision endpoint.
Upload fails
Check that:
- File size is under 100MB
- File type is supported (images, videos, documents)
- Your API credentials are valid
- You're using the correct endpoint for your Content-Type
Video import stuck
Video imports can take time depending on source file size. Use the /videos/{id}/status endpoint to monitor progress. Status values: importing → transcoding → ready
file_url is null
The file_url and download_url fields are only populated when video status is ready. Keep polling the status endpoint until processing completes.