Skip to main content

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

import sys, os
sys.path.insert(0, os.path.expanduser('~/.claude/skills/repurpose-youtube-video/scripts'))
import blotato_client as bc

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
api_key
string
required
Blotato API key read from BLOTATO_API_KEY.
linkedin_account_id
string
LinkedIn account ID from BLOTATO_LINKEDIN_ACCOUNT_ID. Empty string if not set.
instagram_account_id
string
Instagram account ID from BLOTATO_INSTAGRAM_ACCOUNT_ID. Empty string if not set.
freepik_api_key
string
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.
url
string
required
Full YouTube URL. Timestamps (&t=...) should be stripped before calling — use re.sub(r'[&?]t=\d+s?', '', url).
Returns a dict:
title
string
required
Video title.
description
string
required
Video description, truncated to 3000 characters.
transcript
string
required
Full transcript text joined into a single string. Empty string if unavailable.
summary
string
required
Always an empty string — Claude derives the summary from transcript.
keyPoints
string[]
required
Always an empty list — Claude derives key points from transcript.
tags
string[]
required
Video tags from YouTube metadata.
chapters
string[]
required
Chapter titles extracted from the video’s chapter list.
channel
string
required
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.
platform
string
required
"linkedin" or "instagram".
api_key
string
required
Blotato API key.
Returns a list of account dicts as returned by the Blotato /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:
  1. POST /v2/media/uploads with {"filename": ...} → receives presignedUrl and publicUrl.
  2. PUT presignedUrl with the binary body and the specified Content-Type.
The presigned URL expires quickly, so the PUT happens immediately after step 1. The endpoint is rate-limited to 10 requests per minute per user.
file_bytes
bytes
required
Raw binary content to upload (e.g. the return value of ov.render_linkedin_hook()).
filename
string
required
Filename sent to Blotato (e.g. "linkedin-hook.png").
api_key
string
required
Blotato API key.
mime
string
default:"image/png"
MIME type used as the Content-Type header on the presigned PUT.
Returns the 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.
public_url
string
required
Any publicly accessible image or video URL.
api_key
string
required
Blotato API key.
Returns the new Blotato-hosted URL string.

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.
account_id
string
required
The Blotato account ID for the target platform.
platform
string
required
"linkedin" or "instagram".
text
string
required
Post caption text. For Instagram, bc.enforce_ig_hashtags() is automatically applied before publishing.
media_urls
string[]
required
List of media URLs. A single URL produces a single image post; multiple URLs produce a carousel on Instagram.
api_key
string
required
Blotato API key.
schedule_time
string
default:"None"
ISO-8601 UTC timestamp for deferred publishing (e.g. "2026-06-01T14:00:00Z"). Pass None to publish immediately.
share_to_feed
boolean
default:"True"
Instagram only. Sets shareToFeed: true on the post body.
Returns the Blotato response dict, which includes a 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.
submission_id
string
required
The postSubmissionId value from the bc.publish_post response.
api_key
string
required
Blotato API key.
timeout
number
default:"120"
Maximum seconds to wait before raising TimeoutError. Default is 120s (40 polls × 3s).
Raises 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".
text
string
required
Instagram caption text, potentially containing more than 5 hashtags.
Returns the cleaned text string with at most 5 hashtags.

Error codes

HTTP codeMeaningBehavior
401Invalid or revoked API keyRaises RuntimeError — relay the error and ask the user to check .env
422Validation error (e.g. too many hashtags, missing required field)Raises RuntimeError with the Blotato error message
429Rate limit hitAutomatically retried once after a 10-second wait; raises RuntimeError if the retry also fails

Build docs developers (and LLMs) love