# Get Part URLs

> Part of the [SpatialGen API documentation](/index.md). [HTML version of this page](/api/direct-upload/part-urls/).

Request presigned upload URLs for one direct-upload file.

## API context

-   API requests use `https://spatialgen.com` with the `/api` path prefix, included once.
-   Authenticate requests to SpatialGen API endpoints with the `X-SPATIALGEN-APPKEY` HTTP header.
-   Use a key from the workspace that owns the requested resources. Follow the roles and scopes specified for each endpoint below.
-   Keep `admin` and `upload` keys on a trusted backend. `readonly` keys may be used in client apps for permitted read operations.
-   Presigned upload URLs have their own authorization. Do not send your SpatialGen API key to those URLs.

See the [API key guide](/guides/get-started.md) for roles, key creation, expiration, revocation, and rotation.

* * *

**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

`admin`, `upload`

## 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`.

```js
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`.

```js
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

```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

```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"
    }
  ]
}
```
