---
title: "List uploads"
method: GET
path: "/uploads"
tags: ["Uploads"]
---

# List uploads

`GET /uploads`

## Request

- Base URL: `https://api.shortsync.app/v1`
- URL: `https://api.shortsync.app/v1/uploads`
- Auth: HTTP bearer

Returns uploads in the workspace, newest first. Cursor-paginated.
The `status` field is derived: `reserved` means the slot exists
but the bytes haven't been finalized, `ready` means the upload
has been finalized and has metadata available. List calls do
**not** trigger lazy-finalize for stale reservations — that
happens on `GET /uploads/{upload_id}` (and on the opportunistic
background timer after `POST /uploads`).

## Query parameters

- `status` string[]
- `created_after` string, date-time
- `created_before` string, date-time
- `cursor` string
- `limit` integer

## Response `200`

Uploads.

- object
  - `data` object[], required
    - `id` string, required
    - `status` 'reserved' | 'ready', required: - `reserved` - ticket issued, bytes not yet finalized - `ready` - bytes finalized, usable as a post source In v1 the server skips the post-upload media probe, so transitional `uploaded` / `failed` states are reserved for future use.
    - `filename` string, required: Original filename if supplied to `POST /uploads`; otherwise derived from the S3 object key (typically the literal `"upload"` for empty-body reservations).
    - `content_type` string, required: Canonical MIME of the uploaded bytes (e.g., `video/mp4`, `image/jpeg`), read from the `Content-Type` the client set on the PUT to the presigned URL and validated against the allow-list at finalize.
    - `size_bytes` integer, required
    - `workspace_id` string, required
    - `media` UploadMedia: Probed properties of the uploaded file. Populated for `video` uploads via server-side ffprobe at finalize time; fields fall back to `null` when a probe field can't be read. Images currently report `content_kind: "image"` with all other fields `null`.
      - `content_kind` 'video' | 'image'
      - `duration_seconds` number, nullable
      - `width` integer, nullable
      - `height` integer, nullable
      - `aspect_ratio` number, nullable
      - `fps` number, nullable
      - `bitrate_kbps` integer, nullable
      - `video_codec` string, nullable
      - `audio_codec` string, nullable
    - `error` object, nullable
      - `code` string
      - `message` string
    - `created_at` string, date-time, required
    - `updated_at` string, date-time
  - `pagination` object, required
    - `next_cursor` string, nullable, required: Pass into `cursor` on the next request. `null` when no more pages.

## Other responses

- `401`: Missing, malformed, or revoked token.
- `403`: Token is valid but cannot access this resource. Common cases: - `INSUFFICIENT_SCOPE` - token lacks the required scope. - `WORKSPACE_NOT_ALLOWED` - account token is allowlisted to other workspaces.
- `429`: Per-key sliding-window rate limit (60 req/min), per-org monthly request quota, or per-user upload cap was hit. `RATE_LIMIT_EXCEEDED` carries the window headers; `QUOTA_EXCEEDED` carries `details.quota` (which counter), `used`, `limit`, `resets_at`, and `upgrade_url`. `UPLOAD_QUOTA_EXCEEDED` (Free tier on `POST /posts` only) carries the same shape plus `details.remaining`.

---

[API](https://skmtc.dev/shortsync/apis/shortsync-api.md) · [All operations](https://skmtc.dev/shortsync/apis/shortsync-api/llms.txt) · [OpenAPI document](https://skmtc.dev/shortsync/apis/shortsync-api/revisions/71fdaef1e400?raw)
