Quickstart
Go from an API key to a scheduled post with curl.
This walks through the REST API end to end: list accounts, upload a video, and schedule it. If you use Claude, Cursor, or ChatGPT, the MCP server does the same thing without a key.
Every request goes to https://www.brainyshorts.com. Don’t use api.brainyshorts.com.
Get a key and connect an account
Sign in at brainyshorts.com, connect a social account, and create a key at Dashboard → API keys.
export BRAINY_API_KEY="ba_sk_..."
export BRAINY="https://www.brainyshorts.com/api/cli"List connected accounts
curl -s "$BRAINY/accounts" -H "Authorization: Bearer $BRAINY_API_KEY"{
"accounts": [
{ "id": "3f0c...", "platform": "instagram", "account_handle": "@example", "token_valid": true, "created_at": "..." }
]
}Keep the id and platform of each account you want to post to.
Reserve an upload
BrainyShorts checks the file’s hashes before it accepts it, so compute them first.
FILE=clip.mp4
SIZE=$(wc -c < "$FILE" | tr -d ' ')
SHA256=$(shasum -a 256 "$FILE" | cut -d' ' -f1)
MD5=$(openssl md5 -r "$FILE" | cut -d' ' -f1)
curl -s -X POST "$BRAINY/media/uploads" \
-H "Authorization: Bearer $BRAINY_API_KEY" \
-H "Content-Type: application/json" \
-d "{\"content_type\":\"video/mp4\",\"content_length\":$SIZE,\"content_sha256\":\"$SHA256\",\"content_md5\":\"$MD5\"}" \
> reservation.jsoncontent_type is one of image/jpeg, image/png, image/webp, or video/mp4. The response holds an asset_id, a presigned upload_url, and the exact upload_headers to send.
If the response says "already_uploaded": true, you uploaded this exact file before. Skip the next two steps and use media.public_url.
Upload the bytes
Send every header from upload_headers exactly as returned. The URL is signed against them, so a missing or changed header fails.
HEADERS=()
while IFS= read -r h; do HEADERS+=(-H "$h"); done \
< <(jq -r '.upload_headers | to_entries[] | "\(.key): \(.value)"' reservation.json)
curl -s -X PUT "$(jq -r .upload_url reservation.json)" "${HEADERS[@]}" --data-binary @"$FILE"Complete the upload
curl -s -X PATCH "$BRAINY/media/uploads" \
-H "Authorization: Bearer $BRAINY_API_KEY" \
-H "Content-Type: application/json" \
-d "{\"asset_id\":\"$(jq -r .asset_id reservation.json)\"}" \
> media.jsonThe response has a public_url on storage.brainyshorts.com, a domain every supported platform accepts.
Schedule the post
curl -s -X POST "$BRAINY/posts" \
-H "Authorization: Bearer $BRAINY_API_KEY" \
-H "Content-Type: application/json" \
-d @- <<JSON
{
"title": "Launch teaser",
"caption": "Something new is coming.",
"media_type": "video",
"media_urls": ["$(jq -r .public_url media.json)"],
"targets": [{ "social_account_id": "3f0c...", "platform": "instagram" }],
"action": "schedule",
"scheduled_at": "2026-10-01T17:00:00Z"
}
JSONThe response is { "post": {...}, "social_posts": [...] }, with one social_posts entry per target. BrainyShorts publishes it at scheduled_at.
Next steps
- REST API covers updates, deletes, errors, and articles.
- Bulk scheduling schedules hundreds of posts safely.
- Platforms lists each platform’s rules.
