Skip to content

Create a project from prepared media

Use this workflow when you already have final clips, voiceover, script, and optional timed captions. It materializes a project without creative generation. The documented contract targets dapi:

POST /api/v1/auth/organization/{organizationId}/workspace/{workspaceId}/projects/prepared

Authenticate with x-api-key. Supply idempotencyKey, templateId, name, language, and scenes. Each scene must match the selected template and include all required fields from the PreparedProjectRequest schema. Copy composition IDs and dynamic item types from the template.

Timing and captions

  • Times are milliseconds. trimEndMs is an absolute source end time: a trim from 2 to 5 seconds is 2000 to 5000.
  • transcript can be null, or contain language and sentences. Sentences may include word-level startMs and endMs; preserve those when available.
  • Use ai-voice or mic layers for audio. Each scene can have at most one master visual layer.
  • Required nullable fields (audioOnlyUrl, stagePositionId, transcript) must be sent explicitly as null when unused.
  • Optional timeline supports v1 crossfades and v2 native or video-bridge transitions. Refer to project scene IDs and keep durations within scene timing. An empty transitions array explicitly disables transitions.

Idempotency and export

New projects return HTTP 201:

{ "projectId": "PROJECT_ID", "status": "ready", "reused": false }

Repeating a key in the same workspace returns HTTP 200 with reused: true. It returns the original project without applying changed media or scripts. Use a new key for a different project.

Creation does not trigger export. To preserve supplied media and captions:

curl -X POST "https://dapi.shuffllmedia.com/api/v1/auth/project/PROJECT_ID/export" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"toEnhance": false}'

Poll the returned editId using the export workflow. To regenerate captions from saved scene scripts, use toEnhance: true and toUseScriptForSubtitles: true instead.