---
title: "Upload a source file"
method: POST
path: "/v1/files/upload"
tags: ["Files"]
---

# Upload a source file

`POST /v1/files/upload`

## Request

- Base URL: `https://contentmaschine.ai/api`
- URL: `https://contentmaschine.ai/api/v1/files/upload`
- Auth: one of:
  - HTTP bearer
  - OAuth 2 (authorization code, authorization URL `https://contentmaschine.ai/api/oauth/authorize`, token URL `https://contentmaschine.ai/api/oauth/token`)

Upload a file into your library and receive a `file_uuid`. This is the single
ingest route for the whole API: pass the uuid to the image endpoints
(`/v1/images/vary`, `/fuse`, `/upscale`, `/remove-background`, `/describe`,
`/instagram-enhance`), as a video start frame, to `/v1/audio/transcribe`, or to
`/v1/videos/merge`.

ACCEPTED TYPES (this list is read from the server's own allowlist, not restated):
`image/png`, `image/jpeg`, `image/webp`, `image/gif`, `audio/mpeg`, `audio/wav`, `video/mp4`.
The type is SNIFFED from the bytes; the filename extension is not trusted.

SIZE LIMITS, and they are MEASURED against the deployed server rather than copied
from a constant:
- images: 25 MB
- audio and video: 48 MB

The 48 MB figure is deliberately below the gateway request-body limit of 50 MB,
which was measured byte-for-byte on the deployed stack: a 52,428,800-byte request
body was accepted and 52,428,801 bytes was cut off mid-upload with an HTML error
page. The margin exists so that an oversized upload gets THIS API's JSON 413 with a
usable message instead of the gateway's HTML. Note the gateway limit applies to the
whole multipart REQUEST BODY - the file plus framing plus the filename - not to the
file alone. A body past that limit does not produce a JSON error at all.

`width` and `height` are returned for images and are null for audio and video.
The response shape is otherwise unchanged from when this route was images-only.

## Response `201`

Stored

- object
  - `success` boolean
  - `data` object
    - `file_uuid` string: Pass this as file_uuid to the image endpoints.
    - `mime_type` string
    - `size_bytes` integer
    - `width` integer, nullable: Images only; null for audio and video.
    - `height` integer, nullable: Images only; null for audio and video.

## Other responses

- `400`: No file field, or a file the server could not read.
- `401`: Missing or invalid API key.
- `413`: Too large: over 25 MB for an image, or over 48 MB for audio/video. A request BODY over the 50 MB gateway limit is cut off before this handler runs and returns an HTML page instead.
- `415`: Unsupported type. The message lists the accepted mime types.
- `default`: Any other error. Every failure this API emits uses the same envelope; branch on `error.type`, never on `error.message`, and quote `error.correlation_id` to support.

---

[API](https://skmtc.dev/contentmaschine/apis/contentmaschine-ai-api.md) · [All operations](https://skmtc.dev/contentmaschine/apis/contentmaschine-ai-api/llms.txt) · [OpenAPI document](https://skmtc.dev/contentmaschine/apis/contentmaschine-ai-api/revisions/28c74f46051c?raw)
