CoreViz
API

Upload Media

Upload photos and videos to a collection via multipart form upload

Upload Media

Upload an image or video file to a CoreViz collection using multipart form data.

Endpoint

POST /api/upload/multipart

Authentication

Requires Authorization: Bearer token or x-api-key. The authenticated user must have admin or owner role in the collection's organization.

Request

Content-Type: multipart/form-data

FieldTypeRequiredDescription
filebinaryYesThe file to upload
datasetIdstringYesTarget collection ID
pathstringNoltree folder path for the upload (e.g. collectionId.folderId). Defaults to collection root
namestringNoCustom file name to store in CoreViz. Defaults to a timestamp-prefixed original name
widthintegerNoImage/video width in pixels (metadata only)
heightintegerNoImage/video height in pixels (metadata only)
durationnumberNoVideo duration in seconds
exifstringNoJSON string of EXIF metadata

Supported File Types

FormatMIME Type
JPEGimage/jpeg
PNGimage/png
GIFimage/gif
WebPimage/webp
HEICimage/heic

Example Request

curl -X POST https://lab.coreviz.io/api/upload/multipart \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -F "file=@/path/to/photo.jpg" \
  -F "datasetId=COLLECTION_ID" \
  -F "path=collectionId.campaignFolderId" \
  -F "name=hero-shot.jpg"

Response

Status Code: 200 OK

{
  "success": true,
  "mediaId": "newMediaId123",
  "url": "https://blob.vercel-storage.com/.../hero-shot.jpg",
  "message": "File uploaded successfully"
}

If the file is blocked by content moderation:

{
  "success": true,
  "mediaId": "newMediaId123",
  "url": null,
  "message": "File uploaded but blocked by content moderation"
}

Response Fields

FieldTypeDescription
successbooleanWhether the upload completed
mediaIdstringID of the newly created media item
urlstring | nullPublic blob URL (null if blocked by moderation)
messagestringStatus message

What Happens After Upload

Once uploaded, CoreViz automatically:

  1. Stores the file in blob storage (Vercel Blob)
  2. Creates a media record in the database with the specified path
  3. Runs background AI processing: frame extraction, caption generation, object detection, CLIP embedding
  4. Runs content moderation — blocked items will have url: null

Error Responses

StatusDescription
400Missing file, missing datasetId, or unsupported file type
401Missing or invalid authentication
403Insufficient permissions (requires admin or owner role)
404Collection not found
500Blob upload or processing failed

JavaScript Example

// Browser — File input
async function uploadFile(file, collectionId, folderPath) {
  const formData = new FormData();
  formData.append('file', file);
  formData.append('datasetId', collectionId);
  if (folderPath) formData.append('path', folderPath);

  const res = await fetch('https://lab.coreviz.io/api/upload/multipart', {
    method: 'POST',
    headers: { 'Authorization': `Bearer ${token}` },
    body: formData,
  });
  return res.json(); // { success, mediaId, url, message }
}
# Python
import requests

with open('/path/to/photo.jpg', 'rb') as f:
    res = requests.post(
        'https://lab.coreviz.io/api/upload/multipart',
        headers={'Authorization': 'Bearer YOUR_TOKEN'},
        files={'file': ('photo.jpg', f, 'image/jpeg')},
        data={
            'datasetId': 'COLLECTION_ID',
            'path': 'collectionId.campaignFolderId',
            'name': 'hero-shot.jpg',
        }
    )
print(res.json())

Using the SDK

The @coreviz/sdk wraps this endpoint with Node.js file path support:

const result = await sdk.media.upload('/path/to/photo.jpg', {
  collectionId: 'COLLECTION_ID',
  path: 'collectionId.campaignFolderId',
  name: 'hero-shot.jpg',
});

See Media — upload() for full SDK documentation.