---
name: sendhour
description: Schedule and publish social media posts to TikTok, YouTube, Instagram, Threads, Bluesky, X, LinkedIn through Sendhour. Use when the user asks to post, schedule, queue, cancel or check social media posts, to upload media for them, to find what is going viral in their niche, or to see how their accounts and posts performed.
---

# Sendhour

Sendhour (https://sendhour.com) publishes posts to the user's connected social accounts at the time they pick.
The API key is in `$SENDHOUR_API_KEY` (created in Sendhour → Settings → API access). If Sendhour's
MCP tools are available (list_accounts, schedule_post, …), prefer them. If the `sendhour` command
is installed (`curl -fsSL https://sendhour.com/install.sh | sh`), `sendhour help` lists its commands; add
`--json` for machine-readable output. Otherwise use the REST calls below. Full reference: https://sendhour.com/docs

## Rules

- Posts made with `POST /api/v1/posts` are published at `scheduled_at` without further review. Confirm the text, media, accounts and time with the user before scheduling. If they want to check a post in Sendhour first, create a draft (`POST /api/v1/drafts`) and give them the `review_url`.
- `needs_review` means Sendhour could not tell whether the network received the post. Never post it again before the user checks the account.
- Times are ISO 8601 with an offset (`2026-10-20T07:30:00-04:00`). Ask for the user's time zone if unsure. Up to 60 days ahead; omit `scheduled_at` to publish now.

## Calls

```sh
H="Authorization: Bearer $SENDHOUR_API_KEY"

# 1. Accounts (ids, network, can_schedule)
curl -s https://sendhour.com/api/v1/accounts -H "$H"

# 2. Media: a local file …
curl -s -X PUT "https://sendhour.com/api/v1/media?filename=clip.mp4" -H "$H" -H "Content-Type: video/mp4" --data-binary @clip.mp4
#    … or a public URL
curl -s -X POST https://sendhour.com/api/v1/media/from-url -H "$H" -H "Content-Type: application/json" -d '{"url":"https://example.com/photo.jpg"}'

# 3a. Schedule (one post per account)
curl -s -X POST https://sendhour.com/api/v1/posts -H "$H" -H "Content-Type: application/json" -d '{
  "account_ids": ["acc_…", "acc_…"],
  "caption": "Five slow mornings worth copying",
  "media_ids": ["med_…"],
  "scheduled_at": "2026-10-20T07:30:00-04:00"
}'

# 3b. Draft for the user to confirm in Sendhour (TikTok drafts add "kind": "video" or "photo")
curl -s -X POST https://sendhour.com/api/v1/drafts -H "$H" -H "Content-Type: application/json" -d '{"account_id":"acc_…","kind":"video","caption":"…","media_ids":["med_…"]}'

# 4. Check, list, cancel
curl -s https://sendhour.com/api/v1/posts/post_… -H "$H"
curl -s "https://sendhour.com/api/v1/posts?status=scheduled,draft" -H "$H"
curl -s -X DELETE https://sendhour.com/api/v1/posts/post_… -H "$H"

# 5. Ideas: public posts beating their account's usual views (read-only)
curl -s "https://sendhour.com/api/v1/viral?platform=tiktok&kind=slideshow&days=30&limit=20" -H "$H"

# 6. Analytics: how the accounts and published posts did (read-only; days = 7, 30 or 90)
curl -s "https://sendhour.com/api/v1/analytics?days=30" -H "$H"

# 7. Every public TikTok video on the accounts, however it was posted, with views by day (read-only)
curl -s "https://sendhour.com/api/v1/videos?days=7" -H "$H"
```

`/api/v1/viral` (MCP: `search_viral`) filters: `q`, `platform` (tiktok/youtube), `niche`, `kind`
(video/slideshow), `days` (7/30/90/0), `outliers=false`, `saved=true`, `sort` (ratio/views/newest), `limit`, `page`.
`ratio` = views ÷ the account's usual views. Link the user to `url`; never download or repost
someone else's video.

`/api/v1/analytics` (MCP: `get_analytics`): `days` (7/30/90, default 30), `account_id` (comma-separated),
`limit` (top posts, up to 20). Returns `totals` and `accounts` (views, engagement, followers, posts published, with the
previous period) and `top_posts` by engagement with their lifetime `stats`. Check it before planning new posts to
repeat what worked. `null` = not reported or no data yet.

`/api/v1/videos` (MCP: `list_videos`): every public video on the TikTok accounts, including ones posted in the TikTok
app or finished from the inbox. `days` (7/30/90 by posting date, default 30), `account_id`, `limit` (up to 200). Each
video has lifetime `stats` and `by_day` (stats as last seen each UTC day), so judge a post on its growth over several
days, not its first day.

## Per-network fields and limits

| Network | Fields | Limits |
|---|---|---|
| TikTok | `title` (photo, 90 chars), `content_posting_method` (DIRECT_POST default publishes; UPLOAD only sends to the TikTok inbox), `privacy_level` (PUBLIC_TO_EVERYONE default, MUTUAL_FOLLOW_FRIENDS, FOLLOWER_OF_CREATOR, SELF_ONLY), `comment` (default true), `duet`/`stitch` (true allows; off by default), `autoAddMusic` (photo, yes/no), `video_made_with_ai`, `brand_organic_toggle`, `brand_content_toggle`. Drafts: `kind` (video/photo) | 1 video, or 1–35 photos. About 15 posts per account per day. |
| YouTube | `title` (2–100 chars, required), `visibility` (public/unlisted/private, required), `made_for_kids` | One MP4/MOV video. Description up to 5,000 chars. |
| Instagram | `post_type` (post/story) | Needs a photo or video. JPEG photos, up to 10. Story = exactly one item. 2,200 chars. |
| Threads | — | Up to 500 chars and 10 photos or one video. |
| Bluesky | — | Up to 300 chars and 4 photos. |
| X | — | Up to 280 chars and 4 photos or one video. |
| LinkedIn | — | Up to 3,000 chars and 20 photos or one video. |

Errors come back as `{ "error": "…", "problems": ["…"] }` with HTTP 4xx. Fix the listed problems
and retry; 402 means the workspace has no active plan (none yet, or it ended).
