Skip to main content

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:

  1. Creates a SeaweedFS bucket named client-{your_client_id}
  2. Creates a PeerTube channel for video storage
  3. Stores credentials securely in your client record
  4. 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

info

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.

warning

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
}
tip

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
}
tip

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:

  1. Worker receives job with your client_id
  2. Worker fetches your media credentials via internal API
  3. Logo is uploaded to your bucket, not a shared one
  4. 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

EndpointMethodDescriptionContent-Type
/media/images/uploadPOSTUpload image with validation (v2.28.8)multipart/form-data
/media/files/uploadPOSTUpload file (multipart)multipart/form-data
/media/files/upload-base64POSTUpload file (base64)application/json
/media/files/listGETList files in bucket-
/media/files/deleteDELETEDelete filesapplication/json
/media/statsGETGet storage stats-

Video Operations

EndpointMethodDescriptionContent-Type
/media/videos/importPOSTImport video from URLapplication/json
/media/videos/listGETList videos in channel-
/media/videos/{id}/statusGETGet video status & URLs-
note

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 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.png
  • https://media.spideriq.ai/client-cli-abc123/images/product.jpg
note

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 logos
  • images/ - Product images
  • documents/ - 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

  1. Create External API Request
  2. 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"
      }
tip

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:

  1. Create External API Request
  2. 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
      }

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", use file_url for the direct .mp4 link

N8N Integration

Upload File in N8N

Use the HTTP Request node:

  1. Method: POST
  2. URL: https://spideriq.ai/api/v1/media/files/upload-base64
  3. Authentication: Header Auth
    • Name: Authorization
    • Value: Bearer {your_client_token}
  4. Body Content Type: JSON
  5. Body Parameters:
    • file_data: {{ $binary.data.data }} (for binary input)
    • filename: image.jpg
    • folder: n8n-uploads

Import Video in N8N

  1. Method: POST
  2. URL: https://spideriq.ai/api/v1/media/videos/import
  3. Body Content Type: JSON
  4. 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: importingtranscodingready

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.