Upload methods
The API supports two upload methods depending on your file size and use case.
Presigned URLs (recommended for large files)
Generate a time-limited URL and upload directly to Azure Blob Storage. This is required for files over 10 MB and is also useful when you want to offload upload work from your API server.
Flow:
- Call
/api/integrations/uploads/url to get a presigned URL
- Upload your file to the returned URL with a
PUT
- Create a submission with the returned
blobPath
Advantages:
- Handles large files (up to the per-category maximums)
- Reduced load on your API server
- Good for parallel uploads
Disadvantages:
- Two requests instead of one
- The URL expires after 1 hour
Direct uploads (simpler for small files)
Stream your file directly through the API. This is simpler for files at or under the 10 MB direct-upload cap.
Flow:
- Call
/api/integrations/uploads/direct with your file
- Get back the
blobPath immediately
- Create a submission with the
blobPath
Advantages:
- Single request
- Simpler implementation
Disadvantages:
- Limited to files of 10 MB or smaller
Presigned URL flow
1. Generate upload URL
POST /api/integrations/uploads/url
{
"filename": "campaign-video.mp4",
"contentType": "video/mp4"
}
Response 200 OK:
{
"uploadUrl": "https://<account>.blob.core.windows.net/assets/<path>?<sas>",
"blobPath": "<workspace-id>/campaign-video.mp4",
"expiresAt": "2026-06-03T13:00:00Z"
}
The presigned URL expires after 1 hour. Possible errors: 401 (auth), 403 (invalid filename), 415 (content type not in the allowlist), 422 (validation).
2. Upload to Azure
Use the returned uploadUrl to upload your file with a PUT and the x-ms-blob-type: BlockBlob header.
curl -X PUT \
-H "x-ms-blob-type: BlockBlob" \
--data-binary @campaign-video.mp4 \
"https://<account>.blob.core.windows.net/assets/<path>?<sas>"
Once the upload succeeds, create a submission referencing the blobPath. See Submissions.
Direct upload flow
POST /api/integrations/uploads/direct as multipart/form-data with the field name file.
curl -X POST \
-H "X-API-Key: your-api-key-here" \
-F "file=@small-file.pdf" \
https://mm-midmarket-integrations-api-preview.azurewebsites.net/api/integrations/uploads/direct
Response 201 Created:
{
"blobPath": "<workspace-id>/small-file.pdf",
"sizeBytes": 24576,
"contentType": "application/pdf"
}
Possible errors: 401, 403 (invalid filename), 413 (file exceeds 10 MB — the message points you to /uploads/url), 415, 422, 500.
Upload limits
| Limit | Value |
|---|
| Direct upload cap | 10 MB (use a presigned URL for larger files) |
| Max video size | 5 GB |
| Max audio size | 500 MB |
| Max image size | 50 MB |
| Max document size | 100 MB |
| Presigned URL expiration | 1 hour |
| Allowed content types | See Assets |
Uploads exceeding the size limit are rejected. The content type must be in the allowlist and match the actual file format.
Best practices
For batch operations, use presigned URLs with parallel uploads. Batch the resulting assets into a single submission to stay within rate limits.
- Files over 10 MB: use presigned URLs.
- Files at or under 10 MB: direct upload is fine.
- Batch uploads: use presigned URLs with parallelization.
- Content type: ensure
contentType is in the allowlist and matches the actual file format.
Troubleshooting
Upload URL expired
If your presigned URL expires before the upload completes, generate a new one and try again.
Invalid content type
Ensure your contentType is one of the allowed MIME types and matches the actual file format. For example:
- MP4 files:
video/mp4
- PDF files:
application/pdf
- MP3 files:
audio/mpeg
File too large for direct upload
A 413 from /uploads/direct means the file exceeds the 10 MB direct-upload cap. Switch to the presigned URL flow.