Documentation Index
Fetch the complete documentation index at: https://mintlify.com/Zoen-DEV/repurpose-youtube-video/llms.txt
Use this file to discover all available pages before exploring further.
blotato_client.py is the main helper script for the skill. It handles all Blotato API calls, local YouTube metadata and transcript extraction, and media uploads to Blotato’s presigned upload endpoint. The script uses only Python stdlib (urllib) — no third-party HTTP client is required.
Setup
bc.load_config()
Returns a dict with all credentials read from .env. Searches in this order: .env in the current working directory, then .env in the skill root (~/.claude/skills/repurpose-youtube-video/). File values take precedence — environment variables are only used to fill keys not already present in the .env file.
Raises SystemExit if BLOTATO_API_KEY is missing.
Returns
Blotato API key read from
BLOTATO_API_KEY.LinkedIn account ID from
BLOTATO_LINKEDIN_ACCOUNT_ID. Empty string if not set.Instagram account ID from
BLOTATO_INSTAGRAM_ACCOUNT_ID. Empty string if not set.Freepik API key from
FREEPIK_API_KEY. Empty string if not set.bc.extract_youtube_local(url)
Extracts metadata and transcript from a YouTube video locally, without using the Blotato API. Requires yt-dlp for metadata and youtube-transcript-api for the transcript. If the transcript is unavailable (private video, no subtitles, region block), the function returns an empty string for transcript and continues gracefully.
Full YouTube URL. Timestamps (
&t=...) should be stripped before calling — use re.sub(r'[&?]t=\d+s?', '', url).Video title.
Video description, truncated to 3000 characters.
Full transcript text joined into a single string. Empty string if unavailable.
Always an empty string — Claude derives the summary from
transcript.Always an empty list — Claude derives key points from
transcript.Video tags from YouTube metadata.
Chapter titles extracted from the video’s chapter list.
Channel name (falls back to uploader name if channel is unavailable).
bc.get_accounts(platform, *, api_key)
Returns a list of social accounts connected to the Blotato workspace for the given platform.
"linkedin" or "instagram".Blotato API key.
/users/me/accounts endpoint.
bc.upload_media_local(file_bytes, filename, *, api_key, mime="image/png")
Uploads raw binary data (e.g. a Pillow-rendered PNG) to Blotato using a two-step presigned upload flow:
POST /v2/media/uploadswith{"filename": ...}→ receivespresignedUrlandpublicUrl.PUT presignedUrlwith the binary body and the specifiedContent-Type.
Raw binary content to upload (e.g. the return value of
ov.render_linkedin_hook()).Filename sent to Blotato (e.g.
"linkedin-hook.png").Blotato API key.
MIME type used as the
Content-Type header on the presigned PUT.publicUrl string — a Blotato-hosted URL usable in mediaUrls when publishing a post.
bc.upload_media_from_url(public_url, *, api_key)
Re-hosts a publicly accessible media URL on Blotato’s CDN. Useful for taking a Freepik-hosted URL and getting a Blotato-hosted one, decoupling the post from Freepik’s CDN lifetime.
Any publicly accessible image or video URL.
Blotato API key.
bc.publish_post(account_id, platform, text, media_urls, *, api_key, schedule_time=None, share_to_feed=True)
Publishes or schedules a post on LinkedIn or Instagram via the Blotato /posts endpoint.
The Blotato account ID for the target platform.
"linkedin" or "instagram".Post caption text. For Instagram,
bc.enforce_ig_hashtags() is automatically applied before publishing.List of media URLs. A single URL produces a single image post; multiple URLs produce a carousel on Instagram.
Blotato API key.
ISO-8601 UTC timestamp for deferred publishing (e.g.
"2026-06-01T14:00:00Z"). Pass None to publish immediately.Instagram only. Sets
shareToFeed: true on the post body.postSubmissionId field used by bc.poll_post_status.
bc.poll_post_status(submission_id, *, api_key, timeout=120)
Polls GET /posts/{submission_id} at 3-second intervals until the post reaches a terminal status.
The
postSubmissionId value from the bc.publish_post response.Blotato API key.
Maximum seconds to wait before raising
TimeoutError. Default is 120s (40 polls × 3s).RuntimeError if the post status reaches failed or error. Raises TimeoutError if timeout is exceeded.
Returns the final post status dict on success (published or scheduled).
bc.enforce_ig_hashtags(text)
Trims hashtags beyond the Instagram hard limit of 5. Called automatically by bc.publish_post when platform == "instagram".
Instagram caption text, potentially containing more than 5 hashtags.
Error codes
| HTTP code | Meaning | Behavior |
|---|---|---|
401 | Invalid or revoked API key | Raises RuntimeError — relay the error and ask the user to check .env |
422 | Validation error (e.g. too many hashtags, missing required field) | Raises RuntimeError with the Blotato error message |
429 | Rate limit hit | Automatically retried once after a 10-second wait; raises RuntimeError if the retry also fails |