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

# Video Posts

> How to schedule a video with a caption through the API: the endpoints, the file limits, and which platforms accept video.

You can push a finished video in, set the caption and hashtags, and have Marky publish it at a time you pick. It is the same two calls as any other post — the only extra thing to know is how the video gets attached, and which of your connected accounts can take it.

## The short version

```bash theme={null}
# Attach the video and schedule it, in one call.
curl -X POST https://api.mymarky.ai/api/businesses/{business_id}/posts \
  -H "Authorization: Bearer mk_live_your_key_here" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: my-unique-request-id" \
  -d '{
    "caption": "Behind the scenes of this week build. #smallbusiness #marketing",
    "media_urls": ["https://my-cdn.example.com/clips/week-12.mp4"],
    "status": "SCHEDULED",
    "scheduled_publish_time": "2026-12-01T14:00:00Z",
    "restrict_publish_to": ["instagram", "tiktok", "youtube"]
  }'
```

That is the whole flow. Hashtags are not a separate field: put them in `caption`, exactly as you want them to appear.

<Note>
  Send an `Idempotency-Key` header. If the request times out and you resend it with the same key, you get the original post back instead of a second copy — so a network blip can never double-post a video.
</Note>

## Three ways to attach the video

Pick the one that matches where your file already is.

| Your file is...                                       | Use                                                       | How                                                                            |
| ----------------------------------------------------- | --------------------------------------------------------- | ------------------------------------------------------------------------------ |
| On a public URL (CDN, S3, your own server)            | `media_urls` on [create post](/api-reference/create-post) | Pass the URL. Marky downloads it at save time and stores its own durable copy. |
| On a public URL, and you want it in the library first | `POST /api/media/from-url`                                | Returns a media asset; pass its `id` in `media_ids`.                           |
| On a disk, as a file you can POST                     | [upload media](/api-reference/upload-media)               | Multipart upload straight into the library.                                    |
| On a disk, in a sandbox that can only `PUT`           | `POST /api/media/uploads`, then `PUT` the bytes           | Gives you a one-hour upload URL. The `PUT` response is the media asset.        |

Marky always re-hosts the file at save time rather than fetching your link later. That is deliberate: a signed or throwaway link that expires before the platform reads it would turn into a publish failure hours after your call already returned `201`. Re-hosting means the link handed to Instagram or TikTok is always one we serve.

The trade is that **the link has to work at the moment you call us.** A URL we cannot fetch fails the request with a `400` right then, which is the signal you want.

<Tip>
  Your video URL does **not** need a `.mp4` in it. A presigned S3 link or a bare CDN object key works — we read the server's `Content-Type` to tell a video from an image.
</Tip>

## File limits

|                    | Limit                                         |
| ------------------ | --------------------------------------------- |
| Max video size     | 500 MB                                        |
| Max image size     | 20 MB                                         |
| Recommended format | MP4 (H.264) or MOV                            |
| Also accepted      | AVI, MKV, WebM, FLV, WMV, M4V, 3GP, MPG, MPEG |

Anything over 500 MB is rejected: a `413` from the upload endpoints, a `400` from `create_post` when the oversized file is behind a `media_urls` link. Trim or re-encode first — we do not compress on your behalf.

## Platform coverage

Every platform Marky publishes to takes video except one.

| Platform                    | Video | What to know                                                                                                                 |
| --------------------------- | :---: | ---------------------------------------------------------------------------------------------------------------------------- |
| Instagram (feed / Reels)    |   ✅   |                                                                                                                              |
| Instagram Story             |   ✅   | A video over **60 seconds** is skipped for Story only. The rest of the post still publishes.                                 |
| Facebook                    |   ✅   |                                                                                                                              |
| TikTok                      |   ✅   | Platform ceiling is **10 minutes**. Many accounts have a lower per-creator cap, and we check the real one before publishing. |
| YouTube                     |   ✅   | **Video only.** An image-only post is skipped for YouTube.                                                                   |
| LinkedIn (page and profile) |   ✅   |                                                                                                                              |
| X (Twitter)                 |   ✅   |                                                                                                                              |
| Pinterest                   |   ✅   |                                                                                                                              |
| Google Business Profile     |   ❌   | Google does not support video posts. A video-only post is skipped for Google Business.                                       |

"Skipped" means that one account is dropped from this post and the others still go out. You will not get a failure row or a failure email for a skip.

Use `restrict_publish_to` to target platforms by name, or `restrict_publish_to_integration_ids` when a workspace has several accounts on the same platform and you want specific ones. Omit both and the post goes to every connected account.

## Separate captions per platform

One video, a different caption on each platform, in the same call:

```json theme={null}
{
  "caption": "Behind the scenes of this week build. #smallbusiness",
  "media_urls": ["https://my-cdn.example.com/clips/week-12.mp4"],
  "status": "SCHEDULED",
  "scheduled_publish_time": "2026-12-01T14:00:00Z",
  "platform_overrides": [
    { "platform": "youtube", "title": "Week 12 build log", "caption": "Full breakdown in the description." },
    { "platform": "linkedIn", "caption": "What we shipped this week, and the one thing that broke." }
  ]
}
```

## Scheduling rules

* `scheduled_publish_time` is ISO 8601 and must be **in the future**. A past time is a `400`.
* `status: "SCHEDULED"` requires `scheduled_publish_time`. Missing it is a `400`.
* To let Marky pick the slot from your posting schedule instead, create the post with `status: "NEW"`, then `POST /api/businesses/{business_id}/posts/{post_id}/queue`.
* To schedule a post you already created, call [schedule post](/api-reference/schedule-post).

## Knowing it published

Register a webhook once and Marky will tell you:

```bash theme={null}
curl -X POST https://api.mymarky.ai/api/webhooks \
  -H "Authorization: Bearer mk_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://your-app.com/webhook", "events": ["post.published"]}'
```

Or poll [get post](/api-reference/get-post) and read its status. Watch metrics land on [get post stats](/api-reference/get-post-stats) once the platform reports them — see [Stats Coverage by Platform](/api-reference/stats-coverage) for which fields each platform fills in.
