La migración de Sora 2 a Veo 3.1 tiene una fecha de referencia concreta: OpenAI ha programado la retirada de la API de vídeos, sora-2 y sora-2-pro para el 24 de septiembre de 2026. El aviso se publicó el 24 de marzo; esa fecha no era la del cierre. A 5 de septiembre de 2026, el plazo todavía no ha vencido y OpenAI no indica un modelo de sustitución en esa entrada de su calendario de retiradas.
Veo 3.1 es una alternativa que puedes evaluar, pero cambiar el nombre del modelo no completa la migración. Tienes que comprobar que admite tus entregables, adaptar el procesamiento asíncrono y guardar un archivo reproducible antes de dar el trabajo por terminado. Para una aplicación que genera anuncios breves a partir de una imagen, el encaje puede ser razonable. Para otra que promete una toma continua de 20 segundos, hay que rediseñar el resultado o buscar una alternativa que cumpla ese requisito.
Esta guía compara las API oficiales de OpenAI y Gemini Developer API. Las suscripciones a aplicaciones y las interfaces de intermediarios tienen condiciones propias; sus precios y formatos no sirven para deducir los de estas API.
Qué cambia en los vídeos que puedes entregar
La primera comprobación es el formato del producto que ya vendes. La guía actual de Sora incluye generaciones de 16 y 20 segundos en ambas variantes, vídeo horizontal y vertical, y salida de 1920 × 1080 o 1080 × 1920 en Sora 2 Pro. Anota qué duraciones y dimensiones utiliza realmente tu aplicación: son las que la nueva integración tendrá que admitir o adaptar.
En Gemini API, Veo 3.1 y Veo 3.1 Fast ofrecen 4, 6 u 8 segundos, relaciones de aspecto 16:9 y 9:16, y 24 fotogramas por segundo. Las resoluciones 1080p y 4K exigen 8 segundos; las imágenes de referencia también. El audio se genera junto al vídeo en esta interfaz. Las combinaciones permitidas están en las especificaciones de Veo.
| Requisito de tu aplicación | Consecuencia al pasar a Veo 3.1 |
|---|---|
| Un clip de 8 segundos, horizontal o vertical | Hay formatos equivalentes; comprueba el encuadre y el contenido con tus materiales. |
| Una única generación de 16 o 20 segundos | No cabe en la duración ordinaria de Veo 3.1. Dividirla en planos modifica el entregable. |
| 1080p o 4K | Solicita 8 segundos y aplica la tarifa de esa resolución. La salida documentada es de 24 fps. |
| Un fotograma inicial concreto | Utiliza la entrada de imagen; no transfieras un identificador de recurso de OpenAI. |
| Continuidad entre personajes o productos | Prepara nuevas referencias y verifica el resultado; los identificadores de Sora no son recursos de Google. |
| Audio o diálogo en español | Añade una evaluación de pronunciación, contenido y sincronización; el soporte de idioma no garantiza el resultado. |
Las especificaciones describen posibilidades, no un ganador universal en física, movimiento o calidad de voz. Para elegir entre Standard y Fast, utiliza escenas representativas de tu aplicación y criterios de aceptación fijados antes de generar: producto reconocible, encuadre correcto, acciones completas y audio utilizable.
Fotograma inicial, referencias y extensión son operaciones distintas
El input_reference de Sora condiciona el primer fotograma. En Veo, image desempeña esa función; last_frame en el SDK de Python se combina con la imagen inicial para indicar el fotograma final. reference_images permite aportar hasta tres imágenes de referencia. Elegir entre estas entradas depende de si necesitas animar una composición concreta o conservar rasgos del objeto durante la escena. Consulta los modos de entrada de Veo.
La extensión tampoco importa un proyecto de Sora. Google documenta la ampliación de vídeos generados con Veo, en tramos de 7 segundos y hasta 20 extensiones, con salida de extensión limitada a 720p. No puedes dar por compatible un MP4 arbitrario de Sora. Extraer un fotograma de un vídeo propio y usarlo para iniciar otro clip es una nueva generación, con una continuidad que tendrás que valorar. Véanse las condiciones de extensión.
Antes de integrar desde España, comprueba el modo de generación
España figura en la lista de regiones admitidas de Gemini API. Eso permite plantear una integración directa, pero no sustituye la comprobación de la cuenta, los requisitos de acceso y la facturación.
Hay una restricción que afecta a la configuración: para la UE, Reino Unido, Suiza y MENA, Google admite únicamente allow_adult en personGeneration. A la vez, la tabla general de Veo 3.1 indica allow_all para texto a vídeo y extensión, y allow_adult para imagen a vídeo, interpolación e imágenes de referencia. Deben cumplirse las restricciones del modo y las de la región, no solo una de ellas. La documentación no permite deducir una combinación válida de texto a vídeo o extensión para España cambiando ese valor sin más. Comprueba el modo concreto con el servicio antes de ofrecerlo a tus usuarios. Restricciones regionales y tabla de parámetros.
El ejemplo de esta guía utiliza imagen a vídeo y allow_adult, una combinación coherente con ambas condiciones documentadas. Ese valor controla la generación de personas; no obliga a incluir personas en la escena.
Para el idioma, Google declara soporte completo de inglés y señala que los demás idiomas no se han evaluado y pueden dar resultados variables. Puedes separar la descripción de cámara y movimiento del diálogo deseado, pero un texto en español no garantiza una voz española correcta. Si tu aplicación vende locuciones, revisa el acento, los nombres propios y las palabras exactas antes de aceptar el clip. Los filtros de audio también pueden impedir la generación. Limitaciones de idioma y audio.
Cuánto cuesta sustituir cada clip
Compara segundos generados, resolución y variante de modelo. Una cuota mensual de una aplicación no representa el presupuesto de una integración por API.
Las tarifas oficiales de Sora son 0,10 USD por segundo para sora-2 a 1280 × 720 o 720 × 1280. En sora-2-pro, esas dimensiones cuestan 0,30 USD/s; 1792 × 1024 o 1024 × 1792 cuestan 0,50 USD/s, y 1920 × 1080 o 1080 × 1920 cuestan 0,70 USD/s. La tarifa de 0,50 USD/s no corresponde a 1920 × 1080. Fuentes: Sora 2 y Sora 2 Pro.
En Gemini Developer API, Veo 3.1 Standard cuesta 0,40 USD/s a 720p o 1080p y 0,60 USD/s a 4K. Fast cuesta 0,10, 0,12 y 0,30 USD/s, respectivamente. Lite cuesta 0,05 USD/s a 720p y 0,08 USD/s a 1080p, sin 4K. No hay nivel gratuito para estas generaciones. Son las tarifas con audio de Gemini API, consultadas el 5 de septiembre de 2026; no son precios de Vertex AI ni de un intermediario.
| Generación de 8 segundos | 720p | 1080p | 4K |
|---|---|---|---|
| Sora 2 | 0,80 USD | — | — |
| Sora 2 Pro | 2,40 USD | 5,60 USD | — |
| Veo 3.1 Standard | 3,20 USD | 3,20 USD | 4,80 USD |
| Veo 3.1 Fast | 0,80 USD | 0,96 USD | 2,40 USD |
| Veo 3.1 Lite | 0,40 USD | 0,64 USD | — |
La tabla multiplica la tarifa por ocho; no mide la calidad obtenida ni expresa importes en euros o con IVA. Lite puede servir para estudiar el presupuesto, pero conviene revisar sus funciones antes de adoptarlo: no se deben trasladar automáticamente a esa variante todas las capacidades de Standard y Fast.
Para 100 clips de 8 segundos a 720p, el coste calculado es de 80 USD con Sora 2, 80 USD con Veo 3.1 Fast o 320 USD con Veo 3.1 Standard. La migración no implica un ahorro por sí sola. Si, como hipótesis, generas con Fast esos 100 clips y solo aceptas 60, el coste por clip aceptado será 80 / 60 = 1,33 USD. Es una forma más útil de evaluar el presupuesto que comparar solo el precio de una generación.

Google indica que cobra las generaciones completadas correctamente. Un clip que el servicio genera pero que tú descartas por motivos creativos sigue teniendo coste. Registra por separado errores de generación, problemas de descarga y descartes editoriales: mezclar esas categorías oculta de dónde viene el gasto.
Cambia el procesamiento del trabajo, no solo la petición
La API nativa de Sora crea un trabajo con POST /v1/videos. Devuelve un id y un estado; se consulta mediante GET /v1/videos/{id} y, al completarse, se descarga con GET /v1/videos/{id}/content. También documenta los eventos video.completed y video.failed para notificaciones mediante webhook. Estos detalles pertenecen a la API de generación de vídeo de OpenAI, no a chat.completions.
Gemini API crea una operación con predictLongRunning. Devuelve un name, que debes conservar completo para consultar su estado. Al finalizar, debes comprobar el posible error y la presencia de un vídeo antes de descargarlo. La documentación de operaciones asíncronas muestra ese proceso separado de la generación de texto ordinaria.
| Responsabilidad | Sora nativo | Veo en Gemini API |
|---|---|---|
| Crear | POST /v1/videos | POST /v1beta/models/{modelo}:predictLongRunning |
| Identificar el trabajo | id | name de la operación |
| Consultar | GET /v1/videos/{id} | GET /v1beta/{name} |
| Interpretar el resultado | queued, in_progress, completed, failed | done, posible error y contenido de response |
| Obtener el archivo | Endpoint /content | URI del vídeo devuelta en la respuesta, con autenticación |
Conserva en tu base de datos un identificador propio del trabajo, el proveedor, el modelo solicitado, los parámetros, el identificador del proveedor y la ubicación final del archivo. Un trabajo iniciado en Sora debe seguir consultándose en OpenAI mientras ese servicio esté disponible; no se convierte en una operación de Google al cambiar una opción global.
También conviene distinguir «generado» de «entregado». Marca la entrega cuando hayas guardado y verificado el archivo. Google conserva los vídeos generados en sus servidores durante dos días, por lo que debes descargarlos con prontitud y utilizar almacenamiento propio para su conservación. Plazo de retención de Veo.
Ejemplo REST: de una imagen a un vídeo descargado
El siguiente ejemplo adapta el esquema REST documentado por Google. Necesitas curl, jq, una clave en la variable de entorno GEMINI_API_KEY, acceso de pago al modelo y un PNG propio llamado fotograma.png. Ejecutarlo crea una generación facturable si se completa correctamente. Usa un directorio nuevo para cada trabajo y conserva sus archivos hasta resolverlo.
Envía una sola petición de creación
La imagen aporta el fotograma inicial. Los parámetros solicitan un clip de 8 segundos, 720p y 16:9. No añadas reintentos automáticos a esta petición de creación.
bash#!/usr/bin/env bash set -euo pipefail [[ ! -e creacion.json ]] || { echo "Revisa el trabajo existente antes de crear otro."; exit 1; } base64 < fotograma.png > fotograma.b64 jq -n --rawfile img fotograma.b64 '{ instances: [{ prompt: "Slow camera movement around the object. Preserve its shape and colours. Soft ambient sound.", image: {inlineData: { mimeType: "image/png", data: ($img | gsub("\\s"; "")) }} }], parameters: { aspectRatio: "16:9", durationSeconds: 8, resolution: "720p", personGeneration: "allow_adult" } }' > peticion.json curl --fail-with-body --silent --show-error \ 'https://generativelanguage.googleapis.com/v1beta/models/veo-3.1-generate-preview:predictLongRunning' \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ --data-binary @peticion.json \ --output creacion.json jq -er '.name | select(type == "string" and length > 0)' \ creacion.json > operacion.txt
Continúa únicamente si has obtenido un nombre de operación válido. Si se interrumpe la conexión y no sabes si el proveedor aceptó la petición, conserva la respuesta y revisa el incidente antes de volver a crear: una segunda petición podría generar otro vídeo. Este ejemplo no presupone una garantía de idempotencia.
Consulta la operación guardada
Este bloque se puede volver a ejecutar para consultar el mismo trabajo. No inicia otra generación. Guarda cada respuesta válida y hace como máximo 90 consultas, con pausas de 10 segundos entre ellas. Son unos 15 minutos de pausas, además del tiempo de las peticiones; esta frecuencia es una decisión del ejemplo, no una duración garantizada del servicio.
bash#!/usr/bin/env bash set -euo pipefail operation_name=$(cat operacion.txt) [[ -n "$operation_name" ]] || exit 1 finished=false for ((attempt=0; attempt<90; attempt++)); do curl --fail-with-body --silent --show-error \ -H "x-goog-api-key: $GEMINI_API_KEY" \ "https://generativelanguage.googleapis.com/v1beta/$operation_name" \ --output estado.tmp.json jq -e 'type == "object"' estado.tmp.json > /dev/null mv estado.tmp.json estado.json if jq -e '.done == true' estado.json > /dev/null; then finished=true break fi sleep 10 done if [[ "$finished" != true ]]; then echo 'Sigue pendiente. Conserva operacion.txt y vuelve a consultar.' exit 2 fi if jq -e '.error != null' estado.json > /dev/null; then jq '.error' estado.json exit 1 fi jq -er '.response.generateVideoResponse.generatedSamples[0].video.uri | select(type == "string" and length > 0)' estado.json > video-uri.txt
done: true significa que la operación terminó, no que necesariamente tengas un vídeo. Si hay un error o falta la URI, no pases a la descarga como si hubiera un resultado válido. Un tiempo de espera agotado tampoco cancela el trabajo remoto: conserva su nombre y reanuda las consultas. En producción, adapta las pausas y el tratamiento de errores transitorios a las respuestas del servicio.
Descarga y verifica el archivo
Tras obtener una URI válida, descarga con la misma clave. El archivo temporal evita que otro proceso confunda una descarga interrumpida con el vídeo definitivo.
bash#!/usr/bin/env bash set -euo pipefail video_uri=$(cat video-uri.txt) curl --fail --location --silent --show-error \ -H "x-goog-api-key: $GEMINI_API_KEY" \ "$video_uri" --output resultado.part.mp4 test -s resultado.part.mp4 ffprobe -v error -show_entries \ stream=codec_type,width,height,r_frame_rate:format=duration \ -of json resultado.part.mp4
El último comando requiere ffprobe, incluido en FFmpeg. Revisa que exista una pista de vídeo, que la duración y las dimensiones correspondan a lo solicitado y que haya audio si tu producto lo necesita. Reproduce el archivo para valorar su contenido; después puedes renombrarlo a resultado.mp4 y registrar la entrega. La extensión .mp4, una descarga con HTTP 200 o un archivo no vacío, por separado, no prueban que el resultado sea utilizable.
Cómo cambiar el tráfico sin perder los trabajos anteriores
Empieza por separar la selección del proveedor para nuevos trabajos del proveedor guardado en cada trabajo ya existente. Así podrás probar Veo sin dejar de consultar y descargar los vídeos pendientes de Sora. Los webhooks de OpenAI que ya tengas implementados deberán seguir vinculados a sus propios trabajos; la integración de Veo debe gestionar su operación con el mecanismo documentado para Gemini.

Antes de ampliar el uso de Veo, comprueba estas situaciones con tu aplicación:
- Se reinicia el proceso durante la espera: recupera el nombre de operación guardado y continúa consultando, sin crear otra generación.
- La operación termina sin un vídeo: conserva el error o la respuesta, informa al usuario y no marques una entrega satisfactoria.
- Falla la descarga: vuelve a descargar el resultado disponible en lugar de regenerarlo; recuerda el plazo de conservación del proveedor.
- El formato solicitado no está admitido: rechaza o adapta la solicitud antes de enviarla, con una explicación clara para el usuario.
- El vídeo existe, pero no cumple el encargo: clasifícalo como descarte creativo y suma su coste al cálculo por resultado aceptado.
Para pasar a producción, fija criterios concretos con tus propios materiales: proporción de entregas correctas, tiempo hasta disponer del archivo, coste por clip aceptado y cumplimiento de las escenas que prometes. Empieza con un conjunto acotado de trabajos nuevos, compara los resultados y amplía el tráfico cuando esos criterios se cumplan.
Mientras la API de Sora siga disponible, una reversión puede devolver los nuevos trabajos a la integración anterior. Después de su fecha de retirada, Sora deja de ser un plan de reversión válido: necesitas otra alternativa comprobada o una forma explícita de pausar las funciones que no puedas servir. Archiva los vídeos y datos necesarios antes del cambio definitivo. Para ampliar el seguimiento de la retirada, consulta la guía sobre el cierre de la API de Sora 2.
La migración estará resuelta cuando una petición admitida produzca un archivo guardado, reproducible y aceptable para tu usuario, y puedas recuperar el proceso tras un fallo. Ese es el criterio que debe decidir si Veo 3.1 sustituye tu integración con Sora 2.



