Referencia de la API
Última actualización: 12 de septiembre de 2026
API de Aiva Studio
La API pública y el MCP son dos transportes sobre el mismo registro de operaciones que usa el tablero. Lo único que cambia entre ellos es cómo se prueba la identidad: una tool nueva aparece en los tres a la vez.
Base: https://studio.aivacompany.com
Autenticación
Una sola credencial para todo: una clave sk_live_… que se crea en
Ajustes → Claves de API.
Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxx
De la clave se guarda únicamente su SHA-256. Se muestra en claro una sola vez, al crearla — no hay forma de recuperarla después, ni para nosotros. Si se pierde, se revoca y se emite otra.
Permisos
| Scope | Qué habilita |
|---|---|
read |
Consultar marca, productos, material, trabajos, calendario, presupuesto |
write |
Además, crear briefs, entradas de calendario y planes de generación |
generate |
Además, aprobar lotes (es decir, gastar) |
Una clave nunca llega a admin ni a owner: no puede cambiar el plan, tocar
credenciales ni administrar miembros. Con write alcanza como mucho el rol editor.
Límite de tasa
120 peticiones por minuto por clave (no por dirección IP). Al pasarse, 429.
Errores
Forma estable, siempre JSON:
{ "error": "Mensaje pensado para que lo lea una persona", "reason": "role" }
| Código | Cuándo |
|---|---|
400 |
Cuerpo malformado o datos que no pasan la validación |
401 |
Clave ausente, inválida, vencida o revocada |
403 |
La clave no tiene el permiso, o la operación no se expone por este canal |
404 |
La tool no existe |
422 |
Regla de negocio: supera el tope, falta la clave de generación, el modo realista bloquea la pieza |
429 |
Límite de tasa |
Nunca sale el mensaje crudo de la base: filtraría nombres de tablas y columnas.
REST
GET /api/public/v1/tools
Catálogo de lo que esta clave puede llamar. Cada entrada trae allowed, así no hay
que descubrirlo a fuerza de 403.
{
"tools": [
{
"name": "buscar_material",
"description": "Busca tomas dentro del material propio…",
"inputSchema": { "type": "object", "properties": { "…": {} } },
"mutates": false,
"minRole": "viewer",
"allowed": true
}
],
"scopes": ["read"]
}
POST /api/public/v1/tools
{ "tool": "buscar_material", "input": { "tags": ["fuego", "comida"], "limit": 5 } }
Respuesta:
{ "ok": true, "result": { "scenes": [ … ], "count": 5 } }
MCP
POST /api/mcp — Streamable HTTP sin estado, JSON-RPC 2.0, misma clave. Protocolo
2025-06-18.
// initialize
{ "jsonrpc": "2.0", "id": 1, "method": "initialize" }
// tools/list — sólo devuelve lo que la clave puede llamar de verdad
{ "jsonrpc": "2.0", "id": 2, "method": "tools/list" }
// tools/call
{
"jsonrpc": "2.0", "id": 3, "method": "tools/call",
"params": { "name": "consultar_marca", "arguments": {} }
}
Un fallo de una tool vuelve como result con isError: true, no como error de JSON-RPC:
así el modelo lo lee y corrige, en vez de creer que el transporte está caído.
Por qué el MCP es de solo lectura
No es cautela genérica. Son dos razones concretas:
- El mecanismo de confirmación asume una pantalla. Las mutaciones van en dos fases: la primera devuelve una vista previa y un token firmado, la segunda ejecuta lo previsualizado. Ese token viaja por la interfaz y nunca como texto hacia el modelo. Por MCP tendría que pasar por el contexto del modelo, que debilita el mecanismo de verdad.
- Una clave es un espacio de trabajo, no una persona. El registro de auditoría diría "la clave X" en vez de "Juan", y un audit que no puede nombrar a alguien no sirve para responder quién hizo qué.
Tres candados independientes lo sostienen, y ninguno alcanza solo: la variable
MCP_EXPOSE_WRITE_TOOLS en false, las claves emitidas sin el scope de escritura, y
assertCanExecute, que rechaza mutar cuando no hay un actor identificado.
Se habilitarán cuando exista una confirmación que no dependa de una pantalla.
Tools disponibles
Marca y bibliotecas
| Tool | Muta | Qué hace |
|---|---|---|
consultar_marca |
no | Marca activa con sus tres archivos, y si alcanza para escribir textos |
proponer_marca_con_ia |
sí (confirm) |
Con lo que ya leyó POST /api/brand/capture (portada, páginas internas, PDFs), propone los tres archivos completos + menú + horario/dirección/teléfono + redes, cada bloque con confidence y evidence. Es una PROPUESTA para revisar, no se guarda sola. Sin confirmed:true sólo devuelve el costo estimado (≈USD 0,02, es texto) |
guardar_datos_negocio |
sí | Guarda horario/dirección/teléfono en studio_workspaces.config.business |
listar_productos |
no | Productos y si tienen foto real aprobada |
crear_producto |
sí | Producto con su foto real de referencia |
eliminar_producto |
sí | Elimina un producto y su foto, si nada más lo usa (si no, dice dónde) |
listar_lugares |
no | Espacios del negocio con su foto |
crear_lugar |
sí | Espacio del negocio: la terraza, la barra, el salón |
eliminar_lugar |
sí | Elimina un lugar y su foto, si nada más lo usa (si no, dice dónde) |
listar_personas |
no | Presentadores reutilizables |
crear_persona |
sí | Presentador reutilizable a partir de una foto aprobada |
eliminar_persona |
sí | Elimina una persona y su foto, si nada más la usa (si no, dice dónde) |
Clones (presentadores generados por IA)
| Tool | Muta | Qué hace |
|---|---|---|
listar_clones |
no | Clones de plataforma (todos) + propios (creados con IA o subidos), con su hoja de vistas y si tienen voz |
crear_clon_ia |
sí (confirm) |
Escribe un personaje neutro (nunca parecido a alguien real) con IA y encola su foto maestra (ruta text_to, la única excepción documentada a "todo parte de una referencia"). Sin confirmed:true sólo devuelve el costo estimado del clon completo |
generar_hoja_clon |
sí (confirm) |
Arma las vistas que falten (frente, tres cuartos, cuerpo entero, sonriendo, hablando) a partir de la maestra ya generada, con nano-banana-pro/edit |
regenerar_vista_clon |
sí (confirm) |
Regenera una vista puntual sin tocar las demás |
asignar_voz_clon |
sí | Asigna (o quita) la voz de ElevenLabs de un clon |
listar_voces |
no | Voces disponibles en la cuenta de ElevenLabs conectada |
probar_voz_clon |
sí (confirm) |
Genera una muestra corta ("Escuchar") con una voz antes de asignarla |
crear_clon_plataforma |
sí (confirm) |
Como crear_clon_ia, pero de PLATAFORMA (visible para todos). Sólo el super admin del fleet, que paga con su propia cuenta de fal. Oculta de la API pública y el MCP (internalOnly) |
Ingesta inteligente y conocimiento
| Tool | Muta | Qué hace |
|---|---|---|
registrar_ingesta |
sí | Registra fotos recién subidas para describir con IA. Los videos del mismo lote se mandan directo a analizar_material |
describir_ingesta |
sí (confirm) |
Manda las fotos pendientes a un modelo de visión (tipo, nombre, descripción, etiquetas, conocimiento). Sin confirmed:true sólo devuelve el costo estimado (~US$0,002/foto) |
listar_ingesta |
no | Ítems de ingesta con su foto firmada y lo que propuso la IA |
confirmar_ingesta |
sí | Crea el producto/lugar/persona con esa foto como maestra (o la agrega a uno existente si es duplicado), guarda la nota de conocimiento y marca el ítem confirmado |
descartar_ingesta |
sí | Descarta un ítem pendiente o descrito: borra también la foto (bucket + registro) |
agregar_nota_conocimiento |
sí | Nota manual de conocimiento reutilizable sobre un producto, lugar, persona, la marca o algo general |
listar_notas_conocimiento |
no | Notas de conocimiento, filtrables por sujeto |
Material propio y radar
| Tool | Muta | Qué hace |
|---|---|---|
buscar_material |
no | Tomas por etiqueta, producto, lugar o un video puntual (assetId), con el segundo exacto |
listar_material |
no | Videos cargados, agrupados: si están analizados, etiquetados y transcritos, su portada y las primeras palabras dichas |
analizar_material |
sí | Corta un video en tomas, saca miniaturas y lo vuelve buscable |
etiquetar_material |
sí | Etiqueta con IA las tomas de un video ya analizado (o de todos los pendientes, all: true), SIN volver a cortarlo |
transcribir_material |
sí | Transcribe con IA el audio de un video ya analizado (o de todos los pendientes con audio, all: true), SIN volver a cortarlo |
eliminar_material |
sí | Borra un video propio (archivo, miniaturas, tomas y transcripción). Rechaza el borrado si ya se usó en una pieza armada o publicada |
escanear_nicho |
sí | Mira una cuenta del rubro en Instagram y guarda lo que rinde por encima de su propia media (escaneo manual, puntual) |
registrar_referencia |
sí | Guarda el desglose estructural de una pieza que funciona |
listar_referencias |
no | Referencias ordenadas por cuánto superan la media de su cuenta |
agregar_fuente_radar |
sí | Carga una cuenta o un hashtag de Instagram, o una cuenta/hashtag/palabra clave de TikTok, para que el radar la revise solo |
listar_fuentes_radar |
no | Fuentes cargadas, cuándo se revisaron y el costo aproximado de revisarlas todas |
quitar_fuente_radar |
sí | Deja de revisar una fuente |
revisar_radar |
sí | Corre todas las fuentes vencidas del workspace (Instagram + TikTok vía Apify, gancho/formato clasificados por IA, portada propia alojada en el bucket, cuenta propia marcada aparte) |
tendencias_del_nicho |
no | Audios, formatos, ganchos y duración que se repiten entre los atípicos de los últimos 14 días (excluye la cuenta propia del workspace) |
completar_portadas_radar |
sí (sin costo) | Recorre piezas guardadas sin portada propia e intenta alojarla ahora; reporta cuántas ya habían caducado del lado del proveedor |
desglosar_referencia |
sí (confirmación) | Desglosa UNA pieza orgánica en gancho, formato visual, ángulo, oferta, CTA y qué tomas propias replicarían el patrón |
desglosar_atipicos_radar |
sí (confirmación) | Desglosa en lote todas las piezas atípicas sin desglose todavía |
clasificar_referencias_radar |
sí (confirmación) | Clasifica gancho/formato por IA de piezas orgánicas que quedaron sin clasificar (atípicas o no) |
Estrategia
| Tool | Muta | Qué hace |
|---|---|---|
crear_brief |
sí | Brief validado contra la puerta de cumplimiento del formato |
crear_brief_con_ia |
sí | Escribe un brief con IA desde una referencia del radar, una adaptación de Ad Spy, o uno de los 40 conceptos prearmados. Exige la marca completa (mismo candado que adaptar_a_mi_marca) y pasa por checkFormatCompliance + findClaimIssues |
listar_conceptos |
no | Los 40 conceptos prearmados de plataforma (formato + gancho + plantilla), filtrables por formato |
obtener_brief |
no | Un brief puntual con lo necesario para precargar la generación (generate-panel.tsx) |
listar_briefs |
no | Briefs del espacio de trabajo |
revisar_variacion |
no | Si un lote varía de verdad o es la misma pieza repetida |
sugerir_formatos |
no | En qué formatos llevar el mismo mensaje |
listar_pilares |
no | Pilares de contenido y su peso semanal; propone 4 de gastro la primera vez |
registrar_resultado |
sí | Carga a mano cómo le fue a una pieza publicada (vistas, alcance, guardados, comentarios) |
listar_resultados_pieza |
no | Resultados cargados de piezas publicadas, más recientes primero |
Ad Spy
| Tool | Muta | Qué hace |
|---|---|---|
seguir_competidor |
sí | Empieza a seguir los anuncios pagos de un competidor |
listar_competidores |
no | A quién se sigue y cuándo se revisó por última vez |
revisar_competidor |
sí | Trae los anuncios que un competidor tiene corriendo ahora |
desglosar_pieza |
sí | Desglosa una referencia u anuncio en gancho, formato, ángulo, oferta y CTA |
adaptar_a_mi_marca |
sí | Reescribe una pieza con tu marca, manteniendo estructura y ritmo |
listar_adaptaciones |
no | Guiones ya adaptados, con la referencia de la que salió cada uno |
Generación
| Tool | Muta | Qué hace |
|---|---|---|
planificar_lote |
sí | Arma el plan y su costo sin gastar |
aprobar_lote |
sí | Aprueba y encola. Acá empieza el gasto |
listar_trabajos |
no | Estado, costo, semilla y error de cada trabajo |
listar_resultados |
no | Piezas ya generadas, con su imagen, para elegir cuáles animar |
marcar_ganadoras |
sí | Marca qué piezas valen la pena. Animar exige esto primero |
consultar_presupuesto |
no | Gasto del mes contra el tope |
Lienzo (iterar imágenes + placa de texto)
| Tool | Muta | Qué hace |
|---|---|---|
variar_imagen |
sí (confirm) |
1 a 4 variaciones de una imagen ya generada o una foto real, manteniendo la referencia. Sin confirmed:true sólo devuelve el costo estimado — llamarla de nuevo con confirmed:true gasta |
editar_imagen |
sí (confirm) |
Edita con una instrucción puntual ("quitá el vaso de la derecha"). En modo realista, pasa la instrucción por el modelo barato preguntando si cambia el producto o el local; si sí, la rechaza con el motivo |
remixar_con_referencia |
sí (confirm) |
Combina una imagen base con una segunda referencia en una composición nueva. Sólo usa rutas con max_reference_images >= 2 |
crear_placa |
sí | Compone un titular/subtítulo/CTA editable sobre una imagen, en 4:5, 9:16 y 1:1, con sharp — no gasta saldo de proveedor. Revisa el texto contra las afirmaciones prohibidas de la marca |
copy_para_placa |
no | 5 opciones de titular + subtítulo + CTA en la voz de la marca, para una placa |
listar_piezas_lienzo |
no | Galería del workspace: estáticas generadas, fotos reales y placas ya hechas |
Armado de video
| Tool | Muta | Qué hace |
|---|---|---|
material_para_armar |
no | Tomas propias, clips y estáticas ganadoras, y audio del workspace — el material disponible para armar una pieza |
sugerir_timeline |
no | Propone una línea de tiempo con el mejor material propio, a partir de un brief o de un gancho de texto |
previsualizar_pieza |
sí | Arma una prueba corta (15 s, mitad de resolución) antes del render completo. No gasta saldo de proveedor |
armar_pieza |
sí | Arma la pieza completa y la encola para render. confirm: true — la pantalla pide confirmación antes de llamarla |
estado_render |
no | Estado de un render puntual, con el resultado si ya terminó |
listar_renders |
no | Renders recientes (pruebas y piezas finales) |
Calendario y publicación
| Tool | Muta | Qué hace |
|---|---|---|
crear_entrada_calendario |
sí | Evento puntual o recurrente con su plantilla de brief |
que_toca_esta_semana |
no | Qué hay que producir en los próximos días |
brief_desde_calendario |
sí | Convierte una entrada del calendario en un brief listo |
programar_publicacion |
sí | Programa una pieza en un canal (export, meta_instagram, meta_facebook, whatsapp, tiktok) |
exportar_paquete |
no | Archivo, texto, etiquetas y relación de aspecto |
listar_canales |
no | Qué canales están conectados y cuáles faltan |
reintentar_publicacion |
sí | Vuelve a programar para ya una publicación que quedó en failed |
Rendimiento
Lee el PROPIO perfil público de Instagram y TikTok con Apify (BYOK del cliente) — sin conectar
ninguna app de Meta ni de TikTok, decisión del owner (2026-09-13). No mide pauta paga: mide lo
orgánico, que es lo que le importa a un negocio que no corre Meta Ads. TikTok depende de
lib/research/tiktok.ts, que otro agente construye en paralelo; hasta que exista,
listar_perfiles_propios/actualizar_metricas_rendimiento aceptan el handle de TikTok pero la
captura de esa plataforma devuelve skipped: 'pending_tiktok_module' (no es un error).
| Tool | Muta | Qué hace |
|---|---|---|
configurar_perfiles_propios |
sí | Guarda tu usuario propio de Instagram y/o TikTok |
listar_perfiles_propios |
no | Tus handles configurados, cuándo se leyó por última vez, y el costo estimado de Apify de la próxima corrida |
actualizar_metricas_rendimiento |
sí | Trae de nuevo las métricas propias y las cruza con lo publicado desde Studio. Rate-limit fail-closed (gasta la cuenta de Apify del cliente) |
resumen_rendimiento |
no | Mediana propia, atípicos (≥ 2×), rendimiento por pilar/formato/gancho/hora/duración, y "repetir" (n≥2, ≥1,5× la mediana) / "dejar" |
listar_piezas_con_metricas |
no | Piezas publicadas con su curva de capturas (día 1/3/7) |
Producir
La pantalla donde una idea, un producto o una referencia del radar se convierten en una
producción completa: la IA arma el plan con TODO lo que ya existe (marca, productos y lugares
con foto, material propio, tendencias del nicho, rendimiento) y nada se ejecuta sin aprobación.
Estas tools no reescriben nada — orquestan crear_brief, planificar_lote/aprobar_lote,
marcar_ganadoras y armar_pieza por dentro, así que el mismo candado de presupuesto, de
fidelidad y de tope mensual de esas tools protege también a Producir.
| Tool | Muta | Qué hace |
|---|---|---|
planificar_produccion |
sí (no gasta) | Escribe con IA el plan completo —concepto, gancho, formato recomendado con su razón, guion escena por escena, copy y costo desglosado— a partir de una idea libre, un producto, una referencia del radar o un concepto. Sólo guarda el plan para revisar |
aprobar_produccion |
sí (confirm) |
Aprueba el plan: guarda el brief y planifica + aprueba el lote de estáticas. Acá empieza el gasto |
elegir_ganadoras_produccion |
sí (confirm) |
Marca ganadoras entre las estáticas generadas y anima sólo esas |
armar_produccion |
sí (confirm) |
Arma el video final con las tomas propias y los clips animados de la producción, y lo encola para render |
estado_produccion |
no | Estado de una producción puntual — avanza el paso guardado si el lote o el render de fondo ya terminaron, y trae los trabajos del lote activo con miniatura |
listar_producciones |
no | Producciones del workspace con su estado, más recientes primero |
miniclips_desde_producto |
sí (confirm) |
Propone 3 a 6 mini-conceptos de 5 s de un producto con foto (ángulos distintos) y genera una estática por concepto. Cada uno queda como clip SUELTO, no como parte de un video — al elegir ganadoras se anima cada una por separado |
El contrato del plan (studio_productions.plan jsonb) es lo que la pantalla mostró y el
cliente aprobó: título, concepto, gancho y su tipo, formato recomendado de CONTENIDO (talking_head
/pov_hands/montage/tutorial/asmr/behind_the_scenes, con la razón) más el formato de
ANUNCIO que exige crear_brief, guion escena por escena (cada una con su origen — footage con
el id de la toma propia resuelta, o generate_static con el prompt y el producto/lugar ancla —,
y luego con el trabajo/asset que fue dejando a su paso por generación y animación), copy,
hashtags, música, guion de locución, y el costo desglosado (estáticas, animaciones, locución). Se
guarda tal cual se aprobó: ejecutar más tarde usa lo que se revisó, nunca lo que se recalcule
después — mismo principio que studio_batches.plan.
Tres cosas que conviene saber antes de automatizar
El costo se estima antes, siempre. planificar_lote devuelve el costo y el
presupuesto restante sin gastar nada; aprobar_lote es el que gasta. La separación existe
también por API, no sólo en la pantalla: un script que llame directo a aprobar sin haber
mirado el plan se va a chocar igual con el tope mensual, que se aplica en el código.
Animar exige elegir primero. planificar_lote con kind: "animate" requiere que cada
variación traiga el sourceJobId de una estática marcada como ganadora con marcar_ganadoras.
No es burocracia: un video cuesta entre diez y cien veces más que la imagen de la que sale, y ese
saldo es de la cuenta del cliente, no un crédito nuestro.
El modo realista puede rechazar una pieza. Si el espacio de trabajo está en modo
real, una variación que nombra un producto o un lugar sin foto real aprobada devuelve
422 con el motivo y el arreglo. No es un error del integrador: es la regla que evita que
salga publicado un local que no es el del cliente.
Las tools del Lienzo que gastan usan confirmed, no lote. variar_imagen,
editar_imagen y remixar_con_referencia son de un solo llamado: sin confirmed:true (o
ausente) devuelven { preview: true, costEstimatedUsd, overBudget, ... } sin crear nada;
llamadas de nuevo con confirmed:true crean el lote, encolan y ahí empieza el gasto. Es el
mismo principio de planificar_lote/aprobar_lote condensado en una tool porque acá no hace
falta editar el plan entre medio. crear_placa no sigue este patrón: no tiene costo de
proveedor (el texto se renderiza con sharp), así que muta directo.
Captura de marca en dos llamadas, no una. POST /api/brand/capture (endpoint del
tablero, no una tool) lee el sitio — portada + hasta 8 páginas internas + PDFs — y devuelve
un manifest con sources: {url, kind, excerpt}[]: el corpus de texto de cada página/PDF
leído, con su evidencia. Ese manifest.sources es justo el input de proponer_marca_con_ia
— no hace falta releer el sitio para pedir la propuesta de IA, y por eso la tool no recibe
una URL para volver a buscar, sino el texto que ya se levantó.