{
  "openapi": "3.1.0",
  "info": {
    "title": "Mosaic AI API",
    "description": "Professional-grade video editing workflows powered by AI agents",
    "version": "2.0.0",
    "contact": {
      "email": "adish@mosaic.so"
    }
  },
  "servers": [
    {
      "url": "https://api.mosaic.so"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ],
  "paths": {
    "/whoami": {
      "get": {
        "summary": "Get current user info",
        "description": "Get information about the current user based on the API key.",
        "operationId": "whoAmI",
        "tags": [
          "Auth"
        ],
        "responses": {
          "200": {
            "description": "User information retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/User"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          }
        }
      }
    },
    "/agent/create": {
      "post": {
        "summary": "Create an agent",
        "description": "Create an agent template (metadata only). Graph mutations are handled via /agent/{agent_id}/update.",
        "operationId": "createAgent",
        "tags": [
          "Agents"
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 120
                  },
                  "description": {
                    "type": "string",
                    "maxLength": 5000
                  },
                  "visibility": {
                    "type": "string",
                    "enum": [
                      "public",
                      "private"
                    ]
                  },
                  "workspace_id": {
                    "type": "string",
                    "format": "uuid"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Agent created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgentMutationResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequestError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenError"
          }
        }
      }
    },
    "/avatar-profiles": {
      "get": {
        "summary": "Get avatars",
        "description": "List reusable AI Avatars from the organization's primary workspace.",
        "operationId": "listAvatarProfiles",
        "tags": [
          "Avatar Profiles"
        ],
        "responses": {
          "200": {
            "description": "Avatar profiles",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "avatar_profiles": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/AvatarProfile"
                      }
                    }
                  },
                  "required": [
                    "avatar_profiles"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenError"
          }
        }
      }
    },
    "/avatar-profiles/create": {
      "post": {
        "summary": "Create avatar",
        "description": "Create a reusable AI Avatar in the organization's primary workspace. Provide either a video source or an image plus audio source. Sources should represent one person only, with clean single-speaker audio from that person. URL sources are stored as Mosaic asset records.",
        "operationId": "createAvatarProfile",
        "tags": [
          "Avatar Profiles"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200
                  },
                  "sources": {
                    "type": "object",
                    "description": "Avatar source media. Required: either video_url/video_id, or image_url/image_id plus audio_url/audio_id. Use one visible person and clean single-speaker audio from that same person.",
                    "properties": {
                      "video_url": {
                        "type": "string",
                        "format": "uri",
                        "nullable": true,
                        "description": "4-15 second source video URL. Should show one person and contain clean single-speaker audio from that person."
                      },
                      "audio_url": {
                        "type": "string",
                        "format": "uri",
                        "nullable": true,
                        "description": "4-15 second voice reference audio URL. Should contain clean single-speaker speech from the same person shown in the image."
                      },
                      "image_url": {
                        "type": "string",
                        "format": "uri",
                        "nullable": true,
                        "description": "Character image URL. Should show one person only."
                      },
                      "video_id": {
                        "type": "string",
                        "format": "uuid",
                        "nullable": true,
                        "description": "Existing video asset ID. Should follow the same one-person, clear-audio guidance."
                      },
                      "audio_id": {
                        "type": "string",
                        "format": "uuid",
                        "nullable": true,
                        "description": "Existing audio asset ID. Should contain clean single-speaker speech."
                      },
                      "image_id": {
                        "type": "string",
                        "format": "uuid",
                        "nullable": true,
                        "description": "Existing image asset ID. Should show one person only."
                      }
                    },
                    "additionalProperties": false
                  }
                },
                "required": [
                  "name",
                  "sources"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Avatar profile created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid",
                      "description": "Avatar profile ID. Pass this as avatar_profile_id in an AI Avatar tile."
                    },
                    "video_preview_url": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "Signed video preview URL. Null until a preview/reference video is available."
                    },
                    "name": {
                      "type": "string",
                      "description": "Avatar display name."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "pending",
                        "processing",
                        "ready",
                        "failed"
                      ],
                      "description": "Avatar processing state. Ready means fully prepared; pending/processing can be used while the run waits; failed cannot be used."
                    },
                    "status_message": {
                      "type": "string",
                      "nullable": true,
                      "description": "Error message when status is failed; otherwise null."
                    }
                  },
                  "required": [
                    "id",
                    "video_preview_url",
                    "name",
                    "status",
                    "status_message"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequestError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenError"
          },
          "409": {
            "$ref": "#/components/responses/ConflictError"
          }
        }
      }
    },
    "/avatar-profiles/{id}": {
      "get": {
        "summary": "Get avatar",
        "description": "Return one AI Avatar, including processing status and reference URLs when available.",
        "operationId": "getAvatarProfile",
        "tags": [
          "Avatar Profiles"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Avatar profile",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid",
                      "description": "Avatar profile ID. Pass this as avatar_profile_id in an AI Avatar tile."
                    },
                    "video_preview_url": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "Signed video preview URL. Null until a preview/reference video is available."
                    },
                    "name": {
                      "type": "string",
                      "description": "Avatar display name."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "pending",
                        "processing",
                        "ready",
                        "failed"
                      ],
                      "description": "Avatar processing state. Ready means fully prepared; pending/processing can be used while the run waits; failed cannot be used."
                    },
                    "status_message": {
                      "type": "string",
                      "nullable": true,
                      "description": "Error message when status is failed; otherwise null."
                    }
                  },
                  "required": [
                    "id",
                    "video_preview_url",
                    "name",
                    "status",
                    "status_message"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          }
        }
      }
    },
    "/agent/{agent_id}/update": {
      "post": {
        "summary": "Update an agent",
        "description": "Update agent metadata and/or apply ordered graph operations.",
        "operationId": "updateAgent",
        "tags": [
          "Agents"
        ],
        "parameters": [
          {
            "name": "agent_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 120
                  },
                  "description": {
                    "type": "string",
                    "maxLength": 5000
                  },
                  "visibility": {
                    "type": "string",
                    "enum": [
                      "public",
                      "private"
                    ]
                  },
                  "operations": {
                    "type": "array",
                    "minItems": 1,
                    "items": {
                      "oneOf": [
                        {
                          "type": "object",
                          "properties": {
                            "op": {
                              "type": "string",
                              "enum": [
                                "create_node"
                              ]
                            },
                            "temp_ref_id": {
                              "type": "string",
                              "description": "Temporary request-scoped node reference for linking operations in the same payload. Not persisted."
                            },
                            "node_type_id": {
                              "type": "string",
                              "format": "uuid"
                            },
                            "params_used": {
                              "type": "object",
                              "additionalProperties": true
                            }
                          },
                          "required": [
                            "op",
                            "node_type_id"
                          ]
                        },
                        {
                          "type": "object",
                          "properties": {
                            "op": {
                              "type": "string",
                              "enum": [
                                "update_node"
                              ]
                            },
                            "agent_node_id": {
                              "type": "string",
                              "format": "uuid"
                            },
                            "params_used": {
                              "type": "object",
                              "additionalProperties": true
                            }
                          },
                          "required": [
                            "op",
                            "agent_node_id",
                            "params_used"
                          ]
                        },
                        {
                          "type": "object",
                          "properties": {
                            "op": {
                              "type": "string",
                              "enum": [
                                "delete_node"
                              ]
                            },
                            "agent_node_id": {
                              "type": "string",
                              "format": "uuid"
                            }
                          },
                          "required": [
                            "op",
                            "agent_node_id"
                          ]
                        },
                        {
                          "type": "object",
                          "description": "Provide exactly one source reference and exactly one target reference.",
                          "properties": {
                            "op": {
                              "type": "string",
                              "enum": [
                                "create_connection"
                              ]
                            },
                            "source_agent_node_id": {
                              "type": "string",
                              "format": "uuid",
                              "description": "Source existing node identifier."
                            },
                            "source_temp_ref_id": {
                              "type": "string",
                              "description": "Source temp reference from an earlier create_node operation in the same request; must already exist."
                            },
                            "target_agent_node_id": {
                              "type": "string",
                              "format": "uuid",
                              "description": "Target existing node identifier."
                            },
                            "target_temp_ref_id": {
                              "type": "string",
                              "description": "Target temp reference from an earlier create_node operation in the same request; must already exist."
                            }
                          },
                          "required": [
                            "op"
                          ]
                        },
                        {
                          "type": "object",
                          "description": "Provide exactly one source reference and exactly one target reference.",
                          "properties": {
                            "op": {
                              "type": "string",
                              "enum": [
                                "delete_connection"
                              ]
                            },
                            "source_agent_node_id": {
                              "type": "string",
                              "format": "uuid",
                              "description": "Source existing node identifier."
                            },
                            "source_temp_ref_id": {
                              "type": "string",
                              "description": "Source temp reference from an earlier create_node operation in the same request; must already exist."
                            },
                            "target_agent_node_id": {
                              "type": "string",
                              "format": "uuid",
                              "description": "Target existing node identifier."
                            },
                            "target_temp_ref_id": {
                              "type": "string",
                              "description": "Target temp reference from an earlier create_node operation in the same request; must already exist."
                            }
                          },
                          "required": [
                            "op"
                          ]
                        }
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Agent updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgentMutationResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequestError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          }
        }
      },
      "patch": {
        "summary": "Update an agent (PATCH alias)",
        "description": "Alias for POST /agent/{agent_id}/update.",
        "operationId": "updateAgentPatch",
        "tags": [
          "Agents"
        ],
        "parameters": [
          {
            "name": "agent_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 120
                  },
                  "description": {
                    "type": "string",
                    "maxLength": 5000
                  },
                  "visibility": {
                    "type": "string",
                    "enum": [
                      "public",
                      "private"
                    ]
                  },
                  "operations": {
                    "type": "array",
                    "minItems": 1,
                    "items": {
                      "oneOf": [
                        {
                          "type": "object",
                          "properties": {
                            "op": {
                              "type": "string",
                              "enum": [
                                "create_node"
                              ]
                            },
                            "temp_ref_id": {
                              "type": "string",
                              "description": "Temporary request-scoped node reference for linking operations in the same payload. Not persisted."
                            },
                            "node_type_id": {
                              "type": "string",
                              "format": "uuid"
                            },
                            "params_used": {
                              "type": "object",
                              "additionalProperties": true
                            }
                          },
                          "required": [
                            "op",
                            "node_type_id"
                          ]
                        },
                        {
                          "type": "object",
                          "properties": {
                            "op": {
                              "type": "string",
                              "enum": [
                                "update_node"
                              ]
                            },
                            "agent_node_id": {
                              "type": "string",
                              "format": "uuid"
                            },
                            "params_used": {
                              "type": "object",
                              "additionalProperties": true
                            }
                          },
                          "required": [
                            "op",
                            "agent_node_id",
                            "params_used"
                          ]
                        },
                        {
                          "type": "object",
                          "properties": {
                            "op": {
                              "type": "string",
                              "enum": [
                                "delete_node"
                              ]
                            },
                            "agent_node_id": {
                              "type": "string",
                              "format": "uuid"
                            }
                          },
                          "required": [
                            "op",
                            "agent_node_id"
                          ]
                        },
                        {
                          "type": "object",
                          "description": "Provide exactly one source reference and exactly one target reference.",
                          "properties": {
                            "op": {
                              "type": "string",
                              "enum": [
                                "create_connection"
                              ]
                            },
                            "source_agent_node_id": {
                              "type": "string",
                              "format": "uuid",
                              "description": "Source existing node identifier."
                            },
                            "source_temp_ref_id": {
                              "type": "string",
                              "description": "Source temp reference from an earlier create_node operation in the same request; must already exist."
                            },
                            "target_agent_node_id": {
                              "type": "string",
                              "format": "uuid",
                              "description": "Target existing node identifier."
                            },
                            "target_temp_ref_id": {
                              "type": "string",
                              "description": "Target temp reference from an earlier create_node operation in the same request; must already exist."
                            }
                          },
                          "required": [
                            "op"
                          ]
                        },
                        {
                          "type": "object",
                          "description": "Provide exactly one source reference and exactly one target reference.",
                          "properties": {
                            "op": {
                              "type": "string",
                              "enum": [
                                "delete_connection"
                              ]
                            },
                            "source_agent_node_id": {
                              "type": "string",
                              "format": "uuid",
                              "description": "Source existing node identifier."
                            },
                            "source_temp_ref_id": {
                              "type": "string",
                              "description": "Source temp reference from an earlier create_node operation in the same request; must already exist."
                            },
                            "target_agent_node_id": {
                              "type": "string",
                              "format": "uuid",
                              "description": "Target existing node identifier."
                            },
                            "target_temp_ref_id": {
                              "type": "string",
                              "description": "Target temp reference from an earlier create_node operation in the same request; must already exist."
                            }
                          },
                          "required": [
                            "op"
                          ]
                        }
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Agent updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgentMutationResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequestError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          }
        }
      }
    },
    "/agent/{agent_id}/delete": {
      "post": {
        "summary": "Delete an agent",
        "description": "Soft-delete an agent and detach template nodes/connections.",
        "operationId": "deleteAgent",
        "tags": [
          "Agents"
        ],
        "parameters": [
          {
            "name": "agent_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Agent deleted successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "agent_id": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          }
        }
      },
      "delete": {
        "summary": "Delete an agent (DELETE alias)",
        "description": "Alias for POST /agent/{agent_id}/delete.",
        "operationId": "deleteAgentAlias",
        "tags": [
          "Agents"
        ],
        "parameters": [
          {
            "name": "agent_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Agent deleted successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "agent_id": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          }
        }
      }
    },
    "/agent/{agent_id}/run": {
      "post": {
        "summary": "Run an agent",
        "description": "Execute an agent workflow. Supports standard video-input workflows and generation-only workflows (AI Avatar, Video Generation, Audio Generation, or Image Generation). Canonical input model is `video_inputs` (per Video Input tile). Top-level input arrays (`video_ids`, `node_render_ids`, `video_urls`) are shorthand for single-input runs. Do not mix top-level input arrays with `video_inputs` in the same request.",
        "operationId": "runAgent",
        "tags": [
          "Agents"
        ],
        "parameters": [
          {
            "name": "agent_id",
            "in": "path",
            "required": true,
            "description": "The ID of the agent to run",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "video_inputs": {
                    "type": "array",
                    "description": "Canonical per-tile input mapping. Each entry must include `agent_node_id` and at least one of `video_ids`, `node_render_ids`, or `video_urls`. Required for multi-input runs.",
                    "items": {
                      "type": "object",
                      "properties": {
                        "agent_node_id": {
                          "type": "string",
                          "description": "Template Video Input `agent_node_id` from GET /agent/{agent_id}."
                        },
                        "video_ids": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "node_render_ids": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "video_urls": {
                          "type": "array",
                          "items": {
                            "type": "string",
                            "format": "uri"
                          }
                        }
                      },
                      "required": [
                        "agent_node_id"
                      ]
                    }
                  },
                  "video_ids": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Top-level shorthand for single-input runs. Video UUIDs from the Uploads API (or existing workspace video assets)."
                  },
                  "node_render_ids": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Top-level shorthand for single-input runs. Completed agent_node_render IDs from prior run outputs (`GET /agent_run/{run_id}` -> `outputs[].id`) or run webhooks."
                  },
                  "video_urls": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uri"
                    },
                    "description": "Top-level shorthand for single-input runs. Video URLs to ingest (including YouTube and signed HTTP/HTTPS URLs). YouTube videos max 5 hours, signed URLs max 5 hours / 5 GB per input."
                  },
                  "callback_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Optional webhook URL for status updates"
                  },
                  "update_params": {
                    "type": "object",
                    "description": "Optional parameters to override node parameters in the agent workflow. Key is agent_node_id, value is parameter object. Parameters are validated against each node's schema; invalid node IDs/values return 400 and the run is not created.",
                    "additionalProperties": true
                  },
                  "ignore_nodes": {
                    "type": "array",
                    "description": "Optional list of agent_node_id values to bypass for this run. Ignored nodes are removed from the runtime graph and their incoming edges are rewired directly to their downstream nodes.",
                    "items": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Agent run started successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "run_id": {
                      "type": "string",
                      "description": "Unique identifier for this agent run"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequestError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLargeError"
          }
        }
      }
    },
    "/agent/{agent_id}/duplicate": {
      "post": {
        "summary": "Duplicate agent",
        "description": "Duplicate an existing agent template and return the duplicated graph payload.",
        "operationId": "duplicateAgent",
        "tags": [
          "Agents"
        ],
        "parameters": [
          {
            "name": "agent_id",
            "in": "path",
            "required": true,
            "description": "The ID of the source agent to duplicate",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AgentDuplicateRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Agent duplicated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgentMetadataResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequestError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          }
        }
      }
    },
    "/agent/{agent_id}": {
      "get": {
        "summary": "Get agent metadata",
        "description": "Retrieve agent metadata, agent nodes, and connections.",
        "operationId": "getAgentMetadata",
        "tags": [
          "Agents"
        ],
        "parameters": [
          {
            "name": "agent_id",
            "in": "path",
            "required": true,
            "description": "The ID of the agent",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Agent metadata retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgentMetadataResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          }
        }
      }
    },
    "/node_types": {
      "get": {
        "summary": "List node types",
        "description": "List all available node types for your organization.",
        "operationId": "listNodeTypes",
        "tags": [
          "Agents"
        ],
        "responses": {
          "200": {
            "description": "Node types retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "node_types": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NodeTypeSummary"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenError"
          }
        }
      }
    },
    "/node_type/{node_type_id}": {
      "get": {
        "summary": "Get node type",
        "description": "Get a single node type by node_type_id.",
        "operationId": "getNodeType",
        "tags": [
          "Agents"
        ],
        "parameters": [
          {
            "name": "node_type_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Node type retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "node_type": {
                      "$ref": "#/components/schemas/NodeTypeSummary"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequestError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          }
        }
      }
    },
    "/agent_nodes/{agent_node_id}": {
      "get": {
        "summary": "Get agent node",
        "description": "Get a single agent node instance by agent_node_id.",
        "operationId": "getAgentNode",
        "tags": [
          "Agents"
        ],
        "parameters": [
          {
            "name": "agent_node_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Agent node retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "agent_node": {
                      "$ref": "#/components/schemas/AgentNodeSummary"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequestError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          }
        }
      }
    },
    "/agent/{agent_id}/runs": {
      "get": {
        "summary": "List agent runs",
        "description": "List recent runs for an agent with optional filtering.",
        "operationId": "listAgentRuns",
        "tags": [
          "Agents"
        ],
        "parameters": [
          {
            "name": "agent_id",
            "in": "path",
            "required": true,
            "description": "The ID of the agent",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Comma-separated statuses to filter by",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "ISO timestamp for earliest run",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "ISO timestamp for latest run",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Number of runs to return (max 100)",
            "schema": {
              "type": "integer",
              "default": 25
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "Cursor for pagination (created_at timestamp)",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Agent runs retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgentRunsResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          }
        }
      }
    },
    "/agent_run/{run_id}": {
      "get": {
        "summary": "Get agent run status",
        "description": "Retrieve the current status, credit-blocked state (`needs_credits`), and outputs of an agent run.",
        "operationId": "getAgentRunStatus",
        "tags": [
          "Agents"
        ],
        "parameters": [
          {
            "name": "run_id",
            "in": "path",
            "required": true,
            "description": "The ID of the agent run",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Agent run status retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgentRunStatus"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          }
        }
      }
    },
    "/agent_run/{run_id}/nodes": {
      "get": {
        "summary": "Get run nodes",
        "description": "Retrieve node-level status details for a run, including node type metadata and whether any node task is currently credit-blocked.",
        "operationId": "getAgentRunNodes",
        "tags": [
          "Agents"
        ],
        "parameters": [
          {
            "name": "run_id",
            "in": "path",
            "required": true,
            "description": "The ID of the agent run",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Run nodes retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgentRunNodesResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          }
        }
      }
    },
    "/agent_run/{run_id}/resume": {
      "post": {
        "summary": "Resume agent run",
        "description": "Resume a failed or cancelled run by re-queueing eligible runtime nodes. Trigger/source nodes are excluded from resume. This is also used to continue credit-blocked runs after credits are added.",
        "operationId": "resumeAgentRun",
        "tags": [
          "Agents"
        ],
        "parameters": [
          {
            "name": "run_id",
            "in": "path",
            "required": true,
            "description": "The ID of the agent run to resume",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Agent run resumed successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgentRunResumeResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "409": {
            "description": "Run cannot be resumed from its current state",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/agent_run/{run_id}/cancel": {
      "post": {
        "summary": "Cancel agent run",
        "description": "Cancel an ongoing agent run",
        "operationId": "cancelAgentRun",
        "tags": [
          "Agents"
        ],
        "parameters": [
          {
            "name": "run_id",
            "in": "path",
            "required": true,
            "description": "The ID of the agent run to cancel",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Agent run cancelled successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "run_id": {
                      "type": "string"
                    },
                    "tasks_cancelled": {
                      "type": "number"
                    },
                    "nodes_reset": {
                      "type": "number"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          }
        }
      }
    },
    "/agent/{agent_id}/triggers": {
      "get": {
        "summary": "Get agent trigger",
        "description": "Retrieve the YouTube trigger configured for an agent",
        "operationId": "getAgentTriggers",
        "tags": [
          "Triggers"
        ],
        "parameters": [
          {
            "name": "agent_id",
            "in": "path",
            "required": true,
            "description": "The ID of the agent",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Triggers retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Trigger"
                  },
                  "description": "Array of triggers configured for the agent. Returns empty array if no triggers are configured."
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          }
        }
      }
    },
    "/agent/{agent_id}/triggers/add_youtube_channels": {
      "post": {
        "summary": "Add YouTube channel listeners",
        "description": "Add YouTube channels to monitor for new videos. Creates a trigger if none exist, updates a trigger with matching filter options when possible, or creates a new trigger node when filter options differ. If a channel already exists on another YouTube trigger node for the same agent, it is moved to the selected trigger node. Execution is deduplicated per target Video Input so matching duplicate trigger tiles do not create duplicate runs for the same target input.",
        "operationId": "addYoutubeListeners",
        "tags": [
          "Triggers"
        ],
        "parameters": [
          {
            "name": "agent_id",
            "in": "path",
            "required": true,
            "description": "The ID of the agent",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "youtube_channels": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Array of YouTube channel IDs or URLs to monitor. Channels are moved from other YouTube trigger nodes on the same agent to the selected trigger node when necessary."
                  },
                  "trigger_callback_url": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Optional webhook URL saved on the YouTube trigger and used as `callback_url` for each triggered run. Provide `null` to clear an existing callback URL; omit the field to keep it unchanged."
                  },
                  "filter_options": {
                    "$ref": "#/components/schemas/YouTubeTriggerFilterOptions"
                  }
                },
                "required": [
                  "youtube_channels"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Listeners added successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    },
                    "channel_ids": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Canonical YouTube channel IDs derived from the provided inputs (e.g. URLs/handles)."
                    },
                    "channels": {
                      "type": "array",
                      "description": "Stable mapping of each provided input to its resolved canonical channel_id.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "input": {
                            "type": "string"
                          },
                          "channel_id": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "input",
                          "channel_id"
                        ]
                      }
                    },
                    "youtube_channel_details": {
                      "type": "array",
                      "description": "Detailed information for each added channel including subscriber count and thumbnail.",
                      "items": {
                        "$ref": "#/components/schemas/YouTubeChannelDetail"
                      }
                    },
                    "filter_options": {
                      "$ref": "#/components/schemas/YouTubeTriggerFilterOptions"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequestError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          }
        }
      }
    },
    "/agent/{agent_id}/triggers/remove_youtube_channels": {
      "post": {
        "summary": "Remove YouTube channel listeners",
        "description": "Remove YouTube channels from monitoring across all YouTube trigger nodes for the agent. Empty trigger nodes are deleted automatically.",
        "operationId": "removeYoutubeListeners",
        "tags": [
          "Triggers"
        ],
        "parameters": [
          {
            "name": "agent_id",
            "in": "path",
            "required": true,
            "description": "The ID of the agent",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "youtube_channels": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Array of YouTube channel IDs or URLs to stop monitoring"
                  }
                },
                "required": [
                  "youtube_channels"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Listeners removed successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequestError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          }
        }
      }
    },
    "/uploads/video/get_upload_url": {
      "post": {
        "summary": "Get video upload URL",
        "description": "Get a pre-signed URL for video upload. Use this to upload videos for node parameters. Max 5GB, 1 hour duration. After uploading, call `/uploads/video/finalize_upload` to get the video UUID.",
        "operationId": "getVideoUploadUrl",
        "tags": [
          "Uploads"
        ],
        "responses": {
          "200": {
            "description": "Upload URL generated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VideoUploadUrlResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          }
        }
      }
    },
    "/uploads/video/finalize_upload": {
      "post": {
        "summary": "Finalize video upload",
        "description": "Finalize a video upload after the file has been uploaded. Returns the video UUID which you can use in agent `update_params`.",
        "operationId": "finalizeVideoUpload",
        "tags": [
          "Uploads"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "video_id": {
                    "type": "string",
                    "description": "The video ID returned from get_upload_url"
                  }
                },
                "required": [
                  "video_id"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Video finalized successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VideoUploadFinalizeResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequestError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          }
        }
      }
    },
    "/uploads/audio/get_upload_url": {
      "post": {
        "summary": "Get audio upload URL",
        "description": "Get a pre-signed URL for audio upload. Use this to upload audio for node parameters (e.g., background music). Max 500MB, 5 hour duration. After uploading, call `/uploads/audio/finalize_upload` to get the audio UUID.",
        "operationId": "getAudioUploadUrl",
        "tags": [
          "Uploads"
        ],
        "responses": {
          "200": {
            "description": "Upload URL generated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AudioUploadUrlResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          }
        }
      }
    },
    "/uploads/audio/finalize_upload": {
      "post": {
        "summary": "Finalize audio upload",
        "description": "Finalize an audio upload after the file has been uploaded. Returns the audio UUID which you can use in agent `update_params`.",
        "operationId": "finalizeAudioUpload",
        "tags": [
          "Uploads"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "audio_id": {
                    "type": "string",
                    "description": "The audio ID returned from get_upload_url"
                  }
                },
                "required": [
                  "audio_id"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Audio finalized successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AudioUploadFinalizeResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequestError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          }
        }
      }
    },
    "/uploads/image/get_upload_url": {
      "post": {
        "summary": "Get image upload URL",
        "description": "Get a pre-signed URL for image upload. Use this to upload images for node parameters (e.g., logos, watermarks). Max 50MB. After uploading, call `/uploads/image/finalize_upload` to get the image UUID.",
        "operationId": "getImageUploadUrl",
        "tags": [
          "Uploads"
        ],
        "responses": {
          "200": {
            "description": "Upload URL generated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ImageUploadUrlResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          }
        }
      }
    },
    "/uploads/image/finalize_upload": {
      "post": {
        "summary": "Finalize image upload",
        "description": "Finalize an image upload after the file has been uploaded. Returns the image UUID which you can use in agent `update_params`.",
        "operationId": "finalizeImageUpload",
        "tags": [
          "Uploads"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "image_id": {
                    "type": "string",
                    "description": "The image ID returned from get_upload_url"
                  }
                },
                "required": [
                  "image_id"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Image finalized successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ImageUploadFinalizeResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequestError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          }
        }
      }
    },
    "/social/connections": {
      "get": {
        "summary": "List social connections",
        "description": "List connected social accounts available as post destinations.",
        "operationId": "listSocialConnections",
        "tags": [
          "Social"
        ],
        "responses": {
          "200": {
            "description": "Social connections",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SocialConnectionsResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequestError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          }
        }
      },
      "post": {
        "summary": "Create social connection",
        "description": "Create a short-lived social account setup URL for a new connection.",
        "operationId": "createSocialConnection",
        "tags": [
          "Social"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SocialConnectionCreateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Connect URL created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SocialConnectUrlResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequestError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          }
        }
      }
    },
    "/social/connect/{connect_token}": {
      "get": {
        "summary": "Open social connect URL",
        "description": "Redirect a short-lived Mosaic social connect URL to the platform linking flow.",
        "operationId": "openSocialConnectUrl",
        "tags": [
          "Social"
        ],
        "security": [],
        "parameters": [
          {
            "name": "connect_token",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "302": {
            "description": "Redirect to platform linking flow"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          }
        }
      }
    },
    "/social/post": {
      "post": {
        "summary": "Create social post",
        "description": "Publish immediately or schedule a social post. Future scheduled posts return a trackable post_id with status scheduled until publishing completes.",
        "operationId": "createSocialPost",
        "tags": [
          "Social"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SocialPostRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Social post created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SocialPostResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequestError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          }
        }
      }
    },
    "/social/posts": {
      "get": {
        "summary": "List social posts",
        "description": "List social posts for the API key's organization with cursor pagination. Results are sorted by created_at descending.",
        "operationId": "listSocialPosts",
        "tags": [
          "Social"
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            },
            "description": "Maximum posts to return. Defaults to 20 and caps at 100."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Cursor returned by the previous response."
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "scheduled",
                "pending_approval",
                "processing",
                "posted",
                "partial_failure",
                "failed",
                "rejected"
              ]
            },
            "description": "Filter by social post status."
          },
          {
            "name": "platform",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "x",
                "linkedin",
                "instagram",
                "facebook",
                "tiktok",
                "youtube"
              ]
            },
            "description": "Filter by destination platform."
          },
          {
            "name": "social_connection_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Filter to posts that target one connected account."
          }
        ],
        "responses": {
          "200": {
            "description": "Social posts",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SocialPostListResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequestError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenError"
          }
        }
      }
    },
    "/social/post/{post_id}/analytics": {
      "get": {
        "summary": "Get social post analytics",
        "description": "Get analytics for a social post using the post_id returned by POST /social/post.",
        "operationId": "getSocialPostAnalytics",
        "tags": [
          "Social"
        ],
        "parameters": [
          {
            "name": "post_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "social_connection_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Use one specific connected account."
          }
        ],
        "responses": {
          "200": {
            "description": "Social post analytics",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SocialPostAnalyticsResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequestError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          }
        }
      }
    },
    "/social/post/{post_id}": {
      "get": {
        "summary": "Get social post",
        "description": "Get social post status, destination results, links, and available analytics. Scheduled posts return scheduled while waiting or processing, then posted after destination publishing succeeds.",
        "operationId": "getSocialPost",
        "tags": [
          "Social"
        ],
        "parameters": [
          {
            "name": "post_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "social_connection_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Use one specific connected account."
          }
        ],
        "responses": {
          "200": {
            "description": "Social post",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SocialPostResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequestError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          }
        }
      },
      "patch": {
        "summary": "Update social post",
        "description": "Update supported lifecycle, moderation, and platform-specific metadata fields on a social post. Text, media, and destination platforms cannot be edited after creation. schedule_date only changes Mosaic's queued publish time before a scheduled post is published. approved only applies to posts waiting for approval. Platform-specific update options support Instagram and LinkedIn comment settings plus YouTube metadata.",
        "operationId": "updateSocialPost",
        "tags": [
          "Social"
        ],
        "parameters": [
          {
            "name": "post_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "schedule_date": {
                    "type": "string",
                    "format": "date-time",
                    "description": "New queued publish timestamp as an ISO string. Only valid before a scheduled post publishes."
                  },
                  "approved": {
                    "type": "boolean",
                    "description": "Set to true to approve a post that is waiting for approval."
                  },
                  "disable_comments": {
                    "type": "boolean",
                    "description": "Disable or re-enable comments. Supported only for instagram and linkedin. Prefer platform_options.instagram.disable_comments or platform_options.linkedin.disable_comments for new integrations."
                  },
                  "platform_options": {
                    "type": "object",
                    "properties": {
                      "instagram": {
                        "type": "object",
                        "properties": {
                          "disable_comments": {
                            "type": "boolean",
                            "description": "Disable or re-enable comments for an Instagram destination."
                          }
                        },
                        "additionalProperties": false,
                        "description": "Supported Instagram existing-post updates."
                      },
                      "linkedin": {
                        "type": "object",
                        "properties": {
                          "disable_comments": {
                            "type": "boolean",
                            "description": "Disable or re-enable comments for a LinkedIn destination."
                          }
                        },
                        "additionalProperties": false,
                        "description": "Supported LinkedIn existing-post updates."
                      },
                      "youtube": {
                        "type": "object",
                        "properties": {
                          "visibility": {
                            "type": "string",
                            "enum": [
                              "unlisted",
                              "private",
                              "public"
                            ]
                          },
                          "title": {
                            "type": "string"
                          },
                          "description": {
                            "type": "string"
                          },
                          "category_id": {
                            "type": "integer"
                          }
                        },
                        "additionalProperties": false,
                        "description": "Supported YouTube metadata updates."
                      }
                    },
                    "additionalProperties": false,
                    "description": "Platform-specific update options. Supports instagram.disable_comments, linkedin.disable_comments, and youtube metadata."
                  },
                  "youtube_options": {
                    "type": "object",
                    "properties": {
                      "visibility": {
                        "type": "string",
                        "enum": [
                          "unlisted",
                          "private",
                          "public"
                        ]
                      },
                      "title": {
                        "type": "string"
                      },
                      "description": {
                        "type": "string"
                      },
                      "category_id": {
                        "type": "integer"
                      }
                    },
                    "additionalProperties": false,
                    "deprecated": true,
                    "description": "Backward-compatible alias for platform_options.youtube."
                  },
                  "social_connection_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Update using one specific connected account. Required for platform-specific fields when the destination platform cannot be inferred."
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Social post updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SocialPostUpdateResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequestError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          }
        }
      },
      "delete": {
        "summary": "Delete social post",
        "description": "Delete a social post.",
        "operationId": "deleteSocialPost",
        "tags": [
          "Social"
        ],
        "parameters": [
          {
            "name": "post_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "social_connection_id": {
                    "type": "string",
                    "format": "uuid"
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Social post deleted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SocialPostResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequestError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          }
        }
      }
    },
    "/social/connections/{social_connection_id}": {
      "get": {
        "summary": "Get social connection",
        "description": "Get status and account metadata for one social connection.",
        "operationId": "getSocialConnection",
        "tags": [
          "Social"
        ],
        "parameters": [
          {
            "name": "social_connection_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Social connection",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SocialConnection"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequestError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          }
        }
      },
      "delete": {
        "summary": "Delete social connection",
        "description": "Disconnect one social account.",
        "operationId": "deleteSocialConnection",
        "tags": [
          "Social"
        ],
        "parameters": [
          {
            "name": "social_connection_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Connection deleted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SocialConnectionDeleteResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequestError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          }
        }
      }
    },
    "/social/post/{post_id}/comments": {
      "get": {
        "summary": "Get social post comments",
        "description": "Get comments for a published social post. Comments and nested replies are sorted by created_at descending; top-level comments are sorted before pagination.",
        "operationId": "getSocialPostComments",
        "tags": [
          "Social"
        ],
        "parameters": [
          {
            "name": "post_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "social_connection_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Use one specific connected account."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 1000,
              "default": 100
            },
            "description": "Maximum comments to return. Defaults to 100 and caps at 1000."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Cursor returned by the previous response."
          }
        ],
        "responses": {
          "200": {
            "description": "Social post comments",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SocialPostCommentsResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequestError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "AvatarProfile": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Avatar profile ID. Pass this as avatar_profile_id in an AI Avatar tile."
          },
          "video_preview_url": {
            "type": "string",
            "format": "uri",
            "nullable": true,
            "description": "Signed video preview URL. Null until a preview/reference video is available."
          },
          "name": {
            "type": "string",
            "description": "Avatar display name."
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "processing",
              "ready",
              "failed"
            ],
            "description": "Avatar processing state. Ready means fully prepared; pending/processing can be used while the run waits; failed cannot be used."
          },
          "status_message": {
            "type": "string",
            "nullable": true,
            "description": "Error message when status is failed; otherwise null."
          }
        },
        "required": [
          "id",
          "video_preview_url",
          "name",
          "status",
          "status_message"
        ]
      },
      "User": {
        "type": "object",
        "properties": {
          "user_id": {
            "type": "string",
            "description": "Unique identifier for the user"
          },
          "email": {
            "type": "string",
            "nullable": true,
            "description": "User's email address"
          },
          "is_admin": {
            "type": "boolean",
            "description": "Whether the user has admin privileges"
          },
          "api_key_id": {
            "type": "string",
            "description": "ID of the API key used for the request"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "When the API key was created"
          },
          "last_used_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "When the API key was last used"
          }
        }
      },
      "AgentRunStatus": {
        "type": "object",
        "properties": {
          "agent_id": {
            "type": "string",
            "description": "ID of the agent that started this run."
          },
          "started_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the agent run started"
          },
          "status": {
            "type": "string",
            "enum": [
              "running",
              "completed",
              "failed",
              "partial_complete",
              "cancelled"
            ],
            "description": "Current status of the agent run"
          },
          "status_message": {
            "type": "string",
            "nullable": true,
            "description": "Optional message providing details about the current status"
          },
          "needs_credits": {
            "type": "boolean",
            "description": "True when one or more runtime tasks in this run are marked `needs_credits=true` (insufficient credits)."
          },
          "node_status_counts": {
            "$ref": "#/components/schemas/NodeStatusCounts"
          },
          "inputs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/VideoInput"
            },
            "description": "Array of input videos"
          },
          "outputs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AgentOutput"
            },
            "description": "Array of output videos"
          },
          "errors": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "original_node_id": {
                  "type": "string",
                  "nullable": true,
                  "description": "Template agent_node_id these errors originated from"
                },
                "messages": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  },
                  "description": "List of error messages from failed tasks in this node"
                }
              },
              "required": [
                "original_node_id",
                "messages"
              ]
            },
            "description": "Error messages grouped by template node. Empty array when the run has no errors."
          }
        }
      },
      "AgentRunNode": {
        "type": "object",
        "properties": {
          "agent_node_id": {
            "type": "string",
            "description": "Runtime agent node ID for this run."
          },
          "original_node_id": {
            "type": "string",
            "nullable": true,
            "description": "Template agent_node_id this runtime node was cloned from."
          },
          "status": {
            "type": "string",
            "description": "Current runtime status for the node."
          },
          "status_message": {
            "type": "string",
            "nullable": true,
            "description": "Optional status details for the node."
          },
          "node_type": {
            "$ref": "#/components/schemas/NodeTypeSummary"
          },
          "needs_credits": {
            "type": "boolean",
            "description": "True when any runtime task attached to this node is currently marked `needs_credits`."
          },
          "errors": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Error messages from failed tasks in this node. Empty array when the node has no errors."
          }
        },
        "required": [
          "agent_node_id",
          "original_node_id",
          "status",
          "status_message",
          "node_type",
          "needs_credits",
          "errors"
        ]
      },
      "AgentRunNodesResponse": {
        "type": "object",
        "properties": {
          "run_id": {
            "type": "string"
          },
          "nodes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AgentRunNode"
            }
          }
        },
        "required": [
          "run_id",
          "nodes"
        ]
      },
      "AgentRunResumeResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "run_id": {
            "type": "string"
          },
          "agent_state_id": {
            "type": "string"
          },
          "nodes_queued": {
            "type": "integer"
          },
          "nodes_considered": {
            "type": "integer"
          },
          "requeued_nodes": {
            "type": "integer"
          },
          "requeued_node_tasks_detached": {
            "type": "integer"
          },
          "requeued_node_active_tasks_cancelled": {
            "type": "integer"
          },
          "requeued_node_active_tasks_total": {
            "type": "integer"
          }
        },
        "required": [
          "success",
          "run_id",
          "agent_state_id",
          "nodes_queued",
          "nodes_considered",
          "requeued_nodes",
          "requeued_node_tasks_detached",
          "requeued_node_active_tasks_cancelled",
          "requeued_node_active_tasks_total"
        ]
      },
      "UpdatedNode": {
        "type": "object",
        "properties": {
          "original_node_id": {
            "type": "string",
            "nullable": true,
            "description": "Template agent_node_id this runtime node was cloned from"
          },
          "status": {
            "type": "string",
            "description": "Current status of the node"
          },
          "status_message": {
            "type": "string",
            "nullable": true,
            "description": "Optional human-readable status message"
          },
          "errors": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Error messages from failed tasks in this node. Empty array when the node has no errors."
          },
          "outputs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AgentOutput"
            },
            "description": "Optional list of outputs produced by this node in this update"
          }
        }
      },
      "RunProgressWebhook": {
        "type": "object",
        "properties": {
          "flag": {
            "type": "string",
            "enum": [
              "RUN_PROGRESS"
            ]
          },
          "agent_id": {
            "type": "string",
            "description": "UUID of the agent that started this run."
          },
          "run_id": {
            "type": "string",
            "description": "UUID of the run (same value used in `GET /agent_run/{run_id}`)."
          },
          "status": {
            "type": "string",
            "enum": [
              "running"
            ]
          },
          "node_status_counts": {
            "$ref": "#/components/schemas/NodeStatusCounts"
          },
          "updated_nodes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/UpdatedNode"
            },
            "description": "Optional list of nodes that changed status in this batch"
          },
          "triggered_by": {
            "$ref": "#/components/schemas/TriggeredBy",
            "nullable": true
          }
        }
      },
      "AgentRunsResponse": {
        "type": "object",
        "properties": {
          "runs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AgentRunSummary"
            }
          },
          "next_cursor": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Pagination cursor for the next page"
          }
        }
      },
      "AgentRunSummary": {
        "type": "object",
        "properties": {
          "run_id": {
            "type": "string"
          },
          "agent_id": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "running",
              "completed",
              "failed",
              "partial_complete",
              "cancelled"
            ]
          },
          "status_message": {
            "type": "string",
            "nullable": true
          },
          "started_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "node_status_counts": {
            "$ref": "#/components/schemas/NodeStatusCounts"
          },
          "inputs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/VideoInput"
            }
          },
          "outputs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AgentOutput"
            }
          },
          "triggered_by": {
            "$ref": "#/components/schemas/TriggeredBy",
            "nullable": true
          }
        }
      },
      "TriggeredBy": {
        "description": "Standard trigger metadata exposed as `triggered_by` in run APIs and webhooks. Google Drive triggers use the storage trigger shape with `type: \"storage_trigger\"` and `provider: \"google_drive\"`.",
        "oneOf": [
          {
            "$ref": "#/components/schemas/YouTubeTriggerInfo"
          },
          {
            "$ref": "#/components/schemas/StorageTriggerInfo"
          }
        ]
      },
      "YouTubeTriggerInfo": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "youtube"
            ]
          },
          "channel_id": {
            "type": "string",
            "nullable": true,
            "description": "YouTube channel ID when available."
          },
          "video_id": {
            "type": "string",
            "description": "YouTube video ID that triggered the run."
          },
          "video_title": {
            "type": "string",
            "description": "Title of the triggering YouTube video."
          },
          "video_url": {
            "type": "string",
            "format": "uri",
            "description": "Canonical YouTube URL for the triggering video."
          },
          "triggered_at": {
            "type": "string",
            "format": "date-time",
            "description": "When Mosaic created the trigger context."
          },
          "trigger_id": {
            "type": "string",
            "nullable": true,
            "description": "Trigger subscription ID when the run came from a saved YouTube trigger. `null` for manual API runs started from a YouTube URL."
          },
          "target_video_input_agent_node_id": {
            "type": "string",
            "nullable": true,
            "description": "Template Video Input node targeted by this run when the trigger fans out to multiple inputs."
          }
        },
        "required": [
          "type",
          "video_id",
          "video_title",
          "video_url",
          "triggered_at"
        ],
        "additionalProperties": true,
        "example": {
          "type": "youtube",
          "channel_id": "UCX6OQ3DkcsbYNE6H8uQQuVA",
          "video_id": "dQw4w9WgXcQ",
          "video_title": "New upload",
          "video_url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
          "triggered_at": "2026-03-08T21:14:12.000Z",
          "trigger_id": "1f8bc8f7-1f77-4ff0-bdf8-8db4bf999999",
          "target_video_input_agent_node_id": "eb3cc4be-8f0e-4ca0-9d92-1a6a44aaaaaa"
        }
      },
      "StorageTriggerInfo": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "storage_trigger"
            ]
          },
          "provider": {
            "type": "string",
            "enum": [
              "google_drive",
              "aws_s3",
              "s3"
            ],
            "description": "Trigger source provider. Google Drive trigger runs use `google_drive`; `s3` is accepted for legacy rows."
          },
          "storage_trigger_subscription_id": {
            "type": "string",
            "description": "Internal storage trigger subscription ID used to associate runs with the configured trigger."
          },
          "batch_window_id": {
            "type": "string",
            "description": "Internal batch window ID used to group runs created from the same trigger flush."
          },
          "drive_paths": {
            "type": "array",
            "description": "Canonical Google Drive paths for all files included in this run.",
            "items": {
              "type": "string"
            }
          },
          "triggered_at": {
            "type": "string",
            "format": "date-time",
            "description": "When Mosaic created the storage-trigger run."
          }
        },
        "required": [
          "type",
          "provider",
          "triggered_at"
        ],
        "additionalProperties": true,
        "example": {
          "type": "storage_trigger",
          "provider": "google_drive",
          "storage_trigger_subscription_id": "8f2ceef6-f96c-4495-8582-bb5677bbbbbb",
          "batch_window_id": "4b6fd593-5a95-4ec5-9d36-59dc9edddddd",
          "drive_paths": [
            "/My Drive/Uploads/clip-1.mp4",
            "/My Drive/Uploads/clip-2.mp4"
          ],
          "triggered_at": "2026-03-08T21:14:12.000Z"
        }
      },
      "AgentMutationResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "agent_id": {
            "type": "string",
            "format": "uuid"
          },
          "operations_applied": {
            "type": "integer"
          },
          "created_nodes": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "temp_ref_id": {
                  "type": "string",
                  "nullable": true
                },
                "agent_node_id": {
                  "type": "string",
                  "format": "uuid"
                }
              }
            }
          }
        },
        "required": [
          "success",
          "agent_id",
          "operations_applied",
          "created_nodes"
        ]
      },
      "AgentDuplicateRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 120
          },
          "description": {
            "type": "string",
            "maxLength": 5000
          },
          "visibility": {
            "type": "string",
            "enum": [
              "public",
              "private"
            ]
          }
        },
        "additionalProperties": false
      },
      "AgentMetadataResponse": {
        "type": "object",
        "properties": {
          "agent": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "description": {
                "type": "string"
              },
              "visibility": {
                "type": "string",
                "nullable": true
              },
              "created_at": {
                "type": "string",
                "format": "date-time"
              },
              "updated_at": {
                "type": "string",
                "format": "date-time"
              }
            }
          },
          "agent_nodes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AgentNodeSummary"
            }
          },
          "connections": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AgentConnection"
            }
          }
        }
      },
      "AgentNodeSummary": {
        "type": "object",
        "properties": {
          "agent_node_id": {
            "type": "string"
          },
          "node_type": {
            "$ref": "#/components/schemas/NodeTypeSummary"
          },
          "params_used": {
            "type": "object",
            "additionalProperties": true
          }
        }
      },
      "NodeTypeSummary": {
        "type": "object",
        "properties": {
          "node_type_id": {
            "type": "string",
            "format": "uuid"
          },
          "node_type_name": {
            "type": "string",
            "nullable": true
          },
          "docs_url": {
            "type": "string",
            "nullable": true,
            "description": "Canonical docs page URL derived from nodes.docs_path."
          },
          "params_docs_url": {
            "type": "string",
            "nullable": true,
            "description": "Exact docs section URL derived from nodes.docs_anchor (for node params/API details)."
          }
        }
      },
      "AgentConnection": {
        "type": "object",
        "properties": {
          "source_agent_node_id": {
            "type": "string"
          },
          "target_agent_node_id": {
            "type": "string"
          }
        }
      },
      "NodeStatusCounts": {
        "type": "object",
        "properties": {
          "completed": {
            "type": "integer",
            "description": "Number of nodes that finished successfully (completed, partial_complete)"
          },
          "in_progress": {
            "type": "integer",
            "description": "Number of nodes currently processing or waiting (running, queued)"
          },
          "failed": {
            "type": "integer",
            "description": "Number of nodes that failed or are blocked (failed, blocked)"
          }
        }
      },
      "AgentOutput": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Unique identifier for this output render"
          },
          "video_url": {
            "type": "string",
            "nullable": true,
            "description": "Signed URL to download the output video (valid for 7 days). Null if render failed."
          },
          "thumbnail_url": {
            "type": "string",
            "nullable": true,
            "description": "Signed URL for the video thumbnail (valid for 7 days)"
          },
          "premiere_prproj_url": {
            "type": "string",
            "nullable": true,
            "description": "Signed URL to download the Premiere Pro timeline package zip attached to this render (when available)."
          },
          "sources": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RenderSource"
            },
            "description": "Source citations for licensed or external media used in this output. Getty b-roll sources include timing, query, asset IDs when resolved, placement, and rights metadata."
          },
          "completed_at": {
            "type": "string",
            "format": "date-time",
            "description": "ISO 8601 timestamp when this output finished rendering"
          },
          "original_node_id": {
            "type": "string",
            "nullable": true,
            "description": "Template agent_node_id this output originated from. Use this to map outputs to specific nodes in your agent."
          }
        }
      },
      "RenderSource": {
        "type": "object",
        "properties": {
          "provider": {
            "type": "string",
            "description": "Source provider. Getty sources use `getty`."
          },
          "source_kind": {
            "type": "string",
            "description": "Source category, for example `licensed_library`."
          },
          "media_type": {
            "type": "string",
            "description": "Media type such as `image` or `video`."
          },
          "provider_asset_id": {
            "type": "string",
            "nullable": true,
            "description": "Provider asset ID, such as the Getty image/video ID, when resolved."
          },
          "render_asset_id": {
            "type": "string",
            "nullable": true,
            "description": "Internal render/timeline asset ID for this source usage."
          },
          "query": {
            "type": "string",
            "nullable": true,
            "description": "Search query used to choose the source."
          },
          "title": {
            "type": "string",
            "nullable": true
          },
          "credit": {
            "type": "string",
            "nullable": true
          },
          "source_url": {
            "type": "string",
            "nullable": true
          },
          "display_url": {
            "type": "string",
            "nullable": true
          },
          "rights_status": {
            "type": "string",
            "description": "Known rights status, for example `licensed`, `restricted`, or `unknown`."
          },
          "start_ms": {
            "type": "number",
            "nullable": true,
            "description": "Start timestamp of the source usage in the rendered output."
          },
          "end_ms": {
            "type": "number",
            "nullable": true,
            "description": "End timestamp of the source usage in the rendered output."
          },
          "start_seconds": {
            "type": "number",
            "nullable": true
          },
          "end_seconds": {
            "type": "number",
            "nullable": true
          },
          "placement": {
            "type": "string",
            "nullable": true,
            "description": "Placement chosen by the editor, such as `full_screen` or `partial_screen`."
          },
          "layout": {
            "type": "string",
            "nullable": true,
            "description": "Layout region, such as `top`, `bottom`, or `full`."
          },
          "getty_asset_family": {
            "type": "string",
            "nullable": true,
            "description": "Getty asset family, such as `editorial` or `creative`."
          },
          "source_metadata": {
            "type": "object",
            "additionalProperties": true
          },
          "rights_metadata": {
            "type": "object",
            "additionalProperties": true
          }
        }
      },
      "Trigger": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Unique identifier for the trigger"
          },
          "type": {
            "type": "string",
            "enum": [
              "youtube"
            ],
            "description": "Type of trigger"
          },
          "youtube_channels": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "List of YouTube channel IDs"
          },
          "youtube_channel_details": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/YouTubeChannelDetail"
            },
            "description": "Optional expanded channel details for the configured YouTube channels"
          },
          "callback_url": {
            "type": "string",
            "nullable": true,
            "description": "Optional webhook URL saved on the trigger and used as `callback_url` for each triggered run."
          },
          "filter_options": {
            "$ref": "#/components/schemas/YouTubeTriggerFilterOptions"
          }
        }
      },
      "YouTubeTriggerFilterOptions": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "duration": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "min_seconds": {
                "type": "integer",
                "nullable": true,
                "minimum": 0,
                "description": "Minimum video duration in seconds (inclusive)."
              },
              "max_seconds": {
                "type": "integer",
                "nullable": true,
                "minimum": 0,
                "description": "Maximum video duration in seconds (inclusive)."
              }
            }
          }
        },
        "description": "Optional per-trigger filtering options for YouTube triggers. At least one of `min_seconds` or `max_seconds` must be set to activate duration filtering, and when both are provided `min_seconds` must be less than or equal to `max_seconds`."
      },
      "YouTubeChannelDetail": {
        "type": "object",
        "properties": {
          "channel_id": {
            "type": "string",
            "description": "YouTube channel ID"
          },
          "channel_name": {
            "type": "string",
            "description": "Display name for the YouTube channel"
          },
          "channel_handle": {
            "type": "string",
            "nullable": true,
            "description": "YouTube channel handle (if available)"
          },
          "thumbnail_url": {
            "type": "string",
            "nullable": true,
            "description": "URL for the channel profile picture (if available)"
          },
          "subscriber_count": {
            "type": "integer",
            "nullable": true,
            "description": "Number of subscribers for the channel (if available)"
          }
        }
      },
      "VideoInput": {
        "type": "object",
        "properties": {
          "video_url": {
            "type": "string",
            "description": "URL of the input video"
          },
          "thumbnail_url": {
            "type": "string",
            "nullable": true,
            "description": "URL of the input video thumbnail"
          }
        }
      },
      "VideoUploadUrlResponse": {
        "type": "object",
        "properties": {
          "video_id": {
            "type": "string",
            "description": "UUID for the video. Use this to call finalize_upload and in update_params."
          },
          "upload_url": {
            "type": "string",
            "description": "URL to POST the file to"
          },
          "upload_fields": {
            "type": "object",
            "description": "Form fields to include before the file in the POST request",
            "additionalProperties": {
              "type": "string"
            }
          },
          "max_file_size_bytes": {
            "type": "integer",
            "description": "Maximum file size (5GB)"
          }
        }
      },
      "VideoUploadFinalizeResponse": {
        "type": "object",
        "properties": {
          "video_id": {
            "type": "string",
            "description": "UUID for the video. Use this in update_params when running agents."
          }
        }
      },
      "AudioUploadUrlResponse": {
        "type": "object",
        "properties": {
          "audio_id": {
            "type": "string",
            "description": "UUID for the audio. Use this to call finalize_upload and in update_params."
          },
          "upload_url": {
            "type": "string",
            "description": "URL to POST the file to"
          },
          "upload_fields": {
            "type": "object",
            "description": "Form fields to include before the file in the POST request",
            "additionalProperties": {
              "type": "string"
            }
          },
          "max_file_size_bytes": {
            "type": "integer",
            "description": "Maximum file size (100MB)"
          }
        }
      },
      "AudioUploadFinalizeResponse": {
        "type": "object",
        "properties": {
          "audio_id": {
            "type": "string",
            "description": "UUID for the audio. Use this in update_params when running agents."
          }
        }
      },
      "ImageUploadUrlResponse": {
        "type": "object",
        "properties": {
          "image_id": {
            "type": "string",
            "description": "UUID for the image. Use this to call finalize_upload and in update_params."
          },
          "upload_url": {
            "type": "string",
            "description": "URL to POST the file to"
          },
          "upload_fields": {
            "type": "object",
            "description": "Form fields to include before the file in the POST request",
            "additionalProperties": {
              "type": "string"
            }
          },
          "max_file_size_bytes": {
            "type": "integer",
            "description": "Maximum file size (50MB)"
          }
        }
      },
      "ImageUploadFinalizeResponse": {
        "type": "object",
        "properties": {
          "image_id": {
            "type": "string",
            "description": "UUID for the image. Use this in update_params when running agents."
          }
        }
      },
      "SocialDestination": {
        "type": "object",
        "properties": {
          "social_connection_id": {
            "type": "string",
            "format": "uuid"
          },
          "platform": {
            "type": "string",
            "enum": [
              "x",
              "linkedin",
              "instagram",
              "facebook",
              "tiktok",
              "youtube"
            ]
          },
          "account_name": {
            "type": "string",
            "nullable": true
          },
          "account_username": {
            "type": "string",
            "nullable": true
          },
          "profile_url": {
            "type": "string",
            "nullable": true
          },
          "username": {
            "type": "string",
            "nullable": true,
            "description": "Backward-compatible account username field."
          },
          "display_name": {
            "type": "string",
            "nullable": true,
            "description": "Backward-compatible account display name field."
          },
          "user_image": {
            "type": "string",
            "nullable": true,
            "description": "Backward-compatible account avatar/image field."
          }
        },
        "required": [
          "social_connection_id",
          "platform"
        ]
      },
      "SocialPostResult": {
        "type": "object",
        "properties": {
          "social_connection_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "platform": {
            "type": "string",
            "enum": [
              "x",
              "linkedin",
              "instagram",
              "facebook",
              "tiktok",
              "youtube"
            ]
          },
          "status": {
            "type": "string",
            "nullable": true,
            "description": "Destination status. scheduled means the destination is waiting or processing; success means it published; error means publishing failed for that destination."
          },
          "platform_post_id": {
            "type": "string",
            "nullable": true,
            "description": "Native post ID from the destination platform. Null while a scheduled destination is still waiting to publish."
          },
          "post_url": {
            "type": "string",
            "nullable": true
          },
          "message": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "SocialDestinationPostResult": {
        "type": "object",
        "properties": {
          "social_connection_id": {
            "type": "string",
            "format": "uuid"
          },
          "platform": {
            "type": "string",
            "enum": [
              "x",
              "linkedin",
              "instagram",
              "facebook",
              "tiktok",
              "youtube"
            ]
          },
          "status": {
            "type": "string",
            "nullable": true,
            "description": "Destination status. scheduled means the destination is waiting or processing; success means it published; error means publishing failed for that destination."
          },
          "platform_post_id": {
            "type": "string",
            "nullable": true,
            "description": "Native post ID from the destination platform. Null while a scheduled destination is still waiting to publish."
          },
          "post_url": {
            "type": "string",
            "nullable": true
          },
          "message": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "social_connection_id",
          "platform"
        ]
      },
      "SocialConnectionsResponse": {
        "type": "object",
        "properties": {
          "connected_accounts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SocialDestination"
            }
          }
        },
        "required": [
          "connected_accounts"
        ]
      },
      "SocialPostRequest": {
        "type": "object",
        "properties": {
          "post": {
            "type": "string"
          },
          "platforms": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "x",
                "linkedin",
                "instagram",
                "facebook",
                "tiktok",
                "youtube"
              ]
            },
            "minItems": 1
          },
          "destinations": {
            "type": "array",
            "description": "Explicit connected accounts to publish to. Use social_connection_id values from GET /social/connections.",
            "minItems": 1,
            "items": {
              "oneOf": [
                {
                  "type": "string",
                  "format": "uuid"
                },
                {
                  "type": "object",
                  "properties": {
                    "social_connection_id": {
                      "type": "string",
                      "format": "uuid"
                    }
                  },
                  "required": [
                    "social_connection_id"
                  ]
                }
              ]
            }
          },
          "media_urls": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uri"
            }
          },
          "schedule_date": {
            "type": "string",
            "format": "date-time",
            "description": "Future ISO timestamp to schedule the post. Omit to publish immediately."
          },
          "workspace_id": {
            "type": "string",
            "format": "uuid"
          }
        },
        "anyOf": [
          {
            "required": [
              "platforms"
            ]
          },
          {
            "required": [
              "destinations"
            ]
          }
        ],
        "additionalProperties": true
      },
      "SocialPostResponse": {
        "type": "object",
        "properties": {
          "post_id": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "nullable": true,
            "description": "Aggregate status for the social post across destinations. Common values are scheduled, processing, pending_approval, posted, partial_failure, failed, and rejected."
          },
          "publishing_status": {
            "type": "string",
            "nullable": true,
            "description": "Status returned by an immediate publishing attempt. Null while a future-scheduled post is still queued."
          },
          "scheduled_at": {
            "type": "string",
            "nullable": true,
            "description": "Scheduled publish time as an ISO timestamp. For immediate posts this is the creation time."
          },
          "platforms": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "x",
                "linkedin",
                "instagram",
                "facebook",
                "tiktok",
                "youtube"
              ]
            }
          },
          "links": {
            "type": "array",
            "description": "Public destination links. This can be empty while a scheduled post is waiting to publish.",
            "items": {
              "type": "object",
              "properties": {
                "platform": {
                  "type": "string",
                  "enum": [
                    "x",
                    "linkedin",
                    "instagram",
                    "facebook",
                    "tiktok",
                    "youtube"
                  ]
                },
                "post_url": {
                  "type": "string",
                  "nullable": true
                },
                "social_connection_id": {
                  "type": "string",
                  "format": "uuid",
                  "nullable": true
                }
              }
            }
          },
          "results": {
            "type": "array",
            "description": "Per-destination publishing outcomes. Native destination IDs and URLs can be null while scheduled.",
            "items": {
              "$ref": "#/components/schemas/SocialPostResult"
            }
          },
          "destination_results": {
            "description": "Canonical per-destination outcomes keyed by social_connection_id for create responses and returned as a list by get responses.",
            "oneOf": [
              {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/SocialDestinationPostResult"
                }
              },
              {
                "type": "object",
                "additionalProperties": {
                  "$ref": "#/components/schemas/SocialDestinationPostResult"
                }
              }
            ]
          },
          "destinations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SocialDestination"
            }
          },
          "stats": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true,
            "description": "Backward-compatible analytics payload. Prefer analytics for new integrations."
          },
          "error": {
            "type": "string",
            "nullable": true
          },
          "publishing_errors": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "created_at": {
            "type": "string",
            "nullable": true
          },
          "updated_at": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true,
            "description": "Post description or caption when available."
          },
          "thumbnail_url": {
            "type": "string",
            "nullable": true,
            "format": "uri",
            "description": "Post thumbnail URL when available."
          },
          "analytics": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/SocialPostAnalyticsPayload"
              },
              {
                "type": "null"
              }
            ]
          }
        }
      },
      "SocialPostsPagination": {
        "type": "object",
        "properties": {
          "limit": {
            "type": "integer",
            "description": "Maximum posts requested."
          },
          "returned": {
            "type": "integer",
            "description": "Number of posts returned in this page."
          },
          "has_more": {
            "type": "boolean",
            "description": "Whether another page is available."
          },
          "next_cursor": {
            "type": "string",
            "nullable": true,
            "description": "Opaque cursor for the next page. Null when has_more is false."
          },
          "sort": {
            "type": "string",
            "enum": [
              "created_at_desc"
            ]
          }
        },
        "required": [
          "limit",
          "returned",
          "has_more",
          "next_cursor",
          "sort"
        ],
        "additionalProperties": false
      },
      "SocialPostListResponse": {
        "type": "object",
        "properties": {
          "posts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SocialPostResponse"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/SocialPostsPagination"
          }
        },
        "required": [
          "posts",
          "pagination"
        ],
        "additionalProperties": false
      },
      "SocialPostAnalyticsResponse": {
        "type": "object",
        "properties": {
          "post_id": {
            "type": "string"
          },
          "platform": {
            "type": "string",
            "enum": [
              "x",
              "linkedin",
              "instagram",
              "facebook",
              "tiktok",
              "youtube"
            ],
            "nullable": true
          },
          "social_connection_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "stats": {
            "type": "object",
            "additionalProperties": true,
            "description": "Backward-compatible analytics payload. Prefer analytics for new integrations."
          },
          "analytics": {
            "$ref": "#/components/schemas/SocialPostAnalyticsPayload"
          }
        },
        "required": [
          "post_id",
          "platform",
          "social_connection_id",
          "analytics",
          "stats"
        ],
        "additionalProperties": false
      },
      "SocialConnectionCreateRequest": {
        "type": "object",
        "properties": {
          "platform": {
            "type": "string",
            "enum": [
              "x",
              "linkedin",
              "instagram",
              "facebook",
              "tiktok",
              "youtube"
            ]
          },
          "connection_name": {
            "type": "string"
          },
          "redirect_url": {
            "type": "string",
            "format": "uri"
          }
        },
        "required": [
          "platform"
        ],
        "additionalProperties": false
      },
      "SocialConnectUrlResponse": {
        "type": "object",
        "properties": {
          "platform": {
            "type": "string",
            "enum": [
              "x",
              "linkedin",
              "instagram",
              "facebook",
              "tiktok",
              "youtube"
            ]
          },
          "connect_url": {
            "type": "string",
            "format": "uri",
            "description": "Short-lived Mosaic URL that opens the social account setup flow."
          }
        },
        "required": [
          "platform",
          "connect_url"
        ]
      },
      "SocialConnection": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SocialDestination"
          },
          {
            "type": "object",
            "properties": {
              "connected": {
                "type": "boolean"
              }
            },
            "required": [
              "connected"
            ]
          }
        ]
      },
      "SocialConnectionDeleteResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "platform": {
            "type": "string",
            "enum": [
              "x",
              "linkedin",
              "instagram",
              "facebook",
              "tiktok",
              "youtube"
            ]
          },
          "social_connection_id": {
            "type": "string",
            "format": "uuid"
          }
        },
        "required": [
          "success",
          "platform",
          "social_connection_id"
        ]
      },
      "SocialComment": {
        "type": "object",
        "properties": {
          "comment_id": {
            "type": "string",
            "nullable": true
          },
          "platform_comment_id": {
            "type": "string",
            "nullable": true
          },
          "platform": {
            "type": "string",
            "enum": [
              "x",
              "linkedin",
              "instagram",
              "facebook",
              "tiktok",
              "youtube"
            ],
            "nullable": true
          },
          "social_connection_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "text": {
            "type": "string",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "nullable": true,
            "description": "Creation timestamp. Null when the source response does not include it."
          },
          "comment_url": {
            "type": "string",
            "nullable": true,
            "format": "uri",
            "description": "Direct comment URL. Null when the source response does not include it."
          },
          "like_count": {
            "type": "number",
            "nullable": true,
            "description": "Like count. Null when the source response does not include it."
          },
          "reply_count": {
            "type": "number",
            "nullable": true,
            "description": "Reply count. Null when the source response does not include it."
          },
          "parent_comment_id": {
            "type": "string",
            "nullable": true,
            "description": "Parent comment ID for replies. Null for top-level comments or when the source response does not include it."
          },
          "author": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/SocialCommentAuthor"
              },
              {
                "type": "null"
              }
            ],
            "description": "Fixed author object. Null when the source response does not include author metadata."
          },
          "replies": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SocialComment"
            }
          },
          "raw": {
            "oneOf": [
              {
                "type": "object",
                "additionalProperties": true
              },
              {
                "type": "null"
              }
            ],
            "description": "Unnormalized platform-specific comment payload."
          },
          "media": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SocialCommentMedia"
            }
          }
        },
        "additionalProperties": false,
        "required": [
          "comment_id",
          "platform_comment_id",
          "platform",
          "social_connection_id",
          "text",
          "created_at",
          "comment_url",
          "like_count",
          "reply_count",
          "parent_comment_id",
          "author",
          "media",
          "replies",
          "raw"
        ]
      },
      "SocialPostCommentsResponse": {
        "type": "object",
        "properties": {
          "post_id": {
            "type": "string"
          },
          "platform": {
            "type": "string",
            "enum": [
              "x",
              "linkedin",
              "instagram",
              "facebook",
              "tiktok",
              "youtube"
            ],
            "nullable": true
          },
          "social_connection_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "comments": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SocialComment"
            }
          },
          "metadata": {
            "type": "object",
            "additionalProperties": true
          },
          "pagination": {
            "$ref": "#/components/schemas/SocialCommentsPagination"
          }
        },
        "required": [
          "post_id",
          "platform",
          "social_connection_id",
          "comments",
          "metadata",
          "pagination"
        ],
        "additionalProperties": false
      },
      "SocialAnalyticsMetrics": {
        "type": "object",
        "description": "Fixed normalized metric object. Every key is always present. A value is a number when the source response includes that metric and null when it does not.",
        "properties": {
          "likes": {
            "type": "number",
            "nullable": true
          },
          "comments": {
            "type": "number",
            "nullable": true
          },
          "shares": {
            "type": "number",
            "nullable": true
          },
          "impressions": {
            "type": "number",
            "nullable": true
          },
          "views": {
            "type": "number",
            "nullable": true
          },
          "video_views": {
            "type": "number",
            "nullable": true
          },
          "video_viewers": {
            "type": "number",
            "nullable": true
          },
          "video_watch_time_ms": {
            "type": "number",
            "nullable": true
          },
          "engagement": {
            "type": "number",
            "nullable": true
          },
          "clicks": {
            "type": "number",
            "nullable": true
          },
          "saves": {
            "type": "number",
            "nullable": true
          },
          "bookmarks": {
            "type": "number",
            "nullable": true
          },
          "quotes": {
            "type": "number",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "required": [
          "likes",
          "comments",
          "shares",
          "impressions",
          "views",
          "video_views",
          "video_viewers",
          "video_watch_time_ms",
          "engagement",
          "clicks",
          "saves",
          "bookmarks",
          "quotes"
        ]
      },
      "SocialPlatformAnalytics": {
        "type": "object",
        "properties": {
          "platform": {
            "type": "string",
            "enum": [
              "x",
              "linkedin",
              "instagram",
              "facebook",
              "tiktok",
              "youtube"
            ]
          },
          "platform_post_id": {
            "type": "string",
            "nullable": true,
            "description": "Native post ID from the destination platform. Null when the source response does not include it."
          },
          "post_url": {
            "type": "string",
            "nullable": true,
            "format": "uri",
            "description": "Public post URL. Null when the source response does not include it."
          },
          "metrics": {
            "$ref": "#/components/schemas/SocialAnalyticsMetrics"
          },
          "raw_metrics": {
            "type": "object",
            "additionalProperties": true,
            "description": "Unnormalized platform-specific analytics payload."
          }
        },
        "required": [
          "platform",
          "platform_post_id",
          "post_url",
          "metrics",
          "raw_metrics"
        ],
        "additionalProperties": false
      },
      "SocialPostAnalyticsPayload": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "nullable": true,
            "description": "Analytics status. Null when the source response does not include a status."
          },
          "totals": {
            "$ref": "#/components/schemas/SocialAnalyticsMetrics"
          },
          "platforms": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SocialPlatformAnalytics"
            }
          },
          "metadata": {
            "type": "object",
            "additionalProperties": true
          }
        },
        "required": [
          "status",
          "totals",
          "platforms",
          "metadata"
        ],
        "additionalProperties": false
      },
      "SocialCommentAuthor": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "username": {
            "type": "string",
            "nullable": true
          },
          "profile_url": {
            "type": "string",
            "nullable": true,
            "format": "uri"
          },
          "profile_image_url": {
            "type": "string",
            "nullable": true,
            "format": "uri"
          }
        },
        "additionalProperties": false,
        "required": [
          "id",
          "name",
          "username",
          "profile_url",
          "profile_image_url"
        ]
      },
      "SocialCommentsPagination": {
        "type": "object",
        "properties": {
          "limit": {
            "type": "integer"
          },
          "returned": {
            "type": "integer"
          },
          "total_available": {
            "type": "integer"
          },
          "has_more": {
            "type": "boolean"
          },
          "next_cursor": {
            "type": "string",
            "nullable": true
          },
          "sort": {
            "type": "string",
            "enum": [
              "created_at_desc"
            ],
            "description": "Comments and nested replies are sorted by created_at descending. Comments without created_at sort after comments with timestamps; ties sort by platform, comment_id, and platform_comment_id. Top-level comments are sorted before pagination."
          }
        },
        "required": [
          "limit",
          "returned",
          "total_available",
          "has_more",
          "next_cursor",
          "sort"
        ],
        "additionalProperties": false
      },
      "SocialCommentMedia": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "image",
              "video",
              "gif",
              "audio",
              "document",
              "unknown"
            ]
          },
          "url": {
            "type": "string",
            "nullable": true,
            "format": "uri"
          },
          "thumbnail_url": {
            "type": "string",
            "nullable": true,
            "format": "uri"
          },
          "mime_type": {
            "type": "string",
            "nullable": true
          },
          "alt_text": {
            "type": "string",
            "nullable": true
          },
          "raw": {
            "type": "object",
            "additionalProperties": true
          }
        },
        "required": [
          "type",
          "url",
          "thumbnail_url",
          "mime_type",
          "alt_text",
          "raw"
        ],
        "additionalProperties": false
      },
      "SocialPostUpdateDestinationResult": {
        "type": "object",
        "properties": {
          "social_connection_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "platform": {
            "type": "string",
            "enum": [
              "x",
              "linkedin",
              "instagram",
              "facebook",
              "tiktok",
              "youtube"
            ],
            "nullable": true
          },
          "status": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "social_connection_id",
          "platform",
          "status"
        ],
        "additionalProperties": false
      },
      "SocialPostUpdateResponse": {
        "type": "object",
        "properties": {
          "post_id": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "nullable": true
          },
          "scheduled_at": {
            "type": "string",
            "nullable": true
          },
          "updated_destinations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SocialPostUpdateDestinationResult"
            }
          }
        },
        "required": [
          "post_id",
          "status",
          "scheduled_at",
          "updated_destinations"
        ],
        "additionalProperties": false
      }
    },
    "responses": {
      "UnauthorizedError": {
        "description": "Authentication failed",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "detail": {
                  "type": "string",
                  "example": "Invalid or missing API key"
                }
              }
            }
          }
        }
      },
      "BadRequestError": {
        "description": "Invalid request",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "detail": {
                  "type": "string",
                  "example": "Validation error message"
                },
                "issues": {
                  "type": "array",
                  "description": "Optional structured validation issues.",
                  "items": {
                    "type": "object",
                    "properties": {
                      "code": {
                        "type": "string"
                      },
                      "message": {
                        "type": "string"
                      },
                      "field": {
                        "type": "string",
                        "nullable": true
                      },
                      "node_id": {
                        "type": "string",
                        "nullable": true
                      },
                      "node_type_id": {
                        "type": "string",
                        "nullable": true
                      },
                      "node_name": {
                        "type": "string",
                        "nullable": true
                      },
                      "param_name": {
                        "type": "string",
                        "nullable": true
                      },
                      "operation_step": {
                        "type": "integer",
                        "nullable": true
                      }
                    },
                    "required": [
                      "code",
                      "message"
                    ]
                  }
                }
              }
            }
          }
        }
      },
      "NotFoundError": {
        "description": "Resource not found",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "detail": {
                  "type": "string",
                  "example": "Resource not found"
                }
              }
            }
          }
        }
      },
      "PayloadTooLargeError": {
        "description": "Payload too large",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "detail": {
                  "type": "string",
                  "example": "File size exceeds limit"
                }
              }
            }
          }
        }
      },
      "ForbiddenError": {
        "description": "Access denied",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "detail": {
                  "type": "string",
                  "example": "Workspace access required"
                }
              }
            }
          }
        }
      },
      "ConflictError": {
        "description": "Conflict",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "error": {
                  "type": "string",
                  "example": "Processing already in progress"
                }
              }
            }
          }
        }
      }
    },
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Use your API key prefixed with 'Bearer'"
      },
      "apiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "Use your API key in the X-API-Key header"
      }
    }
  }
}