{
  "openapi": "3.0.1",
  "info": {
    "title": "Upload-Post API",
    "description": "Upload-Post is a unified social media API that allows you to upload videos, photos, text, and documents to 22 social media platforms (TikTok, Instagram, LinkedIn, YouTube, Facebook, X/Twitter, Threads, Pinterest, Bluesky, Reddit, Discord, Telegram, WordPress and more) with a single API call. Features include scheduling, queue system, async uploads, FFmpeg media processing, analytics, webhooks, and white-label user management.",
    "version": "1.0.0",
    "contact": {
      "name": "Upload-Post Support",
      "url": "https://upload-post.com"
    },
    "license": {
      "name": "Proprietary",
      "url": "https://upload-post.com/terms"
    }
  },
  "servers": [
    {
      "url": "https://api.upload-post.com/api",
      "description": "Production server"
    }
  ],
  "tags": [
    {
      "name": "Content Upload",
      "description": "Upload video, photo, text, and document content to social media platforms."
    },
    {
      "name": "Upload Management",
      "description": "Check upload status, view history, and manage scheduled posts."
    },
    {
      "name": "Queue System",
      "description": "Configure and preview the automatic post queue."
    },
    {
      "name": "Platform Integration",
      "description": "Retrieve platform-specific data: Facebook pages, LinkedIn pages, Pinterest boards, Reddit posts, and analytics."
    },
    {
      "name": "User Management",
      "description": "Create, list, get, and delete user profiles."
    },
    {
      "name": "Authentication",
      "description": "Verify API keys, generate and validate JWT tokens for white-label integration."
    },
    {
      "name": "FFmpeg Editor",
      "description": "Process and transform media using FFmpeg commands on Upload-Post infrastructure."
    },
    {
      "name": "Webhooks",
      "description": "Configure real-time webhook and Telegram notifications for upload events."
    },
    {
      "name": "Instagram Interactions",
      "description": "Retrieve Instagram media, comments, conversations, and send direct messages or private replies."
    }
  ],
  "security": [
    {
      "ApiKeyAuth": []
    }
  ],
  "paths": {
    "/upload": {
      "post": {
        "operationId": "uploadVideo",
        "summary": "Upload video",
        "description": "Upload a video to one or more social media platforms. Supports TikTok, Instagram, LinkedIn, YouTube, Facebook, X (Twitter), Threads, Pinterest, Bluesky, Reddit, Discord, and Telegram. Supports immediate, async, scheduled, and queued uploads.",
        "tags": ["Content Upload"],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": ["user", "platform[]", "video"],
                "properties": {
                  "user": {
                    "type": "string",
                    "description": "User profile identifier."
                  },
                  "platform[]": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/VideoPlatformEnum"
                    },
                    "description": "Platform(s) to upload to."
                  },
                  "video": {
                    "type": "string",
                    "format": "binary",
                    "description": "The video file to upload (binary file) or a public video URL."
                  },
                  "title": {
                    "type": "string",
                    "description": "Default title/caption of the video. Required for YouTube and Reddit; optional for all other platforms. Platform-specific titles override this."
                  },
                  "description": {
                    "type": "string",
                    "description": "Optional extended text used on LinkedIn commentary, Facebook descriptions, YouTube descriptions, and Pinterest notes. Ignored elsewhere."
                  },
                  "scheduled_date": {
                    "type": "string",
                    "format": "date-time",
                    "description": "ISO-8601 date/time to schedule publishing (e.g., '2025-12-31T23:45:00Z'). Must be in the future (≤365 days). Omit for immediate upload. Cannot be used with `add_to_queue`."
                  },
                  "timezone": {
                    "type": "string",
                    "description": "IANA timezone identifier (e.g., 'Europe/Madrid', 'America/New_York'). If provided, `scheduled_date` is interpreted in this timezone. Defaults to UTC."
                  },
                  "async_upload": {
                    "type": "boolean",
                    "description": "If true, returns immediately with a `request_id` and processes in the background. If false but upload takes >59s, automatically switches to async.",
                    "default": false
                  },
                  "add_to_queue": {
                    "type": "boolean",
                    "description": "If true, automatically schedules the post to the next available queue slot. Cannot be used with `scheduled_date`.",
                    "default": false
                  },
                  "first_comment": {
                    "type": "string",
                    "description": "Automatically post a first comment after publishing. Supported on Instagram, Facebook, Threads, Bluesky, Reddit, X, YouTube, and LinkedIn."
                  },
                  "instagram_first_comment": {
                    "type": "string",
                    "description": "[Instagram] Platform-specific first comment. Overrides `first_comment`."
                  },
                  "facebook_first_comment": {
                    "type": "string",
                    "description": "[Facebook] Platform-specific first comment. Overrides `first_comment`."
                  },
                  "x_first_comment": {
                    "type": "string",
                    "description": "[X] Platform-specific first comment. Overrides `first_comment`."
                  },
                  "threads_first_comment": {
                    "type": "string",
                    "description": "[Threads] Platform-specific first comment. Overrides `first_comment`."
                  },
                  "youtube_first_comment": {
                    "type": "string",
                    "description": "[YouTube] Platform-specific first comment. Overrides `first_comment`."
                  },
                  "reddit_first_comment": {
                    "type": "string",
                    "description": "[Reddit] Platform-specific first comment. Overrides `first_comment`."
                  },
                  "bluesky_first_comment": {
                    "type": "string",
                    "description": "[Bluesky] Platform-specific first comment. Overrides `first_comment`."
                  },
                  "linkedin_first_comment": {
                    "type": "string",
                    "description": "[LinkedIn] Platform-specific first comment. Overrides `first_comment`."
                  },
                  "first_comment_media[]": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "binary"
                    },
                    "description": "Image files to attach to the first comment as inline images. Currently supported on Reddit. Not available for scheduled or queued posts."
                  },
                  "instagram_title": {
                    "type": "string",
                    "description": "[Instagram] Specific title. Fallbacks to `title`."
                  },
                  "facebook_title": {
                    "type": "string",
                    "description": "[Facebook] Specific title. Fallbacks to `title`. Ignored if facebook_media_type is STORIES."
                  },
                  "tiktok_title": {
                    "type": "string",
                    "description": "[TikTok] Specific title. Fallbacks to `title`."
                  },
                  "linkedin_title": {
                    "type": "string",
                    "description": "[LinkedIn] Specific title. Fallbacks to `title`."
                  },
                  "x_title": {
                    "type": "string",
                    "description": "[X] Specific title. Fallbacks to `title`."
                  },
                  "youtube_title": {
                    "type": "string",
                    "description": "[YouTube] Specific title. Fallbacks to `title`."
                  },
                  "pinterest_title": {
                    "type": "string",
                    "description": "[Pinterest] Specific title. Fallbacks to `title`."
                  },
                  "threads_title": {
                    "type": "string",
                    "description": "[Threads] Specific title. Fallbacks to `title`."
                  },
                  "threads_topic_tag": {
                    "type": "string",
                    "description": "[Threads] A topic tag for the post (1-50 characters). Cannot contain periods (.) or ampersands (&). One tag per post.",
                    "maxLength": 50
                  },
                  "bluesky_title": {
                    "type": "string",
                    "description": "[Bluesky] Specific text. Fallbacks to `title`."
                  },
                  "reddit_title": {
                    "type": "string",
                    "description": "[Reddit] Specific title. Fallbacks to `title`."
                  },
                  "privacy_level": {
                    "$ref": "#/components/schemas/TikTokPrivacyLevel"
                  },
                  "disable_duet": {
                    "type": "boolean",
                    "description": "[TikTok] Disable duet feature.",
                    "default": false
                  },
                  "disable_comment": {
                    "type": "boolean",
                    "description": "[TikTok] Disable comments.",
                    "default": false
                  },
                  "disable_stitch": {
                    "type": "boolean",
                    "description": "[TikTok] Disable stitch feature.",
                    "default": false
                  },
                  "post_mode": {
                    "$ref": "#/components/schemas/TikTokPostMode"
                  },
                  "cover_timestamp": {
                    "type": "integer",
                    "description": "[TikTok] Timestamp in milliseconds for video cover.",
                    "default": 1000
                  },
                  "brand_content_toggle": {
                    "type": "boolean",
                    "description": "[TikTok] Set to true for paid partnerships promoting third-party brands.",
                    "default": false
                  },
                  "brand_organic_toggle": {
                    "type": "boolean",
                    "description": "[TikTok] Set to true when promoting the creator's own business.",
                    "default": false
                  },
                  "is_aigc": {
                    "type": "boolean",
                    "description": "[TikTok] Indicates if content is AI-generated.",
                    "default": false
                  },
                  "media_type": {
                    "$ref": "#/components/schemas/InstagramVideoMediaType"
                  },
                  "share_mode": {
                    "$ref": "#/components/schemas/InstagramShareMode"
                  },
                  "share_to_feed": {
                    "type": "boolean",
                    "description": "[Instagram] Whether to share to feed (only for regular Reels, not Trial Reels).",
                    "default": true
                  },
                  "collaborators": {
                    "type": "string",
                    "description": "[Instagram] Comma-separated list of collaborator usernames. Not available for Trial Reels."
                  },
                  "cover_url": {
                    "type": "string",
                    "description": "[Instagram] URL for custom video cover. Alternative to cover_image binary upload."
                  },
                  "cover_image": {
                    "type": "string",
                    "format": "binary",
                    "description": "[Instagram] Binary cover image for Reels (JPEG, max 8MB). If both cover_image and cover_url are provided, cover_url takes precedence."
                  },
                  "audio_name": {
                    "type": "string",
                    "description": "[Instagram] Name of the audio track embedded in your video (Reels only)."
                  },
                  "user_tags": {
                    "type": "string",
                    "description": "[Instagram] Comma-separated list of user tags."
                  },
                  "location_id": {
                    "type": "string",
                    "description": "[Instagram] Instagram location ID."
                  },
                  "is_ai_generated": {
                    "type": "boolean",
                    "description": "Cross-platform AI-disclosure flag. Set to `true` to self-disclose the content as AI-generated. On Instagram (Reels, photos, carousels) it is forwarded as Meta's `is_ai_generated` and shows the \"AI info\" label under the account name; the label cannot be added or removed after publishing. On TikTok it maps to `is_aigc`, on YouTube to `containsSyntheticMedia` and on X to `made_with_ai`; a platform-specific value takes precedence over this alias. See the AI Content Labeling guide.",
                    "default": false
                  },
                  "thumb_offset": {
                    "type": "string",
                    "description": "[Instagram] Timestamp offset for video thumbnail."
                  },
                  "linkedin_description": {
                    "type": "string",
                    "description": "[LinkedIn] Sent as the LinkedIn commentary. If omitted, reuses `title`."
                  },
                  "visibility": {
                    "$ref": "#/components/schemas/LinkedInVisibility"
                  },
                  "target_linkedin_page_id": {
                    "type": "string",
                    "description": "[LinkedIn] LinkedIn page ID to upload to an organization page."
                  },
                  "youtube_description": {
                    "type": "string",
                    "description": "[YouTube] Populates snippet.description. If omitted, uses `title`."
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "[YouTube] Array of video tags."
                  },
                  "categoryId": {
                    "type": "string",
                    "description": "[YouTube] Video category ID.",
                    "default": "22"
                  },
                  "privacyStatus": {
                    "$ref": "#/components/schemas/YouTubePrivacyStatus"
                  },
                  "embeddable": {
                    "type": "boolean",
                    "description": "[YouTube] Whether video is embeddable.",
                    "default": true
                  },
                  "license": {
                    "type": "string",
                    "description": "[YouTube] Video license ('youtube' or 'creativeCommon').",
                    "default": "youtube",
                    "enum": ["youtube", "creativeCommon"]
                  },
                  "publicStatsViewable": {
                    "type": "boolean",
                    "description": "[YouTube] Whether public stats are viewable.",
                    "default": true
                  },
                  "thumbnail": {
                    "type": "string",
                    "format": "binary",
                    "description": "[YouTube] Custom thumbnail image file (JPG/PNG/GIF/BMP, max 2MB). Not supported for Shorts."
                  },
                  "thumbnail_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "[YouTube] Alternative: provide thumbnail as a public URL."
                  },
                  "selfDeclaredMadeForKids": {
                    "type": "boolean",
                    "description": "[YouTube] Explicit declaration for COPPA compliance.",
                    "default": false
                  },
                  "containsSyntheticMedia": {
                    "type": "boolean",
                    "description": "[YouTube] Declaration that video contains AI-generated content.",
                    "default": false
                  },
                  "defaultLanguage": {
                    "type": "string",
                    "description": "[YouTube] Language of title and description (BCP-47 code, e.g., 'es', 'en')."
                  },
                  "defaultAudioLanguage": {
                    "type": "string",
                    "description": "[YouTube] Language of the video audio (BCP-47 code, e.g., 'es-ES', 'en-US')."
                  },
                  "allowedCountries": {
                    "type": "string",
                    "description": "[YouTube] Comma-separated ISO 3166-1 alpha-2 country codes where the video is allowed. Cannot be used with `blockedCountries`."
                  },
                  "blockedCountries": {
                    "type": "string",
                    "description": "[YouTube] Comma-separated ISO 3166-1 alpha-2 country codes where the video is blocked. Cannot be used with `allowedCountries`."
                  },
                  "hasPaidProductPlacement": {
                    "type": "boolean",
                    "description": "[YouTube] Declaration of paid product placements for FTC compliance.",
                    "default": false
                  },
                  "recordingDate": {
                    "type": "string",
                    "format": "date-time",
                    "description": "[YouTube] Recording date (ISO 8601, e.g., '2024-01-15T14:30:00Z')."
                  },
                  "facebook_page_id": {
                    "type": "string",
                    "description": "[Facebook] Facebook Page ID where the video will be posted. Required for Facebook. Auto-detected if only one page is connected."
                  },
                  "facebook_description": {
                    "type": "string",
                    "description": "[Facebook] Sent as video description. Ignored for STORIES."
                  },
                  "facebook_media_type": {
                    "$ref": "#/components/schemas/FacebookVideoMediaType"
                  },
                  "video_state": {
                    "type": "string",
                    "description": "[Facebook] Desired state of the video.",
                    "default": "PUBLISHED",
                    "enum": ["DRAFT", "PUBLISHED"]
                  },
                  "x_long_text_as_post": {
                    "type": "boolean",
                    "description": "[X] When true, publishes long text as a single post instead of a thread.",
                    "default": false
                  },
                  "reply_settings": {
                    "$ref": "#/components/schemas/XReplySettings"
                  },
                  "geo_place_id": {
                    "type": "string",
                    "description": "[X] Place ID for geographic location."
                  },
                  "nullcast": {
                    "type": "boolean",
                    "description": "[X] Whether to publish without broadcasting (promoted-only posts).",
                    "default": false
                  },
                  "for_super_followers_only": {
                    "type": "boolean",
                    "description": "[X] Tweet exclusive for super followers.",
                    "default": false
                  },
                  "community_id": {
                    "type": "string",
                    "description": "[X] Community ID for posting to specific communities."
                  },
                  "share_with_followers": {
                    "type": "boolean",
                    "description": "[X] Share community post with followers.",
                    "default": false
                  },
                  "direct_message_deep_link": {
                    "type": "string",
                    "description": "[X] Link to take conversation to private Direct Message."
                  },
                  "tagged_user_ids": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "[X] Array of user IDs to tag in the media (max 10)."
                  },
                  "reply_to_id": {
                    "type": "string",
                    "description": "[X] ID of the tweet to reply to."
                  },
                  "exclude_reply_user_ids": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "[X] User IDs to exclude from replying. Requires `reply_to_id`."
                  },
                  "pinterest_description": {
                    "type": "string",
                    "description": "[Pinterest] Pin description. If omitted, reuses `title`."
                  },
                  "pinterest_board_id": {
                    "type": "string",
                    "description": "[Pinterest] Pinterest board ID to publish to. Required when platform includes pinterest."
                  },
                  "pinterest_alt_text": {
                    "type": "string",
                    "description": "[Pinterest] Alt text for the video."
                  },
                  "pinterest_link": {
                    "type": "string",
                    "description": "[Pinterest] Destination link for the video Pin."
                  },
                  "pinterest_cover_image_url": {
                    "type": "string",
                    "description": "[Pinterest] URL of an image to use as the video cover."
                  },
                  "pinterest_cover_image_content_type": {
                    "type": "string",
                    "description": "[Pinterest] Content type of the cover image (e.g., image/jpeg)."
                  },
                  "pinterest_cover_image_data": {
                    "type": "string",
                    "description": "[Pinterest] Base64 encoded cover image data."
                  },
                  "pinterest_cover_image_key_frame_time": {
                    "type": "integer",
                    "description": "[Pinterest] Time in milliseconds of the video frame to use as cover."
                  },
                  "subreddit": {
                    "type": "string",
                    "description": "[Reddit] Name of the subreddit (without 'r/'). Required when platform includes reddit."
                  },
                  "flair_id": {
                    "type": "string",
                    "description": "[Reddit] ID of the flair to apply to the post."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Upload completed synchronously or async processing started.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/SyncUploadResponse"
                    },
                    {
                      "$ref": "#/components/schemas/AsyncUploadResponse"
                    }
                  ]
                }
              }
            }
          },
          "202": {
            "description": "Post scheduled or queued successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/ScheduledUploadResponse"
                    },
                    {
                      "$ref": "#/components/schemas/QueuedUploadResponse"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/upload_photos": {
      "post": {
        "operationId": "uploadPhotos",
        "summary": "Upload photos",
        "description": "Upload photos (and mixed media for Instagram/Threads carousels) to social media platforms. Supports TikTok, Instagram, LinkedIn, Facebook, X (Twitter), Threads, Pinterest, Bluesky, Reddit, Discord, and Telegram.",
        "tags": ["Content Upload"],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": ["user", "platform[]", "photos[]"],
                "properties": {
                  "user": {
                    "type": "string",
                    "description": "User profile identifier."
                  },
                  "platform[]": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/PhotoPlatformEnum"
                    },
                    "description": "Platform(s) to upload to."
                  },
                  "photos[]": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "binary"
                    },
                    "description": "Array of photo files. Instagram & Threads also accept videos for mixed carousels."
                  },
                  "title": {
                    "type": "string",
                    "description": "Default title/caption. Required for Reddit; optional for all other platforms. Platform-specific titles override this."
                  },
                  "description": {
                    "type": "string",
                    "description": "Optional extended text used on TikTok photo descriptions, LinkedIn commentary, Facebook descriptions, Pinterest notes, and Reddit bodies. Ignored elsewhere."
                  },
                  "scheduled_date": {
                    "type": "string",
                    "format": "date-time",
                    "description": "ISO-8601 date/time to schedule publishing. Must be in the future (≤365 days). Cannot be used with `add_to_queue`."
                  },
                  "timezone": {
                    "type": "string",
                    "description": "IANA timezone identifier. Defaults to UTC."
                  },
                  "async_upload": {
                    "type": "boolean",
                    "description": "If true, returns immediately with a `request_id`.",
                    "default": false
                  },
                  "add_to_queue": {
                    "type": "boolean",
                    "description": "If true, schedules to next available queue slot. Cannot be used with `scheduled_date`.",
                    "default": false
                  },
                  "first_comment": {
                    "type": "string",
                    "description": "Automatically post a first comment after publishing."
                  },
                  "instagram_first_comment": {
                    "type": "string",
                    "description": "[Instagram] Platform-specific first comment."
                  },
                  "facebook_first_comment": {
                    "type": "string",
                    "description": "[Facebook] Platform-specific first comment."
                  },
                  "x_first_comment": {
                    "type": "string",
                    "description": "[X] Platform-specific first comment."
                  },
                  "threads_first_comment": {
                    "type": "string",
                    "description": "[Threads] Platform-specific first comment."
                  },
                  "reddit_first_comment": {
                    "type": "string",
                    "description": "[Reddit] Platform-specific first comment."
                  },
                  "bluesky_first_comment": {
                    "type": "string",
                    "description": "[Bluesky] Platform-specific first comment."
                  },
                  "first_comment_media[]": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "binary"
                    },
                    "description": "One or more image files to attach to the first comment. Currently supported on Reddit. Not available for scheduled or queued posts."
                  },
                  "instagram_title": {
                    "type": "string",
                    "description": "[Instagram] Specific title."
                  },
                  "facebook_title": {
                    "type": "string",
                    "description": "[Facebook] Specific title."
                  },
                  "tiktok_title": {
                    "type": "string",
                    "description": "[TikTok] Specific title."
                  },
                  "linkedin_title": {
                    "type": "string",
                    "description": "[LinkedIn] Specific title."
                  },
                  "x_title": {
                    "type": "string",
                    "description": "[X] Specific title."
                  },
                  "pinterest_title": {
                    "type": "string",
                    "description": "[Pinterest] Specific title."
                  },
                  "threads_title": {
                    "type": "string",
                    "description": "[Threads] Specific title."
                  },
                  "threads_topic_tag": {
                    "type": "string",
                    "description": "[Threads] A topic tag for the post (1-50 characters). Cannot contain periods (.) or ampersands (&). One tag per post.",
                    "maxLength": 50
                  },
                  "bluesky_title": {
                    "type": "string",
                    "description": "[Bluesky] Specific text."
                  },
                  "reddit_title": {
                    "type": "string",
                    "description": "[Reddit] Specific title."
                  },
                  "linkedin_description": {
                    "type": "string",
                    "description": "[LinkedIn] Post commentary."
                  },
                  "visibility": {
                    "type": "string",
                    "description": "[LinkedIn] Visibility setting.",
                    "default": "PUBLIC",
                    "enum": ["PUBLIC"]
                  },
                  "target_linkedin_page_id": {
                    "type": "string",
                    "description": "[LinkedIn] LinkedIn page ID to upload to an organization."
                  },
                  "facebook_page_id": {
                    "type": "string",
                    "description": "[Facebook] Facebook Page ID. Required when platform includes facebook. Auto-detected if only one page is connected."
                  },
                  "facebook_media_type": {
                    "$ref": "#/components/schemas/FacebookPhotoMediaType"
                  },
                  "x_long_text_as_post": {
                    "type": "boolean",
                    "description": "[X] When true, publishes long text as a single post.",
                    "default": false
                  },
                  "reply_settings": {
                    "$ref": "#/components/schemas/XReplySettings"
                  },
                  "geo_place_id": {
                    "type": "string",
                    "description": "[X] Place ID for geographic location."
                  },
                  "nullcast": {
                    "type": "boolean",
                    "description": "[X] Publish without broadcasting.",
                    "default": false
                  },
                  "for_super_followers_only": {
                    "type": "boolean",
                    "description": "[X] Exclusive for super followers.",
                    "default": false
                  },
                  "community_id": {
                    "type": "string",
                    "description": "[X] Community ID."
                  },
                  "share_with_followers": {
                    "type": "boolean",
                    "description": "[X] Share community post with followers.",
                    "default": false
                  },
                  "direct_message_deep_link": {
                    "type": "string",
                    "description": "[X] Direct Message deep link."
                  },
                  "tagged_user_ids": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "[X] User IDs to tag in photos (max 10)."
                  },
                  "reply_to_id": {
                    "type": "string",
                    "description": "[X] ID of the tweet to reply to."
                  },
                  "exclude_reply_user_ids": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "[X] User IDs to exclude from replying."
                  },
                  "post_mode": {
                    "$ref": "#/components/schemas/TikTokPostMode"
                  },
                  "privacy_level": {
                    "$ref": "#/components/schemas/TikTokPrivacyLevel"
                  },
                  "auto_add_music": {
                    "type": "boolean",
                    "description": "[TikTok] Automatically add background music to photos.",
                    "default": false
                  },
                  "disable_comment": {
                    "type": "boolean",
                    "description": "[TikTok] Disable comments.",
                    "default": false
                  },
                  "brand_content_toggle": {
                    "type": "boolean",
                    "description": "[TikTok] Paid partnership promoting third-party brands.",
                    "default": false
                  },
                  "brand_organic_toggle": {
                    "type": "boolean",
                    "description": "[TikTok] Promoting the creator's own business.",
                    "default": false
                  },
                  "photo_cover_index": {
                    "type": "integer",
                    "description": "[TikTok] Index (0-based) of the photo to use as cover/thumbnail.",
                    "default": 0
                  },
                  "tiktok_description": {
                    "type": "string",
                    "description": "[TikTok] Description for photo posts."
                  },
                  "media_type": {
                    "$ref": "#/components/schemas/InstagramPhotoMediaType"
                  },
                  "collaborators": {
                    "type": "string",
                    "description": "[Instagram] Comma-separated collaborator usernames."
                  },
                  "user_tags": {
                    "type": "string",
                    "description": "[Instagram] Comma-separated user tags."
                  },
                  "location_id": {
                    "type": "string",
                    "description": "[Instagram] Instagram location ID."
                  },
                  "is_ai_generated": {
                    "type": "boolean",
                    "description": "Cross-platform AI-disclosure flag. Set to `true` to self-disclose the content as AI-generated. On Instagram (single photos and carousels) it is forwarded as Meta's `is_ai_generated` and shows the \"AI info\" label under the account name; for carousels it applies to the whole post. The label cannot be added or removed after publishing. On X it maps to `made_with_ai`. See the AI Content Labeling guide.",
                    "default": false
                  },
                  "pinterest_description": {
                    "type": "string",
                    "description": "[Pinterest] Pin description."
                  },
                  "pinterest_board_id": {
                    "type": "string",
                    "description": "[Pinterest] Board ID. Required when platform includes pinterest."
                  },
                  "pinterest_alt_text": {
                    "type": "string",
                    "description": "[Pinterest] Alt text for the image."
                  },
                  "pinterest_link": {
                    "type": "string",
                    "description": "[Pinterest] Destination link for the Pin."
                  },
                  "subreddit": {
                    "type": "string",
                    "description": "[Reddit] Subreddit name (without 'r/'). Required when platform includes reddit."
                  },
                  "flair_id": {
                    "type": "string",
                    "description": "[Reddit] Flair ID to apply."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Upload completed synchronously or async processing started.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/SyncUploadResponse"
                    },
                    {
                      "$ref": "#/components/schemas/AsyncUploadResponse"
                    }
                  ]
                }
              }
            }
          },
          "202": {
            "description": "Post scheduled or queued successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/ScheduledUploadResponse"
                    },
                    {
                      "$ref": "#/components/schemas/QueuedUploadResponse"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/upload_text": {
      "post": {
        "operationId": "uploadText",
        "summary": "Upload text post",
        "description": "Upload text-only posts to social media platforms. Supports X (Twitter), LinkedIn, Facebook, Threads, Reddit, Bluesky, Discord, and Telegram. Automatically creates threads on X (>280 chars), Threads (>500 chars), and Bluesky (>300 chars).",
        "tags": ["Content Upload"],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": ["user", "platform[]", "title"],
                "properties": {
                  "user": {
                    "type": "string",
                    "description": "User profile identifier."
                  },
                  "platform[]": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/TextPlatformEnum"
                    },
                    "description": "Platform(s) to upload to."
                  },
                  "title": {
                    "type": "string",
                    "description": "Default text content for the post."
                  },
                  "description": {
                    "type": "string",
                    "description": "Optional extended body used on Reddit (becomes post text). Ignored elsewhere."
                  },
                  "scheduled_date": {
                    "type": "string",
                    "format": "date-time",
                    "description": "ISO-8601 date/time to schedule publishing. Cannot be used with `add_to_queue`."
                  },
                  "timezone": {
                    "type": "string",
                    "description": "IANA timezone identifier. Defaults to UTC."
                  },
                  "async_upload": {
                    "type": "boolean",
                    "description": "If true, returns immediately with a `request_id`.",
                    "default": false
                  },
                  "add_to_queue": {
                    "type": "boolean",
                    "description": "If true, schedules to next queue slot.",
                    "default": false
                  },
                  "first_comment": {
                    "type": "string",
                    "description": "Automatically post a first comment after publishing."
                  },
                  "facebook_first_comment": {
                    "type": "string",
                    "description": "[Facebook] Platform-specific first comment."
                  },
                  "x_first_comment": {
                    "type": "string",
                    "description": "[X] Platform-specific first comment."
                  },
                  "threads_first_comment": {
                    "type": "string",
                    "description": "[Threads] Platform-specific first comment."
                  },
                  "reddit_first_comment": {
                    "type": "string",
                    "description": "[Reddit] Platform-specific first comment."
                  },
                  "bluesky_first_comment": {
                    "type": "string",
                    "description": "[Bluesky] Platform-specific first comment."
                  },
                  "first_comment_media[]": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "binary"
                    },
                    "description": "One or more image files to attach to the first comment. Currently supported on Reddit. Not available for scheduled or queued posts."
                  },
                  "linkedin_title": {
                    "type": "string",
                    "description": "[LinkedIn] Specific text for LinkedIn."
                  },
                  "x_title": {
                    "type": "string",
                    "description": "[X] Specific text for X."
                  },
                  "facebook_title": {
                    "type": "string",
                    "description": "[Facebook] Specific text for Facebook."
                  },
                  "threads_title": {
                    "type": "string",
                    "description": "[Threads] Specific text for Threads."
                  },
                  "threads_topic_tag": {
                    "type": "string",
                    "description": "[Threads] A topic tag for the post (1-50 characters). Cannot contain periods (.) or ampersands (&). One tag per post.",
                    "maxLength": 50
                  },
                  "bluesky_title": {
                    "type": "string",
                    "description": "[Bluesky] Specific text for Bluesky."
                  },
                  "target_linkedin_page_id": {
                    "type": "string",
                    "description": "[LinkedIn] LinkedIn page ID to post to an organization page."
                  },
                  "x_long_text_as_post": {
                    "type": "boolean",
                    "description": "[X] When true, long text is published as a single post.",
                    "default": false
                  },
                  "reply_settings": {
                    "$ref": "#/components/schemas/XReplySettings"
                  },
                  "quote_tweet_id": {
                    "type": "string",
                    "description": "[X] ID of the tweet to quote. Mutually exclusive with `card_uri`, `poll_options`, and `direct_message_deep_link`."
                  },
                  "geo_place_id": {
                    "type": "string",
                    "description": "[X] Place ID for geographic location."
                  },
                  "nullcast": {
                    "type": "boolean",
                    "description": "[X] Publish without broadcasting.",
                    "default": false
                  },
                  "for_super_followers_only": {
                    "type": "boolean",
                    "description": "[X] Exclusive for super followers.",
                    "default": false
                  },
                  "community_id": {
                    "type": "string",
                    "description": "[X] Community ID."
                  },
                  "share_with_followers": {
                    "type": "boolean",
                    "description": "[X] Share community post with followers.",
                    "default": false
                  },
                  "direct_message_deep_link": {
                    "type": "string",
                    "description": "[X] Direct Message deep link. Mutually exclusive with `card_uri`, `quote_tweet_id`, and `poll_options`."
                  },
                  "card_uri": {
                    "type": "string",
                    "description": "[X] Card URI for Twitter Cards/ads. Mutually exclusive with `quote_tweet_id`, `direct_message_deep_link`, and `poll_options`."
                  },
                  "poll_options": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "[X] Array of poll options (2-4 options, max 25 chars each). Mutually exclusive with `card_uri`, `quote_tweet_id`, and `direct_message_deep_link`."
                  },
                  "poll_duration": {
                    "type": "integer",
                    "description": "[X] Poll duration in minutes (5-10080). Requires `poll_options`.",
                    "default": 1440,
                    "minimum": 5,
                    "maximum": 10080
                  },
                  "poll_reply_settings": {
                    "type": "string",
                    "description": "[X] Who can reply to poll. Requires `poll_options`.",
                    "enum": ["following", "mentionedUsers", "subscribers", "verified"]
                  },
                  "reply_to_id": {
                    "type": "string",
                    "description": "[X/Bluesky] ID or URL of the post to reply to."
                  },
                  "exclude_reply_user_ids": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "[X] User IDs to exclude from replying. Requires `reply_to_id`."
                  },
                  "facebook_page_id": {
                    "type": "string",
                    "description": "[Facebook] Facebook Page ID. Required when platform includes facebook. Auto-detected if only one page is connected."
                  },
                  "facebook_link_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "[Facebook] Optional URL for link preview in text posts. Overrides generic `link_url` for Facebook."
                  },
                  "link_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Generic URL to include as a link preview card. Works for LinkedIn, Bluesky, Facebook, and Reddit. Platform-specific parameters (`linkedin_link_url`, `bluesky_link_url`, `facebook_link_url`, `reddit_link_url`) take priority."
                  },
                  "linkedin_link_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "[LinkedIn] Optional URL for link preview card in text posts. Overrides generic `link_url` for LinkedIn."
                  },
                  "bluesky_link_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "[Bluesky] Optional URL for external embed link preview in text posts. Overrides generic `link_url` for Bluesky."
                  },
                  "reddit_link_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "[Reddit] URL for creating a Reddit link post with a URL preview card. Overrides generic `link_url` for Reddit."
                  },
                  "threads_long_text_as_post": {
                    "type": "boolean",
                    "description": "[Threads] If true, long text is a single post. If false, creates a thread if >500 chars.",
                    "default": false
                  },
                  "subreddit": {
                    "type": "string",
                    "description": "[Reddit] Subreddit name (without 'r/'). Required when platform includes reddit."
                  },
                  "flair_id": {
                    "type": "string",
                    "description": "[Reddit] Flair template ID."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Upload completed synchronously or async processing started.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/SyncUploadResponse"
                    },
                    {
                      "$ref": "#/components/schemas/AsyncUploadResponse"
                    }
                  ]
                }
              }
            }
          },
          "202": {
            "description": "Post scheduled or queued successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/ScheduledUploadResponse"
                    },
                    {
                      "$ref": "#/components/schemas/QueuedUploadResponse"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/upload_document": {
      "post": {
        "operationId": "uploadDocument",
        "summary": "Upload document",
        "description": "Upload documents (PDF, PPT, PPTX, DOC, DOCX) to LinkedIn as native document posts displayed as carousels/viewers. Only LinkedIn is supported.",
        "tags": ["Content Upload"],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": ["user", "platform[]", "document", "title"],
                "properties": {
                  "user": {
                    "type": "string",
                    "description": "User profile identifier."
                  },
                  "platform[]": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": ["linkedin"]
                    },
                    "description": "Must be [\"linkedin\"]. Only LinkedIn supports document uploads."
                  },
                  "document": {
                    "type": "string",
                    "format": "binary",
                    "description": "The document file (PDF, PPT, PPTX, DOC, DOCX) or a public URL. Max 100MB, 300 pages."
                  },
                  "title": {
                    "type": "string",
                    "description": "Document title displayed on the post."
                  },
                  "description": {
                    "type": "string",
                    "description": "Post commentary/text that appears above the document."
                  },
                  "visibility": {
                    "$ref": "#/components/schemas/LinkedInVisibility"
                  },
                  "target_linkedin_page_id": {
                    "type": "string",
                    "description": "LinkedIn page ID to post to a company page instead of personal profile."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Document uploaded successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentUploadResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/uploadposts/status": {
      "get": {
        "operationId": "getUploadStatus",
        "summary": "Get upload status",
        "description": "Check the status of asynchronous uploads (via `request_id`) or scheduled posts (via `job_id`). At least one parameter must be provided.",
        "tags": ["Upload Management"],
        "parameters": [
          {
            "name": "request_id",
            "in": "query",
            "description": "The request identifier returned by upload endpoints when `async_upload=true`.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "job_id",
            "in": "query",
            "description": "The job identifier returned by scheduled posts (with `scheduled_date`).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Status retrieved successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UploadStatusResponse"
                }
              }
            }
          },
          "400": {
            "description": "Missing both request_id and job_id.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "request_id or job_id is required"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/uploadposts/history": {
      "get": {
        "operationId": "getUploadHistory",
        "summary": "Get upload history",
        "description": "Retrieve a paginated list of past uploads across all platforms, ordered most recent first.",
        "tags": ["Upload Management"],
        "parameters": [
          {
            "$ref": "#/components/parameters/PageParam"
          },
          {
            "$ref": "#/components/parameters/LimitParam"
          }
        ],
        "responses": {
          "200": {
            "description": "Upload history retrieved successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UploadHistoryResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/uploadposts/schedule": {
      "get": {
        "operationId": "listScheduledPosts",
        "summary": "List scheduled posts",
        "description": "Retrieve all pending scheduled posts for the authenticated user.",
        "tags": ["Upload Management"],
        "responses": {
          "200": {
            "description": "Scheduled posts retrieved successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "scheduled_posts": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ScheduledPost"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/uploadposts/schedule/{job_id}": {
      "delete": {
        "operationId": "cancelScheduledPost",
        "summary": "Cancel a scheduled post",
        "description": "Cancel and delete a scheduled post and its associated assets.",
        "tags": ["Upload Management"],
        "parameters": [
          {
            "$ref": "#/components/parameters/JobIdPathParam"
          }
        ],
        "responses": {
          "200": {
            "description": "Scheduled post cancelled successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string",
                      "example": "Job abc123 cancelled and assets deleted."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      },
      "patch": {
        "operationId": "editScheduledPost",
        "summary": "Edit a scheduled post",
        "description": "Update the scheduled date, title, or caption of a scheduled post.",
        "tags": ["Upload Management"],
        "parameters": [
          {
            "$ref": "#/components/parameters/JobIdPathParam"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "scheduled_date": {
                    "type": "string",
                    "format": "date-time",
                    "description": "New ISO-8601 date/time in UTC. Must be in the future and within 1 year."
                  },
                  "title": {
                    "type": "string",
                    "description": "New post title/caption."
                  },
                  "caption": {
                    "type": "string",
                    "description": "New caption/description."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Scheduled post updated successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "job_id": {
                      "type": "string"
                    },
                    "scheduled_date": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "title": {
                      "type": "string"
                    },
                    "caption": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/uploadposts/queue/settings": {
      "get": {
        "operationId": "getQueueSettings",
        "summary": "Get queue settings",
        "description": "Retrieve the current queue configuration (timezone, time slots, active days) for a profile.",
        "tags": ["Queue System"],
        "parameters": [
          {
            "$ref": "#/components/parameters/ProfileQueryParam"
          }
        ],
        "responses": {
          "200": {
            "description": "Queue settings retrieved successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QueueSettingsResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      },
      "post": {
        "operationId": "updateQueueSettings",
        "summary": "Update queue settings",
        "description": "Update the queue configuration (timezone, time slots, active days) for a profile.",
        "tags": ["Queue System"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["profile_username"],
                "properties": {
                  "profile_username": {
                    "type": "string",
                    "description": "The profile to update settings for."
                  },
                  "timezone": {
                    "type": "string",
                    "description": "IANA timezone (e.g., 'Europe/London')."
                  },
                  "slots": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/QueueSlot"
                    },
                    "description": "Array of slot objects. Max 24 slots.",
                    "maxItems": 24
                  },
                  "days_of_week": {
                    "type": "array",
                    "items": {
                      "type": "integer",
                      "minimum": 0,
                      "maximum": 6
                    },
                    "description": "Active days: 0=Monday, 1=Tuesday, ..., 6=Sunday."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Queue settings updated successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QueueSettingsResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/uploadposts/queue/preview": {
      "get": {
        "operationId": "getQueuePreview",
        "summary": "Preview queue slots",
        "description": "Preview the next upcoming queue slots and their availability for a profile.",
        "tags": ["Queue System"],
        "parameters": [
          {
            "$ref": "#/components/parameters/ProfileQueryParam"
          },
          {
            "name": "count",
            "in": "query",
            "description": "Number of slots to return.",
            "schema": {
              "type": "integer",
              "default": 10,
              "maximum": 50
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Queue preview retrieved successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QueuePreviewResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/uploadposts/queue/next-slot": {
      "get": {
        "operationId": "getNextQueueSlot",
        "summary": "Get next available queue slot",
        "description": "Get the next available queue slot for a profile.",
        "tags": ["Queue System"],
        "parameters": [
          {
            "$ref": "#/components/parameters/ProfileQueryParam"
          }
        ],
        "responses": {
          "200": {
            "description": "Next slot retrieved successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NextSlotResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/analytics/{profile_username}": {
      "get": {
        "operationId": "getAnalytics",
        "summary": "Get analytics",
        "description": "Retrieve analytics data for a user profile across one or more social media platforms. Returns metrics like followers, views, impressions, reach, and time series data. Note: Instagram's API renamed 'impressions' to 'views'; both fields are returned for compatibility.",
        "tags": ["Platform Integration"],
        "parameters": [
          {
            "name": "profile_username",
            "in": "path",
            "required": true,
            "description": "The unique username of the profile.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "platforms",
            "in": "query",
            "required": true,
            "description": "Comma-separated list of platforms: instagram, tiktok, linkedin, facebook, x, youtube, threads, pinterest, reddit, bluesky.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page_id",
            "in": "query",
            "description": "Required for Facebook analytics. The Facebook Page ID.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page_urn",
            "in": "query",
            "description": "LinkedIn only. Organization/company page URN or numeric ID to fetch analytics for. LinkedIn analytics are available only for organization/company pages you administer — personal profiles are not supported, because LinkedIn's API does not expose member-level analytics. If omitted, the first administered organization page is used.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Analytics data retrieved successfully. Response keys are platform names with platform-specific metrics.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AnalyticsResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/uploadposts/post-analytics/cached": {
      "get": {
        "operationId": "getCachedPostAnalytics",
        "summary": "Get cached per-post analytics",
        "description": "Replays per-post metrics that Upload-Post already fetched, instead of calling the social platforms again. Because it never touches the platforms during the request, it is NOT subject to the platform analytics rate limit of 100 requests / 5 minutes that applies to the live /uploadposts/post-analytics endpoints, and it is paginated — built for re-reading a large back catalogue. IMPORTANT: this is a write-through cache filled as a side effect of live reads. A post appears here only after it has been fetched at least once through a live per-post endpoint, and there is no background refresh — captured_at is the last time that post was read live. To refresh a post, call the live endpoint for it.",
        "tags": ["Platform Integration"],
        "parameters": [
          {
            "name": "user",
            "in": "query",
            "required": true,
            "schema": { "type": "string" },
            "description": "The profile_username of the profile to read snapshots for."
          },
          {
            "name": "platform",
            "in": "query",
            "required": false,
            "schema": { "type": "string", "enum": ["instagram", "tiktok", "youtube", "facebook", "linkedin", "threads", "pinterest", "reddit"] },
            "description": "Restrict the result to a single platform. When omitted, all platforms are returned and the response echoes platform: null."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": { "type": "integer", "default": 50, "minimum": 1, "maximum": 200 },
            "description": "Number of posts per page. Defaults to 50, maximum 200."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": { "type": "string" },
            "description": "Opaque next-page token. Pass back exactly the value returned in next_cursor by the previous response. An invalid cursor returns 400."
          },
          {
            "name": "since",
            "in": "query",
            "required": false,
            "schema": { "type": "string", "format": "date" },
            "description": "Start of the date range in YYYY-MM-DD format. Defaults to 30 days ago."
          },
          {
            "name": "until",
            "in": "query",
            "required": false,
            "schema": { "type": "string", "format": "date" },
            "description": "End of the date range in YYYY-MM-DD format. Defaults to today."
          }
        ],
        "responses": {
          "200": {
            "description": "Cached post analytics retrieved successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean" },
                    "profile_username": { "type": "string" },
                    "platform": { "type": "string", "nullable": true, "description": "The platform filter applied, or null when none was requested." },
                    "since": { "type": "string", "format": "date" },
                    "until": { "type": "string", "format": "date" },
                    "source": { "type": "string", "example": "snapshot_cache", "description": "Always 'snapshot_cache' — a marker that these numbers came from the daily snapshot, not a live platform call." },
                    "posts": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "post_id": { "type": "string", "description": "The post's native ID on the platform." },
                          "platform": { "type": "string" },
                          "profile_username": { "type": "string" },
                          "date": { "type": "string", "format": "date", "description": "Snapshot date this row belongs to." },
                          "captured_at": { "type": "string", "format": "date-time", "description": "The last time this post was fetched live from the platform. Use it to judge freshness; nothing refreshes it in the background." },
                          "metrics": { "type": "object", "additionalProperties": true, "description": "Metrics captured for this post. Keys vary per platform (e.g. YouTube returns views, likes, comments, favorites; TikTok adds reach, favorites, new_followers, profile_views, full_video_watched_rate, average_time_watched, total_time_watched, is_ai_generated, the per-second retention curve, impression_sources and audience_types). What the platform did not report is omitted, never zeroed. Read the keys present rather than assuming a fixed schema." },
                          "post_url": { "type": "string", "nullable": true },
                          "media_type": { "type": "string", "nullable": true },
                          "upload_timestamp": { "type": "string", "format": "date-time", "nullable": true }
                        }
                      }
                    },
                    "limit": { "type": "integer", "description": "The effective page size applied." },
                    "next_cursor": { "type": "string", "nullable": true, "description": "Token to pass as 'cursor' on the next request. Null when there are no more pages." },
                    "has_more": { "type": "boolean" }
                  }
                }
              }
            }
          },
          "400": { "description": "Missing user, invalid platform, malformed since/until date, or an invalid cursor." },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "500": { "$ref": "#/components/responses/InternalServerError" }
        }
      }
    },
    "/uploadposts/facebook/pages": {
      "get": {
        "operationId": "getFacebookPages",
        "summary": "Get Facebook pages",
        "description": "Retrieve Facebook page IDs associated with user profiles. Use the page_id for posting to Facebook pages.",
        "tags": ["Platform Integration"],
        "parameters": [
          {
            "name": "profile",
            "in": "query",
            "description": "Profile username. If not specified, returns all pages for your account.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Facebook pages retrieved successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "pages": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/FacebookPage"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/uploadposts/linkedin/pages": {
      "get": {
        "operationId": "getLinkedInPages",
        "summary": "Get LinkedIn pages",
        "description": "Retrieve LinkedIn company pages associated with the authenticated user's accounts. Use the page ID for posting to LinkedIn organization pages.",
        "tags": ["Platform Integration"],
        "parameters": [
          {
            "name": "profile",
            "in": "query",
            "description": "Profile username. If omitted, returns pages from all connected LinkedIn accounts.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "LinkedIn pages retrieved successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "pages": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/LinkedInPage"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/uploadposts/pinterest/boards": {
      "get": {
        "operationId": "getPinterestBoards",
        "summary": "Get Pinterest boards",
        "description": "Retrieve all Pinterest boards (public and secret) from a connected Pinterest account. Use the board ID for posting Pins.",
        "tags": ["Platform Integration"],
        "parameters": [
          {
            "name": "profile",
            "in": "query",
            "description": "Profile username. If omitted, uses the first connected Pinterest account.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Pinterest boards retrieved successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "boards": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/PinterestBoard"
                      }
                    },
                    "pinterest_account_used": {
                      "type": "string",
                      "description": "Pinterest username of the account used."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/uploadposts/reddit/detailed-posts": {
      "get": {
        "operationId": "getRedditDetailedPosts",
        "summary": "Get Reddit detailed posts",
        "description": "Retrieve detailed posts from a Reddit account connected to a profile, including complete media information. Supports automatic pagination up to 2000 posts.",
        "tags": ["Platform Integration"],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "profile_username",
            "in": "query",
            "required": true,
            "description": "Username of the profile with a connected Reddit account.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Reddit posts retrieved successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "posts": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/RedditPost"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/uploadposts/tiktok/music/trending": {
      "get": {
        "operationId": "getTiktokTrendingMusic",
        "summary": "Get TikTok trending music",
        "description": "Trending tracks from TikTok's Commercial Music Library, to soundtrack a TikTok post. Pass the returned `id` as `tiktok_music_id` on an upload — not `commercial_music_id`, which TikTok rejects on public posts.",
        "tags": ["Platform Integration"],
        "parameters": [
          { "$ref": "#/components/parameters/TikTokProfile" },
          { "$ref": "#/components/parameters/TikTokMusicGenre" },
          { "$ref": "#/components/parameters/TikTokMusicCountry" },
          { "$ref": "#/components/parameters/TikTokMusicDateRange" }
        ],
        "responses": {
          "200": {
            "description": "Trending tracks retrieved successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "genre": { "type": "string", "example": "ALL" },
                    "country_code": { "type": "string", "example": "US" },
                    "date_range": { "type": "string", "example": "7DAY" },
                    "cached": {
                      "type": "boolean",
                      "description": "False when this request had to fetch the chart from TikTok."
                    },
                    "tracks": {
                      "type": "array",
                      "items": { "$ref": "#/components/schemas/TikTokMusicTrack" }
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/TikTokReconnectRequired" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "409": { "$ref": "#/components/responses/TikTokReauthRequired" },
          "502": { "$ref": "#/components/responses/TikTokUpstreamError" }
        }
      }
    },
    "/uploadposts/tiktok/music/search": {
      "get": {
        "operationId": "searchTiktokMusic",
        "summary": "Search TikTok music",
        "description": "Search the Commercial Music Library by song title or artist. TikTok has **no** music search endpoint, so this searches the trending charts Upload-Post caches per genre/country/period, not TikTok's whole catalogue: a song that is not trending in the chart you query will not be found. Matching is case- and accent-insensitive and every word must match.",
        "tags": ["Platform Integration"],
        "parameters": [
          { "$ref": "#/components/parameters/TikTokProfile" },
          {
            "name": "q",
            "in": "query",
            "description": "Text matched against titles and artists. Omit it to get the chart in trending order.",
            "schema": { "type": "string", "maxLength": 80 }
          },
          { "$ref": "#/components/parameters/TikTokMusicGenre" },
          { "$ref": "#/components/parameters/TikTokMusicCountry" },
          { "$ref": "#/components/parameters/TikTokMusicDateRange" },
          {
            "name": "limit",
            "in": "query",
            "description": "Maximum tracks to return.",
            "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 }
          }
        ],
        "responses": {
          "200": {
            "description": "Matching tracks, ranked by relevance.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "query": { "type": "string", "example": "bad bunny" },
                    "genre": { "type": "string" },
                    "country_code": { "type": "string" },
                    "date_range": { "type": "string" },
                    "limit": { "type": "integer" },
                    "total": {
                      "type": "integer",
                      "description": "How many tracks matched before `limit` was applied."
                    },
                    "tracks": {
                      "type": "array",
                      "items": { "$ref": "#/components/schemas/TikTokMusicTrack" }
                    },
                    "catalog": {
                      "type": "object",
                      "description": "What the search actually ran against, so you can tell \"no results\" apart from \"the cache is still warming up\".",
                      "properties": {
                        "tracks_indexed": { "type": "integer" },
                        "genres_indexed": { "type": "array", "items": { "type": "string" } },
                        "cached": { "type": "boolean" }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/TikTokReconnectRequired" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "409": { "$ref": "#/components/responses/TikTokReauthRequired" },
          "502": { "$ref": "#/components/responses/TikTokUpstreamError" }
        }
      }
    },
    "/uploadposts/tiktok/locations": {
      "get": {
        "operationId": "getTiktokLocations",
        "summary": "Search TikTok locations",
        "description": "Search TikTok's place database for the `location_id` needed to tag a location on a post. TikTok requires the id and the name together: send them as `tiktok_location_id` + `tiktok_location_name`. Returns at most 20 matches; an empty array means TikTok found no match, and is a 200 rather than an error.",
        "tags": ["Platform Integration"],
        "parameters": [
          { "$ref": "#/components/parameters/TikTokProfile" },
          {
            "name": "q",
            "in": "query",
            "required": true,
            "description": "Free-text search query (venue, brand or place name).",
            "schema": { "type": "string", "maxLength": 100 }
          }
        ],
        "responses": {
          "200": {
            "description": "Matching places.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "query": { "type": "string" },
                    "locations": {
                      "type": "array",
                      "items": { "$ref": "#/components/schemas/TikTokLocation" }
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/TikTokReconnectRequired" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "409": { "$ref": "#/components/responses/TikTokReauthRequired" },
          "502": { "$ref": "#/components/responses/TikTokUpstreamError" }
        }
      }
    },
    "/uploadposts/tiktok/settings": {
      "get": {
        "operationId": "getTiktokPublishingSettings",
        "summary": "Get TikTok publishing settings",
        "description": "What the connected TikTok account is allowed to publish. TikTok narrows the four `privacy_level` values per account — a private account has no `PUBLIC_TO_EVERYONE` — and asking for one the account does not have fails the upload with `error_code: \"tiktok_privacy_unavailable\"`. Read `privacy_level_options` and offer only those. This matters most on photo posts, where TikTok requires a privacy level and Upload-Post defaults to `PUBLIC_TO_EVERYONE`.",
        "tags": ["Platform Integration"],
        "parameters": [{ "$ref": "#/components/parameters/TikTokProfile" }],
        "responses": {
          "200": {
            "description": "Account publishing settings.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "privacy_level_options": {
                      "type": "array",
                      "description": "The privacy levels THIS account may publish with.",
                      "items": {
                        "type": "string",
                        "enum": ["PUBLIC_TO_EVERYONE", "MUTUAL_FOLLOW_FRIENDS", "FOLLOWER_OF_CREATOR", "SELF_ONLY"]
                      },
                      "example": ["FOLLOWER_OF_CREATOR", "MUTUAL_FOLLOW_FRIENDS", "SELF_ONLY"]
                    },
                    "max_video_post_duration_sec": {
                      "type": "integer",
                      "description": "Longest video the account can publish, in seconds.",
                      "example": 600
                    },
                    "comment_disabled": {
                      "type": "boolean",
                      "description": "True when the account has comments turned off account-wide."
                    },
                    "duet_disabled": { "type": "boolean" },
                    "stitch_disabled": { "type": "boolean" }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/TikTokReconnectRequired" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "409": { "$ref": "#/components/responses/TikTokReauthRequired" },
          "502": { "$ref": "#/components/responses/TikTokUpstreamError" }
        }
      }
    },
    "/uploadposts/audience": {
      "get": {
        "operationId": "getAudienceInsights",
        "summary": "Audience insights (any platform)",
        "description": "Who follows a connected account, when they are online, what they tap on the profile and how it compares to its category. One endpoint per QUESTION with a `platform`, exactly like /uploadposts/comments and /uploadposts/post-analytics — never one URL per network. Only `tiktok` answers today; any other value returns 400 with error_code `platform_not_supported` and a message naming the supported ones. `activity_by_hour` (24 entries, followers online per hour, summed over the window) is the field to build a publishing schedule on. The window is trimmed to what the platform accepts — at most 60 days, always ending before today — so read the `range` that comes back, not the one you sent. Requires the `profile_analytics` capability.",
        "tags": [
          "Platform Integration"
        ],
        "parameters": [
          {
            "name": "platform",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "tiktok"
              ]
            },
            "description": "The network to ask. Only tiktok answers today."
          },
          {
            "name": "user",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Profile username as configured in Upload-Post. `profile` is accepted as an alias."
          },
          {
            "name": "start_date",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "First day of the window, ISO YYYY-MM-DD. Defaults to end_date minus 29 days."
          },
          {
            "name": "end_date",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Last day of the window, ISO YYYY-MM-DD. Must be earlier than today. Defaults to yesterday."
          },
          {
            "name": "benchmark_category",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "PERSONAL_BLOG",
                "MACHINERY_AND_EQUIPMENT",
                "HEALTH_AND_WELLNESS",
                "PETS",
                "AUTOMOTIVE_AND_TRANSPORTATION",
                "EDUCATION_AND_TRAINING",
                "FOOD_AND_BEVERAGE",
                "REAL_ESTATE",
                "ELECTRONICS",
                "SHOPPING_AND_RETAIL",
                "PUBLIC_ADMINISTRATION",
                "ART_AND_CRAFTS",
                "BABY",
                "GAMING",
                "RESTAURANTS_AND_BARS",
                "HOME_FURNITURE_AND_APPLIANCES",
                "PROFESSIONAL_SERVICES",
                "SOFTWARE_AND_APPS",
                "MEDIA_AND_ENTERTAINMENT",
                "BEAUTY",
                "SPORTS_FITNESS_AND_OUTDOORS",
                "CLOTHING_AND_ACCESSORIES",
                "TRAVEL_AND_TOURISM",
                "OTHERS",
                "FINANCE_AND_INVESTING"
              ]
            },
            "description": "Adds the `benchmark` block: the averages of that content category. Case-insensitive; the full list also comes back in `benchmark_categories` on every call."
          }
        ],
        "responses": {
          "200": {
            "description": "Audience insights.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "platform": {
                      "type": "string",
                      "example": "tiktok"
                    },
                    "range": {
                      "type": "object",
                      "description": "The window actually queried, after trimming. Render this one, not your input.",
                      "properties": {
                        "start_date": {
                          "type": "string",
                          "format": "date"
                        },
                        "end_date": {
                          "type": "string",
                          "format": "date"
                        }
                      }
                    },
                    "audience": {
                      "type": "object",
                      "description": "Follower distribution. Every percentage is a fraction of 1.",
                      "properties": {
                        "countries": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "country": {
                                "type": "string",
                                "example": "ES"
                              },
                              "percentage": {
                                "type": "number",
                                "description": "Fraction of 1, not a number out of 100."
                              }
                            }
                          }
                        },
                        "cities": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "city": {
                                "type": "string",
                                "example": "Madrid"
                              },
                              "percentage": {
                                "type": "number",
                                "description": "Fraction of 1, not a number out of 100."
                              }
                            }
                          }
                        },
                        "ages": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "age": {
                                "type": "string",
                                "example": "25-34"
                              },
                              "percentage": {
                                "type": "number",
                                "description": "Fraction of 1, not a number out of 100."
                              }
                            }
                          }
                        },
                        "genders": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "gender": {
                                "type": "string",
                                "example": "female"
                              },
                              "percentage": {
                                "type": "number",
                                "description": "Fraction of 1, not a number out of 100."
                              }
                            }
                          }
                        }
                      }
                    },
                    "activity_by_hour": {
                      "type": "array",
                      "description": "24 entries, \"0\"-\"23\" in the account's local time, ordered numerically. Followers online in that hour, summed over the window.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "hour": {
                            "type": "string",
                            "example": "14"
                          },
                          "followers_online": {
                            "type": "integer",
                            "example": 1494
                          }
                        }
                      }
                    },
                    "followers_daily": {
                      "type": "array",
                      "description": "One row per day, oldest first.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "date": {
                            "type": "string",
                            "format": "date"
                          },
                          "total": {
                            "type": "integer",
                            "nullable": true
                          },
                          "new": {
                            "type": "integer",
                            "nullable": true
                          },
                          "lost": {
                            "type": "integer",
                            "nullable": true
                          }
                        }
                      }
                    },
                    "profile_actions": {
                      "type": "object",
                      "description": "Totals over the window for the profile's tappable elements. null means the platform reported nothing for this account — which is NOT the same fact as 0.",
                      "properties": {
                        "bio_link_clicks": {
                          "type": "integer",
                          "nullable": true,
                          "example": 318
                        },
                        "address_clicks": {
                          "type": "integer",
                          "nullable": true
                        },
                        "app_download_clicks": {
                          "type": "integer",
                          "nullable": true
                        },
                        "email_clicks": {
                          "type": "integer",
                          "nullable": true
                        },
                        "phone_number_clicks": {
                          "type": "integer",
                          "nullable": true
                        },
                        "lead_submissions": {
                          "type": "integer",
                          "nullable": true
                        }
                      }
                    },
                    "bio_description": {
                      "type": "string",
                      "nullable": true,
                      "description": "The account's current bio text."
                    },
                    "benchmark_categories": {
                      "type": "array",
                      "description": "The 25 values benchmark_category accepts. Always present, so a picker can be built without a second call.",
                      "items": {
                        "type": "string",
                        "enum": [
                          "PERSONAL_BLOG",
                          "MACHINERY_AND_EQUIPMENT",
                          "HEALTH_AND_WELLNESS",
                          "PETS",
                          "AUTOMOTIVE_AND_TRANSPORTATION",
                          "EDUCATION_AND_TRAINING",
                          "FOOD_AND_BEVERAGE",
                          "REAL_ESTATE",
                          "ELECTRONICS",
                          "SHOPPING_AND_RETAIL",
                          "PUBLIC_ADMINISTRATION",
                          "ART_AND_CRAFTS",
                          "BABY",
                          "GAMING",
                          "RESTAURANTS_AND_BARS",
                          "HOME_FURNITURE_AND_APPLIANCES",
                          "PROFESSIONAL_SERVICES",
                          "SOFTWARE_AND_APPS",
                          "MEDIA_AND_ENTERTAINMENT",
                          "BEAUTY",
                          "SPORTS_FITNESS_AND_OUTDOORS",
                          "CLOTHING_AND_ACCESSORIES",
                          "TRAVEL_AND_TOURISM",
                          "OTHERS",
                          "FINANCE_AND_INVESTING"
                        ]
                      }
                    },
                    "benchmark": {
                      "type": "object",
                      "description": "Only when benchmark_category was sent. Only the metrics the platform actually returned are present.",
                      "properties": {
                        "category": {
                          "type": "string",
                          "example": "SOFTWARE_AND_APPS"
                        },
                        "average_comments": {
                          "type": "number"
                        },
                        "average_engagement_rate": {
                          "type": "number",
                          "description": "Fraction of 1.",
                          "example": 0.0144
                        },
                        "average_follower_count": {
                          "type": "number"
                        },
                        "average_follower_growth": {
                          "type": "number"
                        },
                        "average_likes": {
                          "type": "number"
                        },
                        "average_shares": {
                          "type": "number"
                        },
                        "average_video_count": {
                          "type": "number"
                        },
                        "average_video_views": {
                          "type": "number"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/PlatformNotSupported"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/TikTokReauthRequired"
          },
          "502": {
            "$ref": "#/components/responses/TikTokUpstreamError"
          }
        }
      }
    },
    "/uploadposts/suggestions": {
      "get": {
        "operationId": "getSuggestions",
        "summary": "Hashtag and keyword suggestions (any platform)",
        "description": "What to tag a post with (`type=hashtags`) and what people search around a keyword (`type=keywords`). One endpoint per QUESTION with a `platform`, never one URL per network. Only `tiktok` answers today; any other value returns 400 with error_code `platform_not_supported`. `type=hashtags` needs the `profile_analytics` capability, which any recent connection has; `type=keywords` needs `trend_search`, which is granted only when the account is (re)connected.",
        "tags": [
          "Platform Integration"
        ],
        "parameters": [
          {
            "name": "platform",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "tiktok"
              ]
            },
            "description": "The network to ask. Only tiktok answers today."
          },
          {
            "name": "user",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Profile username as configured in Upload-Post. `profile` is accepted as an alias."
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "hashtags",
                "keywords"
              ],
              "default": "hashtags"
            },
            "description": "Which answer you want."
          },
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The seed keyword."
          },
          {
            "name": "country_code",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "ISO 3166-1 alpha-2 country to rank hashtag suggestions for, e.g. ES."
          },
          {
            "name": "language",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Language code for the hashtag suggestions, e.g. es."
          }
        ],
        "responses": {
          "200": {
            "description": "Suggestions.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "platform": {
                      "type": "string",
                      "example": "tiktok"
                    },
                    "type": {
                      "type": "string",
                      "example": "hashtags"
                    },
                    "query": {
                      "type": "string",
                      "example": "instant camera"
                    },
                    "hashtags": {
                      "type": "array",
                      "description": "Only for type=hashtags.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "name": {
                            "type": "string",
                            "description": "The tag WITHOUT the leading #.",
                            "example": "instantcamera"
                          },
                          "view_count": {
                            "type": "integer",
                            "format": "int64",
                            "description": "Lifetime views of content carrying the tag. Reaches 12 digits — parse as a 64-bit integer.",
                            "example": 128970043215
                          }
                        }
                      }
                    },
                    "keywords": {
                      "type": "array",
                      "description": "Only for type=keywords. Passed through as the platform returns it; treat each object as an open shape.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "keyword": {
                            "type": "string",
                            "example": "instant camera film"
                          },
                          "search_volume": {
                            "type": "integer",
                            "example": 61200
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/PlatformNotSupported"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/TikTokReauthRequired"
          },
          "502": {
            "$ref": "#/components/responses/TikTokUpstreamError"
          }
        }
      }
    },
    "/uploadposts/me": {
      "get": {
        "operationId": "getCurrentUser",
        "summary": "Get current user",
        "description": "Verify the validity of your API key and retrieve basic account information including email and subscription plan.",
        "tags": ["Authentication"],
        "responses": {
          "200": {
            "description": "API key is valid.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string",
                      "example": "Token is valid"
                    },
                    "email": {
                      "type": "string",
                      "format": "email",
                      "example": "user@example.com"
                    },
                    "plan": {
                      "type": "string",
                      "example": "Professional"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/uploadposts/users": {
      "post": {
        "operationId": "createUserProfile",
        "summary": "Create user profile",
        "description": "Create a new user profile linked to a user on your platform.",
        "tags": ["User Management"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["username"],
                "properties": {
                  "username": {
                    "type": "string",
                    "description": "A unique identifier for the user on your platform."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Profile created successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "profile": {
                      "$ref": "#/components/schemas/UserProfile"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "409": {
            "description": "A profile with this username already exists.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listUserProfiles",
        "summary": "List user profiles",
        "description": "Retrieve a list of all user profiles created under your API key.",
        "tags": ["User Management"],
        "responses": {
          "200": {
            "description": "Profiles retrieved successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "limit": {
                      "type": "integer",
                      "description": "Maximum profiles allowed by plan."
                    },
                    "plan": {
                      "type": "string",
                      "description": "Subscription plan."
                    },
                    "profiles": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/UserProfile"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      },
      "delete": {
        "operationId": "deleteUserProfile",
        "summary": "Delete user profile",
        "description": "Delete an existing user profile and its associated data (including social connections).",
        "tags": ["User Management"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["username"],
                "properties": {
                  "username": {
                    "type": "string",
                    "description": "The unique identifier of the profile to delete."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Profile deleted successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string",
                      "example": "Perfil eliminado correctamente"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/uploadposts/users/{username}": {
      "get": {
        "operationId": "getUserProfile",
        "summary": "Get a specific user profile",
        "description": "Retrieve information for a single user profile by username.",
        "tags": ["User Management"],
        "parameters": [
          {
            "name": "username",
            "in": "path",
            "required": true,
            "description": "The username of the profile to retrieve.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Profile retrieved successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "profile": {
                      "$ref": "#/components/schemas/UserProfile"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/uploadposts/users/generate-jwt": {
      "post": {
        "operationId": "generateJwt",
        "summary": "Generate JWT URL",
        "description": "Generate a secure, single-use URL containing a JWT. Users visit this URL to link their social media accounts. The JWT is valid for 48 hours.",
        "tags": ["Authentication"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["username"],
                "properties": {
                  "username": {
                    "type": "string",
                    "description": "The user profile identifier for which the JWT is generated."
                  },
                  "redirect_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "URL to redirect to after linking social accounts."
                  },
                  "logo_image": {
                    "type": "string",
                    "format": "uri",
                    "description": "URL to a logo image for branding the linking page."
                  },
                  "redirect_button_text": {
                    "type": "string",
                    "description": "Text for the redirect button after linking.",
                    "default": "Logout connection"
                  },
                  "connect_title": {
                    "type": "string",
                    "description": "Custom title for the connection page.",
                    "default": "Connect Social Media Accounts"
                  },
                  "connect_description": {
                    "type": "string",
                    "description": "Custom description for the connection page.",
                    "default": "Connect your social media accounts to manage your posts."
                  },
                  "platforms": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": ["tiktok", "instagram", "linkedin", "youtube", "facebook", "x", "threads", "discord", "telegram"]
                    },
                    "description": "Platforms to show for connection. Defaults to all supported platforms."
                  },
                  "show_calendar": {
                    "type": "boolean",
                    "description": "Whether to show the calendar view on the connection page.",
                    "default": true
                  },
                  "language": {
                    "type": "string",
                    "enum": ["en", "es", "de", "fr", "pt", "pl", "tr"],
                    "description": "Forces the connection page language for this profile. When omitted, the page auto-detects the visitor's browser language and falls back to English."
                  },
                  "ui_labels": {
                    "type": "object",
                    "nullable": true,
                    "additionalProperties": { "type": "string", "maxLength": 300 },
                    "maxProperties": 100,
                    "propertyNames": { "pattern": "^[a-zA-Z0-9_.]+$" },
                    "description": "Flat object of connect-page i18n dot-path keys mapped to replacement strings, for white-label text overrides beyond connect_title/connect_description/redirect_button_text. Max 100 entries; keys must match ^[a-zA-Z0-9_.]+$; values must be strings of at most 300 characters. Omitting the field leaves previously stored labels untouched; sending null or {} clears them. Returned inside the profile object by GET /uploadposts/users/validate-jwt. Keys refer to the connect page's own translation keys, so only override keys you have confirmed exist.",
                    "example": { "connect.connectButton": "Baglan", "connect.notConnected": "Bagli degil" }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "JWT URL generated successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "access_url": {
                      "type": "string",
                      "description": "Secure URL for the user to visit and link accounts."
                    },
                    "duration": {
                      "type": "string",
                      "description": "JWT validity period.",
                      "example": "48h"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/uploadposts/users/validate-jwt": {
      "get": {
        "operationId": "validateJwt",
        "summary": "Validate JWT",
        "description": "Validate a JWT token and return the associated profile details. Uses Bearer token authentication.",
        "tags": ["Authentication"],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Validation result. Returns profile if valid, or isValid=false if invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "success": {
                          "type": "boolean",
                          "example": true
                        },
                        "profile": {
                          "$ref": "#/components/schemas/UserProfile"
                        }
                      }
                    },
                    {
                      "type": "object",
                      "properties": {
                        "isValid": {
                          "type": "boolean",
                          "example": false
                        },
                        "reason": {
                          "type": "string",
                          "example": "Token expired or invalid signature"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/uploadposts/ffmpeg/jobs/upload": {
      "post": {
        "operationId": "createFfmpegJob",
        "summary": "Create FFmpeg job",
        "description": "Submit a media processing job using an FFmpeg command template. Supports single or multiple input files via multipart upload or JSON with URLs. Jobs are asynchronous — poll the status endpoint until finished.",
        "tags": ["FFmpeg Editor"],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": ["file", "full_command", "output_extension"],
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "Primary media file to process. Referenced as {input} or {input0}."
                  },
                  "file1": {
                    "type": "string",
                    "format": "binary",
                    "description": "Second input file. Referenced as {input1}."
                  },
                  "file2": {
                    "type": "string",
                    "format": "binary",
                    "description": "Third input file. Referenced as {input2}."
                  },
                  "full_command": {
                    "type": "string",
                    "description": "FFmpeg command template using {input}/{input0}, {input1}, etc. and {output} placeholders. Example: 'ffmpeg -y -i {input} -c:v libx264 -crf 23 {output}'"
                  },
                  "output_extension": {
                    "type": "string",
                    "description": "Desired output file extension (e.g., 'mp4', 'wav', 'mp3', 'mov', 'webm')."
                  },
                  "publish": {
                    "type": "boolean",
                    "description": "Whether to publish the result."
                  }
                }
              }
            },
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["files", "full_command", "output_extension"],
                "properties": {
                  "files": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uri"
                    },
                    "description": "Array of input file URLs. Referenced as {input0}, {input1}, etc."
                  },
                  "full_command": {
                    "type": "string",
                    "description": "FFmpeg command template using {input0}, {input1}, etc. and {output} placeholders."
                  },
                  "output_extension": {
                    "type": "string",
                    "description": "Desired output file extension."
                  },
                  "publish": {
                    "type": "boolean",
                    "description": "Whether to publish the result."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "FFmpeg job created successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "job_id": {
                      "type": "string",
                      "description": "Unique job identifier for polling status.",
                      "example": "a97bbb5a-139b-46ca-b893-6e8d303d5934"
                    },
                    "status": {
                      "type": "string",
                      "example": "PENDING"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/uploadposts/ffmpeg/jobs/{job_id}": {
      "get": {
        "operationId": "getFfmpegJobStatus",
        "summary": "Get FFmpeg job status",
        "description": "Poll the status of an FFmpeg processing job. Statuses: PENDING, PROCESSING, FINISHED, ERROR.",
        "tags": ["FFmpeg Editor"],
        "parameters": [
          {
            "$ref": "#/components/parameters/JobIdPathParam"
          }
        ],
        "responses": {
          "200": {
            "description": "Job status retrieved successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FFmpegJob"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/uploadposts/ffmpeg/jobs/{job_id}/download": {
      "get": {
        "operationId": "downloadFfmpegResult",
        "summary": "Download FFmpeg result",
        "description": "Download the processed file when job status is FINISHED. Returns binary media with appropriate Content-Type and Content-Disposition headers.",
        "tags": ["FFmpeg Editor"],
        "parameters": [
          {
            "$ref": "#/components/parameters/JobIdPathParam"
          }
        ],
        "responses": {
          "200": {
            "description": "Processed file download.",
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/uploadposts/ffmpeg/consumption": {
      "get": {
        "operationId": "getFfmpegConsumption",
        "summary": "Get FFmpeg consumption",
        "description": "Check your current FFmpeg usage, remaining quota, and processing history for the current month.",
        "tags": ["FFmpeg Editor"],
        "responses": {
          "200": {
            "description": "Consumption data retrieved successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FFmpegConsumptionResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/uploadposts/users/notifications": {
      "post": {
        "operationId": "configureNotifications",
        "summary": "Configure webhook notifications",
        "description": "Configure notification preferences for upload events. Supports webhook (POST to your URL) and Telegram notifications.",
        "tags": ["Webhooks"],
        "servers": [
          {
            "url": "https://app.upload-post.com/api",
            "description": "Application server (notifications endpoint)"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "channels": {
                    "type": "object",
                    "properties": {
                      "webhook": {
                        "type": "boolean",
                        "description": "Enable/disable webhook notifications."
                      },
                      "telegram": {
                        "type": "boolean",
                        "description": "Enable/disable Telegram notifications."
                      }
                    }
                  },
                  "webhook_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "URL to receive webhook POST requests."
                  },
                  "telegram_chat_id": {
                    "type": "string",
                    "description": "Telegram chat ID for notifications."
                  },
                  "webhook_events": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": ["upload_completed", "social_account.connected", "social_account.disconnected", "social_account.reauth_required"]
                    },
                    "description": "List of webhook event types to subscribe to. If omitted, all events are enabled."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Notification settings updated successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "notifications": {
                      "type": "object",
                      "properties": {
                        "channels": {
                          "type": "object",
                          "properties": {
                            "webhook": {
                              "type": "boolean"
                            },
                            "telegram": {
                              "type": "boolean"
                            }
                          }
                        },
                        "webhook_url": {
                          "type": "string"
                        },
                        "telegram_chat_id": {
                          "type": "string"
                        },
                        "webhook_events": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        },
        "callbacks": {
          "uploadCompleted": {
            "{$request.body#/webhook_url}": {
              "post": {
                "summary": "Upload completed webhook",
                "description": "Sent to your webhook URL when an upload completes (success or failure).",
                "requestBody": {
                  "required": true,
                  "content": {
                    "application/json": {
                      "schema": {
                        "$ref": "#/components/schemas/WebhookPayload"
                      }
                    }
                  }
                },
                "responses": {
                  "200": {
                    "description": "Webhook received successfully."
                  }
                }
              }
            }
          },
          "socialAccountStatusChanged": {
            "{$request.body#/webhook_url}": {
              "post": {
                "summary": "Social account connection status changed",
                "description": "Sent when a social account is connected, disconnected, or requires re-authentication.",
                "requestBody": {
                  "required": true,
                  "content": {
                    "application/json": {
                      "schema": {
                        "$ref": "#/components/schemas/ConnectionStatusPayload"
                      }
                    }
                  }
                },
                "responses": {
                  "200": {
                    "description": "Webhook received successfully."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/uploadposts/media": {
      "get": {
        "operationId": "getUserMedia",
        "summary": "Get media list",
        "description": "Retrieve a list of recent media (posts, reels, videos, pins, tweets, etc.) from a connected social media account. Supports Instagram, TikTok, YouTube, LinkedIn, Facebook, X (Twitter), Threads, Pinterest, Bluesky, and Reddit.",
        "tags": ["Platform Integration"],
        "parameters": [
          {
            "name": "platform",
            "in": "query",
            "required": true,
            "schema": { "type": "string", "enum": ["instagram", "tiktok", "youtube", "linkedin", "facebook", "x", "threads", "pinterest", "bluesky", "reddit"] },
            "description": "The platform to retrieve media from."
          },
          {
            "name": "user",
            "in": "query",
            "required": true,
            "schema": { "type": "string" },
            "description": "Profile username as configured in Upload-Post."
          },
          {
            "name": "page_urn",
            "in": "query",
            "required": false,
            "schema": { "type": "string" },
            "description": "LinkedIn only. Selects which LinkedIn page to fetch posts from. Accepts a numeric organization ID (e.g., 12345), a full URN (e.g., urn:li:organization:12345), or 'me' to force the connected member's personal profile. If omitted, accounts connected as an organization admin auto-resolve to their first administered organization; otherwise the personal profile is used."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": { "type": "integer", "default": 25, "minimum": 1, "maximum": 100 },
            "description": "Number of media items to return. Defaults to 25 and is clamped to 1-100, then capped again by the platform's own maximum page size: Instagram/Facebook/Threads/Bluesky/X/Pinterest/Reddit/LinkedIn 100, YouTube 50, TikTok 20."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": { "type": "string" },
            "description": "Opaque next-page token. Pass back exactly the value returned in pagination.next_cursor by the previous response. Not supported on LinkedIn, Discord and Telegram: sending a cursor for those platforms returns 400 with a message naming the platform."
          }
        ],
        "responses": {
          "200": {
            "description": "Media list retrieved successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean" },
                    "media": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": { "type": "string", "description": "Platform-specific unique identifier for the media item." },
                          "caption": { "type": "string", "nullable": true, "description": "Text content, caption, or title of the post." },
                          "media_type": { "type": "string", "enum": ["IMAGE", "VIDEO", "CAROUSEL_ALBUM", "TEXT"], "description": "Type of media content." },
                          "media_url": { "type": "string", "nullable": true, "description": "Direct URL to the media file (image or video). Available on most platforms. Returns null for TikTok, YouTube, and when the platform does not provide a direct media URL. URLs are temporary and may expire." },
                          "permalink": { "type": "string", "nullable": true, "description": "Direct URL to the post on the platform." },
                          "timestamp": { "type": "string", "format": "date-time", "nullable": true, "description": "ISO 8601 timestamp of when the post was created." },
                          "thumbnail_url": { "type": "string", "nullable": true, "description": "URL of the thumbnail or preview image." }
                        }
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "description": "Page metadata. Additive: every pre-existing response key is unchanged.",
                      "properties": {
                        "limit": { "type": "integer", "description": "The effective limit applied after clamping and per-platform capping.", "example": 50 },
                        "next_cursor": { "type": "string", "nullable": true, "description": "Token to pass as 'cursor' on the next request. Null on the last page.", "example": "QVFIUkc..." },
                        "has_more": { "type": "boolean", "description": "True when another page is available." }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": { "description": "Missing or invalid parameters, platform account not linked, or a cursor was supplied for LinkedIn, Discord or Telegram (which do not support cursors)." },
          "500": { "description": "Internal server error." }
        }
      }
    },
    "/uploadposts/comments": {
      "get": {
        "operationId": "getPostComments",
        "summary": "List post comments (multi-platform)",
        "description": "List comments on one of your posts. Supported platforms: Instagram, Facebook, YouTube (account must be connected with the youtube.force-ssl scope), LinkedIn (organization posts) and TikTok. For YouTube, post_id is the video ID; for LinkedIn, post_id is the post URN (e.g. urn:li:ugcPost:123); for TikTok, post_id is the video id. Instagram comments are returned newest-first per Meta Graph API v3.2+. Pass comment_id to get the replies under one comment instead of the post's top-level comments. TikTok requires the `comments` capability — TikTok grants comment permission only at the moment the account is connected, so an account connected earlier must be reconnected from Manage Users or the call answers 400 with error_code `tiktok_reconnect_required`.",
        "tags": ["Instagram Interactions"],
        "parameters": [
          {
            "name": "platform",
            "in": "query",
            "required": false,
            "schema": { "type": "string", "enum": ["instagram", "facebook", "youtube", "linkedin", "tiktok"], "default": "instagram" },
            "description": "Platform to list comments from. Defaults to 'instagram'."
          },
          {
            "name": "user",
            "in": "query",
            "required": true,
            "schema": { "type": "string" },
            "description": "Profile username as configured in Upload-Post."
          },
          {
            "name": "post_id",
            "in": "query",
            "required": false,
            "schema": { "type": "string" },
            "description": "Post identifier. YouTube = the video ID; LinkedIn = the post URN (urn:li:ugcPost:...); Instagram = numeric media ID. Use post_id or post_url (one is required)."
          },
          {
            "name": "post_url",
            "in": "query",
            "required": false,
            "schema": { "type": "string" },
            "description": "Full post URL. Alternative to post_id."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": { "type": "integer", "minimum": 1 },
            "description": "Maximum comments to return per page."
          },
          {
            "name": "after",
            "in": "query",
            "required": false,
            "schema": { "type": "string" },
            "description": "Pagination cursor returned in `pagination.next_cursor` of the previous response. Pass it back to fetch the next page."
          },
          {
            "name": "comment_id",
            "in": "query",
            "required": false,
            "schema": { "type": "string" },
            "description": "TikTok only. Returns the replies hanging off this comment instead of the post's top-level comments - the same question narrowed to a parent, not a separate URL. post_id is still required. TikTok indexes a newly created comment asynchronously: listing within ~10 seconds of writing one returns a list without it."
          }
        ],
        "responses": {
          "200": {
            "description": "Comments retrieved successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean" },
                    "comments": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": { "type": "string", "description": "Comment ID." },
                          "text": { "type": "string" },
                          "timestamp": { "type": "string", "format": "date-time" },
                          "user": {
                            "type": "object",
                            "properties": {
                              "id": { "type": "string", "description": "Commenter's IGSID." },
                              "username": { "type": "string" }
                            }
                          }
                        }
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "description": "Cursor pagination metadata.",
                      "properties": {
                        "next_cursor": {
                          "type": "string",
                          "nullable": true,
                          "description": "Opaque cursor to pass as `after` for the next page. Null on the last page."
                        },
                        "has_next": {
                          "type": "boolean",
                          "description": "True if more pages are available."
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": { "description": "Missing parameters, invalid post identifier, or an unsupported platform (e.g. tiktok)." },
          "403": { "description": "The connected account lacks the required scope (e.g. YouTube not connected with youtube.force-ssl)." },
          "500": { "description": "Internal server error." }
        }
      }
    },
    "/uploadposts/comments/create": {
      "post": {
        "operationId": "createComment",
        "summary": "Create a comment or reply (multi-platform)",
        "description": "Post a comment or reply on Instagram, Facebook, YouTube, LinkedIn or TikTok. Provide exactly one of comment_id (reply to that comment), post_id or post_url (top-level comment). Instagram supports replies only, so comment_id is required. For LinkedIn, post_id is the post URN. On TikTok, post_id (the video id) is always required — adding comment_id on top of it turns the call into a reply — and the connection must report the `comments` capability, i.e. a reconnected account, or the call answers 400 with error_code `tiktok_reconnect_required`.",
        "tags": ["Instagram Interactions"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["platform", "user", "message"],
                "properties": {
                  "platform": { "type": "string", "enum": ["instagram", "facebook", "youtube", "linkedin", "tiktok"], "description": "Target platform." },
                  "user": { "type": "string", "description": "Profile username as configured in Upload-Post." },
                  "message": { "type": "string", "description": "The comment text." },
                  "comment_id": { "type": "string", "description": "Reply to this comment. Required for Instagram. Provide exactly one of comment_id, post_id or post_url." },
                  "post_id": { "type": "string", "description": "Top-level comment on this post. LinkedIn = post URN (urn:li:ugcPost:...); YouTube = video ID." },
                  "post_url": { "type": "string", "description": "Top-level comment on this post (by URL). Alternative to post_id." }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Comment created successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean" },
                    "id": { "type": "string", "description": "ID of the created comment." },
                    "message": { "type": "string" }
                  }
                }
              }
            }
          },
          "400": { "description": "Missing fields, more than one target provided, Instagram without comment_id, or an unsupported platform." },
          "403": { "description": "The connected account lacks the required scope." },
          "500": { "description": "Internal server error." }
        }
      }
    },
    "/uploadposts/comments/delete": {
      "delete": {
        "operationId": "deleteComment",
        "summary": "Delete a comment (multi-platform)",
        "description": "Delete a comment on Instagram, Facebook, YouTube, LinkedIn or TikTok. For LinkedIn, post_id (the post URN) is also required; TikTok deletes from comment_id alone, and only comments written by the connected account. TikTok also requires the `comments` capability (a reconnected account), or the call answers 400 with error_code `tiktok_reconnect_required`. Also accepts POST with the same body.",
        "tags": ["Instagram Interactions"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["platform", "user", "comment_id"],
                "properties": {
                  "platform": { "type": "string", "enum": ["instagram", "facebook", "youtube", "linkedin", "tiktok"], "description": "Target platform." },
                  "user": { "type": "string", "description": "Profile username as configured in Upload-Post." },
                  "comment_id": { "type": "string", "description": "ID of the comment to delete." },
                  "post_id": { "type": "string", "description": "Required for LinkedIn only — the post URN (urn:li:ugcPost:...) the comment belongs to." }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Comment deleted successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean" },
                    "message": { "type": "string" }
                  }
                }
              }
            }
          },
          "400": { "description": "Missing fields, LinkedIn without post_id, or an unsupported platform." },
          "403": { "description": "The connected account lacks the required scope, or you do not own the comment." },
          "500": { "description": "Internal server error." }
        }
      },
      "post": {
        "operationId": "deleteCommentPost",
        "summary": "Delete a comment (POST alias)",
        "description": "POST alias of DELETE /uploadposts/comments/delete, for clients that cannot send a body with DELETE. Same body and behavior.",
        "tags": ["Instagram Interactions"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["platform", "user", "comment_id"],
                "properties": {
                  "platform": { "type": "string", "enum": ["instagram", "facebook", "youtube", "linkedin", "tiktok"], "description": "Target platform." },
                  "user": { "type": "string", "description": "Profile username as configured in Upload-Post." },
                  "comment_id": { "type": "string", "description": "ID of the comment to delete." },
                  "post_id": { "type": "string", "description": "Required for LinkedIn only — the post URN (urn:li:ugcPost:...) the comment belongs to." }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Comment deleted successfully." },
          "400": { "description": "Missing fields, LinkedIn without post_id, or an unsupported platform." },
          "403": { "description": "The connected account lacks the required scope, or you do not own the comment." },
          "500": { "description": "Internal server error." }
        }
      }
    },
    "/uploadposts/comments/action": {
      "post": {
        "operationId": "commentAction",
        "summary": "Hide, like or pin a comment (multi-platform)",
        "description": "Moderate a comment on one of your own posts. One endpoint, because every action is a verb that carries its own inverse: hide/unhide, like/unlike, pin/unpin. You send the verb, never a boolean, so replaying a request can never flip a comment back. Only `tiktok` acts on comments today; any other platform answers 400 with error_code `platform_not_supported`. TikTok requires the `comments` capability (a reconnected account).",
        "tags": ["Instagram Interactions"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["platform", "user", "comment_id", "action"],
                "properties": {
                  "platform": { "type": "string", "enum": ["tiktok"], "description": "The network to act on. Only tiktok today." },
                  "user": { "type": "string", "description": "Profile username as configured in Upload-Post." },
                  "comment_id": { "type": "string", "description": "The comment to act on." },
                  "action": { "type": "string", "enum": ["hide", "unhide", "like", "unlike", "pin", "unpin"], "description": "The verb to apply. Send the inverse verb to undo it." },
                  "post_id": { "type": "string", "description": "The post the comment hangs from. Required for hide, unhide, pin and unpin; do not send it for like/unlike, which resolve from the comment alone." }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Action applied.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "platform": { "type": "string", "example": "tiktok" },
                    "action": { "type": "string", "example": "hide" },
                    "comment_id": { "type": "string", "example": "7401234567890999888" }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/PlatformNotSupported" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/TikTokReauthRequired" },
          "502": { "$ref": "#/components/responses/TikTokUpstreamError" }
        }
      }
    },
    "/uploadposts/posts/retry": {
      "post": {
        "operationId": "retryPost",
        "summary": "Retry a failed upload",
        "description": "Re-enqueue an upload that failed on one or more platforms. Only failed platforms are retried; the original media snapshot is reused, so no re-upload is needed. Provide request_id or job_id.",
        "tags": ["Upload Management"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "request_id": { "type": "string", "description": "The request_id returned by the original async upload. Provide request_id or job_id." },
                  "job_id": { "type": "string", "description": "The scheduled job ID. Alternative to request_id." }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Failed platforms re-enqueued for retry.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean" },
                    "request_id": { "type": "string" },
                    "message": { "type": "string" }
                  }
                }
              }
            }
          },
          "400": { "description": "Neither request_id nor job_id provided." },
          "404": { "description": "No upload found for the given identifier." },
          "409": { "description": "Nothing to retry (no failed platforms)." },
          "500": { "description": "Internal server error." }
        }
      }
    },
    "/uploadposts/posts/unpublish": {
      "post": {
        "operationId": "unpublishPost",
        "summary": "Unpublish (delete) a published post",
        "description": "Delete a post already published to a platform. Supported: facebook, youtube, x, linkedin, threads. Instagram and TikTok do NOT support deletion via API and return a clear error.",
        "tags": ["Upload Management"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["platform", "user", "post_id"],
                "properties": {
                  "platform": { "type": "string", "enum": ["facebook", "youtube", "x", "linkedin", "threads"], "description": "Platform to delete from. Instagram and TikTok are not supported." },
                  "user": { "type": "string", "description": "Profile username as configured in Upload-Post." },
                  "post_id": { "type": "string", "description": "The published post's ID on the target platform." }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Post deleted successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean" },
                    "message": { "type": "string" }
                  }
                }
              }
            }
          },
          "400": { "description": "Missing fields or an unsupported platform (e.g. instagram, tiktok)." },
          "403": { "description": "Not authorized to delete the post." },
          "404": { "description": "No post found for the given post_id." },
          "500": { "description": "Internal server error." }
        }
      }
    },
    "/uploadposts/comments/reply": {
      "post": {
        "operationId": "replyToComment",
        "summary": "Reply to comment (private reply DM)",
        "description": "Send a private reply (DM) to the author of a comment on your Instagram post. The comment must be less than 7 days old.",
        "tags": ["Instagram Interactions"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["platform", "user", "comment_id", "message"],
                "properties": {
                  "platform": { "type": "string", "enum": ["instagram"], "description": "Must be 'instagram'." },
                  "user": { "type": "string", "description": "Profile username as configured in Upload-Post." },
                  "comment_id": { "type": "string", "description": "ID of the comment to reply to (from Get Post Comments)." },
                  "message": { "type": "string", "description": "The private reply message text." },
                  "buttons": {
                    "type": "array",
                    "maxItems": 3,
                    "description": "Up to 3 web_url buttons rendered in the Instagram DM.",
                    "items": {
                      "type": "object",
                      "required": ["title", "url"],
                      "properties": {
                        "title": { "type": "string", "maxLength": 20, "description": "Button label (max 20 chars)." },
                        "url": { "type": "string", "format": "uri", "description": "Destination URL (http/https)." }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Private reply sent successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean" },
                    "recipient_id": { "type": "string" },
                    "message_id": { "type": "string" },
                    "message": { "type": "string" }
                  }
                }
              }
            }
          },
          "400": { "description": "Missing fields or invalid account." },
          "429": { "description": "Daily DM limit exceeded." },
          "500": { "description": "Internal server error." }
        }
      }
    },
    "/uploadposts/dms/conversations": {
      "get": {
        "operationId": "getDmConversations",
        "summary": "Get Instagram DM conversations",
        "description": "Retrieve the list of Instagram DM conversations for an account, including participants and recent messages.",
        "tags": ["Instagram Interactions"],
        "parameters": [
          {
            "name": "platform",
            "in": "query",
            "required": true,
            "schema": { "type": "string", "enum": ["instagram"] },
            "description": "Must be 'instagram'."
          },
          {
            "name": "user",
            "in": "query",
            "required": true,
            "schema": { "type": "string" },
            "description": "Profile username as configured in Upload-Post."
          }
        ],
        "responses": {
          "200": {
            "description": "Conversations retrieved successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean" },
                    "conversations": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": { "type": "string", "description": "Conversation thread ID." },
                          "participants": {
                            "type": "object",
                            "properties": {
                              "data": {
                                "type": "array",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "id": { "type": "string", "description": "Participant IGSID." },
                                    "username": { "type": "string" }
                                  }
                                }
                              }
                            }
                          },
                          "messages": {
                            "type": "object",
                            "properties": {
                              "data": {
                                "type": "array",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "id": { "type": "string" },
                                    "created_time": { "type": "string", "format": "date-time" },
                                    "from": {
                                      "type": "object",
                                      "properties": {
                                        "id": { "type": "string" },
                                        "username": { "type": "string" }
                                      }
                                    },
                                    "message": { "type": "string" }
                                  }
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": { "description": "Missing or invalid parameters." },
          "500": { "description": "Internal server error." }
        }
      }
    },
    "/uploadposts/dms/send": {
      "post": {
        "operationId": "sendDm",
        "summary": "Send Instagram DM",
        "description": "Send a direct message to an Instagram user using their IGSID. The recipient must have messaged your account first (24-hour messaging window policy enforced by Meta).",
        "tags": ["Instagram Interactions"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["platform", "user", "recipient_id", "message"],
                "properties": {
                  "platform": { "type": "string", "enum": ["instagram"], "description": "Must be 'instagram'." },
                  "user": { "type": "string", "description": "Profile username as configured in Upload-Post." },
                  "recipient_id": { "type": "string", "description": "Instagram-Scoped User ID (IGSID) of the recipient." },
                  "message": { "type": "string", "description": "The text message to send." },
                  "buttons": {
                    "type": "array",
                    "maxItems": 3,
                    "description": "Up to 3 web_url buttons rendered in the Instagram DM.",
                    "items": {
                      "type": "object",
                      "required": ["title", "url"],
                      "properties": {
                        "title": { "type": "string", "maxLength": 20, "description": "Button label (max 20 chars)." },
                        "url": { "type": "string", "format": "uri", "description": "Destination URL (http/https)." }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "DM sent successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean" },
                    "recipient_id": { "type": "string" },
                    "message_id": { "type": "string" },
                    "message": { "type": "string" }
                  }
                }
              }
            }
          },
          "400": { "description": "Missing fields or invalid account." },
          "429": { "description": "Daily DM limit exceeded." },
          "500": { "description": "Internal server error." }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "name": "Authorization",
        "in": "header",
        "description": "API Key authentication. Format: `Apikey YOUR_API_KEY`"
      },
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "JWT Bearer token authentication. Used for validate-jwt and reddit detailed-posts endpoints."
      }
    },
    "parameters": {
      "TikTokProfile": {
        "name": "profile",
        "in": "query",
        "required": true,
        "description": "Profile username. Must have a TikTok account connected.",
        "schema": {
          "type": "string"
        }
      },
      "TikTokMusicGenre": {
        "name": "genre",
        "in": "query",
        "description": "Commercial Music Library genre, e.g. `ALL`, `POP`, `HIP_HOP/RAP`, `R&B/SOUL`. The slashes and the ampersand are part of TikTok's enum. Unknown values fall back to `ALL`.",
        "schema": {
          "type": "string",
          "default": "ALL"
        }
      },
      "TikTokMusicCountry": {
        "name": "country_code",
        "in": "query",
        "description": "ISO-3166 alpha-2 country whose trending chart is read. The catalogue is per country, so this changes which tracks come back.",
        "schema": {
          "type": "string",
          "default": "US"
        }
      },
      "TikTokMusicDateRange": {
        "name": "date_range",
        "in": "query",
        "description": "Trending window.",
        "schema": {
          "type": "string",
          "enum": ["1DAY", "7DAY", "30DAY", "90DAY"],
          "default": "7DAY"
        }
      },
      "ProfileQueryParam": {
        "name": "profile_username",
        "in": "query",
        "required": true,
        "description": "The profile username.",
        "schema": {
          "type": "string"
        }
      },
      "JobIdPathParam": {
        "name": "job_id",
        "in": "path",
        "required": true,
        "description": "The unique job identifier.",
        "schema": {
          "type": "string"
        }
      },
      "PageParam": {
        "name": "page",
        "in": "query",
        "description": "Page number (starts at 1).",
        "schema": {
          "type": "integer",
          "default": 1,
          "minimum": 1
        }
      },
      "LimitParam": {
        "name": "limit",
        "in": "query",
        "description": "Number of items per page.",
        "schema": {
          "type": "integer",
          "default": 10,
          "enum": [10, 20, 50, 100]
        }
      }
    },
    "responses": {
      "PlatformNotSupported": {
        "description": "That network cannot answer this question yet. Upload-Post is one endpoint per QUESTION with a `platform`, so the message names the platforms that can. Branch on the error_code, not on a hard-coded platform list: when the network is added, the same call starts returning data. Some endpoints carry the text in `error` instead of `message`.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "success": { "type": "boolean", "example": false },
                "message": { "type": "string", "example": "'instagram' does not support audience insights yet. Supported: tiktok." },
                "error_code": { "type": "string", "example": "platform_not_supported" }
              }
            }
          }
        }
      },
      "TikTokReconnectRequired": {
        "description": "The profile has no TikTok connection able to serve this endpoint. Reconnecting the TikTok account from Manage Users enables it.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "success": {
                  "type": "boolean",
                  "example": false
                },
                "message": {
                  "type": "string",
                  "example": "Profile 'my_profile' has no TikTok connection that supports this endpoint. Reconnect your TikTok account from Manage Users."
                },
                "error_code": {
                  "type": "string",
                  "example": "tiktok_reconnect_required"
                }
              }
            }
          }
        }
      },
      "TikTokReauthRequired": {
        "description": "The TikTok token expired and could not be refreshed; the account must be reconnected.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "success": {
                  "type": "boolean",
                  "example": false
                },
                "message": {
                  "type": "string",
                  "example": "Your TikTok session has expired. Please reconnect your TikTok account at app.upload-post.com/manage-users."
                },
                "reauth_required": {
                  "type": "boolean",
                  "example": true
                }
              }
            }
          }
        }
      },
      "TikTokUpstreamError": {
        "description": "TikTok rejected the request. Its message is returned verbatim.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "success": {
                  "type": "boolean",
                  "example": false
                },
                "message": {
                  "type": "string",
                  "example": "TikTok API error 40002: invalid parameter"
                }
              }
            }
          }
        }
      },
      "BadRequest": {
        "description": "Bad Request — Missing or invalid parameters.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "Unauthorized": {
        "description": "Unauthorized — Invalid or expired token.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "example": {
              "success": false,
              "message": "Invalid or expired token"
            }
          }
        }
      },
      "Forbidden": {
        "description": "Forbidden — Plan restrictions or insufficient permissions.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "NotFound": {
        "description": "Not Found — Resource does not exist.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "TooManyRequests": {
        "description": "Too Many Requests — Monthly limit exceeded.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "success": {
                  "type": "boolean",
                  "example": false
                },
                "message": {
                  "type": "string",
                  "example": "This upload would exceed your monthly limit."
                },
                "usage": {
                  "$ref": "#/components/schemas/UsageInfo"
                }
              }
            }
          }
        }
      },
      "InternalServerError": {
        "description": "Internal Server Error.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      }
    },
    "schemas": {
      "TikTokMusicTrack": {
        "type": "object",
        "description": "One track of TikTok's Commercial Music Library.",
        "properties": {
          "id": {
            "type": "string",
            "description": "Send this as `tiktok_music_id` on an upload. NOT `commercial_music_id`: TikTok rejects that one on public posts.",
            "example": "7205381234567890123"
          },
          "commercial_music_id": {
            "type": "string",
            "description": "TikTok's catalogue id for the same track. Returned for reference only."
          },
          "title": {
            "type": "string",
            "example": "Summer Nights"
          },
          "artist": {
            "type": "string",
            "example": "The Example Band"
          },
          "duration": {
            "type": "number",
            "description": "Track duration in seconds.",
            "example": 32
          },
          "genres": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "example": ["POP"]
          },
          "cover_url": {
            "type": "string",
            "description": "Artwork image URL."
          },
          "preview_url": {
            "type": "string",
            "description": "Audio preview URL."
          },
          "rank": {
            "type": "integer",
            "description": "Position in TikTok's trending chart for the requested filters."
          }
        }
      },
      "TikTokLocation": {
        "type": "object",
        "description": "One TikTok place. Both fields must be sent together on an upload.",
        "properties": {
          "location_id": {
            "type": "string",
            "description": "Send as `tiktok_location_id`.",
            "example": "v2_2f4a1b9c8e"
          },
          "location_name": {
            "type": "string",
            "description": "Send as `tiktok_location_name`. TikTok rejects the id without it.",
            "example": "Museo Nacional del Prado"
          },
          "location_address": {
            "type": "string",
            "description": "Postal address, useful for disambiguating results in a picker.",
            "example": "C. de Ruiz de Alarcon, 23, 28014 Madrid, Spain"
          }
        }
      },
      "VideoPlatformEnum": {
        "type": "string",
        "enum": ["tiktok", "instagram", "linkedin", "youtube", "facebook", "x", "threads", "pinterest", "bluesky", "reddit", "google_business", "discord", "telegram"],
        "description": "Supported platforms for video upload."
      },
      "PhotoPlatformEnum": {
        "type": "string",
        "enum": ["tiktok", "instagram", "linkedin", "facebook", "x", "threads", "pinterest", "bluesky", "reddit", "google_business", "discord", "telegram"],
        "description": "Supported platforms for photo upload."
      },
      "TextPlatformEnum": {
        "type": "string",
        "enum": ["linkedin", "x", "facebook", "threads", "reddit", "bluesky", "google_business", "discord", "telegram"],
        "description": "Supported platforms for text upload."
      },
      "TikTokPrivacyLevel": {
        "type": "string",
        "enum": ["PUBLIC_TO_EVERYONE", "MUTUAL_FOLLOW_FRIENDS", "FOLLOWER_OF_CREATOR", "SELF_ONLY"],
        "description": "[TikTok] Privacy setting for the post.",
        "default": "PUBLIC_TO_EVERYONE"
      },
      "TikTokPostMode": {
        "type": "string",
        "enum": ["DIRECT_POST", "MEDIA_UPLOAD"],
        "description": "[TikTok] DIRECT_POST publishes immediately. MEDIA_UPLOAD sends to TikTok drafts (same as tiktok_upload_to_draft=true). Either field works on any TikTok account.",
        "default": "DIRECT_POST"
      },
      "InstagramVideoMediaType": {
        "type": "string",
        "enum": ["REELS", "STORIES"],
        "description": "[Instagram] Type of video media.",
        "default": "REELS"
      },
      "InstagramPhotoMediaType": {
        "type": "string",
        "enum": ["IMAGE", "STORIES"],
        "description": "[Instagram] Type of photo media. Automatically handles CAROUSEL/REELS logic if mixed media is detected.",
        "default": "IMAGE"
      },
      "InstagramShareMode": {
        "type": "string",
        "enum": ["CUSTOM", "TRIAL_REELS_SHARE_TO_FOLLOWERS_IF_LIKED", "TRIAL_REELS_DONT_SHARE_TO_FOLLOWERS"],
        "description": "[Instagram] Reel posting mode. CUSTOM = regular Reel. Trial Reel modes test content with non-followers first.",
        "default": "CUSTOM"
      },
      "LinkedInVisibility": {
        "type": "string",
        "enum": ["PUBLIC", "CONNECTIONS", "LOGGED_IN", "CONTAINER"],
        "description": "[LinkedIn] Visibility setting for the post. Required when platform includes linkedin.",
        "default": "PUBLIC"
      },
      "YouTubePrivacyStatus": {
        "type": "string",
        "enum": ["public", "unlisted", "private"],
        "description": "[YouTube] Privacy setting for the video.",
        "default": "public"
      },
      "FacebookVideoMediaType": {
        "type": "string",
        "enum": ["REELS", "STORIES"],
        "description": "[Facebook] Type of video media.",
        "default": "REELS"
      },
      "FacebookPhotoMediaType": {
        "type": "string",
        "enum": ["POSTS", "STORIES"],
        "description": "[Facebook] Type of photo media.",
        "default": "POSTS"
      },
      "XReplySettings": {
        "type": "string",
        "enum": ["following", "mentionedUsers", "subscribers", "verified"],
        "description": "[X] Controls who can reply to the tweet."
      },
      "FFmpegJobStatus": {
        "type": "string",
        "enum": ["PENDING", "PROCESSING", "FINISHED", "ERROR"],
        "description": "Status of an FFmpeg processing job."
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": false
          },
          "message": {
            "type": "string"
          },
          "error": {
            "type": "string"
          }
        }
      },
      "UsageInfo": {
        "type": "object",
        "properties": {
          "count": {
            "type": "integer",
            "description": "Current usage count."
          },
          "limit": {
            "type": "integer",
            "description": "Monthly limit."
          },
          "last_reset": {
            "type": "string",
            "format": "date-time",
            "description": "Last reset timestamp."
          }
        }
      },
      "SyncUploadResponse": {
        "type": "object",
        "description": "Synchronous upload response (completed within timeout).",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "results": {
            "type": "object",
            "additionalProperties": {
              "type": "object",
              "properties": {
                "success": {
                  "type": "boolean"
                },
                "url": {
                  "type": "string"
                },
                "publish_id": {
                  "type": "string"
                },
                "container_id": {
                  "type": "string"
                },
                "post_id": {
                  "type": "string"
                },
                "video_was_transcoded": {
                  "type": "boolean"
                },
                "changes": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  },
                  "description": "List of transformations applied to the media."
                },
                "prevalidation_metadata": {
                  "type": "object",
                  "description": "Media metadata detected before upload."
                },
                "error": {
                  "type": "string"
                }
              }
            },
            "description": "Per-platform results keyed by platform name."
          },
          "usage": {
            "$ref": "#/components/schemas/UsageInfo"
          }
        }
      },
      "AsyncUploadResponse": {
        "type": "object",
        "description": "Asynchronous upload response (processing in background).",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "message": {
            "type": "string",
            "example": "Upload initiated successfully in background."
          },
          "request_id": {
            "type": "string",
            "description": "Use this to poll status via GET /uploadposts/status."
          },
          "total_platforms": {
            "type": "integer",
            "description": "Number of platforms being uploaded to."
          }
        }
      },
      "ScheduledUploadResponse": {
        "type": "object",
        "description": "Scheduled upload response.",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "job_id": {
            "type": "string",
            "description": "Scheduled job identifier."
          },
          "scheduled_date": {
            "type": "string",
            "format": "date-time",
            "description": "Scheduled publish date/time in UTC."
          }
        }
      },
      "QueuedUploadResponse": {
        "type": "object",
        "description": "Queued upload response.",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "job_id": {
            "type": "string",
            "description": "Scheduled job identifier."
          },
          "scheduled_date": {
            "type": "string",
            "format": "date-time",
            "description": "Assigned queue slot date/time."
          },
          "queue_slot": {
            "type": "string",
            "format": "date-time",
            "description": "Queue slot datetime."
          },
          "message": {
            "type": "string",
            "example": "Post added to queue"
          }
        }
      },
      "DocumentUploadResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "message": {
            "type": "string"
          },
          "request_id": {
            "type": "string"
          },
          "results": {
            "type": "object",
            "properties": {
              "linkedin": {
                "type": "object",
                "properties": {
                  "success": {
                    "type": "boolean"
                  },
                  "document_urn": {
                    "type": "string"
                  },
                  "post_id": {
                    "type": "string"
                  },
                  "url": {
                    "type": "string"
                  },
                  "platform": {
                    "type": "string"
                  },
                  "content_type": {
                    "type": "string"
                  },
                  "file_size": {
                    "type": "integer"
                  },
                  "filename": {
                    "type": "string"
                  }
                }
              }
            }
          }
        }
      },
      "UploadStatusResponse": {
        "type": "object",
        "properties": {
          "request_id": {
            "type": "string"
          },
          "job_id": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": ["pending", "in_progress", "completed"],
            "description": "Aggregated status."
          },
          "completed": {
            "type": "integer",
            "description": "Number of platforms completed."
          },
          "total": {
            "type": "integer",
            "description": "Total number of platforms."
          },
          "results": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "platform": {
                  "type": "string"
                },
                "success": {
                  "type": "boolean"
                },
                "message": {
                  "type": "string"
                },
                "upload_timestamp": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            }
          },
          "last_update": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "UploadHistoryResponse": {
        "type": "object",
        "properties": {
          "history": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/HistoryItem"
            }
          },
          "total": {
            "type": "integer"
          },
          "page": {
            "type": "integer"
          },
          "limit": {
            "type": "integer"
          }
        }
      },
      "HistoryItem": {
        "type": "object",
        "properties": {
          "user_email": {
            "type": "string"
          },
          "profile_username": {
            "type": "string"
          },
          "platform": {
            "type": "string"
          },
          "media_type": {
            "type": "string",
            "enum": ["video", "photo", "text"]
          },
          "upload_timestamp": {
            "type": "string",
            "format": "date-time"
          },
          "success": {
            "type": "boolean"
          },
          "platform_post_id": {
            "type": "string",
            "nullable": true
          },
          "post_url": {
            "type": "string",
            "nullable": true
          },
          "error_message": {
            "type": "string",
            "nullable": true
          },
          "media_size_bytes": {
            "type": "integer",
            "nullable": true
          },
          "post_title": {
            "type": "string",
            "nullable": true
          },
          "post_caption": {
            "type": "string",
            "nullable": true
          },
          "is_async": {
            "type": "boolean",
            "nullable": true
          },
          "job_id": {
            "type": "string",
            "nullable": true,
            "description": "Present when the upload originated from a scheduled job."
          },
          "video_was_transcoded": {
            "type": "boolean",
            "nullable": true
          },
          "changes": {
            "type": "array",
            "nullable": true,
            "items": {
              "type": "string"
            },
            "description": "List of transformations applied to the media (e.g., transcoding, aspect ratio changes)."
          },
          "prevalidation_metadata": {
            "type": "object",
            "nullable": true,
            "description": "Media metadata detected before upload (dimensions, codec, duration, etc.)."
          },
          "request_id": {
            "type": "string",
            "nullable": true
          },
          "request_id_logs": {
            "type": "string",
            "nullable": true,
            "description": "Internal request ID for log correlation."
          },
          "request_total_platforms": {
            "type": "integer",
            "nullable": true
          },
          "dashboard": {
            "type": "boolean",
            "nullable": true,
            "description": "Whether the upload was initiated from the dashboard."
          }
        }
      },
      "ScheduledPost": {
        "type": "object",
        "properties": {
          "job_id": {
            "type": "string",
            "description": "Unique identifier of the scheduled job."
          },
          "scheduled_date": {
            "type": "string",
            "format": "date-time",
            "description": "ISO-8601 date/time when the post will go live (UTC)."
          },
          "post_type": {
            "type": "string",
            "enum": ["video", "photo", "text"],
            "description": "Type of content."
          },
          "profile_username": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "preview_url": {
            "type": "string",
            "nullable": true,
            "description": "Short-lived signed URL to preview the media. Null for text posts."
          }
        }
      },
      "QueueSlot": {
        "type": "object",
        "properties": {
          "hour": {
            "type": "integer",
            "minimum": 0,
            "maximum": 23,
            "description": "Hour of the slot (0-23)."
          },
          "minute": {
            "type": "integer",
            "minimum": 0,
            "maximum": 59,
            "description": "Minute of the slot (0-59)."
          }
        },
        "required": ["hour", "minute"]
      },
      "QueueSettings": {
        "type": "object",
        "properties": {
          "timezone": {
            "type": "string",
            "description": "IANA timezone.",
            "example": "America/New_York"
          },
          "slots": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/QueueSlot"
            }
          },
          "days_of_week": {
            "type": "array",
            "items": {
              "type": "integer",
              "minimum": 0,
              "maximum": 6
            },
            "description": "Active days: 0=Monday through 6=Sunday."
          }
        }
      },
      "QueueSettingsResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "queue_settings": {
            "$ref": "#/components/schemas/QueueSettings"
          }
        }
      },
      "QueuePreviewResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "timezone": {
            "type": "string"
          },
          "slots": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "datetime_utc": {
                  "type": "string",
                  "format": "date-time"
                },
                "datetime_local": {
                  "type": "string",
                  "format": "date-time"
                },
                "available": {
                  "type": "boolean"
                },
                "is_queue_slot": {
                  "type": "boolean",
                  "description": "Whether this slot is a configured queue slot."
                },
                "scheduled_post": {
                  "type": "object",
                  "nullable": true,
                  "properties": {
                    "job_id": {
                      "type": "string"
                    },
                    "title": {
                      "type": "string"
                    },
                    "platforms": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          },
          "next_available": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "NextSlotResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "next_slot": {
            "type": "object",
            "nullable": true,
            "properties": {
              "datetime_utc": {
                "type": "string",
                "format": "date-time"
              },
              "datetime_local": {
                "type": "string",
                "format": "date-time"
              },
              "timezone": {
                "type": "string"
              }
            }
          },
          "message": {
            "type": "string",
            "description": "Present when no slots are available."
          }
        }
      },
      "AnalyticsResponse": {
        "type": "object",
        "additionalProperties": {
          "type": "object",
          "properties": {
            "followers": {
              "type": "number"
            },
            "reach": {
              "type": "number"
            },
            "views": {
              "type": "number",
              "description": "Total content views. For Instagram, this is the official 'views' metric (replaces deprecated 'impressions'). Same value as 'impressions' field."
            },
            "impressions": {
              "type": "number",
              "description": "Total impressions/views. For Instagram, YouTube, and TikTok this equals the 'views' field. Kept for backwards compatibility."
            },
            "profileViews": {
              "type": "number",
              "description": "Profile views or accounts engaged (Instagram)."
            },
            "likes": {
              "type": "number"
            },
            "comments": {
              "type": "number"
            },
            "shares": {
              "type": "number"
            },
            "saves": {
              "type": "number"
            },
            "video_count": {
              "type": "integer",
              "description": "Total number of videos (TikTok)."
            },
            "following": {
              "type": "integer",
              "description": "Number of accounts followed (TikTok)."
            },
            "reach_timeseries": {
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "date": {
                    "type": "string",
                    "format": "date"
                  },
                  "value": {
                    "type": "number"
                  }
                }
              }
            }
          }
        },
        "description": "Analytics data keyed by platform name. Metrics vary by platform."
      },
      "FacebookPage": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Facebook Page ID. Use this value as `facebook_page_id` in upload endpoints."
          },
          "name": {
            "type": "string",
            "description": "Display name of the Facebook page."
          },
          "picture": {
            "type": "string",
            "nullable": true,
            "description": "URL of the page's profile picture."
          },
          "account_id": {
            "type": "string",
            "description": "Internal identifier for the user's connected Facebook account."
          }
        }
      },
      "LinkedInPage": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "LinkedIn organization URN. Use as `target_linkedin_page_id`."
          },
          "name": {
            "type": "string",
            "description": "Display name of the LinkedIn page."
          },
          "picture": {
            "type": "string",
            "nullable": true,
            "description": "URL of the page logo."
          },
          "account_id": {
            "type": "string",
            "description": "Internal identifier for the connected LinkedIn account."
          },
          "vanityName": {
            "type": "string",
            "nullable": true,
            "description": "Custom vanity URL of the page."
          }
        }
      },
      "PinterestBoard": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Pinterest board ID for posting."
          },
          "name": {
            "type": "string",
            "description": "Display name of the board."
          }
        }
      },
      "RedditPost": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "subreddit": {
            "type": "string"
          },
          "body": {
            "type": "string"
          },
          "likes": {
            "type": "integer"
          },
          "comments": {
            "type": "integer"
          },
          "impressions": {
            "type": "integer"
          },
          "has_image": {
            "type": "boolean"
          },
          "has_video": {
            "type": "boolean"
          },
          "media": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "type": {
                  "type": "string",
                  "enum": ["image", "video", "external_video"]
                },
                "url": {
                  "type": "string"
                },
                "width": {
                  "type": "integer"
                },
                "height": {
                  "type": "integer"
                },
                "duration": {
                  "type": "number",
                  "description": "Duration in seconds (video only)."
                },
                "thumbnail": {
                  "type": "string",
                  "description": "Thumbnail URL (external_video only)."
                },
                "provider": {
                  "type": "string",
                  "description": "Provider name (external_video only)."
                }
              }
            }
          },
          "url": {
            "type": "string"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "thumbnail": {
            "type": "string"
          }
        }
      },
      "UserProfile": {
        "type": "object",
        "properties": {
          "username": {
            "type": "string",
            "description": "Unique profile identifier."
          },
          "created_at": {
            "type": "string",
            "description": "Timestamp of profile creation."
          },
          "social_accounts": {
            "type": "object",
            "additionalProperties": {
              "oneOf": [
                {
                  "type": "object",
                  "properties": {
                    "username": {
                      "type": "string",
                      "description": "Platform-specific user identifier."
                    },
                    "handle": {
                      "type": "string",
                      "description": "Platform handle/username."
                    },
                    "display_name": {
                      "type": "string",
                      "description": "Display name on the platform."
                    },
                    "social_images": {
                      "type": "string",
                      "description": "URL of the profile picture."
                    },
                    "reauth_required": {
                      "type": "boolean",
                      "description": "Whether the account needs to be re-authenticated."
                    }
                  }
                },
                {
                  "type": "string"
                },
                {
                  "type": "object",
                  "nullable": true
                }
              ]
            },
            "description": "Connected social media accounts keyed by platform name."
          }
        }
      },
      "FFmpegJob": {
        "type": "object",
        "properties": {
          "job_id": {
            "type": "string"
          },
          "status": {
            "$ref": "#/components/schemas/FFmpegJobStatus"
          },
          "duration_seconds": {
            "type": "number",
            "description": "Duration of the input media in seconds."
          },
          "output_extension": {
            "type": "string"
          }
        }
      },
      "FFmpegConsumptionResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "consumption": {
            "type": "object",
            "properties": {
              "used_minutes": {
                "type": "number"
              },
              "remaining_minutes": {
                "type": "number"
              },
              "quota_minutes": {
                "type": "number"
              },
              "usage_percentage": {
                "type": "number"
              },
              "total_requests": {
                "type": "integer"
              },
              "current_month": {
                "type": "string"
              },
              "plan": {
                "type": "string"
              }
            }
          },
          "history": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "duration_seconds": {
                  "type": "number"
                },
                "duration_minutes": {
                  "type": "number"
                },
                "timestamp": {
                  "type": "string",
                  "format": "date-time"
                },
                "month": {
                  "type": "string"
                },
                "type": {
                  "type": "string"
                }
              }
            }
          },
          "quota_info": {
            "type": "object",
            "properties": {
              "plan": {
                "type": "string"
              },
              "quota_minutes": {
                "type": "number"
              },
              "reset_day": {
                "type": "integer"
              },
              "next_reset": {
                "type": "string",
                "format": "date"
              }
            }
          }
        }
      },
      "ConnectionStatusPayload": {
        "type": "object",
        "description": "Payload sent to your webhook URL when a social account connection status changes.",
        "properties": {
          "event": {
            "type": "string",
            "enum": ["social_account.connected", "social_account.disconnected", "social_account.reauth_required"],
            "description": "The connection status event type."
          },
          "user_email": {
            "type": "string",
            "description": "The email address of the account owner."
          },
          "platform": {
            "type": "string",
            "description": "The social platform (e.g., instagram, youtube, tiktok, x, linkedin, facebook, threads, pinterest, reddit, bluesky, snapchat, google_business)."
          },
          "account_name": {
            "type": "string",
            "description": "The account identifier on the platform."
          },
          "status": {
            "type": "string",
            "enum": ["connected", "disconnected", "reauth_required"],
            "description": "The new connection status."
          },
          "profile_username": {
            "type": "string",
            "nullable": true,
            "description": "The Upload-Post profile associated with this account."
          },
          "reason": {
            "type": "string",
            "nullable": true,
            "description": "Additional context for the status change (e.g., manual_disconnect, account_blocked, token_refresh_threshold_exceeded)."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "The timestamp of the event in ISO 8601 format."
          }
        }
      },
      "WebhookPayload": {
        "type": "object",
        "description": "Payload sent to your webhook URL when an upload completes.",
        "properties": {
          "event": {
            "type": "string",
            "enum": ["upload_completed"],
            "description": "Event type."
          },
          "user_email": {
            "type": "string"
          },
          "profile_username": {
            "type": "string"
          },
          "platform": {
            "type": "string"
          },
          "media_type": {
            "type": "string",
            "enum": ["video", "photo", "text"]
          },
          "title": {
            "type": "string"
          },
          "caption": {
            "type": "string"
          },
          "result": {
            "type": "object",
            "properties": {
              "success": {
                "type": "boolean"
              },
              "url": {
                "type": "string",
                "nullable": true
              },
              "publish_id": {
                "type": "string",
                "nullable": true
              },
              "post_id": {
                "type": "string",
                "nullable": true
              },
              "error": {
                "type": "string",
                "nullable": true
              }
            }
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      }
    }
  }
}
