# Upload media: images, video and carousels
URL: https://skedcast.com/developers/guides/social-media-api-upload-media

Media doesn't pass through SkedCast's API. You upload straight to storage with a presigned URL, then register the object so processing starts. This is the four-call sequence in short. The media-uploads guide has the full walkthrough, including video covers.

## Upload media in four calls
- POST /media/presign: get an assetId and an upload URL. Idempotency-Key required.
- PUT <url>: upload the raw bytes straight to storage, with no auth header.
- POST /media: register the upload. SkedCast then checks and processes the file.
- POST /posts: reference the assetId in mediaIds.

## Presign, then upload.
```bash
curl -X POST https://api.skedcast.com/v1/media/presign \
  -H "Authorization: Bearer sked_live_YOUR_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{ "clientId": "<clientId>", "filename": "photo.jpg", "contentType": "image/jpeg", "sizeBytes": 482391 }'

curl -X PUT "<url from the response>" \
  -H "Content-Type: image/jpeg" \
  --data-binary @photo.jpg
```

## Multi-image carousels
There's no separate carousel endpoint. Upload each image the same way and pass all their asset ids, in order, in the base POST /posts `mediaIds` array (the limit differs per platform, for example 2–5 images on Pinterest; see the platform limits dataset). Per-slide alt text is a single post-level `mediaAltTexts` map keyed by media asset id.

## Narrowing which platforms get a version
By default SkedCast prepares a version of the asset for every platform you have a connected account on. Pass an explicit `platforms` array on the register call (`["youtube", "tiktok"]`) to skip versions you won't need. This is useful for large batches where you know where an asset is going.

## FAQ
**Q: How do I know when a video is done processing?**
A: Subscribe to the media.ready webhook (the register response names it as readyEvent), or poll GET /v1/media/{id} until ready is true. Don't wait for a particular status string. The final value is transcoded, not ready. See the media-uploads guide for the polling pitfalls.

**Q: Do I have to wait for processing before composing a post?**
A: No. Compose immediately. SkedCast holds the post until the asset is ready, and the wait doesn't count as a failed attempt.
