# Upload source media
> Upload images / audio / video and get a reusable artifact_id.

Capabilities that take source media (image to image, image to video, voice clone, reference audio to music, etc.) accept three reference forms — **artifact is the most reliable**:

| Form | Syntax | When to use |
| --- | --- | --- |
| Uploaded artifact | `{ "type": "artifact", "artifact_id": "artifact_..." }` | Recommended; reusable and immune to external links going stale |
| Public URL | `{ "type": "url", "url": "https://..." }` | Media already has a public address; the platform downloads and re-stores it |
| Data URI | `{ "type": "data_uri", "data": "data:image/png;base64,..." }` | Small files (≤256KB after encoding) |

## Upload

```http
POST /v1/uploads
```

`multipart/form-data`, single file ≤100MB:

```bash curl
curl "$BEATRA_BASE_URL/uploads" \
  -H "Authorization: Bearer $BEATRA_API_KEY" \
  -F "file=@sample.mp3" \
  -F "purpose=voice_clone_source"
```

`purpose` options: `media_input` (default) · `reference_audio` · `voice_clone_source`.

Accepted MIME types: `image/png`, `image/jpeg`, `image/webp`, `image/gif`,
`image/bmp`, `image/tiff`,
`audio/mpeg`, `audio/mp3`, `audio/wav`, `audio/x-wav`, `audio/mp4`,
`audio/x-m4a`, `audio/aac`, `audio/flac`, `audio/ogg`, `audio/webm`,
`video/mp4`, `video/webm`, and `video/quicktime`. If the multipart client sends
`application/octet-stream` (as the `curl` example may), Beatra detects the
concrete type from the file signature. A declared type that does not match the
bytes, or an unsupported type, returns `422 invalid_media` before storage.

Returns `201`:

```json
{
  "object": "upload",
  "artifact_id": "artifact_01JX...",
  "cdn_url": "https://cdn.beatra.ai/.../sample.mp3",
  "mime_type": "audio/mpeg",
  "media_type": "audio",
  "size_bytes": 2097152,
  "duration_ms": 131000,
  "checksum_sha256": "9f86d08..."
}
```

## Rules

- **Instant dedupe**: re-uploading identical content (by `checksum_sha256`) returns `201` with the existing `artifact_id`; storage is not counted twice;
- **Over the limit**: >100MB returns `413 media_too_large`; chunked upload for larger files is not yet available;
- **Type validation**: uploads accept image, audio, and video only; when `media_type` is omitted it is inferred from the verified MIME type; a mismatch or invalid signature returns `422` before storage;
- Artifacts produced by generation tasks (the `artifact_id` in `output`) can likewise be used as input to subsequent tasks.

Full parameters and constraints → [API definition](https://docs.beatra.ai/en/docs/api-reference/operations/uploads/upload_v1_uploads_post)
