APIAPI

Production API 参考地图

本页用于人工导航;生成的 API Reference 与 OpenAPI 才是精确机器合约。

API / MCP 成熟度

文档页面是公开的,但 API/MCP 能力是否可用由实时产品 Manifest 和账户权限决定。foundation / experimental 不等于稳定承诺。

MethodEndpoint权限用途
GET/api/v1/product/manifestread产品事实与成熟度
GET/api/v1/openapiread机器可读 API 合约
GET/api/v1/production/capabilitiesread发现可用制作能力
GET/api/v1/production/verticalsread列出制作 recipes
POST/api/v1/production/plansplan编译不产生付费的制作计划
POST/api/v1/production/plans/:planId/preflightread执行前验证 readiness
POST/api/v1/production/plans/:planId/storyboard/applymutate应用已批准的 Storyboard
POST/api/v1/production/plans/:planId/steps/:stepId/executespend执行一个已确认的计划步骤
POST/api/v1/production/plans/:planId/generatespend启动已确认的持久制作
GET/api/v1/production/jobs/:jobIdread读取持久 Job 状态
GET/api/v1/production/plans/:planId/ledgerread读取执行 ledger
POST/api/v1/production/snapshots/generate-scenespend按准入 FPS 生成一个已确认场景
POST/api/v1/production/snapshots/preflight-sceneread不花费积分,检查场景的准确 FPS 和费用

精确字段以生成合约为准

本页解释意图与权限。精确 schema 请看 /api/v1/docs 与 /api/v1/openapi。

把错误当作状态处理

处理 auth、forbidden、invalid id、missing idempotency、credits、preflight、rate limit、infra 等机器错误码和 HTTP 状态。

谨慎重试读取

可重试的 read 与不可盲目重放的 mutate/spend 明确分离。

Studio、API 和 MCP 的 24 / 30 / 60 FPS

三个接口使用同一份已确认的场景 snapshot 和准入检查。保留请求的 FPS,不会自动回退到 24 FPS。可用性取决于已批准的 worker 和场景的准确条件。

START/END 画布为 704×1280、1280×704 或 960×960。I2V 可生成音频或无音频;A2V 要求有使用权限的源音频,并保留所选起始偏移。本表不代表 ingredients 或 V2V 支持高 FPS。seed 必须是 0–2147483647 的整数。 I2V 和 A2V 在已部署服务明确准入时,支持 24、30、60 FPS 的仅 END 输入。END 引导最后一帧,开头根据提示词生成。保持 start 为空,将图片放在 end 中。这不保证像素完全一致,也不会倒放视频。 A2V 始终需要有使用权限的源音频,以及至少一张 START 或 END 图片;不支持仅音频生成。

FPS可准入类别物理限制
24默认值;所选模态仍需通过自身检查时长、音频和参考取决于所选原生类别
30仅限已批准的 I2V / A2V720p · 2–10 整秒 · 9:16 / 16:9 / 1:1 · I2V/A2V:START、END 或两者;A2V 还需要源音频
60仅限已批准的 I2V / A2V720p · 2–10 整秒 · 9:16 / 16:9 / 1:1 · I2V/A2V:START、END 或两者;A2V 还需要源音频

保存、核对报价,再确认一个场景

创建或读取有权限的项目,通过 PATCH expectedVersion 保存场景,再将相同的 snapshot 和 targetSceneId 发送至 /api/v1/production/snapshots/preflight-scene。检查 data.ready、issues 和 estimatedCredits;此调用不创建 job 或预留积分。使用 confirm=true 和固定 Idempotency-Key 调用 /api/v1/production/snapshots/generate-scene,然后查询返回的 jobId。MCP 使用 myeq.video.preflight_scene 和 myeq.video.generate_scene,付费提交绝不自动重试。场景设置覆盖全局默认值;保留匹配的已确认 sceneContracts。

旧 /video/start、/video/create、/video/create-job 和 /video/preflight 已退役:默认/24 返回 410;30/60 返回 422,要求迁移到 snapshot。25/48/50 不受支持。preflight 失败不会更改 FPS 或收费。检查成功也不预留可用资源或账户余额。

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 · Job已生成 ≠ 已认证