# Media (/en/api/media)

| Type  | Format                           | Limits                                                                                                       |
| ----- | -------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| Photo | JPEG, PNG                        | 8 MB. Instagram: ratio 4:5–1.91:1 (PNG is converted to JPEG)                                                 |
| Video | MP4, MOV (H.264/HEVC, AAC audio) | 300 MB, up to 1920 px wide. Files with the `moov` metadata at the end get it moved to the start (fast start) |

The file type is read from the file's content, not from `Content-Type`.

## From a public URL [#from-a-public-url]

```bash
curl -X POST https://api.tebar.app/v1/media/from-url \
  -H "Authorization: Bearer tb_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com/photo.jpg"}'
```

Only `http`/`https` to public hosts on port 80 or 443.

## Direct upload [#direct-upload]

For photos and small videos (under 100 MB), send the file's content as the body:

```bash
curl -X POST https://api.tebar.app/v1/media/upload \
  -H "Authorization: Bearer tb_live_xxx" \
  -H "Content-Type: image/jpeg" \
  --data-binary @photo.jpg
```

The body must be the file itself, not JSON. JSON or form bodies are refused with `415 raw_body_required`. For media from a link, use `POST /v1/media/from-url` with `{ "url": "https://..." }`.

## Chunked upload (large videos) [#chunked-upload-large-videos]

```http
POST /v1/media/uploads          {"mime_type":"video/mp4","size_bytes":12000000}
→ 201 {"id":"m1..","part_size":8388608,"part_count":2,...}

PUT  /v1/media/m1../parts/1     (the first 8,388,608 bytes, Content-Type: application/octet-stream) → 204
PUT  /v1/media/m1../parts/2     (the rest) → 204
POST /v1/media/m1../complete    → 200 {"type":"video","duration_ms":6000,"width":1080,"height":1920,...}
```

Every part except the last must be exactly `part_size` bytes.

## Alt text and the library [#alt-text-and-the-library]

- `PATCH /v1/media/{id}` with `{"alt_text": "..."}` (≤ 1,000 characters). Threads uses it for photos and videos, Instagram for photos only.
- `GET /v1/media` lists the media library, newest first.
- `DELETE /v1/media/{id}` deletes media. Media used by a scheduled post cannot be deleted (`409 media_in_use`).
