---
title: "Send your own file"
method: POST
path: "/v1/uploads"
tags: ["Uploads"]
---

# Send your own file

`POST /v1/uploads`

## Request

- Base URL: `https://api.tryplayhead.com`
- URL: `https://api.tryplayhead.com/v1/uploads`
- Auth: HTTP bearer

For footage that is private, geo-blocked, or never was on a platform at all. Returns an `upl_…` id that is a valid `url` for every later call about the same video.

Editing and delivery containers work, not just web video: mp4, mov (including ProRes), mkv, webm, avi, mxf (XAVC, XDCAM, AVC-Intra, DNxHD), gxf, lxf, ts and dv. Camera raw — .r3d, .braw, .ari, .crm — needs the manufacturer's own decoder and is refused by name, with the export to make instead.

When the file carries SMPTE timecode, every tile is stamped with it alongside the elapsed time, and `video.start_timecode` reports where the source's own clock starts.

## Response `200`

The upload id and what was probed from the file.

- UploadResult
  - `upload_id` string: Pass this as `upload_id` on a later video call.
  - `video` Video
    - `id` string
    - `platform` string: `youtube`, `tiktok`, `instagram`, `x`, `facebook`, `vimeo`, `reddit`, `twitch`, `dailymotion`, `web` for a generically extracted page, or `upload`.
    - `duration` number: Seconds.
    - `width` integer
    - `height` integer
    - `orientation` string
    - `src_fps` number
    - `title` string, nullable
    - `language` string, nullable
    - `engagement` object, nullable: The platform's own public numbers for the post, read when the link was resolved. A count the platform does not give is null, never 0: Instagram gives no views without a login. Null for an upload.
      - `views` integer, nullable
      - `likes` integer, nullable
      - `comments` integer, nullable
      - `reposts` integer, nullable
      - `posted_at` string, nullable: When the post went up: a date and time, or a date when the platform gives only the day.
      - `read_at` string, date-time: When these numbers were read.
    - `content_box` object, nullable: The picture inside the frame when the source was letterboxed. Present means the tiles show this region, not the full frame.
      - `x` integer
      - `y` integer
      - `width` integer
      - `height` integer
    - `carousel` object, nullable: Present when the post is a photo carousel — N stills with no timeline. One second is one slide: second 0 is slide 1. The number is an index wearing the units the rest of the API speaks, not a duration.
      - `slides` integer
      - `audio_seconds` number, nullable
    - `start_timecode` string, nullable: SMPTE timecode of the source's first frame, e.g. `14:36:27:07`. Present on camera and deck formats, absent on everything from the web. A different clock from the elapsed seconds everywhere else in this response — both are true, and neither should be converted into the other.
    - `interlaced` boolean
    - `audio_tracks` integer: Streams, not channels. A camera master routinely has eight.
  - `size_bytes` integer: What is stored.
  - `received_bytes` integer: What was sent.
  - `credits_charged` number: Zero for a metadata read.

## Other responses

- `401`: Missing, malformed or expired credential.
- `422`: ffprobe cannot read the file as media.
- `429`: Upload rate limited.

---

[API](https://skmtc.dev/tryplayhead/apis/playhead-api.md) · [All operations](https://skmtc.dev/tryplayhead/apis/playhead-api/llms.txt) · [OpenAPI document](https://skmtc.dev/tryplayhead/apis/playhead-api/revisions/21dfb775b852?raw)
