{
 "openapi": "3.1.0",
 "info": {
  "title": "Polf API",
  "version": "2026-07-01",
  "description": "API B2B do Polf — transforma vídeo longo em cortes verticais (Reels/TikTok/Shorts) com legenda PT-BR queimada. Contrato compatível com a Vizard + extras v2 (webhooks nomeados, download durável, sandbox polf-test://, publicação social). Docs completas: https://app.polf.ai/docs/api"
 },
 "servers": [
  {
   "url": "https://api.polf.ai"
  }
 ],
 "paths": {
  "/api/v1/project/create": {
   "post": {
    "summary": "Platform Create",
    "operationId": "platform_create_api_v1_project_create_post",
    "parameters": [
     {
      "name": "INSTACUT_API_KEY",
      "in": "header",
      "required": false,
      "schema": {
       "type": "string",
       "title": "Instacut Api Key"
      }
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/PlatformCreate"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Successful Response",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "additionalProperties": true,
         "title": "Response Platform Create Api V1 Project Create Post"
        }
       }
      }
     },
     "422": {
      "description": "Validation Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/project/query/{project_id}": {
   "get": {
    "summary": "Platform Query",
    "operationId": "platform_query_api_v1_project_query__project_id__get",
    "parameters": [
     {
      "name": "project_id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "title": "Project Id"
      }
     },
     {
      "name": "INSTACUT_API_KEY",
      "in": "header",
      "required": false,
      "schema": {
       "type": "string",
       "title": "Instacut Api Key"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Successful Response",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "additionalProperties": true,
         "title": "Response Platform Query Api V1 Project Query  Project Id  Get"
        }
       }
      }
     },
     "422": {
      "description": "Validation Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/clip/{clip_id}/export": {
   "post": {
    "summary": "Platform Export",
    "description": "Plataforma (B2B): garante a QUEIMA do export (legenda pycaps) de UM clip — usar quando o\nquery devolveu videoUrl=null (o preburn ainda não chegou nele). Mesma máquina do export\nnativo: cache-hit devolve pronto na hora; senão dispara em background (idempotente, não\nre-queima). Assíncrono — acompanhe via GET /api/v1/project/query/{project_id} (videoUrl != null\nquando pronto). Gera export_r2_key (o que o query agora entrega).\n\nv2 (spec, pedido nº7): resposta vira {renderJobId, status}. renderJobId é DETERMINÍSTICO\n(clip_id:fmt) — re-POST do mesmo export devolve o MESMO renderJobId com o status atual\n(idempotente: o cache de export já garantia que não recobra; agora a resposta formaliza).\nstatus ∈ done | exporting | failed.",
    "operationId": "platform_export_api_v1_clip__clip_id__export_post",
    "parameters": [
     {
      "name": "clip_id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "title": "Clip Id"
      }
     },
     {
      "name": "INSTACUT_API_KEY",
      "in": "header",
      "required": false,
      "schema": {
       "type": "string",
       "title": "Instacut Api Key"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Successful Response",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "additionalProperties": true,
         "title": "Response Platform Export Api V1 Clip  Clip Id  Export Post"
        }
       }
      }
     },
     "422": {
      "description": "Validation Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/clips/{clip_id}/download": {
   "get": {
    "summary": "Platform Clip Download",
    "description": "[B2B v2] Download ESTÁVEL do clip: URL que NÃO expira → 302 pra presigned fresca (1h) com\nContent-Disposition: attachment. Mata o re-poll de URL vencida (dor nº1 do consumidor).\nRETENÇÃO DECLARADA: os arquivos ficam 30 dias no R2 (lifecycle); depois o endpoint devolve\n410. É o downloadUrl que o query/webhooks v2 entregam. Auth: header INSTACUT_API_KEY.",
    "operationId": "platform_clip_download_api_v1_clips__clip_id__download_get",
    "parameters": [
     {
      "name": "clip_id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "title": "Clip Id"
      }
     },
     {
      "name": "INSTACUT_API_KEY",
      "in": "header",
      "required": false,
      "schema": {
       "type": "string",
       "title": "Instacut Api Key"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Successful Response",
      "content": {
       "application/json": {
        "schema": {}
       }
      }
     },
     "422": {
      "description": "Validation Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/projects": {
   "get": {
    "summary": "Platform List Projects",
    "description": "[B2B v2] Lista PAGINADA dos projetos da chave (cursor keyset, padrão Stripe/GitHub —\nestável sob inserção). Filtros: externalUserId (o ID do cliente final ecoado do create) e\nstatus v2 (queued|processing|done|failed). limit máx 50. Resposta: {projects[], nextCursor}\n— nextCursor=null quando acabou; repasse-o em `cursor` pra próxima página.",
    "operationId": "platform_list_projects_api_v1_projects_get",
    "parameters": [
     {
      "name": "externalUserId",
      "in": "query",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Externaluserid"
      }
     },
     {
      "name": "status",
      "in": "query",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Status"
      }
     },
     {
      "name": "cursor",
      "in": "query",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Cursor"
      }
     },
     {
      "name": "limit",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "default": 20,
       "title": "Limit"
      }
     },
     {
      "name": "INSTACUT_API_KEY",
      "in": "header",
      "required": false,
      "schema": {
       "type": "string",
       "title": "Instacut Api Key"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Successful Response",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "additionalProperties": true,
         "title": "Response Platform List Projects Api V1 Projects Get"
        }
       }
      }
     },
     "422": {
      "description": "Validation Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/users/{external_user_id}/social-accounts": {
   "get": {
    "summary": "B2B Social Accounts",
    "description": "[B2B social] Contas sociais conectadas do cliente FINAL (externalUserId) — lidas da bundle\n(fonte de verdade). Sem team ainda → lista vazia (chame o /connect primeiro).",
    "operationId": "b2b_social_accounts_api_v1_users__external_user_id__social_accounts_get",
    "parameters": [
     {
      "name": "external_user_id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "title": "External User Id"
      }
     },
     {
      "name": "INSTACUT_API_KEY",
      "in": "header",
      "required": false,
      "schema": {
       "type": "string",
       "title": "Instacut Api Key"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Successful Response",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "additionalProperties": true,
         "title": "Response B2B Social Accounts Api V1 Users  External User Id  Social Accounts Get"
        }
       }
      }
     },
     "422": {
      "description": "Validation Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/users/{external_user_id}/social-accounts/connect": {
   "post": {
    "summary": "B2B Social Connect",
    "description": "[B2B social] Gera a connectUrl (portal OAuth hospedado da bundle — mesmo fluxo do\n/v1/social/connect nativo). Provisiona o team do (chave, externalUserId) lazy na 1ª vez.",
    "operationId": "b2b_social_connect_api_v1_users__external_user_id__social_accounts_connect_post",
    "parameters": [
     {
      "name": "external_user_id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "title": "External User Id"
      }
     },
     {
      "name": "INSTACUT_API_KEY",
      "in": "header",
      "required": false,
      "schema": {
       "type": "string",
       "title": "Instacut Api Key"
      }
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/B2BConnectIn"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Successful Response",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "additionalProperties": true,
         "title": "Response B2B Social Connect Api V1 Users  External User Id  Social Accounts Connect Post"
        }
       }
      }
     },
     "422": {
      "description": "Validation Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/posts": {
   "post": {
    "summary": "B2B Create Post",
    "description": "[B2B social] Publica/agenda 1 clip nas contas do cliente final. Reusa a MESMA máquina do\npublish nativo (create_social_post + worker publish_clip): ingest R2→bundle + create-post\nmulti-rede; caption ausente → copy do clip (gerada on-demand no worker se faltar).\nCota: posts/mês por chave (402 ao estourar). Custo: est_cost_usd por post → admin B2B.",
    "operationId": "b2b_create_post_api_v1_posts_post",
    "parameters": [
     {
      "name": "INSTACUT_API_KEY",
      "in": "header",
      "required": false,
      "schema": {
       "type": "string",
       "title": "Instacut Api Key"
      }
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/B2BPostIn"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Successful Response",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "additionalProperties": true,
         "title": "Response B2B Create Post Api V1 Posts Post"
        }
       }
      }
     },
     "422": {
      "description": "Validation Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      }
     }
    }
   },
   "get": {
    "summary": "B2B List Posts",
    "description": "[B2B social] Lista paginada (cursor keyset, igual /api/v1/projects) dos posts da chave.\nFiltros: externalUserId e status público (processing|scheduled|published|partial|failed|canceled).",
    "operationId": "b2b_list_posts_api_v1_posts_get",
    "parameters": [
     {
      "name": "externalUserId",
      "in": "query",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Externaluserid"
      }
     },
     {
      "name": "status",
      "in": "query",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Status"
      }
     },
     {
      "name": "cursor",
      "in": "query",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Cursor"
      }
     },
     {
      "name": "limit",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "default": 20,
       "title": "Limit"
      }
     },
     {
      "name": "INSTACUT_API_KEY",
      "in": "header",
      "required": false,
      "schema": {
       "type": "string",
       "title": "Instacut Api Key"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Successful Response",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "additionalProperties": true,
         "title": "Response B2B List Posts Api V1 Posts Get"
        }
       }
      }
     },
     "422": {
      "description": "Validation Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/posts/{post_id}": {
   "get": {
    "summary": "B2B Get Post",
    "description": "[B2B social] Status por alvo (platformPostUrl real + errorCode/retriable repassados da\nbundle via errorsVerbose). 404 p/ não-existe E não-é-da-chave (anti-IDOR).",
    "operationId": "b2b_get_post_api_v1_posts__post_id__get",
    "parameters": [
     {
      "name": "post_id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "title": "Post Id"
      }
     },
     {
      "name": "INSTACUT_API_KEY",
      "in": "header",
      "required": false,
      "schema": {
       "type": "string",
       "title": "Instacut Api Key"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Successful Response",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "additionalProperties": true,
         "title": "Response B2B Get Post Api V1 Posts  Post Id  Get"
        }
       }
      }
     },
     "422": {
      "description": "Validation Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      }
     }
    }
   },
   "delete": {
    "summary": "B2B Cancel Post",
    "description": "[B2B social] Cancela um post AGENDADO (post já publicado continua no ar — igual o nativo).",
    "operationId": "b2b_cancel_post_api_v1_posts__post_id__delete",
    "parameters": [
     {
      "name": "post_id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "title": "Post Id"
      }
     },
     {
      "name": "INSTACUT_API_KEY",
      "in": "header",
      "required": false,
      "schema": {
       "type": "string",
       "title": "Instacut Api Key"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Successful Response",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "additionalProperties": true,
         "title": "Response B2B Cancel Post Api V1 Posts  Post Id  Delete"
        }
       }
      }
     },
     "422": {
      "description": "Validation Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/posts/{post_id}/metrics": {
   "get": {
    "summary": "B2B Post Metrics",
    "description": "[B2B social] Métricas por alvo (views/likes/… do MIRROR de analytics — sweep diário da\nbundle, retenção deles = 30d). X não expõe analytics (selo honesto do produto).",
    "operationId": "b2b_post_metrics_api_v1_posts__post_id__metrics_get",
    "parameters": [
     {
      "name": "post_id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "title": "Post Id"
      }
     },
     {
      "name": "INSTACUT_API_KEY",
      "in": "header",
      "required": false,
      "schema": {
       "type": "string",
       "title": "Instacut Api Key"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Successful Response",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "additionalProperties": true,
         "title": "Response B2B Post Metrics Api V1 Posts  Post Id  Metrics Get"
        }
       }
      }
     },
     "422": {
      "description": "Validation Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      }
     }
    }
   }
  }
 },
 "components": {
  "schemas": {
   "B2BConnectIn": {
    "properties": {
     "returnUrl": {
      "type": "string",
      "title": "Returnurl"
     },
     "platform": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Platform"
     }
    },
    "type": "object",
    "required": [
     "returnUrl"
    ],
    "title": "B2BConnectIn"
   },
   "B2BPostIn": {
    "properties": {
     "externalUserId": {
      "type": "string",
      "title": "Externaluserid"
     },
     "clipId": {
      "type": "string",
      "title": "Clipid"
     },
     "targets": {
      "items": {
       "$ref": "#/components/schemas/B2BPostTarget"
      },
      "type": "array",
      "title": "Targets"
     },
     "scheduledAt": {
      "anyOf": [
       {
        "type": "string",
        "format": "date-time"
       },
       {
        "type": "null"
       }
      ],
      "title": "Scheduledat"
     },
     "webhookUrl": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Webhookurl"
     }
    },
    "type": "object",
    "required": [
     "externalUserId",
     "clipId",
     "targets"
    ],
    "title": "B2BPostIn"
   },
   "B2BPostTarget": {
    "properties": {
     "accountId": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Accountid"
     },
     "platform": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Platform"
     },
     "caption": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Caption"
     }
    },
    "type": "object",
    "title": "B2BPostTarget"
   },
   "HTTPValidationError": {
    "properties": {
     "detail": {
      "items": {
       "$ref": "#/components/schemas/ValidationError"
      },
      "type": "array",
      "title": "Detail"
     }
    },
    "type": "object",
    "title": "HTTPValidationError"
   },
   "PlatformCreate": {
    "properties": {
     "videoUrl": {
      "type": "string",
      "title": "Videourl"
     },
     "lang": {
      "type": "string",
      "title": "Lang",
      "default": "pt"
     },
     "videoType": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Videotype"
     },
     "ext": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Ext"
     },
     "videoQuality": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Videoquality"
     },
     "preferLength": {
      "anyOf": [
       {
        "items": {
         "type": "integer"
        },
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "title": "Preferlength"
     },
     "ratioOfClip": {
      "type": "integer",
      "title": "Ratioofclip",
      "default": 1
     },
     "maxClipNumber": {
      "type": "integer",
      "title": "Maxclipnumber",
      "default": 10
     },
     "keyword": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Keyword"
     },
     "removeSilenceSwitch": {
      "type": "integer",
      "title": "Removesilenceswitch",
      "default": 0
     },
     "subtitleSwitch": {
      "type": "integer",
      "title": "Subtitleswitch",
      "default": 1
     },
     "headlineSwitch": {
      "type": "integer",
      "title": "Headlineswitch",
      "default": 1
     },
     "emojiSwitch": {
      "type": "integer",
      "title": "Emojiswitch",
      "default": 0
     },
     "highlightSwitch": {
      "type": "integer",
      "title": "Highlightswitch",
      "default": 0
     },
     "templateId": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Templateid"
     },
     "captionPreset": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Captionpreset"
     },
     "captionAnim": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Captionanim"
     },
     "clipFormat": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Clipformat"
     },
     "headlineStyle": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Headlinestyle"
     },
     "projectName": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Projectname"
     },
     "webhookUrl": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Webhookurl"
     },
     "idempotencyKey": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Idempotencykey"
     },
     "processStartS": {
      "anyOf": [
       {
        "type": "number"
       },
       {
        "type": "null"
       }
      ],
      "title": "Processstarts"
     },
     "processDurationS": {
      "anyOf": [
       {
        "type": "number"
       },
       {
        "type": "null"
       }
      ],
      "title": "Processdurations"
     },
     "externalUserId": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Externaluserid"
     }
    },
    "type": "object",
    "required": [
     "videoUrl"
    ],
    "title": "PlatformCreate",
    "description": "Contrato = API da Vizard (docs.vizard.ai/reference/submit) — cópia direta p/ quem já integra com eles.\n\nSANDBOX (contrato PÚBLICO, padrão test-cards do Stripe — core/sandbox.py):\nvideoUrl aceita fontes mágicas `polf-test://success | fail-source | fail-render | slow`\nque simulam o fluxo inteiro (webhooks v2 reais, clips fake \"[SANDBOX]\", status/erros\nestáveis) SEM reservar/debitar crédito nem usar GPU/download."
   },
   "ValidationError": {
    "properties": {
     "loc": {
      "items": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "integer"
        }
       ]
      },
      "type": "array",
      "title": "Location"
     },
     "msg": {
      "type": "string",
      "title": "Message"
     },
     "type": {
      "type": "string",
      "title": "Error Type"
     },
     "input": {
      "title": "Input"
     },
     "ctx": {
      "type": "object",
      "title": "Context"
     }
    },
    "type": "object",
    "required": [
     "loc",
     "msg",
     "type"
    ],
    "title": "ValidationError"
   }
  },
  "securitySchemes": {
   "ApiKeyAuth": {
    "type": "apiKey",
    "in": "header",
    "name": "INSTACUT_API_KEY",
    "description": "Chave de API por cliente (formato ik_...). Peça a sua ao suporte."
   }
  }
 },
 "security": [
  {
   "ApiKeyAuth": []
  }
 ]
}