Skip to content

Get Part URLs

POST /api/videos/uploads/{uploadSessionId}/files/{uploadId}/part-urls

Fetch presigned upload URLs for one file within a direct upload group.

Allowed API Key Roles

adminupload

Route Parameters

  • uploadSessionId: string UUID for the upload group
  • uploadId: string UUID for the file within that group

Request Body

  • partNumbers: array of positive integers, optional
  • startPartNumber: positive integer, optional
  • count: positive integer up to 10000, optional

For multipart uploads, use one of these two styles:

  • A specific list of parts with partNumbers
  • A range starting at startPartNumber for count parts

For most files, start at 1 and request the total number of parts.

For very large files, you can request smaller batches to improve response times by signing fewer part URLs at once.

Use partNumbers when you need a small set of specific parts, such as retries after a failed upload.

Behavior Notes

  • Single-part uploads return one presigned URL.
  • Multipart uploads return one presigned URL for each requested part.
  • The same file may be queried multiple times until it expires, is completed, or is canceled.

Response Shape

  • uploadId: string
  • fileRole: string
  • fileName: string
  • totalBytes: number
  • partSizeBytes: number
  • totalParts: number
  • uploadStrategy: "single_put" | "multipart"
  • status: string
  • parts: array

Each parts[] item includes:

  • partNumber: number
  • sizeBytes: number
  • byteStart: number
  • byteEnd: number
  • url: string
  • expiresAt: string

Uploading to the Presigned URL

Once you receive a presigned URL, upload directly to that URL with an HTTP PUT request.

  • Do not send your SpatialGen API key to the presigned URL.
  • Send the file bytes directly in the request body.
  • For multipart uploads, each URL is for one specific part number.

Single-Part Uploads

For single_put, send the full file to the returned url.

const response = await fetch(part.url, {
method: 'PUT',
headers: {
'Content-Type': file.type || 'application/octet-stream',
},
body: file,
})

Multipart Uploads

For multipart, slice the file using byteStart and byteEnd, then PUT that slice to the matching url.

const chunk = file.slice(part.byteStart, part.byteEnd + 1)
const response = await fetch(part.url, {
method: 'PUT',
body: chunk,
})
const etag = response.headers.get('ETag')

Save the ETag for each uploaded part. You will send those partNumber and etag values to the complete endpoint when you finalize the file upload.

Example Request

part-urls.js
fetch('https://spatialgen.com/api/videos/uploads/5ea97a59-95e0-4c8b-a634-b0fa9976f6ff/files/402f0bda-a0fa-4551-ae28-7300ab6678dd/part-urls', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-SPATIALGEN-APPKEY': apiKey,
},
body: JSON.stringify({
startPartNumber: 1,
count: 13,
}),
})

Example Response

part-urls-response.json
{
"uploadId": "402f0bda-a0fa-4551-ae28-7300ab6678dd",
"fileRole": "video_left",
"fileName": "left-eye.mov",
"totalBytes": 1287340032,
"partSizeBytes": 104857600,
"totalParts": 13,
"uploadStrategy": "multipart",
"status": "uploading",
"parts": [
{
"partNumber": 1,
"sizeBytes": 104857600,
"byteStart": 0,
"byteEnd": 104857599,
"url": "https://s3.us-west-004.spatialgen.com/sg-library/42/direct-uploads/5ea97a59-95e0-4c8b-a634-b0fa9976f6ff/402f0bda-a0fa-4551-ae28-7300ab6678dd/Ab3dEfGhJkLmNoPqRsTuV.mov?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=...",
"expiresAt": "2026-05-06T18:42:11.000Z"
}
]
}