---
title: "Upload a content file"
method: POST
path: "/content_uploads"
tags: ["Upload"]
---

# Upload a content file

`POST /content_uploads`

## Request

- Base URL: `https://upload.telemetrytv.com`
- URL: `https://upload.telemetrytv.com/content_uploads`
- Auth: none declared. Required headers: `Authorization`

Accepts a multipart file upload, detects its type, optionally converts/resizes it, stores it in S3, and creates (or replaces) a content record. Processing runs asynchronously by default; pass `?wait=true` to block until done.

## Query parameters

- `wait` boolean

## Headers

- `Authorization` string, required
- `REQUEST-ID` string

## Request body `multipart/form-data`

- object
  - `file` string, binary, required: The file to upload. Max 1 GB overall; images additionally capped at 20 MB and 16 000 x 16 000 px (auto-resized to 4 096 x 4 096 if exceeded). Type is detected from magic bytes, falling back to file extension. Supported types: png, jpg, gif, svg, mp4, webm, ogg, mov, avi, pdf, ppt, pptx, doc, docx, xls, xlsx, vtt, srt, zip. No Content-Type header validation is performed.
  - `filename` string: Override the uploaded file's name. Falls back to the multipart filename.
  - `folder_id` string: MongoDB ObjectID of the destination media folder.
  - `upload_state` 'upload' | 'replace': `upload` creates a new content record; `replace` updates an existing one.
  - `content_id` string: Required when `upload_state=replace`. MongoDB ObjectID of the content to replace.
  - `filesync_id` string: ID of the associated filesync entry.
  - `replaced_file_name` string: Original filename of the content being replaced.
  - `replaced_file_s3_path` string: S3 path of the file being replaced.
  - `google_drive_id` string: Google Drive file ID, when the source originates from Google Drive.
  - `google_email` string: Google account email associated with the Drive source.
  - `canva` boolean: Set to `true` when the file originates from a Canva export.
  - `canva_design_id` string: Canva design ID.
  - `canva_export_url` string: Canva export URL.
  - `owner_page_id` string: Page ID that owns this content (e.g. for webshot content).
  - `hidden` boolean: If `true`, the created content record is hidden from the media library (e.g. subtitles).
  - `prompt_id` string: AI prompt ID that triggered this upload.
  - `webshot` object: Webshot metadata. Only relevant when content originates from a web screenshot.
    - `id` string
    - `url` string
    - `width` number
    - `height` number
    - `scroll_x` number
    - `scroll_y` number
    - `zoom` number
    - `refresh` number
    - `delay` number
    - `preload_script` object[]
      - `action` string
      - `target` string
      - `value` string
      - `url` string
      - `scroll_x` number
      - `scroll_y` number

## Response `201`

Upload accepted (or completed when `wait=true`). When `wait=false` returns a Process object. When `wait=true` returns an array of content objects.

- union
  - Process: Process tracking record returned immediately when `wait=false`.
    - `id` string: MongoDB ObjectID of the process.
    - `account_id` string
    - `name` string
    - `content_type` string
    - `upload_state` 'upload' | 'replace'
    - `folder_id` string
    - `content_id` string
    - `hash` string: MD5 hash of the uploaded file.
    - `hidden` boolean
    - `canva` boolean
    - `prompt_id` string
    - `created_at` string, date-time
    - `updated_at` string, date-time
  - ContentResult[]
    - `mime_type` string
    - `name` string
    - `description` string: EXIF/ffmetadata description extracted from the file.
    - `public_url` string, uri
    - `thumb_public_url` string, uri
    - `content_s3_key` string
    - `content_s3_keys` string[]: Present for multi-slide content (e.g. PDF converted to images).
    - `public_urls` string[]: Present for multi-slide content.
    - `meta` Meta
      - `Key` string: S3 object key.
      - `LastModified` string
      - `ETag` string
      - `Size` integer: File size in bytes.
    - `metas` Meta[]: Present for multi-slide content.
      - `Key` string: S3 object key.
      - `LastModified` string
      - `ETag` string
      - `Size` integer: File size in bytes.
    - `width` integer
    - `height` integer
    - `slides` boolean: True if the content was split into multiple slides (e.g. multi-page PDF).
    - `transcoded` boolean: True if a video was transcoded to MP4.
    - `transcoded_at` string, date-time
    - `length` number, float: Video duration in seconds.
    - `filesync_id` string
    - `prompt_id` string

## Other responses

- `400`: Bad request — malformed form data, or image exceeds the 20 MB size limit.
- `401`: Missing or invalid authentication token.
- `402`: Video uploads require a plan upgrade.
- `403`: Authenticated user lacks the required media upload permission.
- `415`: Unsupported file type detected from magic bytes / extension.
- `500`: Internal server error during upload processing.

---

[API](https://skmtc.dev/telemetrytv/apis/upload-service.md) - [All operations](https://skmtc.dev/telemetrytv/apis/upload-service/llms.txt) - [OpenAPI document](https://skmtc.dev/telemetrytv/apis/upload-service/revisions/c42eaf056e71?raw)
