---
title: "Get an upload | GPT-Video API reference"
description: "Returns an open upload with the parts that arrived and the time it expires."
url: "https://www.gpt-video.com/developers/api/get-upload"
operation: "get_upload"
method: "GET"
path: "/v1/uploads/{uploadId}"
scope: "clips:read"
---

Do not assume endpoints have parameters other than the ones explicitly specified.

# Get an upload

Operation id `get_upload`. Request `GET /v1/uploads/{uploadId}`.

Returns an open upload with the parts that arrived and the time it expires.

Beta. This endpoint is supported and can gain new fields. If a change would break your code, we tell you before it takes effect and list it in the changelog.

## About

Use it to resume after a lost connection or a restart: send again only the parts that are not in receivedParts, then call complete_upload (`POST /v1/uploads/{uploadId}/complete`). Only open uploads exist here; an upload that was completed, cancelled or removed for inactivity is not found, and the asset of a completed upload is read with get_asset (`GET /v1/assets/{assetId}`).

## Example use

After a server restart in the middle of a big upload, a script reads the upload to see which parts arrived. It sends only the missing ones and then calls complete_upload (`POST /v1/uploads/{uploadId}/complete`).

## Endpoint

```text
GET https://api.gpt-video.com/v1/uploads/{uploadId}
```

- Scope `clips:read`.
- Rate limit 120 requests a minute for each key and 240 for each account, shared by every `read` call. See [rate limits](/developers/rate-limits.md).
- No `Idempotency-Key`.

## Parameters

### Path

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `uploadId` | string | Required | The id of the upload, as create_upload (`POST /v1/uploads`) returned it. Matches `^upl_[0-9a-f]{20}$`. |

## Request

Check which parts arrived.

```bash title="curl"
curl "https://api.gpt-video.com/v1/uploads/upl_e7b04c92a15d4f36b8c7" \
  -H "Authorization: Bearer $GPT_VIDEO_API_KEY"
```

```ts title="TypeScript"
const res = await fetch("https://api.gpt-video.com/v1/uploads/upl_e7b04c92a15d4f36b8c7", {
  method: "GET",
  headers: {
    "Authorization": `Bearer ${process.env.GPT_VIDEO_API_KEY}`,
  },
});
const data = await res.json();
console.log(data);
```

```python title="Python"
import os

import requests

r = requests.get(
    "https://api.gpt-video.com/v1/uploads/upl_e7b04c92a15d4f36b8c7",
    headers={
        "Authorization": f"Bearer {os.environ['GPT_VIDEO_API_KEY']}",
    },
)
data = r.json()
print(data)
```

```json title="MCP (Full)"
{
  "method": "tools/call",
  "params": {
    "name": "get_upload",
    "arguments": {
      "uploadId": "upl_e7b04c92a15d4f36b8c7"
    }
  }
}
```

## Response

A successful call answers HTTP 200. Returns a [Upload object](/developers/objects.md#upload) in `upload`.

### Fields to check

| Name | Type | Description |
| --- | --- | --- |
| `upload.id` | string | The upload id. It starts with upl_. |

### Response example

```json title="HTTP 200"
{
  "upload": {
    "id": "upl_e7b04c92a15d4f36b8c7",
    "filename": "teaser.mp4",
    "contentType": "video/mp4",
    "sizeBytes": 4096,
    "partSizeBytes": 8388608,
    "partCount": 1,
    "receivedParts": [
      1
    ],
    "createdAt": "2026-09-01T10:40:00.000Z",
    "expiresAt": "2026-09-01T16:41:00.000Z"
  }
}
```

**All response fields**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `upload` | Upload object | Required | Described in [Upload object](/developers/objects.md#upload). |

**More examples**

#### Check an upload that does not exist

`GET /v1/uploads/upl_3b6f9e2d7c0a4e51a8d9`

```json title="HTTP 404"
{
  "error": {
    "code": "NOT_FOUND",
    "message": "Upload upl_3b6f9e2d7c0a4e51a8d9 not found",
    "hint": "Check the id. An id that belongs to another account is not found either.",
    "requestId": "req_6e0a4c8f2d5b9e3a7c1f4b8d"
  }
}
```

## Errors

| Code | Status | When | What to do |
| --- | --- | --- | --- |
| [`NOT_FOUND`](/developers/errors.md#NOT_FOUND) | 404 | Check an upload that does not exist | Change the request, then send it again. |

Every call can also answer these errors. [`VALIDATION_FAILED`](/developers/errors.md#VALIDATION_FAILED), [`UNKNOWN_PARAMETER`](/developers/errors.md#UNKNOWN_PARAMETER), [`UNAUTHORIZED`](/developers/errors.md#UNAUTHORIZED), [`SCOPE_MISSING`](/developers/errors.md#SCOPE_MISSING), [`RATE_LIMITED`](/developers/errors.md#RATE_LIMITED), [`INTERNAL`](/developers/errors.md#INTERNAL), [`UNAVAILABLE`](/developers/errors.md#UNAVAILABLE).

## Cost

No credits are used.

## Related operations

- [`create_upload`](/developers/api/create-upload.md) (`POST /v1/uploads`) Start an upload
- [`upload_part`](/developers/api/upload-part.md) (`PUT /v1/uploads/{uploadId}/parts/{partNumber}`) Send a part of an upload
- [`complete_upload`](/developers/api/complete-upload.md) (`POST /v1/uploads/{uploadId}/complete`) Complete an upload
- [`cancel_upload`](/developers/api/cancel-upload.md) (`DELETE /v1/uploads/{uploadId}`) Cancel an upload

## Questions

### Why is an upload I started yesterday not found?

An upload with no activity is removed when its expiresAt passes, together with its parts. Start a new upload and send the file again.

### Does receivedParts include a part that is still arriving?

No. A part is listed only after all its bytes arrived and were written.
