> ## Documentation Index
> Fetch the complete documentation index at: https://tryunsora.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Upload media

> Import a file into your Unsora media library from a public URL or base64 payload, ready to use in posts, clipping jobs, and generations.

Imports a file into your Unsora media library. Every upload is stored and
recorded as an **asset**, and the returned `url` can be used anywhere a media
URL is accepted — [post media](/docs/api-reference/posts/create_post), reference
images, or [clipping](/docs/api-reference/clippings/create) input.

Available to **every authenticated user** (no paid plan required).

## Two ways to send the file

| Field    | Use for                                             | Limit                           |
| -------- | --------------------------------------------------- | ------------------------------- |
| `url`    | Any publicly reachable file — the server fetches it | 200 MB                          |
| `base64` | Small local files (raw base64 or a `data:` URL)     | \~7 MB (10 MB request body cap) |

Provide exactly one of the two. `fileName` is required with `base64`.

<Tip>
  For large local files, use the signed-URL flow instead:
  [Mint a signed upload URL](/docs/api-reference/uploads/signed-url), `PUT` the bytes
  directly to storage, then [register the asset](/docs/api-reference/uploads/complete).
  The file bytes never pass through the API server.
</Tip>

## Examples

<RequestExample>
  ```bash Import from URL theme={null} theme={null}
  curl -X POST "https://mvp2.tryunsora.com/api/v1/uploads" \
    -H "Authorization: Bearer uns_live_YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{ "url": "https://example.com/video.mp4" }'
  ```

  ```bash Base64 (small file) theme={null} theme={null}
  curl -X POST "https://mvp2.tryunsora.com/api/v1/uploads" \
    -H "Authorization: Bearer uns_live_YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d "{
      \"base64\": \"$(base64 -i photo.png)\",
      \"fileName\": \"photo.png\",
      \"contentType\": \"image/png\"
    }"
  ```
</RequestExample>

## Response

```json theme={null}
{
  "success": true,
  "data": {
    "id": "cm456def",
    "name": "video.mp4",
    "url": "https://.../uploads/usr_123/2026-08-04T10-00-00-000Z-video.mp4",
    "mimeType": "video/mp4",
    "type": "VIDEO",
    "fileSize": 10485760,
    "createdAt": "2026-08-04T10:00:00.000Z"
  }
}
```

The asset `type` is derived from the MIME type: `IMAGE`, `VIDEO`, `AUDIO`, or
`DOCUMENT`.


## OpenAPI

````yaml POST /uploads
openapi: 3.1.0
info:
  title: Unsora API
  version: 1.2.0
  description: >-
    Public API for Unsora integrations. Use Bearer token from Clerk in
    Authorization header.
servers:
  - url: /api/v1
    description: Versioned API
security: []
tags:
  - name: User
  - name: Connect
  - name: Stripe
  - name: Video
  - name: Image
  - name: Influencer
  - name: Thumbnail
  - name: Clipping
  - name: Music
  - name: Voiceover
  - name: Uploads
paths:
  /uploads:
    post:
      tags:
        - Uploads
      summary: Upload media from a URL or base64 payload
      description: >-
        Imports a file into your media library. Pass either `url` (public
        http(s) URL, max 200MB — the server fetches the bytes) or `base64` (raw
        base64 or a data: URL, for small files; the request body is capped at
        10MB). The file is stored and recorded as an upload asset; the returned
        `url` can be used anywhere a media URL is accepted (post media,
        reference images, clipping input). For large local files use the
        signed-URL flow: POST /uploads/signed-url, then PUT the bytes, then POST
        /uploads/complete.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                url:
                  type: string
                  description: Public http(s) URL to import (max 200MB).
                base64:
                  type: string
                  description: 'Base64 file contents (raw or data: URL). Requires fileName.'
                fileName:
                  type: string
                  description: Stored file name (required with base64, optional with url).
                contentType:
                  type: string
                  description: MIME type override, e.g. image/png.
      responses:
        '200':
          description: Uploaded asset
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UploadAssetResponse'
        '400':
          description: Invalid input
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - bearerAuth: []
components:
  schemas:
    UploadAssetResponse:
      type: object
      properties:
        success:
          type: boolean
        data:
          $ref: '#/components/schemas/UploadAsset'
    ErrorResponse:
      type: object
      properties:
        success:
          type: boolean
        error:
          type: string
        code:
          type: string
        message:
          type: string
      required:
        - error
    UploadAsset:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        url:
          type: string
          description: Public URL of the stored file.
        mimeType:
          type: string
        type:
          type: string
          enum:
            - IMAGE
            - VIDEO
            - AUDIO
            - DOCUMENT
        fileSize:
          type: integer
          nullable: true
        createdAt:
          type: string
          format: date-time
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

````