--- title: Uploads | Scenario Docs description: API reference for the enhanced file-upload helper. --- The `uploads` resource is enhanced in two ways: - `create()`, `retrieve()`, and `triggerAction()` return a response where `response.upload` gains `.wait()` — a helper that polls until the upload reaches a terminal state. - `uploadFile()` — a one-call wrapper around the full 4-step S3 multipart upload flow (init → upload parts → complete → poll until imported). --- ## `upload.wait(options?)` Available on `response.upload` after calling `client.uploads.create()`, `client.uploads.retrieve()`, or `client.uploads.triggerAction()`. Polls until the upload has been processed into an entity (asset or model), or reaches a terminal state (`imported`, `complete`, or `failed`). Resolves with the latest upload data so you can read `entityId`, `status`, or `errorMessage` without a follow-up retrieve. **Signature** ``` upload.wait(options?: UploadWaitOptions): Promise ``` **Parameters** | Name | Type | Default | Description | | --------------------- | -------- | -------- | ------------------------------------------------------ | | `options.intervalMs?` | `number` | `2000` | Polling interval in milliseconds. | | `options.timeoutMs?` | `number` | `300000` | Maximum wait time in milliseconds. Throws if exceeded. | **Returns** `Promise` — a new `Upload` instance with the final state. All original upload fields are present. **Errors** Throws `Error` if the upload does not reach a terminal status within `timeoutMs`. **Example** ``` import Scenario from '@scenario-labs/sdk'; const client = new Scenario({ apiKey: '...' }); const res = await client.uploads.retrieve('upload_...'); const done = await res.upload.wait(); if (done.status === 'failed') throw new Error(done.errorMessage); console.log(done.entityId); ``` Note `.wait()` resolves as soon as `entityId` is populated *or* a terminal status is reached — whichever comes first. Terminal statuses are `'imported'`, `'complete'`, and `'failed'`. --- ## `create()`, `retrieve()`, `triggerAction()` — enhanced responses All three base methods are enhanced: each response’s `upload` field gains `.wait()`. ``` // After create const createRes = await client.uploads.create({ fileName: 'photo.jpg', fileSize: 1234, contentType: 'image/jpeg', kind: 'image', parts: 1 }); const done = await createRes.upload.wait(); // After retrieve const retrieveRes = await client.uploads.retrieve('upload_...'); const done2 = await retrieveRes.upload.wait(); // After triggerAction const actionRes = await client.uploads.triggerAction('upload_...', { action: 'complete' }); const done3 = await actionRes.upload.wait(); ``` --- ## `client.uploads.uploadFile(params)` Upload a file end-to-end. Computes an optimal part size within AWS S3 limits, uploads all parts in parallel up to `partConcurrency` at a time, triggers completion, polls until the server validates and imports the file, and returns the resolved entity. The return type narrows on `kind`: passing `'model'` returns a `ModelRetrieveResponse`; everything else returns an `AssetRetrieveResponse`. **Signature** ``` client.uploads.uploadFile( params: UploadFileParams, options?: RequestOptions, ): Promise> ``` **Parameters** | Name | Type | Default | Description | | ------------------------- | ----------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `params.file` | `UploadFileInput` | | The file to upload. See [`UploadFileInput`](#uploadfileinput) for accepted forms. | | `params.fileName` | `string` | | Original filename (e.g. `"photo.jpg"`). | | `params.contentType` | `string` | | MIME type (e.g. `"image/jpeg"`, `"application/octet-stream"`). | | `params.kind` | `UploadKind` | | Upload kind. Determines the return type: `'model'` → `ModelRetrieveResponse`; everything else → `AssetRetrieveResponse`. See the [API Reference](/api/index.md) for valid `kind` values. | | `params.assetOptions?` | `object` | | Extra asset options passed through to the server. Ignored when `kind === 'model'`. | | `params.partConcurrency?` | `number` | `4` | Maximum number of S3 parts uploaded in parallel. | | `params.pollIntervalMs?` | `number` | `2000` | Polling interval for the “upload imported” check, in ms. | | `params.pollTimeoutMs?` | `number` | `300000` | Maximum time to wait for the upload to finish importing, in ms. Throws if exceeded. | **Returns** `Promise>` — the resolved entity after the upload is fully imported and validated by the server. | `kind` | Return type | | ------------- | ----------------------- | | `'model'` | `ModelRetrieveResponse` | | anything else | `AssetRetrieveResponse` | **Errors** Throws `Error` in the following cases: - File is empty (`byteLength === 0`). - File exceeds 5 TiB (AWS S3 hard limit). - Upload reaches `'failed'` status — the error message includes the server’s `errorMessage`. - Upload does not reach a terminal status within `pollTimeoutMs`. ``` try { const asset = await client.uploads.uploadFile({ file: './large-texture.png', fileName: 'large-texture.png', contentType: 'image/png', kind: 'image', pollTimeoutMs: 600_000, // extend to 10 min for large files }); } catch (err) { console.error((err as Error).message); } ``` **Example** ``` import Scenario from '@scenario-labs/sdk'; const client = new Scenario({ apiKey: '...' }); // From a local file path (Node.js) const asset = await client.uploads.uploadFile({ file: './photo.jpg', fileName: 'photo.jpg', contentType: 'image/jpeg', kind: 'image', }); console.log(asset.id, asset.url); // From a Blob const pngBlob = new Blob([pngBytes], { type: 'image/png' }); const uploaded = await client.uploads.uploadFile({ file: pngBlob, fileName: 'generated.png', contentType: 'image/png', kind: 'image', }); ``` Caution Local-path reads (`file: './path/to/file'`) use `node:fs/promises` and throw in browser environments. Pass a `Uint8Array` or `Blob` for browser or non-Node contexts. --- ## `UploadFileInput` The accepted upload input forms: ``` type UploadFileInput = string | Uint8Array | Blob; ``` | Form | Description | | --------------- | ------------------------------------------------------------------------------------------------ | | `string` | A local file path. Read from disk via `node:fs/promises`. **Node.js only** — throws in browsers. | | `Uint8Array` | Raw bytes. `Buffer` is a `Uint8Array` and works here too. | | `Blob` / `File` | Browser-native, or Node ≥ 18 via `fs.openAsBlob()` / constructors. | --- ## `UploadWaitOptions` Options for `upload.wait()`: ``` interface UploadWaitOptions { intervalMs?: number; // Default: 2000 timeoutMs?: number; // Default: 300000 } ``` | Name | Type | Default | Description | | ------------- | -------- | -------- | ------------------------------------------------------ | | `intervalMs?` | `number` | `2000` | Polling interval in milliseconds. | | `timeoutMs?` | `number` | `300000` | Maximum wait time in milliseconds. Throws if exceeded. |