APIAPI

Mapa de referencia de Production API

Orientación humana de la superficie canónica. La referencia generada y OpenAPI siguen siendo la autoridad exacta de máquina.

Madurez API / MCP

La documentación pública se puede compartir, pero la disponibilidad de capacidades API y MCP la gobiernan el manifiesto vivo y el acceso de la cuenta. Foundation o experimental no implican estabilidad.

MétodoEndpointAutoridadPropósito
GET/api/v1/product/manifestreadVerdad y madurez del producto
GET/api/v1/openapireadContrato API legible por máquina
GET/api/v1/production/capabilitiesreadDescubrir capacidades de producción disponibles
GET/api/v1/production/verticalsreadListar recetas de producción
POST/api/v1/production/plansplanCompilar un plan de producción sin gasto
POST/api/v1/production/plans/:planId/preflightreadValidar preparación antes de ejecutar
POST/api/v1/production/plans/:planId/storyboard/applymutateAplicar un Storyboard aprobado
POST/api/v1/production/plans/:planId/steps/:stepId/executespendEjecutar un paso confirmado del plan
POST/api/v1/production/plans/:planId/generatespendIniciar producción durable confirmada
GET/api/v1/production/jobs/:jobIdreadConsultar el estado durable del job
GET/api/v1/production/plans/:planId/ledgerreadConsultar el ledger de ejecución
POST/api/v1/production/snapshots/generate-scenespendGenerar una escena confirmada con sus FPS admitidos
POST/api/v1/production/snapshots/preflight-scenereadComprobar FPS y coste exactos de una escena sin gastar

Usa el contrato generado para los campos exactos

Esta página explica intención y autoridad. Para schemas exactos y operaciones publicadas usa /api/v1/docs y /api/v1/openapi.

Trata los errores como estado, no como prosa

Maneja códigos de error y estados HTTP: autenticación, acceso prohibido, projectId inválido, idempotencia ausente, créditos insuficientes, blockers de preflight, rate limit y fallos de infraestructura.

Reintenta lecturas con criterio

El transporte distingue fallos de lectura potencialmente reintentables de operaciones que nunca deben repetirse a ciegas.

24, 30 y 60 FPS en Studio, API y MCP

Las tres interfaces usan la misma instantánea confirmada de la escena y la misma admisión. Se conservan los FPS solicitados; no hay cambio automático a 24. La disponibilidad depende del worker aprobado y de la escena exacta.

Lienzos START/END: 704×1280, 1280×704 o 960×960. I2V admite audio generado o sin audio; A2V exige audio de origen autorizado y conserva el desplazamiento seleccionado. Esta tabla no habilita FPS altos para ingredientes ni V2V. La semilla es un entero entre 0 y 2147483647. I2V y A2V admiten END sin START a 24, 30 y 60 FPS solo si el servicio desplegado lo autoriza expresamente. END guía el último fotograma; el inicio se genera desde el prompt. Deja start vacío y conserva la imagen en end. Esto no garantiza píxeles idénticos ni invierte el vídeo. A2V siempre necesita audio de origen autorizado y al menos una imagen START o END; el audio solo no está admitido.

FPSClase admitidaLímites físicos
24Por defecto; cada modalidad debe superar su admisiónDuración, audio y referencias dependen de la clase nativa elegida
30Solo I2V / A2V aprobados720p · 2–10 segundos enteros · 9:16 / 16:9 / 1:1 · I2V/A2V: START y/o END; A2V también exige audio de origen
60Solo I2V / A2V aprobados720p · 2–10 segundos enteros · 9:16 / 16:9 / 1:1 · I2V/A2V: START y/o END; A2V también exige audio de origen

Guardar, revisar el precio y confirmar una escena

Crea o lee el proyecto autorizado y guarda la escena con PATCH expectedVersion. Envía la misma snapshot y targetSceneId a /api/v1/production/snapshots/preflight-scene. Revisa data.ready, issues y estimatedCredits; no crea trabajos ni reserva créditos. Genera mediante /api/v1/production/snapshots/generate-scene con confirm=true e Idempotency-Key estable. Consulta el jobId devuelto. MCP usa myeq.video.preflight_scene y myeq.video.generate_scene con la misma snapshot; el envío pagado no se reintenta automáticamente. Los ajustes de escena prevalecen sobre los globales; conserva los sceneContracts confirmados que correspondan.

Las rutas antiguas /video/start, /video/create, /video/create-job y /video/preflight están retiradas: por defecto/24 devuelve 410; 30/60 exige migrar a snapshot con 422. 25/48/50 no están admitidos. Un fallo de preflight no cambia los FPS ni cobra créditos. Una comprobación correcta no reserva disponibilidad ni saldo.

const base = process.env.MYEQ_BASE_URL || 'https://myeq.pro';
const headers = { Authorization: 'Bearer ' + process.env.MYEQ_API_KEY, 'Content-Type': 'application/json' };
async function api(path, method, body, extra = {}) {
  const response = await fetch(base + path, { method, headers: { ...headers, ...extra },
    ...(body === undefined ? {} : { body: JSON.stringify(body) }) });
  const value = await response.json();
  if (!response.ok) throw new Error(JSON.stringify(value));
  return value;
}
const project = await api('/api/v1/projects', 'POST', { title: '60 FPS', aspectRatio: '9:16', duration: 4 });
const sourceAudioUrl = process.env.SOURCE_AUDIO_URL;
const generationInputs = { videoProvider: 'myeq_v2', videoModelSelection: 'myeq_v2',
  inputModality: sourceAudioUrl ? 'audio_to_video' : 'image_to_video', durationSeconds: 4,
  fps: 60, outputResolution: '720p', includeAudio: Boolean(sourceAudioUrl), seed: 12345,
  ...(sourceAudioUrl ? { sourceAudioUrl, sourceAudioStartTime: 0 } : {}) };
const scene = { id: 'scene-1', prompt: 'A slow camera move. Preserve the subject.',
  settings: { fps: 60, durationSeconds: 4 },
  start: process.env.START_URL ? [{ name: 'START', url: process.env.START_URL }] : [],
  end: process.env.END_URL ? [{ name: 'END', url: process.env.END_URL }] : [], context: [], avatar: [] };
const snapshot = { id: crypto.randomUUID(), version: 1, projectId: project.id,
  ownerId: project.ownerUserId, sourceEditorStateVersion: project.version + 1,
  createdAt: new Date().toISOString(), projectTitle: project.title,
  aspectRatio: '9:16', resolution: '720p', durationSeconds: 4, fps: 60,
  generationInputs, scenes: [scene], avatars: [], assetsSummary: [],
  sourceAudio: sourceAudioUrl ? { url: sourceAudioUrl, durationSeconds: null } : null, provenance: { source: 'ui' } };
await api('/api/v1/projects/' + project.id, 'PATCH', { expectedVersion: project.version,
  editorState: { ...project.editorState, generationInputs,
    sceneStoryboard: { scenes: [scene] }, productionSnapshot: snapshot } });
const input = { snapshot, targetSceneId: scene.id };
const quote = await api('/api/v1/production/snapshots/preflight-scene', 'POST', input);
console.log(quote);
if (quote.data?.ready && process.env.CONFIRM_PAID === 'true') {
  const idempotencyKey = process.env.SAVED_IDEMPOTENCY_KEY;
  if (!idempotencyKey) throw new Error('Persist one stable key before submitting');
  const result = await api('/api/v1/production/snapshots/generate-scene', 'POST',
    { ...input, confirm: true }, { 'Idempotency-Key': idempotencyKey });
  console.log(result);
  const jobId = result.data?.pendingTake?.orchestrationJobId || result.data?.asset?.metadata?.jobId;
  if (jobId) console.log(await api('/api/v1/production/jobs/' + encodeURIComponent(jobId), 'GET'));
}
Workspace · Project · Asset · Entity · Storyboard · Plan · JobGenerado ≠ Certificado