{
  "openapi": "3.1.0",
  "info": {
    "title": "Viraloop API",
    "version": "2.0.14",
    "description": "Public API for Viraloop: generate AI short-form social content and schedule it to TikTok, Instagram and YouTube. Authenticate with an API key from https://viraloop.io/settings/developers. Success responses are { success: true, data, pagination? }; errors are { success: false, error: { type, message, hint } }. Mutating operations accept an Idempotency-Key header. Scopes and auth are also published as RFC 9728 metadata at https://viraloop.io/.well-known/oauth-protected-resource.",
    "contact": {
      "url": "https://viraloop.io/developers"
    }
  },
  "servers": [
    {
      "url": "https://viraloop.io/api/v1"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyHeader": []
    }
  ],
  "tags": [
    {
      "name": "me"
    },
    {
      "name": "credits"
    },
    {
      "name": "workspaces"
    },
    {
      "name": "accounts"
    },
    {
      "name": "generations"
    },
    {
      "name": "posts"
    },
    {
      "name": "automations"
    },
    {
      "name": "influencers"
    },
    {
      "name": "videos"
    },
    {
      "name": "assets"
    },
    {
      "name": "content"
    }
  ],
  "paths": {
    "/me": {
      "get": {
        "operationId": "getMe",
        "summary": "Introspect the API key",
        "description": "Returns the team behind the credentials: name, credit balance, plan, default workspace and the scopes granted to the key. Call this first to verify auth works.",
        "tags": [
          "me"
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "example": {
                  "success": true,
                  "data": {
                    "teamId": "665f1b2a9c31a2b3c4d5e6f7",
                    "teamName": "Acme",
                    "credits": 420,
                    "plan": "Growth (monthly)",
                    "planValidUntil": "2026-08-01T00:00:00.000Z",
                    "workspaceId": "665f1b2a9c31a2b3c4d5e6f8",
                    "auth": {
                      "via": "api_key",
                      "keyPrefix": "vl_live_a1b2c3d4",
                      "scopes": [
                        "posts:read",
                        "posts:write"
                      ],
                      "legacy": false
                    }
                  }
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-scopes": [],
        "x-credit-cost": "none",
        "x-cli-command": "viraloop whoami",
        "x-mcp-tool": "viraloop_get_me"
      }
    },
    "/credits": {
      "get": {
        "operationId": "getCredits",
        "summary": "Credit balance and ledger",
        "description": "Returns the team's current credit balance plus a paginated ledger of credit movements (top-ups, spending, rewards, refunds). Turbo content generation does not consume credits; influencer media generation does (createInfluencerVideo: 5 credits per second of video, createInfluencer preview: 10). Failed generations are refunded automatically; running out of credits returns HTTP 402 with error type insufficient_credits.",
        "tags": [
          "credits"
        ],
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1,
              "description": "Page number, starting at 1"
            },
            "description": "Page number, starting at 1"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20,
              "description": "Items per page (max 100)"
            },
            "description": "Items per page (max 100)"
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "recurring",
                "topup",
                "spending",
                "trial",
                "spin",
                "reward",
                "refund"
              ],
              "description": "Filter by entry type"
            },
            "description": "Filter by entry type"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "example": {
                  "success": true,
                  "data": {
                    "balance": 420,
                    "entries": [
                      {
                        "id": "665f1b2a9c31a2b3c4d5e6f9",
                        "credits": -10,
                        "type": "spending",
                        "spendingType": "video_generation",
                        "model": "veo3_fast",
                        "createdAt": "2026-07-01T12:00:00.000Z"
                      }
                    ]
                  },
                  "pagination": {
                    "total": 1,
                    "page": 1,
                    "limit": 20,
                    "pages": 1
                  }
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-scopes": [
          "credits:read"
        ],
        "x-credit-cost": "none",
        "x-cli-command": "viraloop credits",
        "x-mcp-tool": "viraloop_get_credits"
      }
    },
    "/workspaces": {
      "get": {
        "operationId": "listWorkspaces",
        "summary": "List workspaces",
        "description": "Lists the team's workspaces (brands). Most endpoints accept an optional workspaceId and default to the team's default workspace.",
        "tags": [
          "workspaces"
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "example": {
                  "success": true,
                  "data": [
                    {
                      "id": "665f1b2a9c31a2b3c4d5e6f8",
                      "name": "Acme",
                      "isDefault": true,
                      "website": {
                        "url": "https://acme.com",
                        "domain": "acme.com"
                      },
                      "contentAngles": [
                        {
                          "title": "Client Revision Hell",
                          "description": "..."
                        }
                      ],
                      "preferences": {
                        "timezone": "America/New_York",
                        "contentLanguage": "English"
                      }
                    }
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-scopes": [
          "workspaces:read"
        ],
        "x-credit-cost": "none",
        "x-cli-command": "viraloop workspaces list",
        "x-mcp-tool": "viraloop_list_workspaces"
      },
      "post": {
        "operationId": "createWorkspace",
        "summary": "Create a workspace",
        "description": "Creates a workspace (brand) under the team. Provide the brand's website and the brand profile (identity, positioning, content angles) is generated in the background: poll getWorkspace until brandContext.status is ready. One domain can be claimed by only one workspace across all of Viraloop.",
        "tags": [
          "workspaces"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100
                  },
                  "websiteUrl": {
                    "type": "string",
                    "format": "uri",
                    "description": "The brand's website; seeds the auto-generated brand profile"
                  },
                  "logoUrl": {
                    "type": "string",
                    "format": "uri"
                  }
                },
                "required": [
                  "name"
                ],
                "additionalProperties": false
              },
              "example": {
                "name": "Acme",
                "websiteUrl": "https://acme.com"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "example": {
                  "success": true,
                  "data": {
                    "id": "665f1b2a9c31a2b3c4d5e6f9",
                    "name": "Acme",
                    "isDefault": false,
                    "website": {
                      "url": "https://acme.com",
                      "domain": "acme.com"
                    },
                    "preferences": {
                      "timezone": "",
                      "contentLanguage": "English"
                    }
                  }
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-scopes": [
          "workspaces:write"
        ],
        "x-credit-cost": "none",
        "x-idempotent": true,
        "x-rate-limit": {
          "max": 60,
          "windowSec": 3600
        },
        "x-cli-command": "viraloop workspaces create",
        "x-mcp-tool": "viraloop_create_workspace"
      }
    },
    "/workspaces/{id}": {
      "get": {
        "operationId": "getWorkspace",
        "summary": "Get a workspace",
        "description": "Returns one workspace with its brand identity, positioning, tone of voice, content angles and preferences.",
        "tags": [
          "workspaces"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[0-9a-fA-F]{24}$",
              "description": "24 character hex object id"
            },
            "description": "24 character hex object id"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "example": {
                  "success": true,
                  "data": {
                    "id": "665f1b2a9c31a2b3c4d5e6f8",
                    "name": "Acme",
                    "isDefault": true,
                    "identity": {
                      "coreIdentity": "...",
                      "productOffering": "..."
                    },
                    "positioning": {
                      "mission": "..."
                    },
                    "toneVoice": {
                      "dos": [
                        "..."
                      ],
                      "donts": [
                        "..."
                      ]
                    },
                    "contentAngles": [
                      {
                        "title": "...",
                        "description": "..."
                      }
                    ],
                    "preferences": {
                      "timezone": "UTC",
                      "contentLanguage": "English"
                    }
                  }
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-scopes": [
          "workspaces:read"
        ],
        "x-credit-cost": "none",
        "x-cli-command": "viraloop workspaces get <id>"
      }
    },
    "/accounts": {
      "get": {
        "operationId": "listAccounts",
        "summary": "List connected social accounts",
        "description": "Lists the TikTok, Instagram and YouTube accounts connected to the workspace. Use the returned ids in selectedAccounts when creating posts. Connecting accounts (OAuth) happens in the web app, not through this API.",
        "tags": [
          "accounts"
        ],
        "parameters": [
          {
            "name": "platform",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "tiktok",
                "instagram",
                "youtube"
              ]
            }
          },
          {
            "name": "ownerType",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "brand",
                "influencer"
              ]
            }
          },
          {
            "name": "workspaceId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^[0-9a-fA-F]{24}$",
              "description": "Workspace to operate in. Defaults to the team's default workspace."
            },
            "description": "Workspace to operate in. Defaults to the team's default workspace."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "example": {
                  "success": true,
                  "data": [
                    {
                      "id": "665f1b2a9c31a2b3c4d5e700",
                      "platform": "tiktok",
                      "ownerType": "brand",
                      "username": "acme.hq",
                      "displayName": "Acme",
                      "label": "Main",
                      "isDefault": true
                    }
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-scopes": [
          "accounts:read"
        ],
        "x-credit-cost": "none",
        "x-cli-command": "viraloop accounts list",
        "x-mcp-tool": "viraloop_list_accounts"
      }
    },
    "/generations": {
      "post": {
        "operationId": "createGeneration",
        "summary": "Generate AI post suggestions",
        "description": "Generates a batch of ready-to-post content suggestions (video decks with captions, hashtags and rationale) using the workspace's brand context and Turbo configuration. Pass prompt to set the subject, and format to pick wall of text, slideshow or green screen meme. Synchronous: the request returns when generation finishes, typically 5 to 60 seconds depending on count. Review the results, then publish the ones you like via POST /posts with suggestionId.",
        "tags": [
          "generations"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "count": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 10,
                    "default": 5,
                    "description": "How many suggestions to generate (1-10)"
                  },
                  "format": {
                    "type": "string",
                    "enum": [
                      "walloftext",
                      "slideshow",
                      "greenscreen"
                    ],
                    "description": "Force one content format. Omit to use the workspace's configured mix."
                  },
                  "prompt": {
                    "type": "string",
                    "maxLength": 500,
                    "description": "What the batch should be about, e.g. 'why founders burn out on content'. Omit to let Turbo pick from the workspace's content angles."
                  },
                  "influencerId": {
                    "type": "string",
                    "pattern": "^[0-9a-fA-F]{24}$",
                    "description": "Feature this AI influencer in every suggestion"
                  },
                  "workspaceId": {
                    "type": "string",
                    "pattern": "^[0-9a-fA-F]{24}$",
                    "description": "Workspace to operate in. Defaults to the team's default workspace."
                  }
                },
                "additionalProperties": false
              },
              "example": {
                "count": 3,
                "format": "walloftext"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "example": {
                  "success": true,
                  "data": [
                    {
                      "id": "665f1b2a9c31a2b3c4d5e701",
                      "format": "walloftext",
                      "caption": "POV: the client asks for one small change",
                      "postCaption": "Every designer knows this feeling",
                      "hashtags": [
                        "design",
                        "clientwork"
                      ],
                      "status": "pending",
                      "statusUrl": "/api/v1/generations/665f1b2a9c31a2b3c4d5e701"
                    }
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-scopes": [
          "generations:write"
        ],
        "x-credit-cost": "none",
        "x-idempotent": true,
        "x-rate-limit": {
          "max": 10,
          "windowSec": 300
        },
        "x-cli-command": "viraloop generate",
        "x-mcp-tool": "viraloop_generate_content"
      },
      "get": {
        "operationId": "listGenerations",
        "summary": "List suggestions",
        "description": "Lists generated content suggestions in the workspace queue (automation-owned suggestions are excluded). Filter by status: pending (awaiting review), accepted, scheduled.",
        "tags": [
          "generations"
        ],
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "pending",
                "accepted",
                "scheduled",
                "deleted"
              ]
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1,
              "description": "Page number, starting at 1"
            },
            "description": "Page number, starting at 1"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20,
              "description": "Items per page (max 100)"
            },
            "description": "Items per page (max 100)"
          },
          {
            "name": "workspaceId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^[0-9a-fA-F]{24}$",
              "description": "Workspace to operate in. Defaults to the team's default workspace."
            },
            "description": "Workspace to operate in. Defaults to the team's default workspace."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "example": {
                  "success": true,
                  "data": [
                    {
                      "id": "665f1b2a9c31a2b3c4d5e701",
                      "format": "walloftext",
                      "caption": "POV: the client asks for one small change",
                      "status": "pending",
                      "createdAt": "2026-07-02T10:00:00.000Z"
                    }
                  ],
                  "pagination": {
                    "total": 12,
                    "page": 1,
                    "limit": 20,
                    "pages": 1
                  }
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-scopes": [
          "generations:read"
        ],
        "x-credit-cost": "none",
        "x-cli-command": "viraloop generations list",
        "x-mcp-tool": "viraloop_list_generations"
      }
    },
    "/generations/{id}": {
      "get": {
        "operationId": "getGeneration",
        "summary": "Get a suggestion",
        "description": "Returns one suggestion including its full deck (the editable render blueprint), influencer, angle, rationale and remix source. The deck IS the free preview: render its slide images / clips with the caption text boxes overlaid client-side to let a user accept or skip. Previewing and accepting are free; billing only happens when media is downloaded or published.",
        "tags": [
          "generations"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[0-9a-fA-F]{24}$",
              "description": "24 character hex object id"
            },
            "description": "24 character hex object id"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "example": {
                  "success": true,
                  "data": {
                    "id": "665f1b2a9c31a2b3c4d5e701",
                    "format": "walloftext",
                    "caption": "POV: the client asks for one small change",
                    "postCaption": "Every designer knows this feeling",
                    "hashtags": [
                      "design",
                      "clientwork"
                    ],
                    "why": [
                      "Relatable pain point",
                      "Strong hook"
                    ],
                    "angle": {
                      "title": "Client Revision Hell"
                    },
                    "status": "pending",
                    "deck": {
                      "ratio": "9:16",
                      "textBoxes": []
                    }
                  }
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-scopes": [
          "generations:read"
        ],
        "x-credit-cost": "none",
        "x-cli-command": "viraloop generations get <id>",
        "x-mcp-tool": "viraloop_get_generation"
      }
    },
    "/generations/{id}/accept": {
      "post": {
        "operationId": "acceptGeneration",
        "summary": "Accept a generation into the library",
        "description": "Accepts a generated suggestion and saves it to the content library, returning a contentId. That id is what GET /content/{id}/download (fetch the media files) and POST /posts (publish) operate on. Idempotent: re-accepting returns the same contentId. Counts toward the plan's monthly content allowance.",
        "tags": [
          "generations"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[0-9a-fA-F]{24}$",
              "description": "24 character hex object id"
            },
            "description": "24 character hex object id"
          },
          {
            "name": "workspaceId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^[0-9a-fA-F]{24}$",
              "description": "Workspace to operate in. Defaults to the team's default workspace."
            },
            "description": "Workspace to operate in. Defaults to the team's default workspace."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "example": {
                  "success": true,
                  "data": {
                    "id": "665f1b2a9c31a2b3c4d5e711",
                    "status": "accepted",
                    "contentId": "665f1b2a9c31a2b3c4d5e757"
                  }
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-scopes": [
          "generations:write"
        ],
        "x-credit-cost": "none",
        "x-idempotent": true,
        "x-cli-command": "viraloop generations accept <id>",
        "x-mcp-tool": "viraloop_accept_generation"
      }
    },
    "/posts": {
      "post": {
        "operationId": "createPost",
        "summary": "Create and schedule a post",
        "description": "Schedules a post to one or more connected accounts. Four content sources, checked in order: suggestionId (publish a generated suggestion), contentId (publish a saved studio video from any /content operation), deck + format (publish a raw deck), or videoUrl / images (publish your own media). Deck-based posts are rendered server-side after this call returns; the response is 202 with a statusUrl to poll. schedule asap posts as soon as the render is ready; schedule scheduled requires a future scheduledTime. Supports the Idempotency-Key header.",
        "tags": [
          "posts"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "suggestionId": {
                    "type": "string",
                    "pattern": "^[0-9a-fA-F]{24}$",
                    "description": "Publish this generated suggestion (from /generations)"
                  },
                  "contentId": {
                    "type": "string",
                    "pattern": "^[0-9a-fA-F]{24}$",
                    "description": "Publish a saved studio video (from any /content operation). Finished videos post as-is; deck formats render first."
                  },
                  "deck": {
                    "type": "object",
                    "additionalProperties": {},
                    "description": "Raw deck object (advanced; usually use suggestionId or contentId)"
                  },
                  "format": {
                    "type": "string",
                    "enum": [
                      "walloftext",
                      "slideshow",
                      "greenscreen",
                      "grid2x2",
                      "listicle",
                      "askmeanything",
                      "ranking",
                      "splitscreen",
                      "singlefadein",
                      "videohookdemo",
                      "talkingheadgreenscreen"
                    ],
                    "description": "Deck format, required when deck is provided"
                  },
                  "videoUrl": {
                    "type": "string",
                    "format": "uri",
                    "description": "Publicly reachable video URL to post as-is"
                  },
                  "thumbnailUrl": {
                    "type": "string",
                    "format": "uri"
                  },
                  "images": {
                    "type": "array",
                    "items": {
                      "anyOf": [
                        {
                          "type": "string",
                          "format": "uri"
                        },
                        {
                          "type": "object",
                          "properties": {
                            "url": {
                              "type": "string",
                              "format": "uri"
                            },
                            "thumbnailUrl": {
                              "type": "string",
                              "format": "uri"
                            }
                          },
                          "required": [
                            "url"
                          ],
                          "additionalProperties": false
                        }
                      ]
                    },
                    "description": "Image URLs to post as an image/slideshow post"
                  },
                  "selectedAccounts": {
                    "type": "object",
                    "properties": {
                      "tiktok": {
                        "type": "array",
                        "items": {
                          "type": "string",
                          "pattern": "^[0-9a-fA-F]{24}$",
                          "description": "24 character hex object id"
                        }
                      },
                      "instagram": {
                        "type": "array",
                        "items": {
                          "type": "string",
                          "pattern": "^[0-9a-fA-F]{24}$",
                          "description": "24 character hex object id"
                        }
                      },
                      "youtube": {
                        "type": "array",
                        "items": {
                          "type": "string",
                          "pattern": "^[0-9a-fA-F]{24}$",
                          "description": "24 character hex object id"
                        }
                      }
                    },
                    "additionalProperties": false,
                    "description": "Social account ids per platform (from GET /accounts). At least one non-empty platform array is required."
                  },
                  "schedule": {
                    "type": "string",
                    "enum": [
                      "asap",
                      "scheduled"
                    ],
                    "default": "asap"
                  },
                  "scheduledTime": {
                    "type": "string",
                    "description": "Required when schedule is scheduled; must be in the future"
                  },
                  "timezone": {
                    "type": "string",
                    "description": "IANA timezone, default UTC"
                  },
                  "caption": {
                    "type": "string",
                    "maxLength": 2200,
                    "description": "Post caption/description. Defaults to the suggestion's."
                  },
                  "hashtags": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "ownerType": {
                    "type": "string",
                    "enum": [
                      "brand",
                      "influencer"
                    ],
                    "default": "brand"
                  },
                  "influencerId": {
                    "type": "string",
                    "pattern": "^[0-9a-fA-F]{24}$",
                    "description": "Required when ownerType is influencer"
                  },
                  "tiktokSendToInbox": {
                    "type": "boolean",
                    "description": "Send to TikTok inbox as draft instead of publishing"
                  },
                  "workspaceId": {
                    "type": "string",
                    "pattern": "^[0-9a-fA-F]{24}$",
                    "description": "Workspace to operate in. Defaults to the team's default workspace."
                  }
                },
                "required": [
                  "selectedAccounts"
                ],
                "additionalProperties": false
              },
              "example": {
                "suggestionId": "665f1b2a9c31a2b3c4d5e701",
                "selectedAccounts": {
                  "tiktok": [
                    "665f1b2a9c31a2b3c4d5e700"
                  ]
                },
                "schedule": "asap"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Success",
            "content": {
              "application/json": {
                "example": {
                  "success": true,
                  "data": {
                    "id": "665f1b2a9c31a2b3c4d5e702",
                    "kind": "post",
                    "status": "scheduled",
                    "renderStatus": "pending",
                    "scheduledTime": "2026-07-02T10:05:00.000Z",
                    "statusUrl": "/api/v1/posts/665f1b2a9c31a2b3c4d5e702"
                  }
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-scopes": [
          "posts:write"
        ],
        "x-credit-cost": "none",
        "x-idempotent": true,
        "x-rate-limit": {
          "max": 60,
          "windowSec": 300
        },
        "x-terminal-states": [
          "posted",
          "partial",
          "completed",
          "failed"
        ],
        "x-cli-command": "viraloop posts create",
        "x-mcp-tool": "viraloop_create_post"
      },
      "get": {
        "operationId": "listPosts",
        "summary": "List posts",
        "description": "Lists the workspace's posts with optional status, automation and scheduled-time filters.",
        "tags": [
          "posts"
        ],
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "draft",
                "scheduled",
                "processing",
                "completed",
                "failed",
                "posted",
                "partial"
              ]
            }
          },
          {
            "name": "automationId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^[0-9a-fA-F]{24}$",
              "description": "24 character hex object id"
            },
            "description": "24 character hex object id"
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "scheduledTime lower bound"
            },
            "description": "scheduledTime lower bound"
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "scheduledTime upper bound"
            },
            "description": "scheduledTime upper bound"
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1,
              "description": "Page number, starting at 1"
            },
            "description": "Page number, starting at 1"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20,
              "description": "Items per page (max 100)"
            },
            "description": "Items per page (max 100)"
          },
          {
            "name": "workspaceId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^[0-9a-fA-F]{24}$",
              "description": "Workspace to operate in. Defaults to the team's default workspace."
            },
            "description": "Workspace to operate in. Defaults to the team's default workspace."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "example": {
                  "success": true,
                  "data": [
                    {
                      "id": "665f1b2a9c31a2b3c4d5e702",
                      "postType": "video",
                      "status": "posted",
                      "renderStatus": "ready",
                      "scheduledTime": "2026-07-02T10:05:00.000Z",
                      "postedAt": "2026-07-02T10:06:03.000Z",
                      "statusUrl": "/api/v1/posts/665f1b2a9c31a2b3c4d5e702"
                    }
                  ],
                  "pagination": {
                    "total": 1,
                    "page": 1,
                    "limit": 20,
                    "pages": 1
                  }
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-scopes": [
          "posts:read"
        ],
        "x-credit-cost": "none",
        "x-cli-command": "viraloop posts list",
        "x-mcp-tool": "viraloop_list_posts"
      }
    },
    "/posts/{id}": {
      "get": {
        "operationId": "getPost",
        "summary": "Get a post with per-platform results",
        "description": "Returns one post including render state and per-platform posting results (status, post URL, analytics snapshot). Poll this after creating a post: terminal statuses are posted, partial, completed and failed; renderStatus failed is also terminal.",
        "tags": [
          "posts"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[0-9a-fA-F]{24}$",
              "description": "24 character hex object id"
            },
            "description": "24 character hex object id"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "example": {
                  "success": true,
                  "data": {
                    "id": "665f1b2a9c31a2b3c4d5e702",
                    "postType": "video",
                    "status": "posted",
                    "renderStatus": "ready",
                    "videoUrl": "https://cdn.viraloop.io/renders/abc.mp4",
                    "platforms": [
                      {
                        "platform": "tiktok",
                        "status": "posted",
                        "postUrl": "https://www.tiktok.com/@acme.hq/video/123",
                        "analytics": {
                          "views": 1200,
                          "likes": 80,
                          "comments": 4,
                          "shares": 2
                        }
                      }
                    ]
                  }
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-scopes": [
          "posts:read"
        ],
        "x-credit-cost": "none",
        "x-terminal-states": [
          "posted",
          "partial",
          "completed",
          "failed"
        ],
        "x-cli-command": "viraloop posts get <id>",
        "x-mcp-tool": "viraloop_get_post"
      },
      "delete": {
        "operationId": "cancelPost",
        "summary": "Cancel a scheduled post",
        "description": "Cancels a post that has not been published yet (status scheduled). Published or in-flight posts cannot be cancelled; that returns 409.",
        "tags": [
          "posts"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[0-9a-fA-F]{24}$",
              "description": "24 character hex object id"
            },
            "description": "24 character hex object id"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "example": {
                  "success": true,
                  "data": {
                    "id": "665f1b2a9c31a2b3c4d5e702",
                    "status": "cancelled"
                  }
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-scopes": [
          "posts:write"
        ],
        "x-credit-cost": "none",
        "x-cli-command": "viraloop posts cancel <id>",
        "x-mcp-tool": "viraloop_cancel_post"
      }
    },
    "/calendar": {
      "get": {
        "operationId": "getCalendar",
        "summary": "Posting calendar",
        "description": "Returns the workspace's posts falling in a date window (by scheduled time, posted time, or creation time for drafts). Useful to check what is already queued before scheduling more.",
        "tags": [
          "posts"
        ],
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ISO 8601 date or datetime, e.g. 2026-07-03T10:00:00Z"
            },
            "description": "ISO 8601 date or datetime, e.g. 2026-07-03T10:00:00Z"
          },
          {
            "name": "to",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ISO 8601 date or datetime, e.g. 2026-07-03T10:00:00Z"
            },
            "description": "ISO 8601 date or datetime, e.g. 2026-07-03T10:00:00Z"
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "draft",
                "scheduled",
                "processing",
                "completed",
                "failed",
                "posted",
                "partial"
              ]
            }
          },
          {
            "name": "workspaceId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^[0-9a-fA-F]{24}$",
              "description": "Workspace to operate in. Defaults to the team's default workspace."
            },
            "description": "Workspace to operate in. Defaults to the team's default workspace."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "example": {
                  "success": true,
                  "data": [
                    {
                      "id": "665f1b2a9c31a2b3c4d5e702",
                      "status": "scheduled",
                      "scheduledTime": "2026-07-03T10:00:00.000Z",
                      "postType": "video",
                      "platforms": [
                        "tiktok"
                      ]
                    }
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-scopes": [
          "posts:read"
        ],
        "x-credit-cost": "none",
        "x-cli-command": "viraloop calendar"
      }
    },
    "/automations": {
      "post": {
        "operationId": "createAutomation",
        "summary": "Create an automation",
        "description": "Creates a draft automation: a batch of AI posts generated at once and published on a schedule. Set name, cadence, selectedAccounts and settings here or later via PATCH, then call generate, review the posts, and launch. Monthly automation quota depends on the plan.",
        "tags": [
          "automations"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 120
                  },
                  "cadence": {
                    "type": "object",
                    "properties": {
                      "postsPerDay": {
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 10
                      },
                      "lengthDays": {
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 90
                      },
                      "startDate": {
                        "type": "string",
                        "description": "First posting day; defaults to tomorrow"
                      },
                      "timezone": {
                        "type": "string",
                        "description": "IANA timezone for the slots"
                      },
                      "timeSlots": {
                        "type": "array",
                        "items": {
                          "type": "string",
                          "pattern": "^\\d{2}:\\d{2}$"
                        },
                        "description": "Posting times per day, e.g. [\"09:00\", \"15:00\"]"
                      }
                    },
                    "additionalProperties": false,
                    "description": "Posting cadence: how many posts per day, for how many days"
                  },
                  "selectedAccounts": {
                    "type": "object",
                    "properties": {
                      "tiktok": {
                        "type": "array",
                        "items": {
                          "type": "string",
                          "pattern": "^[0-9a-fA-F]{24}$",
                          "description": "24 character hex object id"
                        }
                      },
                      "instagram": {
                        "type": "array",
                        "items": {
                          "type": "string",
                          "pattern": "^[0-9a-fA-F]{24}$",
                          "description": "24 character hex object id"
                        }
                      },
                      "youtube": {
                        "type": "array",
                        "items": {
                          "type": "string",
                          "pattern": "^[0-9a-fA-F]{24}$",
                          "description": "24 character hex object id"
                        }
                      }
                    },
                    "additionalProperties": false,
                    "description": "Social account ids per platform (from GET /accounts). At least one non-empty platform array is required."
                  },
                  "settings": {
                    "type": "object",
                    "properties": {
                      "contentMix": {
                        "type": "object",
                        "additionalProperties": {
                          "type": "number",
                          "minimum": 0,
                          "maximum": 100
                        },
                        "description": "Format weights, keys: walloftext, slideshow, greenscreen, hookdemo"
                      },
                      "remixRatio": {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 100
                      },
                      "angleDistribution": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "title": {
                              "type": "string"
                            },
                            "percent": {
                              "type": "number"
                            }
                          },
                          "required": [
                            "title",
                            "percent"
                          ],
                          "additionalProperties": false
                        }
                      },
                      "mentionBusiness": {
                        "type": "string",
                        "enum": [
                          "never",
                          "rarely",
                          "sometimes",
                          "often",
                          "always"
                        ]
                      },
                      "genderPreference": {
                        "type": "string",
                        "enum": [
                          "any",
                          "men",
                          "women"
                        ]
                      },
                      "ownMediaMix": {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 100
                      },
                      "influencerFrequency": {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 100
                      },
                      "language": {
                        "type": "string",
                        "description": "Content language for this automation; empty follows the workspace preference"
                      },
                      "slideshowVideo": {
                        "type": "object",
                        "properties": {
                          "enabled": {
                            "type": "boolean"
                          },
                          "transition": {
                            "type": "string",
                            "enum": [
                              "cut",
                              "fade",
                              "slide"
                            ]
                          },
                          "slideDuration": {
                            "type": "number",
                            "minimum": 1,
                            "maximum": 15
                          }
                        },
                        "additionalProperties": false,
                        "description": "Render slideshows as one video instead of an image carousel"
                      }
                    },
                    "additionalProperties": false,
                    "description": "Generation settings (defaults are sensible; all optional)"
                  },
                  "ownerType": {
                    "type": "string",
                    "enum": [
                      "brand",
                      "influencer"
                    ]
                  },
                  "influencerId": {
                    "type": "string",
                    "pattern": "^[0-9a-fA-F]{24}$",
                    "description": "Required when ownerType is influencer"
                  },
                  "tiktokMode": {
                    "type": "string",
                    "enum": [
                      "direct",
                      "inbox"
                    ],
                    "description": "TikTok publish mode; inbox sends drafts to the inbox"
                  },
                  "tiktokOptions": {
                    "type": "object",
                    "properties": {
                      "privacyLevel": {
                        "type": "string",
                        "enum": [
                          "PUBLIC_TO_EVERYONE",
                          "MUTUAL_FOLLOW_FRIENDS",
                          "SELF_ONLY"
                        ]
                      },
                      "allowComment": {
                        "type": "boolean"
                      },
                      "allowDuet": {
                        "type": "boolean",
                        "description": "Video posts only"
                      },
                      "allowStitch": {
                        "type": "boolean",
                        "description": "Video posts only"
                      },
                      "autoAddMusic": {
                        "type": "boolean",
                        "description": "Let TikTok pick a song. Image carousels only"
                      }
                    },
                    "additionalProperties": false,
                    "description": "TikTok publish options (direct posting only)"
                  },
                  "workspaceId": {
                    "type": "string",
                    "pattern": "^[0-9a-fA-F]{24}$",
                    "description": "Workspace to operate in. Defaults to the team's default workspace."
                  }
                },
                "required": [
                  "name"
                ],
                "additionalProperties": false
              },
              "example": {
                "name": "July launch week",
                "cadence": {
                  "postsPerDay": 2,
                  "lengthDays": 7,
                  "timezone": "America/New_York"
                },
                "selectedAccounts": {
                  "tiktok": [
                    "665f1b2a9c31a2b3c4d5e700"
                  ]
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "example": {
                  "success": true,
                  "data": {
                    "id": "665f1b2a9c31a2b3c4d5e710",
                    "name": "July launch week",
                    "status": "draft",
                    "cadence": {
                      "postsPerDay": 2,
                      "lengthDays": 7,
                      "timezone": "America/New_York",
                      "timeSlots": []
                    },
                    "totalPosts": 0,
                    "statusUrl": "/api/v1/automations/665f1b2a9c31a2b3c4d5e710"
                  }
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-scopes": [
          "automations:write"
        ],
        "x-credit-cost": "none",
        "x-idempotent": true,
        "x-cli-command": "viraloop automations create",
        "x-mcp-tool": "viraloop_create_automation"
      },
      "get": {
        "operationId": "listAutomations",
        "summary": "List automations",
        "description": "Lists the workspace's automations plus the monthly quota (limit, used, remaining).",
        "tags": [
          "automations"
        ],
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "draft",
                "generating",
                "review",
                "active",
                "completed",
                "cancelled"
              ]
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1,
              "description": "Page number, starting at 1"
            },
            "description": "Page number, starting at 1"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20,
              "description": "Items per page (max 100)"
            },
            "description": "Items per page (max 100)"
          },
          {
            "name": "workspaceId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^[0-9a-fA-F]{24}$",
              "description": "Workspace to operate in. Defaults to the team's default workspace."
            },
            "description": "Workspace to operate in. Defaults to the team's default workspace."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "example": {
                  "success": true,
                  "data": {
                    "automations": [
                      {
                        "id": "665f1b2a9c31a2b3c4d5e710",
                        "name": "July launch week",
                        "status": "active",
                        "totalPosts": 14,
                        "postedCount": 6
                      }
                    ],
                    "quota": {
                      "monthlyLimit": 8,
                      "usedThisMonth": 2,
                      "remaining": 6
                    }
                  },
                  "pagination": {
                    "total": 2,
                    "page": 1,
                    "limit": 20,
                    "pages": 1
                  }
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-scopes": [
          "automations:read"
        ],
        "x-credit-cost": "none",
        "x-cli-command": "viraloop automations list",
        "x-mcp-tool": "viraloop_list_automations"
      }
    },
    "/automations/{id}": {
      "get": {
        "operationId": "getAutomation",
        "summary": "Get an automation",
        "description": "Returns one automation with its live generatedCount. Poll this after calling generate: the automation leaves the generating status when done (review on success).",
        "tags": [
          "automations"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[0-9a-fA-F]{24}$",
              "description": "24 character hex object id"
            },
            "description": "24 character hex object id"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "example": {
                  "success": true,
                  "data": {
                    "id": "665f1b2a9c31a2b3c4d5e710",
                    "name": "July launch week",
                    "status": "review",
                    "totalPosts": 14,
                    "generatedCount": 14,
                    "statusUrl": "/api/v1/automations/665f1b2a9c31a2b3c4d5e710"
                  }
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-scopes": [
          "automations:read"
        ],
        "x-credit-cost": "none",
        "x-terminal-states": [
          "draft",
          "review",
          "active",
          "completed",
          "cancelled"
        ],
        "x-cli-command": "viraloop automations get <id>",
        "x-mcp-tool": "viraloop_get_automation"
      },
      "patch": {
        "operationId": "updateAutomation",
        "summary": "Update a draft automation",
        "description": "Updates name, cadence, selectedAccounts, settings, ownerType, influencerId or tiktokMode. Only allowed while the automation is in draft or review; sub-objects are replaced wholesale.",
        "tags": [
          "automations"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[0-9a-fA-F]{24}$",
              "description": "24 character hex object id"
            },
            "description": "24 character hex object id"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 120
                  },
                  "cadence": {
                    "type": "object",
                    "properties": {
                      "postsPerDay": {
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 10
                      },
                      "lengthDays": {
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 90
                      },
                      "startDate": {
                        "type": "string",
                        "description": "First posting day; defaults to tomorrow"
                      },
                      "timezone": {
                        "type": "string",
                        "description": "IANA timezone for the slots"
                      },
                      "timeSlots": {
                        "type": "array",
                        "items": {
                          "type": "string",
                          "pattern": "^\\d{2}:\\d{2}$"
                        },
                        "description": "Posting times per day, e.g. [\"09:00\", \"15:00\"]"
                      }
                    },
                    "additionalProperties": false,
                    "description": "Posting cadence: how many posts per day, for how many days"
                  },
                  "selectedAccounts": {
                    "type": "object",
                    "properties": {
                      "tiktok": {
                        "type": "array",
                        "items": {
                          "type": "string",
                          "pattern": "^[0-9a-fA-F]{24}$",
                          "description": "24 character hex object id"
                        }
                      },
                      "instagram": {
                        "type": "array",
                        "items": {
                          "type": "string",
                          "pattern": "^[0-9a-fA-F]{24}$",
                          "description": "24 character hex object id"
                        }
                      },
                      "youtube": {
                        "type": "array",
                        "items": {
                          "type": "string",
                          "pattern": "^[0-9a-fA-F]{24}$",
                          "description": "24 character hex object id"
                        }
                      }
                    },
                    "additionalProperties": false,
                    "description": "Social account ids per platform (from GET /accounts). At least one non-empty platform array is required."
                  },
                  "settings": {
                    "type": "object",
                    "properties": {
                      "contentMix": {
                        "type": "object",
                        "additionalProperties": {
                          "type": "number",
                          "minimum": 0,
                          "maximum": 100
                        },
                        "description": "Format weights, keys: walloftext, slideshow, greenscreen, hookdemo"
                      },
                      "remixRatio": {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 100
                      },
                      "angleDistribution": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "title": {
                              "type": "string"
                            },
                            "percent": {
                              "type": "number"
                            }
                          },
                          "required": [
                            "title",
                            "percent"
                          ],
                          "additionalProperties": false
                        }
                      },
                      "mentionBusiness": {
                        "type": "string",
                        "enum": [
                          "never",
                          "rarely",
                          "sometimes",
                          "often",
                          "always"
                        ]
                      },
                      "genderPreference": {
                        "type": "string",
                        "enum": [
                          "any",
                          "men",
                          "women"
                        ]
                      },
                      "ownMediaMix": {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 100
                      },
                      "influencerFrequency": {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 100
                      },
                      "language": {
                        "type": "string",
                        "description": "Content language for this automation; empty follows the workspace preference"
                      },
                      "slideshowVideo": {
                        "type": "object",
                        "properties": {
                          "enabled": {
                            "type": "boolean"
                          },
                          "transition": {
                            "type": "string",
                            "enum": [
                              "cut",
                              "fade",
                              "slide"
                            ]
                          },
                          "slideDuration": {
                            "type": "number",
                            "minimum": 1,
                            "maximum": 15
                          }
                        },
                        "additionalProperties": false,
                        "description": "Render slideshows as one video instead of an image carousel"
                      }
                    },
                    "additionalProperties": false,
                    "description": "Generation settings (defaults are sensible; all optional)"
                  },
                  "ownerType": {
                    "type": "string",
                    "enum": [
                      "brand",
                      "influencer"
                    ]
                  },
                  "influencerId": {
                    "type": "string",
                    "pattern": "^[0-9a-fA-F]{24}$",
                    "description": "24 character hex object id"
                  },
                  "tiktokMode": {
                    "type": "string",
                    "enum": [
                      "direct",
                      "inbox"
                    ]
                  },
                  "tiktokOptions": {
                    "type": "object",
                    "properties": {
                      "privacyLevel": {
                        "type": "string",
                        "enum": [
                          "PUBLIC_TO_EVERYONE",
                          "MUTUAL_FOLLOW_FRIENDS",
                          "SELF_ONLY"
                        ]
                      },
                      "allowComment": {
                        "type": "boolean"
                      },
                      "allowDuet": {
                        "type": "boolean",
                        "description": "Video posts only"
                      },
                      "allowStitch": {
                        "type": "boolean",
                        "description": "Video posts only"
                      },
                      "autoAddMusic": {
                        "type": "boolean",
                        "description": "Let TikTok pick a song. Image carousels only"
                      }
                    },
                    "additionalProperties": false,
                    "description": "TikTok publish options (direct posting only)"
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "example": {
                  "success": true,
                  "data": {
                    "id": "665f1b2a9c31a2b3c4d5e710",
                    "name": "July launch week",
                    "status": "draft",
                    "selectedAccounts": {
                      "tiktok": [
                        "665f1b2a9c31a2b3c4d5e700"
                      ]
                    }
                  }
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-scopes": [
          "automations:write"
        ],
        "x-credit-cost": "none",
        "x-cli-command": "viraloop automations update <id>"
      }
    },
    "/automations/{id}/generate": {
      "post": {
        "operationId": "generateAutomation",
        "summary": "Generate the automation's posts",
        "description": "Generates cadence.postsPerDay x cadence.lengthDays AI posts for the automation, each assigned a schedule slot. Asynchronous: returns 202 immediately; poll the automation until it reaches review (success) or back to draft (nothing generated). Calling it again while generating is a no-op that reports progress. Regenerating an automation in review replaces its posts.",
        "tags": [
          "automations"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[0-9a-fA-F]{24}$",
              "description": "24 character hex object id"
            },
            "description": "24 character hex object id"
          }
        ],
        "responses": {
          "202": {
            "description": "Success",
            "content": {
              "application/json": {
                "example": {
                  "success": true,
                  "data": {
                    "id": "665f1b2a9c31a2b3c4d5e710",
                    "kind": "automation",
                    "status": "generating",
                    "totalPosts": 14,
                    "generatedCount": 0,
                    "statusUrl": "/api/v1/automations/665f1b2a9c31a2b3c4d5e710"
                  }
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-scopes": [
          "automations:write"
        ],
        "x-credit-cost": "none",
        "x-rate-limit": {
          "max": 5,
          "windowSec": 3600
        },
        "x-terminal-states": [
          "draft",
          "review",
          "active",
          "completed",
          "cancelled"
        ],
        "x-cli-command": "viraloop automations generate <id>",
        "x-mcp-tool": "viraloop_generate_automation"
      }
    },
    "/automations/{id}/extend": {
      "post": {
        "operationId": "extendAutomation",
        "summary": "Extend an automation by more days",
        "description": "Adds `days` more days to an active or completed automation: generates cadence.postsPerDay x days new posts, schedules them in the days after the current window and publishes them to the automation's accounts. Posts already scheduled or published are never touched. Extending a completed automation revives it to active. Asynchronous: returns 202 immediately; the automation carries extending=true until the new posts land, so poll GET /automations/{id} until it flips false.",
        "tags": [
          "automations"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[0-9a-fA-F]{24}$",
              "description": "24 character hex object id"
            },
            "description": "24 character hex object id"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "days": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 90,
                    "description": "How many days to add to the automation window"
                  },
                  "workspaceId": {
                    "type": "string",
                    "pattern": "^[0-9a-fA-F]{24}$",
                    "description": "Workspace to operate in. Defaults to the team's default workspace."
                  }
                },
                "required": [
                  "days"
                ],
                "additionalProperties": false
              },
              "example": {
                "days": 7
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Success",
            "content": {
              "application/json": {
                "example": {
                  "success": true,
                  "data": {
                    "id": "665f1b2a9c31a2b3c4d5e710",
                    "kind": "automation",
                    "status": "active",
                    "extending": true,
                    "adding": 7,
                    "statusUrl": "/api/v1/automations/665f1b2a9c31a2b3c4d5e710"
                  }
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-scopes": [
          "automations:write"
        ],
        "x-credit-cost": "none",
        "x-rate-limit": {
          "max": 5,
          "windowSec": 3600
        },
        "x-cli-command": "viraloop automations extend <id> --days <n>",
        "x-mcp-tool": "viraloop_extend_automation"
      }
    },
    "/automations/{id}/launch": {
      "post": {
        "operationId": "launchAutomation",
        "summary": "Launch a reviewed automation",
        "description": "Converts every generated post into a scheduled post at its slot and activates the automation. Requires status review and at least one selected account. Posts render server-side after this returns and publish automatically at their slots.",
        "tags": [
          "automations"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[0-9a-fA-F]{24}$",
              "description": "24 character hex object id"
            },
            "description": "24 character hex object id"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "example": {
                  "success": true,
                  "data": {
                    "id": "665f1b2a9c31a2b3c4d5e710",
                    "kind": "automation",
                    "status": "active",
                    "scheduled": 14,
                    "failed": 0,
                    "statusUrl": "/api/v1/automations/665f1b2a9c31a2b3c4d5e710"
                  }
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-scopes": [
          "automations:write"
        ],
        "x-credit-cost": "none",
        "x-cli-command": "viraloop automations launch <id>",
        "x-mcp-tool": "viraloop_launch_automation"
      }
    },
    "/automations/{id}/cancel": {
      "post": {
        "operationId": "cancelAutomation",
        "summary": "Cancel an automation",
        "description": "Cancels the automation and removes its unsent posts. Content that already went out stays live. Idempotent: cancelling a cancelled or completed automation returns cancelledPosts 0.",
        "tags": [
          "automations"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[0-9a-fA-F]{24}$",
              "description": "24 character hex object id"
            },
            "description": "24 character hex object id"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "example": {
                  "success": true,
                  "data": {
                    "id": "665f1b2a9c31a2b3c4d5e710",
                    "status": "cancelled",
                    "cancelledPosts": 8
                  }
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-scopes": [
          "automations:write"
        ],
        "x-credit-cost": "none",
        "x-cli-command": "viraloop automations cancel <id>",
        "x-mcp-tool": "viraloop_cancel_automation"
      }
    },
    "/automations/{id}/posts": {
      "get": {
        "operationId": "listAutomationPosts",
        "summary": "List an automation's generated posts",
        "description": "Lists the automation's generated posts (suggestions) in schedule order, for review before launching. Each carries caption, postCaption, hashtags, rationale and its assigned scheduledTime.",
        "tags": [
          "automations"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[0-9a-fA-F]{24}$",
              "description": "24 character hex object id"
            },
            "description": "24 character hex object id"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "example": {
                  "success": true,
                  "data": [
                    {
                      "id": "665f1b2a9c31a2b3c4d5e701",
                      "format": "walloftext",
                      "caption": "POV: the client asks for one small change",
                      "postCaption": "Every designer knows this feeling",
                      "hashtags": [
                        "design"
                      ],
                      "status": "pending",
                      "scheduledTime": "2026-07-06T13:00:00.000Z"
                    }
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-scopes": [
          "automations:read"
        ],
        "x-credit-cost": "none",
        "x-cli-command": "viraloop automations posts <id>",
        "x-mcp-tool": "viraloop_list_automation_posts"
      }
    },
    "/influencers": {
      "get": {
        "operationId": "listInfluencers",
        "summary": "List AI influencers",
        "description": "Lists the workspace's AI influencers (virtual personas used to front content).",
        "tags": [
          "influencers"
        ],
        "parameters": [
          {
            "name": "search",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Search name/description/tags"
            },
            "description": "Search name/description/tags"
          },
          {
            "name": "niche",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1,
              "description": "Page number, starting at 1"
            },
            "description": "Page number, starting at 1"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20,
              "description": "Items per page (max 100)"
            },
            "description": "Items per page (max 100)"
          },
          {
            "name": "workspaceId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^[0-9a-fA-F]{24}$",
              "description": "Workspace to operate in. Defaults to the team's default workspace."
            },
            "description": "Workspace to operate in. Defaults to the team's default workspace."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "example": {
                  "success": true,
                  "data": [
                    {
                      "id": "665f1b2a9c31a2b3c4d5e720",
                      "name": "Maya",
                      "niche": "fitness",
                      "style": "realistic",
                      "imageUrl": "https://cdn.viraloop.io/influencers/maya.jpg",
                      "turboEnabled": true
                    }
                  ],
                  "pagination": {
                    "total": 3,
                    "page": 1,
                    "limit": 20,
                    "pages": 1
                  }
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-scopes": [
          "influencers:read"
        ],
        "x-credit-cost": "none",
        "x-cli-command": "viraloop influencers list",
        "x-mcp-tool": "viraloop_list_influencers"
      },
      "post": {
        "operationId": "createInfluencer",
        "summary": "Create an AI influencer",
        "description": "Creates an influencer from a base image you provide (a publicly reachable image URL). A short animated preview is generated in the background when the team has credits. To generate a base image from a prompt instead, use the web app. Set style to \"character\" for a non-human influencer (a mascot, cartoon or stick figure): every prompt the platform builds for it then describes a stylized character instead of a real person, and gender/age/ethnicity do not apply.",
        "tags": [
          "influencers"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100
                  },
                  "imageUrl": {
                    "type": "string",
                    "format": "uri",
                    "description": "Publicly reachable base image of the persona"
                  },
                  "description": {
                    "type": "string",
                    "maxLength": 500
                  },
                  "niche": {
                    "type": "string",
                    "description": "One of the app's niche slugs, e.g. fitness, tech, food"
                  },
                  "style": {
                    "type": "string",
                    "enum": [
                      "realistic",
                      "character"
                    ],
                    "description": "Visual style. \"realistic\" (default) is a photoreal human; \"character\" is a stylized non-human persona."
                  },
                  "characterDescription": {
                    "type": "string",
                    "maxLength": 1500,
                    "description": "For style \"character\": what the character looks like, including its art style. Used to keep later generations on-model."
                  },
                  "gender": {
                    "type": "string",
                    "enum": [
                      "male",
                      "female"
                    ],
                    "description": "Only meaningful for style \"realistic\"."
                  },
                  "age": {
                    "type": "integer",
                    "minimum": 18,
                    "maximum": 99,
                    "description": "Only meaningful for style \"realistic\"."
                  },
                  "ethnicity": {
                    "type": "string",
                    "maxLength": 60,
                    "description": "Only meaningful for style \"realistic\"."
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "workspaceId": {
                    "type": "string",
                    "pattern": "^[0-9a-fA-F]{24}$",
                    "description": "Workspace to operate in. Defaults to the team's default workspace."
                  }
                },
                "required": [
                  "name",
                  "imageUrl"
                ],
                "additionalProperties": false
              },
              "example": {
                "name": "Maya",
                "imageUrl": "https://example.com/maya.jpg",
                "niche": "fitness",
                "gender": "female"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "example": {
                  "success": true,
                  "data": {
                    "id": "665f1b2a9c31a2b3c4d5e720",
                    "name": "Maya",
                    "niche": "fitness",
                    "style": "realistic",
                    "imageUrl": "https://example.com/maya.jpg",
                    "videoPreview": {
                      "status": "pending",
                      "videoUrl": "",
                      "thumbnailUrl": ""
                    }
                  }
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-scopes": [
          "influencers:write"
        ],
        "x-credit-cost": "10 credits for the optional animated preview (skipped when out of credits)",
        "x-idempotent": true,
        "x-rate-limit": {
          "max": 10,
          "windowSec": 3600
        },
        "x-cli-command": "viraloop influencers create",
        "x-mcp-tool": "viraloop_create_influencer"
      }
    },
    "/influencers/{id}": {
      "get": {
        "operationId": "getInfluencer",
        "summary": "Get an influencer",
        "description": "Returns one influencer including its base image, preview video state and Turbo settings.",
        "tags": [
          "influencers"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[0-9a-fA-F]{24}$",
              "description": "24 character hex object id"
            },
            "description": "24 character hex object id"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "example": {
                  "success": true,
                  "data": {
                    "id": "665f1b2a9c31a2b3c4d5e720",
                    "name": "Maya",
                    "description": "Energetic fitness coach",
                    "niche": "fitness",
                    "style": "realistic",
                    "imageUrl": "https://cdn.viraloop.io/influencers/maya.jpg",
                    "turboEnabled": true,
                    "allowedAngles": []
                  }
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-scopes": [
          "influencers:read"
        ],
        "x-credit-cost": "none",
        "x-cli-command": "viraloop influencers get <id>"
      }
    },
    "/influencers/{id}/videos": {
      "post": {
        "operationId": "createInfluencerVideo",
        "summary": "Generate a talking-head video",
        "description": "Generates a talking-head UGC video of the influencer speaking your script (Seedance 2, 9:16). Costs 5 credits per second of video (default 10s = 50 credits), deducted up front and refunded automatically if generation fails. Insufficient credits returns HTTP 402 (insufficient_credits). Asynchronous: returns 202 with the video in processing; poll GET /videos/{videoId} until completed or failed (typically 2 to 10 minutes).",
        "tags": [
          "videos"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[0-9a-fA-F]{24}$",
              "description": "24 character hex object id"
            },
            "description": "24 character hex object id"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "script": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 1000,
                    "description": "What the influencer says (max 1000 chars)"
                  },
                  "imageUrl": {
                    "type": "string",
                    "format": "uri",
                    "description": "Reference image; defaults to the influencer's base image"
                  },
                  "language": {
                    "type": "string",
                    "description": "Spoken language, default English"
                  },
                  "duration": {
                    "type": "integer",
                    "minimum": 5,
                    "maximum": 30
                  },
                  "mode": {
                    "type": "string",
                    "enum": [
                      "speaker",
                      "scene"
                    ],
                    "description": "speaker: talking head; scene: wider shot"
                  }
                },
                "required": [
                  "script"
                ],
                "additionalProperties": false
              },
              "example": {
                "script": "Three things I wish I knew before my first marathon",
                "duration": 10
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Success",
            "content": {
              "application/json": {
                "example": {
                  "success": true,
                  "data": {
                    "id": "665f1b2a9c31a2b3c4d5e730",
                    "kind": "video",
                    "influencerId": "665f1b2a9c31a2b3c4d5e720",
                    "status": "processing",
                    "model": "seedance_2",
                    "creditsUsed": 50,
                    "statusUrl": "/api/v1/videos/665f1b2a9c31a2b3c4d5e730"
                  }
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-scopes": [
          "influencers:write"
        ],
        "x-credit-cost": "5 credits per second (duration 5-30s; default 10s = 50 credits)",
        "x-idempotent": true,
        "x-rate-limit": {
          "max": 10,
          "windowSec": 600
        },
        "x-terminal-states": [
          "completed",
          "failed"
        ],
        "x-cli-command": "viraloop videos create --influencer <id>",
        "x-mcp-tool": "viraloop_create_video"
      },
      "get": {
        "operationId": "listInfluencerVideos",
        "summary": "List an influencer's videos",
        "description": "Lists the influencer's generated videos, newest first, with status and URLs.",
        "tags": [
          "videos"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[0-9a-fA-F]{24}$",
              "description": "24 character hex object id"
            },
            "description": "24 character hex object id"
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "pending",
                "processing",
                "completed",
                "failed"
              ]
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1,
              "description": "Page number, starting at 1"
            },
            "description": "Page number, starting at 1"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20,
              "description": "Items per page (max 100)"
            },
            "description": "Items per page (max 100)"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "example": {
                  "success": true,
                  "data": [
                    {
                      "id": "665f1b2a9c31a2b3c4d5e730",
                      "status": "completed",
                      "videoUrl": "https://cdn.viraloop.io/videos/abc.mp4",
                      "thumbnailUrl": "https://cdn.viraloop.io/videos/abc.jpg"
                    }
                  ],
                  "pagination": {
                    "total": 1,
                    "page": 1,
                    "limit": 20,
                    "pages": 1
                  }
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-scopes": [
          "influencers:read"
        ],
        "x-credit-cost": "none",
        "x-cli-command": "viraloop videos list --influencer <id>"
      }
    },
    "/videos/{id}": {
      "get": {
        "operationId": "getVideo",
        "summary": "Get a video's status",
        "description": "Returns one generated video. Poll this after creating a video: terminal statuses are completed (videoUrl set) and failed (error set). A completed video can be posted via POST /posts with videoUrl.",
        "tags": [
          "videos"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[0-9a-fA-F]{24}$",
              "description": "24 character hex object id"
            },
            "description": "24 character hex object id"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "example": {
                  "success": true,
                  "data": {
                    "id": "665f1b2a9c31a2b3c4d5e730",
                    "status": "completed",
                    "videoUrl": "https://cdn.viraloop.io/videos/abc.mp4",
                    "thumbnailUrl": "https://cdn.viraloop.io/videos/abc.jpg",
                    "completedAt": "2026-07-02T12:08:00.000Z"
                  }
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-scopes": [
          "influencers:read"
        ],
        "x-credit-cost": "none",
        "x-terminal-states": [
          "completed",
          "failed"
        ],
        "x-cli-command": "viraloop videos get <id>",
        "x-mcp-tool": "viraloop_get_video"
      }
    },
    "/assets": {
      "get": {
        "operationId": "listAssets",
        "summary": "List media assets",
        "description": "Lists the workspace's uploaded media library (videos and images used as generation backgrounds and sources). Uploading happens in the web app in v1.",
        "tags": [
          "assets"
        ],
        "parameters": [
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "video",
                "image",
                "audio"
              ]
            }
          },
          {
            "name": "category",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "turboEnabled",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1,
              "description": "Page number, starting at 1"
            },
            "description": "Page number, starting at 1"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20,
              "description": "Items per page (max 100)"
            },
            "description": "Items per page (max 100)"
          },
          {
            "name": "workspaceId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^[0-9a-fA-F]{24}$",
              "description": "Workspace to operate in. Defaults to the team's default workspace."
            },
            "description": "Workspace to operate in. Defaults to the team's default workspace."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "example": {
                  "success": true,
                  "data": [
                    {
                      "id": "665f1b2a9c31a2b3c4d5e740",
                      "kind": "video",
                      "category": "wall-of-text",
                      "name": "gym-broll.mp4",
                      "url": "https://cdn.viraloop.io/assets/gym-broll.mp4",
                      "turboEnabled": true
                    }
                  ],
                  "pagination": {
                    "total": 12,
                    "page": 1,
                    "limit": 20,
                    "pages": 1
                  }
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-scopes": [
          "assets:read"
        ],
        "x-credit-cost": "none",
        "x-cli-command": "viraloop assets list",
        "x-mcp-tool": "viraloop_list_assets"
      },
      "post": {
        "operationId": "createAsset",
        "summary": "Upload media into the workspace",
        "description": "Ingests a publicly reachable file into the workspace's media bank and returns a stable hosted asset. Use this to get a source video, a character photo or an app screenshot into Viraloop before generating a studio format that needs one. The source URL is fetched server-side, so it must be publicly readable (no auth headers, no signed-cookie hosts) and stay up until the request returns. Synchronous.",
        "tags": [
          "assets"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri",
                    "maxLength": 2000,
                    "description": "Publicly reachable https URL of the file to ingest"
                  },
                  "kind": {
                    "type": "string",
                    "enum": [
                      "video",
                      "image",
                      "audio"
                    ],
                    "description": "video, image or audio. Inferred from the response content-type when omitted."
                  },
                  "name": {
                    "type": "string",
                    "maxLength": 200,
                    "description": "Display name in the media bank"
                  },
                  "category": {
                    "type": "string",
                    "maxLength": 100,
                    "description": "Media Bank category"
                  },
                  "workspaceId": {
                    "type": "string",
                    "pattern": "^[0-9a-fA-F]{24}$",
                    "description": "Workspace to operate in. Defaults to the team's default workspace."
                  }
                },
                "required": [
                  "url"
                ],
                "additionalProperties": false
              },
              "example": {
                "url": "https://example.com/clips/reaction.mp4",
                "kind": "video",
                "name": "reaction.mp4"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "example": {
                  "success": true,
                  "data": {
                    "id": "665f1b2a9c31a2b3c4d5e741",
                    "kind": "video",
                    "name": "reaction.mp4",
                    "url": "https://cdn.viraloop.io/assets/reaction.mp4"
                  }
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-scopes": [
          "assets:write"
        ],
        "x-credit-cost": "none",
        "x-idempotent": true,
        "x-rate-limit": {
          "max": 30,
          "windowSec": 300
        },
        "x-cli-command": "viraloop assets upload --url <url>",
        "x-mcp-tool": "viraloop_upload_asset"
      }
    },
    "/content/character-swap": {
      "post": {
        "operationId": "createCharacterSwap",
        "summary": "Swap the character in a video",
        "description": "Replaces the person in a source clip with your character, driven by the clip's motion (Kling motion control, 9:16). Both media URLs must be hosted; upload them with POST /assets first. Costs 2 credits per second of source video, plus 3 credits when scene is 'recreate' (an extra image edit that composites your character into the clip's opening frame). Credits are deducted up front and refunded automatically if generation fails; insufficient credits returns HTTP 402. Asynchronous: returns 202, then poll GET /content/{id} until ready or failed (typically 3 to 20 minutes).",
        "tags": [
          "content"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "videoUrl": {
                    "type": "string",
                    "format": "uri",
                    "description": "Hosted source clip, 3-30 seconds. Its length sets the output length and price."
                  },
                  "characterImageUrl": {
                    "type": "string",
                    "format": "uri",
                    "description": "Hosted photo of the character to swap in; should clearly show one face"
                  },
                  "scene": {
                    "type": "string",
                    "enum": [
                      "image",
                      "recreate"
                    ],
                    "description": "image (default): keep the character photo's own background, borrow only the clip's motion. recreate: composite the character into the clip's first frame instead, keeping the clip's scene but a still background."
                  },
                  "keepSourceAudio": {
                    "type": "boolean",
                    "description": "Lay the clip's original audio over the result. Default true."
                  },
                  "influencerId": {
                    "type": "string",
                    "pattern": "^[0-9a-fA-F]{24}$",
                    "description": "Link the result to this influencer's gallery"
                  },
                  "name": {
                    "type": "string",
                    "maxLength": 200
                  },
                  "workspaceId": {
                    "type": "string",
                    "pattern": "^[0-9a-fA-F]{24}$",
                    "description": "Workspace to operate in. Defaults to the team's default workspace."
                  }
                },
                "required": [
                  "videoUrl",
                  "characterImageUrl"
                ],
                "additionalProperties": false
              },
              "example": {
                "videoUrl": "https://cdn.viraloop.io/assets/reaction.mp4",
                "characterImageUrl": "https://cdn.viraloop.io/assets/maya.jpg",
                "scene": "image"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Success",
            "content": {
              "application/json": {
                "example": {
                  "success": true,
                  "data": {
                    "id": "665f1b2a9c31a2b3c4d5e750",
                    "format": "Character Swap",
                    "status": "processing",
                    "creditsUsed": 20
                  }
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-scopes": [
          "generations:write"
        ],
        "x-credit-cost": "2 credits per second of source video, +3 when scene is 'recreate'",
        "x-idempotent": true,
        "x-rate-limit": {
          "max": 10,
          "windowSec": 300
        },
        "x-terminal-states": [
          "ready",
          "failed"
        ],
        "x-cli-command": "viraloop content character-swap --video <url> --character <url>",
        "x-mcp-tool": "viraloop_create_character_swap"
      }
    },
    "/content/green-screen-mobile": {
      "post": {
        "operationId": "createGreenScreenMobile",
        "summary": "Generate a presenter holding your app",
        "description": "Generates a UGC video of a presenter holding a phone with your app on screen, speaking your script (9:16). Runs two steps server-side: one image edit puts the phone in the presenter's hand, then Seedance animates it. Both media URLs must be hosted; upload them with POST /assets first. Costs 3 credits for the composite plus 5 credits per second of video (default 8s = 43 credits), deducted up front and refunded automatically on failure; insufficient credits returns HTTP 402. Asynchronous: returns 202, then poll GET /content/{id} until ready or failed (typically 2 to 10 minutes).",
        "tags": [
          "content"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "appScreenshot": {
                    "type": "string",
                    "format": "uri",
                    "description": "Hosted screenshot of your app; it is composited onto the phone screen as-is"
                  },
                  "presenterImage": {
                    "type": "string",
                    "format": "uri",
                    "description": "Hosted photo of the presenter; should clearly show their face"
                  },
                  "script": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 1000,
                    "description": "What the presenter says about your app (max 1000 chars)"
                  },
                  "duration": {
                    "type": "integer",
                    "minimum": 4,
                    "maximum": 15,
                    "description": "Seconds, default 8"
                  },
                  "language": {
                    "type": "string",
                    "description": "Spoken language, default English"
                  },
                  "captionOverlay": {
                    "type": "boolean",
                    "description": "Transcribe the speech into a styled caption track. Default true."
                  },
                  "influencerId": {
                    "type": "string",
                    "pattern": "^[0-9a-fA-F]{24}$",
                    "description": "Link the result to this influencer"
                  },
                  "name": {
                    "type": "string",
                    "maxLength": 200
                  },
                  "workspaceId": {
                    "type": "string",
                    "pattern": "^[0-9a-fA-F]{24}$",
                    "description": "Workspace to operate in. Defaults to the team's default workspace."
                  }
                },
                "required": [
                  "appScreenshot",
                  "presenterImage",
                  "script"
                ],
                "additionalProperties": false
              },
              "example": {
                "appScreenshot": "https://cdn.viraloop.io/assets/app-home.png",
                "presenterImage": "https://cdn.viraloop.io/assets/maya.jpg",
                "script": "This is the fastest way to ship short-form video.",
                "duration": 8
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Success",
            "content": {
              "application/json": {
                "example": {
                  "success": true,
                  "data": {
                    "id": "665f1b2a9c31a2b3c4d5e751",
                    "format": "green-screen-mobile",
                    "status": "processing",
                    "creditsUsed": 43
                  }
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-scopes": [
          "generations:write"
        ],
        "x-credit-cost": "3 credits + 5 credits per second (duration 4-15s; default 8s = 43 credits)",
        "x-idempotent": true,
        "x-rate-limit": {
          "max": 10,
          "windowSec": 300
        },
        "x-terminal-states": [
          "ready",
          "failed"
        ],
        "x-cli-command": "viraloop content green-screen-mobile --screenshot <url> --presenter <url>",
        "x-mcp-tool": "viraloop_create_green_screen_mobile"
      }
    },
    "/content/clone-video": {
      "post": {
        "operationId": "createCloneVideo",
        "summary": "Clone a video's motion onto your character",
        "description": "Drives your character with the motion of a reference clip (Kling motion control, 9:16). Unlike character swap this keeps your character's own scene throughout; it borrows only the movement. Both media URLs must be hosted; upload them with POST /assets first. Costs 2 credits per second of reference video, deducted up front and refunded automatically on failure; insufficient credits returns HTTP 402. Asynchronous: returns 202, then poll GET /content/{id} until ready or failed (typically 3 to 20 minutes).",
        "tags": [
          "content"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "imageUrl": {
                    "type": "string",
                    "format": "uri",
                    "description": "Hosted photo of the character to animate"
                  },
                  "videoUrl": {
                    "type": "string",
                    "format": "uri",
                    "description": "Hosted reference clip whose motion is copied. Its length sets the price."
                  },
                  "videoDuration": {
                    "type": "number",
                    "exclusiveMinimum": true,
                    "minimum": 0,
                    "description": "Reference clip length in seconds. Probed from the file when omitted."
                  },
                  "influencerId": {
                    "type": "string",
                    "pattern": "^[0-9a-fA-F]{24}$",
                    "description": "Also save the result to this influencer's gallery"
                  },
                  "name": {
                    "type": "string",
                    "maxLength": 200
                  },
                  "workspaceId": {
                    "type": "string",
                    "pattern": "^[0-9a-fA-F]{24}$",
                    "description": "Workspace to operate in. Defaults to the team's default workspace."
                  }
                },
                "required": [
                  "imageUrl",
                  "videoUrl"
                ],
                "additionalProperties": false
              },
              "example": {
                "imageUrl": "https://cdn.viraloop.io/assets/maya.jpg",
                "videoUrl": "https://cdn.viraloop.io/assets/dance.mp4"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Success",
            "content": {
              "application/json": {
                "example": {
                  "success": true,
                  "data": {
                    "id": "665f1b2a9c31a2b3c4d5e751",
                    "format": "Clone Video",
                    "status": "processing",
                    "statusUrl": "/api/v1/content/665f1b2a9c31a2b3c4d5e751"
                  }
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-scopes": [
          "generations:write"
        ],
        "x-credit-cost": "2 credits per second of reference video",
        "x-idempotent": true,
        "x-rate-limit": {
          "max": 10,
          "windowSec": 300
        },
        "x-terminal-states": [
          "ready",
          "failed"
        ],
        "x-cli-command": "viraloop content clone-video --image <url> --video <url>",
        "x-mcp-tool": "viraloop_create_clone_video"
      }
    },
    "/content/talking-head": {
      "post": {
        "operationId": "createTalkingHeadUgc",
        "summary": "Generate a talking-head UGC video",
        "description": "Generates a UGC video of a person speaking your script to camera (Seedance, 9:16, with voice). Describe the person with gender/age/ethnicity/appearance, or pin their exact likeness with avatarImageUrl (a hosted photo; upload one with POST /assets). Costs 5 credits per second (default 10s = 50 credits), deducted up front and refunded automatically on failure; insufficient credits returns HTTP 402. Asynchronous: returns 202, then poll GET /content/{id} until ready or failed (typically 2 to 10 minutes).",
        "tags": [
          "content"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "script": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 1000,
                    "description": "What the person says (max 1000 chars)"
                  },
                  "avatarImageUrl": {
                    "type": "string",
                    "format": "uri",
                    "description": "Hosted photo pinning the speaker's likeness. Overrides the persona fields."
                  },
                  "duration": {
                    "type": "integer",
                    "minimum": 4,
                    "maximum": 15,
                    "description": "Seconds, default 10"
                  },
                  "language": {
                    "type": "string",
                    "description": "Spoken language, default English"
                  },
                  "mode": {
                    "type": "string",
                    "enum": [
                      "speaker",
                      "scene"
                    ],
                    "description": "speaker (default): head-and-shoulders to camera. scene: a wider shot."
                  },
                  "gender": {
                    "type": "string",
                    "description": "Persona hint, ignored when avatarImageUrl is set"
                  },
                  "age": {
                    "type": "string",
                    "description": "Persona hint, ignored when avatarImageUrl is set"
                  },
                  "ethnicity": {
                    "type": "string",
                    "description": "Persona hint, ignored when avatarImageUrl is set"
                  },
                  "appearance": {
                    "type": "string",
                    "maxLength": 500,
                    "description": "Free-text look, ignored when avatarImageUrl is set"
                  },
                  "referenceImages": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uri"
                    },
                    "maxItems": 3,
                    "description": "Extra hosted reference images (props, setting)"
                  },
                  "captionOverlay": {
                    "type": "boolean",
                    "description": "Transcribe the speech into a styled caption track. Default true."
                  },
                  "influencerId": {
                    "type": "string",
                    "pattern": "^[0-9a-fA-F]{24}$",
                    "description": "Link the result to this influencer"
                  },
                  "name": {
                    "type": "string",
                    "maxLength": 200
                  },
                  "workspaceId": {
                    "type": "string",
                    "pattern": "^[0-9a-fA-F]{24}$",
                    "description": "Workspace to operate in. Defaults to the team's default workspace."
                  }
                },
                "required": [
                  "script"
                ],
                "additionalProperties": false
              },
              "example": {
                "script": "I stopped writing captions by hand and my reach doubled.",
                "duration": 10,
                "gender": "woman",
                "age": "20s"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Success",
            "content": {
              "application/json": {
                "example": {
                  "success": true,
                  "data": {
                    "id": "665f1b2a9c31a2b3c4d5e752",
                    "format": "Talking Head UGC",
                    "status": "processing",
                    "statusUrl": "/api/v1/content/665f1b2a9c31a2b3c4d5e752"
                  }
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-scopes": [
          "generations:write"
        ],
        "x-credit-cost": "5 credits per second (duration 4-15s; default 10s = 50 credits)",
        "x-idempotent": true,
        "x-rate-limit": {
          "max": 20,
          "windowSec": 300
        },
        "x-terminal-states": [
          "ready",
          "failed"
        ],
        "x-cli-command": "viraloop content talking-head --script <text>",
        "x-mcp-tool": "viraloop_create_talking_head"
      }
    },
    "/content/talking-head-green-screen": {
      "post": {
        "operationId": "createTalkingHeadGreenScreen",
        "summary": "Generate a presenter over your demo video",
        "description": "Generates a presenter speaking your script on a green screen, then composites them into the corner of your demo video at render time (9:16). Both media URLs must be hosted; upload them with POST /assets first. Costs 5 credits per second (default 10s = 50 credits), deducted up front and refunded automatically on failure; insufficient credits returns HTTP 402. Asynchronous: returns 202, then poll GET /content/{id} until ready or failed (typically 2 to 15 minutes).",
        "tags": [
          "content"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "script": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 1000,
                    "description": "What the presenter says (max 1000 chars)"
                  },
                  "avatarImageUrl": {
                    "type": "string",
                    "format": "uri",
                    "description": "Hosted photo of the presenter"
                  },
                  "demoVideoUrl": {
                    "type": "string",
                    "format": "uri",
                    "description": "Hosted demo/screen-recording that plays behind"
                  },
                  "demoThumb": {
                    "type": "string",
                    "format": "uri",
                    "description": "Poster image for the demo video"
                  },
                  "avatarPosition": {
                    "type": "string",
                    "enum": [
                      "bottom-left",
                      "bottom-right"
                    ],
                    "description": "Which corner the presenter sits in. Default bottom-right."
                  },
                  "duration": {
                    "type": "integer",
                    "minimum": 4,
                    "maximum": 15,
                    "description": "Seconds, default 10"
                  },
                  "language": {
                    "type": "string",
                    "description": "Spoken language, default English"
                  },
                  "captionOverlay": {
                    "type": "boolean",
                    "description": "Transcribe the speech into a styled caption track. Default false."
                  },
                  "influencerId": {
                    "type": "string",
                    "pattern": "^[0-9a-fA-F]{24}$",
                    "description": "Link the result to this influencer"
                  },
                  "name": {
                    "type": "string",
                    "maxLength": 200
                  },
                  "workspaceId": {
                    "type": "string",
                    "pattern": "^[0-9a-fA-F]{24}$",
                    "description": "Workspace to operate in. Defaults to the team's default workspace."
                  }
                },
                "required": [
                  "script",
                  "avatarImageUrl",
                  "demoVideoUrl"
                ],
                "additionalProperties": false
              },
              "example": {
                "script": "Here is how the scheduler actually works.",
                "avatarImageUrl": "https://cdn.viraloop.io/assets/maya.jpg",
                "demoVideoUrl": "https://cdn.viraloop.io/assets/product-demo.mp4"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Success",
            "content": {
              "application/json": {
                "example": {
                  "success": true,
                  "data": {
                    "id": "665f1b2a9c31a2b3c4d5e753",
                    "format": "Talking Head Green Screen",
                    "status": "processing",
                    "statusUrl": "/api/v1/content/665f1b2a9c31a2b3c4d5e753"
                  }
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-scopes": [
          "generations:write"
        ],
        "x-credit-cost": "5 credits per second (duration 4-15s; default 10s = 50 credits)",
        "x-idempotent": true,
        "x-rate-limit": {
          "max": 20,
          "windowSec": 300
        },
        "x-terminal-states": [
          "ready",
          "failed"
        ],
        "x-cli-command": "viraloop content talking-head-green-screen --script <text> --avatar <url> --demo <url>",
        "x-mcp-tool": "viraloop_create_talking_head_green_screen"
      }
    },
    "/content/interview": {
      "post": {
        "operationId": "createInterview",
        "summary": "Generate an interview (podcast clip) video",
        "description": "Generates a cinematic podcast-clip video: an AI guest in a studio interview setting (broadcast mic, moody lighting) speaking your script as a candid answer (Seedance, 9:16, with voice). Describe the person with gender/age/ethnicity/appearance, or pin their exact likeness with avatarImageUrl (a hosted photo; upload one with POST /assets). Costs 5 credits per second (default 10s = 50 credits), deducted up front and refunded automatically on failure; insufficient credits returns HTTP 402. Asynchronous: returns 202, then poll GET /content/{id} until ready or failed (typically 2 to 10 minutes).",
        "tags": [
          "content"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "script": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 1000,
                    "description": "What the guest says, written as a candid answer (max 1000 chars)"
                  },
                  "avatarImageUrl": {
                    "type": "string",
                    "format": "uri",
                    "description": "Hosted photo pinning the guest's likeness. Overrides the persona fields."
                  },
                  "duration": {
                    "type": "integer",
                    "minimum": 4,
                    "maximum": 15,
                    "description": "Seconds, default 10"
                  },
                  "language": {
                    "type": "string",
                    "description": "Spoken language, default English"
                  },
                  "gender": {
                    "type": "string",
                    "description": "Persona hint, ignored when avatarImageUrl is set"
                  },
                  "age": {
                    "type": "string",
                    "description": "Persona hint, ignored when avatarImageUrl is set"
                  },
                  "ethnicity": {
                    "type": "string",
                    "description": "Persona hint, ignored when avatarImageUrl is set"
                  },
                  "appearance": {
                    "type": "string",
                    "maxLength": 500,
                    "description": "Free-text look, ignored when avatarImageUrl is set"
                  },
                  "captionOverlay": {
                    "type": "boolean",
                    "description": "Transcribe the speech into a styled caption track. Default true."
                  },
                  "influencerId": {
                    "type": "string",
                    "pattern": "^[0-9a-fA-F]{24}$",
                    "description": "Link the result to this influencer"
                  },
                  "name": {
                    "type": "string",
                    "maxLength": 200
                  },
                  "workspaceId": {
                    "type": "string",
                    "pattern": "^[0-9a-fA-F]{24}$",
                    "description": "Workspace to operate in. Defaults to the team's default workspace."
                  }
                },
                "required": [
                  "script"
                ],
                "additionalProperties": false
              },
              "example": {
                "script": "Everyone thinks I got lucky. The truth is I automated the boring half of my content.",
                "duration": 10,
                "gender": "man",
                "age": "30s"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Success",
            "content": {
              "application/json": {
                "example": {
                  "success": true,
                  "data": {
                    "id": "665f1b2a9c31a2b3c4d5e75b",
                    "format": "Interview",
                    "status": "processing",
                    "statusUrl": "/api/v1/content/665f1b2a9c31a2b3c4d5e75b"
                  }
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-scopes": [
          "generations:write"
        ],
        "x-credit-cost": "5 credits per second (duration 4-15s; default 10s = 50 credits)",
        "x-idempotent": true,
        "x-rate-limit": {
          "max": 20,
          "windowSec": 300
        },
        "x-terminal-states": [
          "ready",
          "failed"
        ],
        "x-cli-command": "viraloop content interview --script <text>",
        "x-mcp-tool": "viraloop_create_interview"
      }
    },
    "/content/product-spokesperson": {
      "post": {
        "operationId": "createProductSpokesperson",
        "summary": "Generate a spokesperson holding your product",
        "description": "Generates a UGC video of a person holding your product and talking about it (Seedance, 9:16, with voice). Give either spokespersonImage (a shot of someone already holding it) or avatarImage plus productImage, which are composed into one first. All media URLs must be hosted; upload them with POST /assets first. Costs 5 credits per second (default 8s = 40 credits) plus 3 credits when we compose the shot, deducted up front and refunded automatically on failure; insufficient credits returns HTTP 402. Asynchronous: returns 202, then poll GET /content/{id} until ready or failed (typically 2 to 10 minutes).",
        "tags": [
          "content"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "script": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 1000,
                    "description": "What the spokesperson says (max 1000 chars)"
                  },
                  "spokespersonImage": {
                    "type": "string",
                    "format": "uri",
                    "description": "Hosted photo of a person already holding the product"
                  },
                  "avatarImage": {
                    "type": "string",
                    "format": "uri",
                    "description": "Hosted photo of the person, composed with productImage"
                  },
                  "productImage": {
                    "type": "string",
                    "format": "uri",
                    "description": "Hosted photo of the product, composed with avatarImage"
                  },
                  "instruction": {
                    "type": "string",
                    "maxLength": 300,
                    "description": "Extra direction for the composed shot, e.g. 'outdoors, morning light'"
                  },
                  "duration": {
                    "type": "integer",
                    "minimum": 4,
                    "maximum": 15,
                    "description": "Seconds, default 8"
                  },
                  "language": {
                    "type": "string",
                    "description": "Spoken language, default English"
                  },
                  "captionOverlay": {
                    "type": "boolean",
                    "description": "Transcribe the speech into a styled caption track. Default true."
                  },
                  "influencerId": {
                    "type": "string",
                    "pattern": "^[0-9a-fA-F]{24}$",
                    "description": "Link the result to this influencer"
                  },
                  "name": {
                    "type": "string",
                    "maxLength": 200
                  },
                  "workspaceId": {
                    "type": "string",
                    "pattern": "^[0-9a-fA-F]{24}$",
                    "description": "Workspace to operate in. Defaults to the team's default workspace."
                  }
                },
                "required": [
                  "script"
                ],
                "additionalProperties": false
              },
              "example": {
                "script": "This is the only bottle I take to the gym now.",
                "avatarImage": "https://cdn.viraloop.io/assets/maya.jpg",
                "productImage": "https://cdn.viraloop.io/assets/bottle.png"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Success",
            "content": {
              "application/json": {
                "example": {
                  "success": true,
                  "data": {
                    "id": "665f1b2a9c31a2b3c4d5e754",
                    "format": "Product Spokesperson",
                    "status": "processing",
                    "statusUrl": "/api/v1/content/665f1b2a9c31a2b3c4d5e754"
                  }
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-scopes": [
          "generations:write"
        ],
        "x-credit-cost": "5 credits per second (duration 4-15s; default 8s = 40 credits), +3 when composing the shot",
        "x-idempotent": true,
        "x-rate-limit": {
          "max": 20,
          "windowSec": 300
        },
        "x-terminal-states": [
          "ready",
          "failed"
        ],
        "x-cli-command": "viraloop content product-spokesperson --script <text> --product <url>",
        "x-mcp-tool": "viraloop_create_product_spokesperson"
      }
    },
    "/content/grid-video": {
      "post": {
        "operationId": "createGridVideo",
        "summary": "Create a 2x2 grid video",
        "description": "Writes a listicle heading plus four labelled cells from your brand and prompt, finds a stock photo for each cell, and saves the result to your library (9:16). Costs no credits. Synchronous: the request returns when the deck is built, typically 10 to 40 seconds. Publish it with POST /posts using the deck from GET /content/{id}, or open it in the studio to edit first.",
        "tags": [
          "content"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "prompt": {
                    "type": "string",
                    "maxLength": 500,
                    "description": "What the grid is about. Omit to let the model pick from your brand."
                  },
                  "mentionBusiness": {
                    "type": "boolean",
                    "description": "Make one of the four cells your brand. Default true."
                  },
                  "portrait": {
                    "type": "boolean",
                    "description": "Use portrait cell photos instead of landscape. Default false."
                  },
                  "name": {
                    "type": "string",
                    "maxLength": 200
                  },
                  "workspaceId": {
                    "type": "string",
                    "pattern": "^[0-9a-fA-F]{24}$",
                    "description": "Workspace to operate in. Defaults to the team's default workspace."
                  }
                },
                "additionalProperties": false
              },
              "example": {
                "prompt": "tools every solo founder should be using"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "example": {
                  "success": true,
                  "data": {
                    "id": "665f1b2a9c31a2b3c4d5e755",
                    "format": "2x2 Grid Video",
                    "status": "ready",
                    "title": "tools every solo founder should be using:"
                  }
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-scopes": [
          "generations:write"
        ],
        "x-credit-cost": "none",
        "x-idempotent": true,
        "x-rate-limit": {
          "max": 20,
          "windowSec": 300
        },
        "x-cli-command": "viraloop content grid-video --prompt <text>",
        "x-mcp-tool": "viraloop_create_grid_video"
      }
    },
    "/content/listicle": {
      "post": {
        "operationId": "createListicle",
        "summary": "Create a listicle video",
        "description": "Writes a numbered-list title plus 4 to 6 items from your brand and prompt, lays them over a stock UGC background clip that reveals one item per beat, and saves the result to your library (9:16). Costs no credits. Synchronous: the request returns when the deck is built, typically 5 to 20 seconds. Publish it with POST /posts using the deck from GET /content/{id}, or open it in the studio to edit first.",
        "tags": [
          "content"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "prompt": {
                    "type": "string",
                    "maxLength": 500,
                    "description": "What the list is about. Omit to let the model pick from your brand."
                  },
                  "mentionBusiness": {
                    "type": "boolean",
                    "description": "Make one of the items your brand. Default true."
                  },
                  "layout": {
                    "type": "string",
                    "enum": [
                      "list",
                      "pyramid",
                      "checklist",
                      "countdown"
                    ],
                    "description": "Display style: numbered list (default), tier pyramid, checklist, or countdown to #1."
                  },
                  "name": {
                    "type": "string",
                    "maxLength": 200
                  },
                  "workspaceId": {
                    "type": "string",
                    "pattern": "^[0-9a-fA-F]{24}$",
                    "description": "Workspace to operate in. Defaults to the team's default workspace."
                  }
                },
                "additionalProperties": false
              },
              "example": {
                "prompt": "habits of founders who ship every week"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "example": {
                  "success": true,
                  "data": {
                    "id": "665f1b2a9c31a2b3c4d5e757",
                    "format": "Listicle",
                    "status": "ready",
                    "title": "5 habits of founders who ship every week:"
                  }
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-scopes": [
          "generations:write"
        ],
        "x-credit-cost": "none",
        "x-idempotent": true,
        "x-rate-limit": {
          "max": 20,
          "windowSec": 300
        },
        "x-cli-command": "viraloop content listicle --prompt <text>",
        "x-mcp-tool": "viraloop_create_listicle"
      }
    },
    "/content/ask-me-anything": {
      "post": {
        "operationId": "createAskMeAnything",
        "summary": "Create an Ask Me Anything video",
        "description": "Writes the question your audience actually asks plus the on-video answer from your brand and prompt, lays them over a stock UGC background clip as an IG-style question sticker, and saves the result to your library (9:16). Costs no credits. Synchronous: the request returns when the deck is built, typically 5 to 20 seconds. Publish it with POST /posts using the deck from GET /content/{id}, or open it in the studio to edit first.",
        "tags": [
          "content"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "prompt": {
                    "type": "string",
                    "maxLength": 500,
                    "description": "What the question should be about. Omit to let the model pick from your brand."
                  },
                  "mentionBusiness": {
                    "type": "boolean",
                    "description": "Name the brand in the answer. Default true."
                  },
                  "name": {
                    "type": "string",
                    "maxLength": 200
                  },
                  "workspaceId": {
                    "type": "string",
                    "pattern": "^[0-9a-fA-F]{24}$",
                    "description": "Workspace to operate in. Defaults to the team's default workspace."
                  }
                },
                "additionalProperties": false
              },
              "example": {
                "prompt": "how I stay consistent posting every day"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "example": {
                  "success": true,
                  "data": {
                    "id": "665f1b2a9c31a2b3c4d5e758",
                    "format": "Ask Me Anything",
                    "status": "ready",
                    "title": "how do you post every single day?"
                  }
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-scopes": [
          "generations:write"
        ],
        "x-credit-cost": "none",
        "x-idempotent": true,
        "x-rate-limit": {
          "max": 20,
          "windowSec": 300
        },
        "x-cli-command": "viraloop content ask-me-anything --prompt <text>",
        "x-mcp-tool": "viraloop_create_ask_me_anything"
      }
    },
    "/content/ranking": {
      "post": {
        "operationId": "createRanking",
        "summary": "Create a ranking (tier list) video",
        "description": "Writes a tier-list title plus 5 to 7 tiered items (S/A/B/C) from your brand and prompt, finds a stock photo for each item, and saves an image tier-board video to your library (9:16, items reveal one per beat). Costs no credits. Synchronous: the request returns when the deck is built, typically 10 to 40 seconds. Publish it with POST /posts using the deck from GET /content/{id}, or open it in the studio to edit first.",
        "tags": [
          "content"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "prompt": {
                    "type": "string",
                    "maxLength": 500,
                    "description": "What the ranking is about. Omit to let the model pick from your brand."
                  },
                  "mentionBusiness": {
                    "type": "boolean",
                    "description": "Make one of the items your brand (tier S, revealed last). Default true."
                  },
                  "name": {
                    "type": "string",
                    "maxLength": 200
                  },
                  "workspaceId": {
                    "type": "string",
                    "pattern": "^[0-9a-fA-F]{24}$",
                    "description": "Workspace to operate in. Defaults to the team's default workspace."
                  }
                },
                "additionalProperties": false
              },
              "example": {
                "prompt": "ranking the ways to grow on tiktok"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "example": {
                  "success": true,
                  "data": {
                    "id": "665f1b2a9c31a2b3c4d5e759",
                    "format": "Ranking",
                    "status": "ready",
                    "title": "ranking the ways to grow on tiktok:"
                  }
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-scopes": [
          "generations:write"
        ],
        "x-credit-cost": "none",
        "x-idempotent": true,
        "x-rate-limit": {
          "max": 20,
          "windowSec": 300
        },
        "x-cli-command": "viraloop content ranking --prompt <text>",
        "x-mcp-tool": "viraloop_create_ranking"
      }
    },
    "/content/split-screen": {
      "post": {
        "operationId": "createSplitScreen",
        "summary": "Create a split screen video",
        "description": "Writes an on-brand caption from your prompt (or uses the caption you pass), stacks a stock UGC content clip on top of a looping gameplay/satisfying clip, and saves the result to your library (9:16, duration follows the top clip). Costs no credits. Synchronous: the request returns when the deck is built, typically 5 to 15 seconds. Publish it with POST /posts using the deck from GET /content/{id}, or open it in the studio to edit first.",
        "tags": [
          "content"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "prompt": {
                    "type": "string",
                    "maxLength": 500,
                    "description": "What the caption should be about. Omit to let the model pick from your brand."
                  },
                  "caption": {
                    "type": "string",
                    "maxLength": 300,
                    "description": "Use this exact on-video caption instead of generating one."
                  },
                  "mentionBusiness": {
                    "type": "boolean",
                    "description": "Name the brand in the caption. Default true."
                  },
                  "name": {
                    "type": "string",
                    "maxLength": 200
                  },
                  "workspaceId": {
                    "type": "string",
                    "pattern": "^[0-9a-fA-F]{24}$",
                    "description": "Workspace to operate in. Defaults to the team's default workspace."
                  }
                },
                "additionalProperties": false
              },
              "example": {
                "prompt": "POV: you found the tool that edits for you"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "example": {
                  "success": true,
                  "data": {
                    "id": "665f1b2a9c31a2b3c4d5e75a",
                    "format": "Split Screen",
                    "status": "ready",
                    "title": "POV: you found the tool that edits for you"
                  }
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-scopes": [
          "generations:write"
        ],
        "x-credit-cost": "none",
        "x-idempotent": true,
        "x-rate-limit": {
          "max": 20,
          "windowSec": 300
        },
        "x-cli-command": "viraloop content split-screen --prompt <text>",
        "x-mcp-tool": "viraloop_create_split_screen"
      }
    },
    "/content/fade-in-video": {
      "post": {
        "operationId": "createFadeInVideo",
        "summary": "Create a single fade-in video",
        "description": "Writes one bold caption from your brand and prompt, pairs it with a stock photo that fades in, and saves the result to your library (9:16). Pass imageUrl to use your own picture instead. Costs no credits. Synchronous: the request returns when the deck is built, typically 10 to 30 seconds.",
        "tags": [
          "content"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "prompt": {
                    "type": "string",
                    "maxLength": 500,
                    "description": "What the video is about. Omit to let the model pick from your brand."
                  },
                  "imageUrl": {
                    "type": "string",
                    "format": "uri",
                    "description": "Hosted image to fade in. A stock photo is found when omitted."
                  },
                  "mentionBusiness": {
                    "type": "boolean",
                    "description": "Name the brand in the copy. Default true."
                  },
                  "name": {
                    "type": "string",
                    "maxLength": 200
                  },
                  "workspaceId": {
                    "type": "string",
                    "pattern": "^[0-9a-fA-F]{24}$",
                    "description": "Workspace to operate in. Defaults to the team's default workspace."
                  }
                },
                "additionalProperties": false
              },
              "example": {
                "prompt": "the real reason your reach dropped"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "example": {
                  "success": true,
                  "data": {
                    "id": "665f1b2a9c31a2b3c4d5e756",
                    "format": "Single Fade-in Video",
                    "status": "ready",
                    "title": "the real reason your reach dropped"
                  }
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-scopes": [
          "generations:write"
        ],
        "x-credit-cost": "none",
        "x-idempotent": true,
        "x-rate-limit": {
          "max": 20,
          "windowSec": 300
        },
        "x-cli-command": "viraloop content fade-in-video --prompt <text>",
        "x-mcp-tool": "viraloop_create_fade_in_video"
      }
    },
    "/content/hook-demo": {
      "post": {
        "operationId": "createHookDemo",
        "summary": "Stitch a hook clip onto your demo",
        "description": "Puts a captioned hook clip in front of your product demo and saves the pair to your library (9:16). Both media URLs must be hosted; upload them with POST /assets first. The on-screen line is written from your brand unless you pass caption. Costs no credits. Synchronous: returns when the deck is built, typically 5 to 30 seconds.",
        "tags": [
          "content"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "hookVideoUrl": {
                    "type": "string",
                    "format": "uri",
                    "description": "Hosted attention-grabbing clip that plays first"
                  },
                  "demoVideoUrl": {
                    "type": "string",
                    "format": "uri",
                    "description": "Hosted product demo that plays after the hook"
                  },
                  "caption": {
                    "type": "string",
                    "maxLength": 300,
                    "description": "The line burned over the hook. Written from your brand when omitted."
                  },
                  "prompt": {
                    "type": "string",
                    "maxLength": 500,
                    "description": "What the caption should be about, when caption is omitted"
                  },
                  "hookThumb": {
                    "type": "string",
                    "format": "uri",
                    "description": "Poster image for the hook clip"
                  },
                  "mentionBusiness": {
                    "type": "boolean",
                    "description": "Name the brand in the copy. Default true."
                  },
                  "name": {
                    "type": "string",
                    "maxLength": 200
                  },
                  "workspaceId": {
                    "type": "string",
                    "pattern": "^[0-9a-fA-F]{24}$",
                    "description": "Workspace to operate in. Defaults to the team's default workspace."
                  }
                },
                "required": [
                  "hookVideoUrl",
                  "demoVideoUrl"
                ],
                "additionalProperties": false
              },
              "example": {
                "hookVideoUrl": "https://cdn.viraloop.io/assets/hook.mp4",
                "demoVideoUrl": "https://cdn.viraloop.io/assets/product-demo.mp4",
                "prompt": "scheduling a week of posts in one sitting"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "example": {
                  "success": true,
                  "data": {
                    "id": "665f1b2a9c31a2b3c4d5e757",
                    "format": "Video Hook & Demo",
                    "status": "ready",
                    "title": "i scheduled a whole week in one sitting"
                  }
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-scopes": [
          "generations:write"
        ],
        "x-credit-cost": "none",
        "x-idempotent": true,
        "x-rate-limit": {
          "max": 20,
          "windowSec": 300
        },
        "x-cli-command": "viraloop content hook-demo --hook <url> --demo <url>",
        "x-mcp-tool": "viraloop_create_hook_demo"
      }
    },
    "/content/{id}": {
      "get": {
        "operationId": "getContent",
        "summary": "Get a studio render's status",
        "description": "Polls a piece created by the /content operations or accepted from a generation. status is processing, ready or failed. Video formats carry videoUrl when ready; DECK formats (slideshow, wall of text, green screen, ...) have no flat media until rendered - publishing renders them automatically, or GET /content/{id}/download renders on demand and returns the files. A failed render has already refunded its credits.",
        "tags": [
          "content"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[0-9a-fA-F]{24}$",
              "description": "24 character hex object id"
            },
            "description": "24 character hex object id"
          },
          {
            "name": "workspaceId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^[0-9a-fA-F]{24}$",
              "description": "Workspace to operate in. Defaults to the team's default workspace."
            },
            "description": "Workspace to operate in. Defaults to the team's default workspace."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "example": {
                  "success": true,
                  "data": {
                    "id": "665f1b2a9c31a2b3c4d5e750",
                    "format": "Character Swap",
                    "status": "ready",
                    "videoUrl": "https://cdn.viraloop.io/renders/character_swap.mp4",
                    "thumbnailUrl": "https://cdn.viraloop.io/renders/character_swap.jpg",
                    "durationSec": 8
                  }
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-scopes": [
          "generations:read"
        ],
        "x-terminal-states": [
          "ready",
          "failed"
        ],
        "x-cli-command": "viraloop content get <id>",
        "x-mcp-tool": "viraloop_get_content"
      }
    },
    "/content/{id}/download": {
      "get": {
        "operationId": "downloadContent",
        "summary": "Get a content piece's media files",
        "description": "Returns the finished media files (mp4 for video formats, the slide images for carousels) for a content piece. For deck formats (slideshow, wall of text, green screen and the other studio decks) the FIRST call starts the server-side render and returns 409; poll this endpoint until it returns 200 with the files (typically under a minute). Generations must be accepted first (POST /generations/{id}/accept) to get a content id. Fetching files here marks the piece accepted for metered (enterprise) billing, exactly like publishing it does.",
        "tags": [
          "content"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[0-9a-fA-F]{24}$",
              "description": "24 character hex object id"
            },
            "description": "24 character hex object id"
          },
          {
            "name": "workspaceId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^[0-9a-fA-F]{24}$",
              "description": "Workspace to operate in. Defaults to the team's default workspace."
            },
            "description": "Workspace to operate in. Defaults to the team's default workspace."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "example": {
                  "success": true,
                  "data": {
                    "id": "665f1b2a9c31a2b3c4d5e757",
                    "format": "Slideshow",
                    "files": [
                      {
                        "type": "image",
                        "url": "https://cdn.viraloop.io/renders/slide-1.jpg"
                      },
                      {
                        "type": "image",
                        "url": "https://cdn.viraloop.io/renders/slide-2.jpg"
                      }
                    ]
                  }
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-scopes": [
          "generations:read"
        ],
        "x-credit-cost": "none",
        "x-cli-command": "viraloop content download <id>",
        "x-mcp-tool": "viraloop_download_content"
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Authorization: Bearer vl_live_..."
      },
      "apiKeyHeader": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key"
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "const": false
          },
          "error": {
            "type": "object",
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "invalid_input",
                  "unauthorized",
                  "forbidden_scope",
                  "not_found",
                  "conflict",
                  "insufficient_credits",
                  "usage_limit_reached",
                  "rate_limited",
                  "internal_error"
                ]
              },
              "message": {
                "type": "string"
              },
              "hint": {
                "type": "string",
                "description": "What to do about it. One fixed hint per error type."
              }
            }
          }
        }
      }
    }
  },
  "x-scopes": [
    "credits:read",
    "workspaces:read",
    "workspaces:write",
    "accounts:read",
    "generations:read",
    "generations:write",
    "posts:read",
    "posts:write",
    "automations:read",
    "automations:write",
    "influencers:read",
    "influencers:write",
    "assets:read",
    "assets:write"
  ]
}
