Files
The Files API provides a multipart upload workflow for securely uploading binary files, such as audio recordings,
video files, and cover artwork. Once the upload is complete, the API returns a fileUrl for accessing the uploaded file
and an uploadId that is used as the fileId when referencing the file from V2.0 catalog endpoints.
Files uploaded through these endpoints can only be used with V2.0 API endpoints. They are not compatible with
V1.0 API endpoints. Likewise, files uploaded through V1.0 endpoints, such as POST /media/image/upload, cannot be
referenced in V2.0 API payloads.
Upload Workflow
Uploading a file is a three-step process:
-
Create the upload — Call POST
/files/v1/uploads/createto initialize the upload. The response provides anuploadId, the suggested total number ofparts, and a suggestedchunkSizeBytessized appropriately for the file’spurpose. -
Sign and upload each part — For every part you want to upload, call POST
/files/v1/uploads/sign-partto receive a pre-signedurl, the required HTTPmethod(typicallyPUT), the necessaryheaders, and an expiry timestamp. Upload the binary data directly to the returned URL using the provided method and headers.- Optional splitting (recommended for speed): You can split the file into the suggested number of parts and upload multiple parts in parallel, which can significantly reduce total upload time.
- Single upload (alternative): Chunking is optional. If the API suggests 2 parts, you can sign only part
1and upload the entire file to that URL. You do not need to upload part2. - Time limit: Pre-signed URLs are valid for 20 minutes. Upload attempts made after a URL expires return a
403 Forbiddenerror.
-
Complete the upload — Once all the parts you intend to upload have been transferred successfully, call POST
/files/v1/uploads/completewith theuploadIdand an array containing the part numbers you actually uploaded.- The
partsarray only needs to contain the parts you actually uploaded. For example, use[1]when you uploaded the entire file as a single part. - The order of the part numbers does not determine the order of the file data; the API uses the part numbers to assemble the uploaded file.
- On success, the API returns the final
fileUrl.
- The
The uploadId becomes the file’s fileId. V2.0 catalog payloads reference uploaded files by this ID. For example, posterImageId on a video or recordingVersions[].files[].fileId on a track uses the uploadId returned when the upload was created. Keep this ID once the upload completes.
Content Validation
Beyond the content type and size checks performed during Create Upload, some purposes inspect the file itself after it has been assembled. These checks run during Complete Upload, so a file can be rejected after its bytes have already been transferred.
For example:
PosterImageandCoverImagevalidates image dimensions and aspect ratio.Videovalidates the video container, codecs, resolution, and audio properties.
See Videos and the relevant catalog documentation for the complete requirements for each file type.
A file that fails content validation is not stored, and the upload session is ended. Calling Complete or Sign
Part again for that uploadId returns 404 Upload session not found. Start a new upload with Create Upload after
correcting the file.
File URL and Metadata
The stored file is not necessarily named after the file you uploaded, and its storage URL is not derived from fileName
or uploadId in any way you should rely on.
Always use the fileUrl returned by POST /files/v1/uploads/complete rather than
constructing a URL yourself. The storage location and naming scheme are internal and may change.
The original fileName is retained and returned by catalog endpoints when the file is referenced. For example, a track
or video’s recordingVersions[].files[] entry uses the fileName supplied when the upload was created.
Technical properties extracted during processing, such as duration, bitDepth, sampleRate, bitrate, channels,
resolution, and frameRate, are returned by the catalog endpoints that reference the file.
PNG Conversion
Uploads declared as image/png are re-encoded to JPEG during Complete Upload. The stored bytes are the
converted JPEG, and the stored Content-Type becomes image/jpeg.
Conversion follows the contentType you declared, not the bytes you sent. Make sure the declared MIME type matches
the actual file format. If PNG bytes are uploaded while declaring image/jpeg, the PNG-to-JPEG conversion is skipped.
Supported Purposes, File Types & Size Limits
The purpose field determines which content types are accepted for an upload and how the uploaded file is processed.
Each purpose also has its own maximum file size.
| Purpose | Max file size | Accepted content types |
|---|---|---|
Image, CoverImage, PosterImage | 10 MB | image/jpeg, image/jpg, image/png |
Video | 30 GB | video/mp4, video/mov, video/quicktime |
Audio | 5 GB | audio/wav, audio/flac, audio/x-flac |
VideoCaption | 5 MB | application/ttml+xml, text/scc (UTF-8 encoding only) |
These limits reflect the current configuration and may change over time. If a file exceeds the limit for its purpose, POST /files/v1/uploads/create returns a 400 validation error.
Create Upload
/files/v1/uploads/create Initializes a new upload session. Returns the upload ID, the suggested chunk size, and the suggested number of parts.
Request Body *
object fileName string cover.jpg, recording.wav contentType string purpose. See the Supported Purposes, File Types & Size Limits table above.image/jpeg, image/png, audio/wav, audio/flac, video/mp4 size integer purpose string Image, CoverImage, File, Video, Audio Responses
object uploadId string chunkSizeBytes integer parts integer /files/v1/uploads/create curl -X POST "https://platform.revelator.com/files/v1/uploads/create" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"fileName": "midnight-tides-cover.jpg",
"contentType": "image/jpeg",
"size": 4194304,
"purpose": "CoverImage"
}' curl -X POST "https://platform.revelator.com/files/v1/uploads/create" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"fileName": "midnight-tides-cover.jpg",
"contentType": "image/jpeg",
"size": 4194304,
"purpose": "CoverImage"
}' Example response 200
{
"uploadId": "d9fad28c-c3d5-459b-9aa4-2e64ab679924",
"chunkSizeBytes": 2097152,
"parts": 2
} {
"uploadId": "d9fad28c-c3d5-459b-9aa4-2e64ab679924",
"chunkSizeBytes": 2097152,
"parts": 2
} Sign Part
/files/v1/uploads/sign-part Returns a pre-signed URL for uploading a file part. PUT the binary chunk directly to the returned URL using the provided headers.
Request Body *
object uploadId string partNumber integer 1. If you are not splitting the file, sign only part 1.Responses
object method string url string headers object expiresAtUtc string (date-time) /files/v1/uploads/sign-part curl -X POST "https://platform.revelator.com/files/v1/uploads/sign-part" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"uploadId": "d9fad28c-c3d5-459b-9aa4-2e64ab679924",
"partNumber": 1
}' curl -X POST "https://platform.revelator.com/files/v1/uploads/sign-part" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"uploadId": "d9fad28c-c3d5-459b-9aa4-2e64ab679924",
"partNumber": 1
}' Example response 200
{
"method": "PUT",
"url": "https://files.example-storage.com/temp-uploads/...",
"headers": {
"Content-Type": "application/octet-stream",
"x-ms-blob-type": "BlockBlob"
},
"expiresAtUtc": "2026-03-17T10:18:53.7017793Z"
} {
"method": "PUT",
"url": "https://files.example-storage.com/temp-uploads/...",
"headers": {
"Content-Type": "application/octet-stream",
"x-ms-blob-type": "BlockBlob"
},
"expiresAtUtc": "2026-03-17T10:18:53.7017793Z"
} Complete Upload
/files/v1/uploads/complete Finalizes the upload workflow after your parts (or single file) have been uploaded to their signed URLs. Returns the permanent file URL.
Request Body *
object uploadId string parts integer[] [1] if you uploaded the entire file as one part, or [1, 2] if you split it.Responses
object fileUrl string /files/v1/uploads/complete curl -X POST "https://platform.revelator.com/files/v1/uploads/complete" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"uploadId": "dad5931c-c728-4dfb-bda5-bd67a1905303",
"parts": [
2,
1
]
}' curl -X POST "https://platform.revelator.com/files/v1/uploads/complete" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"uploadId": "dad5931c-c728-4dfb-bda5-bd67a1905303",
"parts": [
2,
1
]
}' Example response 200
{
"fileUrl": "https://files.example-storage.com/images/00000000-0000-0000-0000-000000000000/file.jpg"
} {
"fileUrl": "https://files.example-storage.com/images/00000000-0000-0000-0000-000000000000/file.jpg"
}