Skip to content

URL: https://mkdocs.justinsforge.com/memory/general/reference_social_media_apis/

Social Media API Reference

Covers YouTube Data API v3, Instagram Graph API, and TikTok Content Posting API as they apply to JWVR (YouTube creator), Nova Design (Shopify/social brand), and Gus Outdoor Co (fishing brand). Written 2026-04-30.


Hard Rule: Draft Only, Never Auto-Post

Forge never publishes to any social platform automatically. Every workflow stops at a draft or staged state. Justin reviews and posts manually.

Platform Draft state What Forge does What Justin does
YouTube Upload as privacyStatus=private, publishAt unset Upload file, set title/description/tags/thumbnail, leave private Reviews in YouTube Studio, sets to Public or Scheduled
Instagram Create media container (published=false), do NOT call media_publish Prepare caption, hashtags, media URL, create container Opens Creator Studio, reviews container, taps Publish
TikTok Use video.upload scope (inbox mode), NOT video.publish Upload to TikTok draft inbox Reviews in TikTok app, edits if needed, publishes

No Forge script, n8n workflow, or cron job calls a publish/go-live endpoint on any platform. Any code that would do so must be blocked at the design level, not just commented out.



1. YouTube Data API v3

1.1 What can be automated

Operation API method Quota cost
Upload video videos.insert 100 units
Update video metadata (title, description, tags, category) videos.update 50 units
Schedule video (set status.publishAt + status.privacyStatus=private) videos.update or during insert 50 units
Set thumbnail thumbnails.set 50 units
Set video privacy (public/private/unlisted) videos.update 50 units
Create/update/delete playlist playlists.insert/update/delete 50 units each
Add video to playlist playlistItems.insert 50 units
Fetch video metadata (title, views, likes, comments count, status) videos.list 1 unit
Fetch channel info channels.list 1 unit
Fetch playlist items playlistItems.list 1 unit
Search videos search.list 100 units
List, insert, update, delete comments comments.* 1 unit read / 50 units write
Upload captions captions.insert 400 units
Update captions captions.update 450 units
Set watermarks watermarks.set/unset 50 units each
Get video rating videos.getRating 1 unit

Scheduling mechanics: Set status.privacyStatus=private and status.publishAt to an ISO 8601 future timestamp during videos.insert or videos.update. YouTube flips public at that time automatically. No processing delay at go-live. If publishAt is in the past the video publishes immediately.

Analytics: Channel and video performance data lives in a separate API: YouTube Analytics API v2 (not Data API v3). It provides views, watch time, revenue, audience retention, traffic sources, demographics. Access via youtubeAnalytics.reports.query. Also separate: YouTube Reporting API for bulk export jobs (CSV). Both are free, both require OAuth.

1.2 OAuth 2.0 scopes

All scopes resolve under https://www.googleapis.com/auth/:

Scope (shorthand) Full URI Grants
youtube ...auth/youtube Full account management
youtube.force-ssl ...auth/youtube.force-ssl Read/write/delete videos, ratings, comments, captions (most operations)
youtube.readonly ...auth/youtube.readonly Read-only view of account
youtube.upload ...auth/youtube.upload Upload videos only
youtubepartner ...auth/youtubepartner Partner assets and associated content
youtubepartner-channel-audit ...auth/youtubepartner-channel-audit Private channel audit data (partner program only)

Minimum viable scopes for JWVR pipeline: - Upload + schedule: youtube.upload + youtube.force-ssl - Analytics: add youtube.readonly for Data API metadata reads; enable YouTube Analytics API separately under same credentials - Comment moderation: youtube.force-ssl

Auth flow: Standard OAuth 2.0 with refresh token. Server-side flow (authorization code + PKCE). Tokens stored in ~/.forge-secrets/youtube.env. Refresh tokens do not expire unless revoked or unused for 6 months.

1.3 Quota system

  • Default: 10,000 units per day per Google Cloud project
  • Resets at midnight Pacific Time
  • Quota is per project, not per API key. Multiple keys in one project share the pool.
  • Every request (including invalid ones) costs at least 1 unit.
  • search.list is the quota killer at 100 units. Avoid using it for known channel IDs; use videos.list with explicit IDs instead (1 unit).
  • Quota increase: submit the YouTube API Services Audit and Quota Extension Form. Approval requires demonstrated usage and policy compliance.

Budget math for a JWVR upload-and-schedule workflow (per video): - 1x videos.insert = 100 units - 1x thumbnails.set = 50 units - 1x playlistItems.insert = 50 units - 1x videos.update (description tweak) = 50 units - Total per publish: ~250 units = ~40 publishes before quota exhaustion

At 2 uploads/week that is well within budget. Analytics polling (1 unit per videos.list call) adds negligible cost.

1.4 Rate limits

Beyond daily quota, YouTube applies a concurrent request cap ("Queries per minute per user") that cannot be increased via the standard form. In practice this only bites batch scrapers. For Forge's single-channel use case it is not a concern.

1.5 What CANNOT be done via API

These features are Studio-only or simply not exposed:

Feature Status
Community posts (create/read/delete) Not available via any official API endpoint
Enable/disable monetization on a video Not available. VideoMonetizationDetails is readable in some partner contexts but not settable
Set ad formats (skippable, bumper, etc.) Not available
Super Thanks Not available
Channel membership management (pricing, perks) Member resource is readable; membership configuration not writable
Premiere scheduling Not available. Upload + publishAt creates a scheduled video, not a Premiere with countdown
Live stream scheduling Use YouTube Live Streaming API (separate API), not Data API v3
YouTube Shorts-specific metadata Shorts are uploaded as standard videos; the short format is inferred from aspect ratio and duration
End screens / Cards Not available
Channel sections (homepage layout) Not available

2. Instagram Graph API

2.1 Account requirements

  • Business or Creator account required. Personal accounts cannot use the Graph API for publishing or insights.
  • Must be connected to a Facebook Page (Business Login path) or use Instagram Login (new Business Login API introduced July 2024).
  • Basic Display API was shut down December 4, 2024. Any legacy integration using it is dead. There is no longer a separate "personal account read" API.

For Nova Design and Gus Outdoor Co: Both brands should operate Instagram Business accounts. This is a prerequisite for all automatable actions.

2.2 Content publishing capabilities

Content type Supported Notes
Single image (JPEG) Yes JPEG only; PNG not supported
Single video Yes Up to 90 seconds; some accounts capped at 60s depending on rollout phase
Reels Yes media_type=REELS; portrait (9:16) recommended; up to 90s
Carousel (up to 10 items) Yes Mix of images and videos; counts as 1 post against rate limit
Stories (image or video) Yes Business accounts only
Text-only posts No Not supported
Shopping product tags No Not supported via API

Media hosting requirement: Media files must be on publicly accessible HTTPS servers at the time of container creation. URLs cannot be local. Pattern: upload to Forge's rclone-mounted Google Drive public share or a CDN, then pass the URL to the API.

2.3 Scheduling

Native scheduling is supported. Workflow:

  1. POST to /{ig-user-id}/media with published=false and scheduled_publish_time=<unix_timestamp>. Window: 10 minutes to 30 days in the future.
  2. The endpoint returns a container ID.
  3. At the scheduled time, Meta publishes automatically.

To publish immediately instead: POST to /{ig-user-id}/media_publish with the container ID (omit scheduled_publish_time).

2.4 Analytics endpoints

Account-level (GET /{ig-user-id}/insights): - Reach, impressions, profile views, follower count, online followers by hour - Period options: day, week, month, lifetime - Data retained for up to 90 days

Post/media-level (GET /{ig-media-id}/insights): - Reach, impressions, engagement (likes + comments + saves), video views (Reels only), saves, shares - Period: lifetime only for media insights

Deprecated as of January 8, 2025 (Graph API v21+): - video_views for non-Reels content - email_contacts, website_clicks, phone_call_clicks, text_message_clicks (time series) - profile_views (time series)

Check rate limit headroom: GET /{ig-user-id}/content_publishing_limit returns current 24-hour post count.

2.5 OAuth scopes and token types

For Instagram Business Login (new July 2024 path, simpler): - instagram_business_basic - instagram_business_content_publish - instagram_business_manage_comments - instagram_business_manage_messages - instagram_business_manage_insights (requires Meta app review)

For Facebook Login for Business (older, more complex but deeper integration): - instagram_basic - instagram_content_publish - instagram_manage_comments - instagram_manage_insights - pages_read_engagement - pages_show_list

Token types: - Short-lived user access token: ~1 hour - Long-lived user access token: 60 days (exchange short-lived via server-side call with app secret) - System user access token: never expires (Meta Business Suite, recommended for production automations)

Recommended for Forge: System user access token stored in ~/.forge-secrets/instagram.env per brand. Requires Meta Business Manager setup. Token never expires, no refresh dance.

2.6 Rate limits

Limit Value
API requests 200 requests per hour per Instagram account
Published posts 100 API-published posts per 24-hour moving window (some sources show 25 for feed posts specifically; the conservative limit to plan against is 25 feed posts/day)
Container creation Multiple containers can exist; only published posts count against the cap
Rate limit check GET /{ig-user-id}/content_publishing_limit

HTTP 429 returned when limits exceeded.


3. TikTok Content Posting API

3.1 Account and developer requirements

  • Personal accounts are not eligible. You must be registered as a business or developer entity on TikTok for Developers.
  • An unaudited API client can upload content, but all posts are restricted to private viewing. To publish publicly, the app must pass TikTok's audit.
  • Audit process: Submit app for production review with a demo video, privacy policy URL, and data handling description. Timeline: 5-10 business days. Fastest approvals (3-5 days) go to clear use cases with complete documentation.

3.2 Direct Post vs. Upload-to-Inbox

Mode Behavior Use case
Direct Post (video.publish scope) Posts immediately (or queued to Forge cron for scheduled publish) Marketing automation, scheduled brand posts
Upload to Inbox (video.upload scope) Content lands in creator's TikTok draft inbox for manual review before publishing Creator-review workflows, sensitive content

TikTok's API does not support native future-timestamp scheduling. To schedule a post for a specific time, implement a cron job in Forge that triggers the Direct Post flow at the target time. This is the standard pattern.

3.3 Required OAuth scopes

Scope What it does Special approval needed?
user.info.basic Read avatar and display name No
user.info.stats Read follower count, likes, video count No
video.upload Upload to creator draft inbox Requires production approval
video.publish Direct post to profile Requires production approval
video.list Read public video metadata No
research.data.basic Access public data for research Requires vetted researcher status

Both video.upload and video.publish require app-level approval from TikTok before users can authorize them.

3.4 Video specifications

Parameter Requirement
Format MP4 (H.264 recommended), WebM
Resolution Minimum 540x960px; recommended 1080x1920px (9:16 portrait)
File size 10GB max (128MB in sandbox)
Duration Up to 10 minutes for established accounts; 60 seconds for new/low-trust accounts; max API-reported cap is 300 seconds
Audio AAC stereo, 44.1-48 kHz
Caption 2,200 characters max
Hashtags Up to 30 per post

3.5 Rate limits

Endpoint type Limit
Post initialization (/v2/post/publish/video/init/) 6 requests per minute per access_token
Status check (/v2/post/publish/status/fetch/) 30 requests per minute per access_token
General query endpoints (user info, video query, video list) 600 requests per minute per token
Daily upload cap ~15 posts per day per creator account (shared across all API clients using that account)

HTTP 429 returned on breach. Headers X-RateLimit-Remaining and X-RateLimit-Reset are available for backoff logic.

3.6 Analytics

TikTok's native analytics (views, likes, comments, shares, follower growth) are accessible via the Research API and the Video Query API but require separate scope approvals. For day-to-day Forge use, video.list + user.info.stats provides enough signal for a post-performance tracker without the Research API approval hurdle.


4. Forge Integration Approach

4.1 YouTube (JWVR channel)

Recommended: Direct Python client, with n8n for trigger/notify only.

Rationale: YouTube OAuth uses server-side refresh tokens stored in ~/.forge-secrets/youtube.env. The Forge Python pattern (forge_google_calendar.py, forge_gdrive_*.py) already handles Google OAuth directly. Adding a forge_youtube_client.py follows the same pattern. n8n has a YouTube node but it does not expose the full videos.insert metadata surface needed for scheduling, thumbnail setting, and playlist assignment in one call.

Workflow design (draft-only):

Telegram coordinator bot
  → /stage-youtube skill or coordinator intent
    → forge_youtube_client.py
        video.insert (upload as privacyStatus=private, no publishAt)
        thumbnails.set
        playlistItems.insert (to target playlist)
        → Telegram notify: "Draft ready in YouTube Studio: <title>"
    → analytics poller (cron, daily)
        youtube_analytics_report.query (views, watch time, revenue)
        → write to Notion JWVR analytics DB

What Forge never does: sets status.privacyStatus=public or sets status.publishAt. Justin opens YouTube Studio, reviews the private upload, then schedules or publishes manually.

Auth storage: ~/.forge-secrets/youtube.env with keys YOUTUBE_CLIENT_ID, YOUTUBE_CLIENT_SECRET, YOUTUBE_REFRESH_TOKEN. Refresh token is per-channel, generated via one-time OAuth consent flow.

n8n role (optional): Trigger upload workflow from n8n schedule node; call scripts/n8n/call.sh youtube-publish <payload> webhook pattern to kick off Python script. Keeps scheduling centralized in n8n but execution in Python.

Quota strategy: One GCP project per Forge (not per brand). With JWVR's current volume (1-2 uploads/week), 10,000 units/day is ample. No quota increase request needed initially. Do not use search.list in any automated poller; use explicit video ID lookups.

4.2 Instagram (Nova Design + Gus Outdoor Co)

Recommended: n8n workflow for posting, Python client for analytics pulls.

Rationale: n8n has a mature Instagram node that handles OAuth token management, media container creation, and publish calls. The multi-step container-then-publish flow maps naturally to n8n's node chain. For analytics (which require custom date range queries), a lightweight Python client is more flexible than n8n expression gymnastics.

Staging workflow (n8n, draft-only):

n8n Webhook trigger (from coordinator bot)
  → HTTP Request: create media container (/{ig-user-id}/media)
      params: image_url/video_url, caption (no scheduled_publish_time)
      published=false
  → Wait for container processing (polling loop)
  → Telegram notify: "Instagram container ready for review: <container_id>"
  [STOP. Do NOT call media_publish.]

Justin receives the Telegram notification and publishes from Creator Studio or the app. Tag each n8n workflow forge + stage. Name convention: stage-instagram-photo, stage-instagram-reel.

Note: Instagram media containers without a published call expire after 24 hours. Forge must create the container only when Justin is ready to review and publish within that window, not as a pre-schedule days in advance.

Analytics workflow (Python):

cron (weekly, Sunday)
  → forge_instagram_analytics.py
      GET /{ig-user-id}/media → list recent post IDs
      GET /{media-id}/insights for each
      write summary to Notion brand analytics DB or daily log

Auth storage: One env file per brand. ~/.forge-secrets/instagram-nova.env and ~/.forge-secrets/instagram-gus.env. Both store INSTAGRAM_SYSTEM_USER_TOKEN (non-expiring system user token from Meta Business Manager) plus INSTAGRAM_USER_ID.

Media hosting: Upload source images/videos to Google Drive public share via forge_gdrive_write.py, get public URL, pass to Instagram container creation. Avoids any local server requirement.

Rate limit guard: Add a check against /{ig-user-id}/content_publishing_limit at the top of every n8n post workflow. If quota_usage >= 20, send Telegram warn and abort. This avoids hitting the 25/day cap silently.

4.3 TikTok (Nova Design + Gus Outdoor Co, future)

Recommended: Python client only. No n8n.

Rationale: TikTok's posting flow requires a multi-step chunked upload protocol with status polling. n8n's HTTP Request node can handle it but the error handling and retry logic for a 10-step upload chain is painful in n8n. A dedicated forge_tiktok_client.py wraps the full init-upload-check-publish cycle cleanly.

Staging workflow (draft-only):

Telegram coordinator
  → forge_tiktok_client.py
      POST /v2/post/publish/video/init/ (chunk_size mode, upload_url)
      PUT <upload_url> (chunked video upload)
      GET /v2/post/publish/status/fetch/ (poll until SEND_TO_USER_INBOX status)
      → Telegram notify: "TikTok draft in your inbox: <title>"

Uses video.upload scope (inbox/draft mode), not video.publish. Content lands in Justin's TikTok draft inbox. He reviews in the TikTok app and publishes manually. Forge never calls the publish endpoint.

Auth storage: ~/.forge-secrets/tiktok.env with TIKTOK_CLIENT_KEY, TIKTOK_CLIENT_SECRET, TIKTOK_ACCESS_TOKEN, TIKTOK_REFRESH_TOKEN. TikTok access tokens expire per their OAuth 2.0 spec; the client must handle refresh before each request.

Prerequisite: Developer account registration + production app approval for video.publish scope must happen before this is buildable. Estimated lead time: 1-2 weeks including review.

n8n role: Receive a Telegram or scheduler trigger, call a webhook that invokes forge_tiktok_client.py via the standard scripts/n8n/call.sh outbound pattern. Same pattern as other Forge Python clients triggered from n8n.

4.4 Summary recommendation table

Platform Forge action Draft state Auth pattern
YouTube (JWVR) Python client: upload + metadata Private upload in YouTube Studio OAuth refresh token in ~/.forge-secrets/youtube.env
Instagram (Nova Design) n8n: create container only Unpublished container (24h window) System user token in ~/.forge-secrets/instagram-nova.env
Instagram (Gus Outdoor Co) n8n: create container only Unpublished container (24h window) System user token in ~/.forge-secrets/instagram-gus.env
TikTok (Nova/Gus) Python client: upload to inbox TikTok draft inbox OAuth refresh token in ~/.forge-secrets/tiktok.env

Forge stops before any publish/go-live API call on every platform. Justin publishes from the native app or studio.

  1. YouTube client - fewest approval hurdles, biggest JWVR impact. GCP project already exists (reuse for social APIs). OAuth consent screen setup, scope request, one-time token generation.
  2. Instagram posting (n8n) - Meta Business Manager setup, system user token generation, n8n workflow for one brand (Nova Design), clone for Gus Outdoor Co.
  3. Instagram analytics (Python) - bolt-on after posting is stable.
  4. TikTok - requires developer registration and 5-10 day audit wait. Start the approval process while building YouTube and Instagram, then implement once approved.

5. Quick Reference: Limits at a Glance

Platform Daily post limit Requests/hour Scheduling Analytics
YouTube No hard per-day limit; 10,000 quota units/day total Not published separately; project quota governs Native (publishAt timestamp) Separate API (YouTube Analytics API v2)
Instagram 25-100 feed posts / 24h 200 requests/hour per account Native (scheduled_publish_time UNIX timestamp, 10min-30 days out) Built into Graph API (/insights endpoints)
TikTok ~15 posts/day per creator account 6 init requests/min; 600 query requests/min Not native; implement cron layer Research API (requires approval); basic stats via user.info.stats

[Claude Code]