Sovran
API documentation

Create and edit content

Build compositions, edit saved media, and generate video, voice, or copy.

Choose the task you need below. All routes use the /api/v1 prefix. API access and setup apply to every task. Creation jobs need Generate permission and an active paid plan. Saved content changes need Write. Deletion needs Delete.

A creation job returns 202 with a public job ID. Read it with GET /jobs/{jobId}. Use the public job ID from the API response. See job status and recovery and request limits.

Prepare clips, transcripts, and captions

TaskMethod and routeRequired input
Create a clipPOST /projects/{projectId}/clipsassetId, integer startMs and endMs; optional removeAudio.
List clipsGET /projects/{projectId}/clipsNone.
Prepare a transcriptPOST /assets/{assetId}/transcriptEmpty object {}.
Read a transcriptGET /assets/{assetId}/transcriptNone.
Edit a transcriptPATCH /assets/{assetId}/transcripttranscriptId, expectedUpdatedAt, and passage IDs with replacement text.
List captionsGET /assets/{assetId}/captionsNone.
Read a languageGET /assets/{assetId}/captions/{language}None.
Save a languagePUT /assets/{assetId}/captions/{language}srt text and expectedUpdatedAt; use null for a new language.
Delete a languageDELETE /assets/{assetId}/captions/{language}expectedUpdatedAt.

Transcript edits preserve word timing. They also update automatic source-language captions. A caption update failure is reported separately. Manual captions are preserved. A concurrent edit returns a revision conflict.

Build a composition

A composition is a saved video timeline. Create one with POST /projects/{projectId}/compositions. Read it with GET /compositions/{compositionId}. List project compositions with GET /projects/{projectId}/compositions.

Use this request body for a three-second portrait clip:

POST /api/v1/projects/{projectId}/compositions — request body
{
  "title": "Opening clip",
  "composition": {
    "version": 1,
    "aspectRatio": "9:16",
    "backgroundColor": "#000000",
    "durationInFrames": 90,
    "fps": 30,
    "width": 1080,
    "height": 1920,
    "overlays": [
      {
        "id": 0,
        "type": "video",
        "sourceAssetId": "<READY_PROJECT_VIDEO_ASSET_UUID>",
        "from": 0,
        "durationInFrames": 90,
        "row": 1,
        "left": 0,
        "top": 0,
        "width": 1080,
        "height": 1920,
        "rotation": 0,
        "isDragging": false,
        "styles": {}
      }
    ]
  }
}

The source must belong to this project and contain the selected three-second range. Media overlays use sourceAssetId. An audio override also uses an audio sourceAssetId. Sovran resolves media URLs and preparation data. Do not send src, preview URLs, custom font URLs, background removal data, or external CSS references.

Timeline fields

Overlay types are video, image, sound, text, shape, emoji, and caption. Common fields are id, type, from, durationInFrames, row, left, top, width, height, rotation, and isDragging. Use unique nonnegative integer IDs. Keep each overlay inside the composition duration. See the numeric composition limits.

Lower row numbers appear above higher row numbers. Use text row 0 and video row 1 to show text over video.

OverlayAdditional fields
Textcontent and styles.
VideovideoStartTime, speed, segments; optional layerRole: "broll". Source offsets cannot be negative.
SoundstartFromSound.
CaptionTimed captions and words; optional built-in template, such as basicBlack. Unknown template IDs are rejected.
Video or imageOptional transitionIn with type: "fade", "slide", or "wipe"; optional direction: "from-left", "from-right", "from-top", or "from-bottom"; positive integer durationInFrames no greater than the overlay duration.

Save or delete

Use PUT /compositions/{compositionId} with title, composition, and the saved expectedUpdatedAt. Read the current updatedAt before a change. A revision conflict prevents an older request from overwriting a later edit.

To delete, first read GET /compositions/{compositionId}/delete-impact. Then send DELETE /compositions/{compositionId} with expectedUpdatedAt and the returned fingerprint.

Read GET /sequences/{sequenceId}/compositions for saved sequence timeline edits. To change one through the API, read its version 1 state and create a regular composition. Dashboard batch edit guards remain active.

Export a composition

  1. Read the composition and its current updatedAt.
  2. Send POST /compositions/{compositionId}/render-estimate with expectedUpdatedAt and maxOutputs.
  3. Review the estimate and save its planFingerprint.
  4. Send POST /compositions/{compositionId}/renders with the same input and that fingerprint.
  5. Read the returned public job until it has a terminal status.

Each request creates one output. Use maxOutputs: 1 for a single composition. The source media must be ready before the estimate or charge. Music needs a saved duration. An audio override cannot use media with no audio track. Saved video segments are converted to continuous clips before the estimate.

Optional exportSettings include outputName, resolution (1080p, 4k, vertical, or square), quality (low, medium, or high), and purpose (finished_video, hook, body, cta, or custom). A custom purpose needs customTag. Reusable footage can specify range: {startFrame, endFrame}. Finished videos use the full timeline and the render credit charge. Reusable footage uses the existing zero-credit rule.

Plan and apply AI edits

Read GET /compositions/{compositionId} for its saved revision and overlay IDs. Plans need Read and Generate permissions. Applying a plan also needs Write. All editor requests need an active paid plan and an Idempotency-Key.

Request an edit plan:

POST /api/v1/compositions/{compositionId}/ai-actions — request body
{
  "prompt": "Change the opening text to Try it today.",
  "expectedUpdatedAt": "<COMPOSITION_UPDATED_AT>"
}

The prompt can have at most 4,000 characters. The response is 202. Read GET /jobs/{planJobId}. A completed plan has summary, riskLevel (low, medium, or high), and 1–8 steps. Each step has tool, input, label, and why. Planning does not change the composition.

Review the saved plan before you apply it.

Apply the reviewed plan:

POST /api/v1/compositions/{compositionId}/ai-actions/apply — request body
{
  "planJobId": "<PUBLIC_PLAN_JOB_UUID>",
  "expectedUpdatedAt": "<COMPOSITION_UPDATED_AT>"
}

The plan must be complete and match this composition and revision. The route returns a separate execution job. It saves accepted steps and media identities before work, then applies the final composition once with a revision check. A later edit returns requires_action with revision_conflict. A changed media file, voiceover script, or selected caption file returns requires_action/source_changed. A filename-only rename remains valid. Read the current composition and sources before you request another action.

For one direct edit or search, use POST /compositions/{compositionId}/ai-tools. The editor tool reference lists all tool inputs and examples. Search and caption results are saved on the job. A successful edit returns its applied results and new saved revision.

Remove a video background

Send this request body:

POST /api/v1/compositions/{compositionId}/background-removals — request body
{
  "overlayId": 0,
  "expectedUpdatedAt": "<COMPOSITION_UPDATED_AT>"
}

This route needs Read, Write, and Generate permissions, an active paid plan, and an Idempotency-Key. It returns 202 with a public job ID. Select one continuous, prepared project video range of at most 60 seconds. The stored source must be at most 256 MiB (268,435,456 bytes). Batch compositions and video with alpha are rejected.

Success requires an available cutout and a saved composition. Read saved, saveStatus, compositionUpdatedAt, and outputAssetId in the result. A revision conflict retains the cutout and leaves the later composition unchanged. Review that output and apply it to the current composition through a version 1 update. See background removal limits and recovery.

Generate copy and analyse variations

Use POST /projects/{projectId}/messaging/generate with format: "hooks", "script", or "ab_test". Use 3–12 hooks, 2–4 test groups, or one script. Scripts require personaId and angleId. Active project context is required.

Optional fields include tone, length, language, count, guidance, productHighlights, productSpecId, contextSourceIds, and a saved template { "id": "UUID", "revision": 1 }. These requests need Generate permission and an Idempotency-Key. The result is saved on the job. Save selected copy through /projects/{projectId}/messaging.

Use GET and POST /projects/{projectId}/briefs for briefs. Use /projects/{projectId}/messaging-templates for saved copy templates. Read the OpenAPI schema for their create, read, update, and delete fields.

Use POST /sequences/{sequenceId}/smart-variations with expectedUpdatedAt to analyse combinations. Use GET on the same route to list saved analyses. See analysis limits.

Generate video, edits, and voice

TaskCreate and listRead one result
AI videoPOST and GET /projects/{projectId}/ai-videosGET /ai-videos/{resourceId}
Automatic editPOST and GET /projects/{projectId}/auto-editsGET /auto-edits/{resourceId}
VoiceoverPOST and GET /projects/{projectId}/voiceoversGET /voiceovers/{resourceId}
Avatar videoPOST and GET /projects/{projectId}/avatar-videosGET /avatar-videos/{resourceId}

AI video

Read GET /ai-video-models before you choose a model. Requests use provider, modelId, capability, and input. The capability is t2v, i2v, or r2v. Input fields include prompt, durationSeconds, aspectRatio, resolution, negativePrompt, seed, and generateAudio. Model limits apply. Reference modes require a project referenceAssetId. External input URLs and provider metadata are rejected.

Automatic edit

Use sourceMode: "single_asset" with exactly one sourceAssetId in sourceAssetIds. For a project story, use sourceMode: "project_story", briefTemplateId: "project_story", and a brief. Optional fields include savedTemplate, targetDurationSeconds, aspectRatio, captionsEnabled, hook or video variation settings, verbalSlipsToAvoid, and mustPreserveQuotes. The OpenAPI schema lists supported presets. Saved templates use /projects/{projectId}/auto-edit-templates.

A video variation job can create one automatic child job when paired outputs are missing. Read children and outputEditorProjectIds in the parent result. The parent remains running while the child is pending. It becomes partially_succeeded if some outputs remain unavailable after the child fails.

Retry an eligible failed child with POST /jobs/{childJobId}/retry, {}, and a new Idempotency-Key. Read the returned retry job. See generation retry limits.

Voiceover

Use script (at most 1,000 characters), voiceId, language, and optional voiceType: "preset" or "clone", modelId, and style (at most 500 characters). Read GET /voices?language=English for current choices. A clone must be ready in the same workspace.

Avatar and voice clone

Create an avatar with POST /avatars. Supply projectId, displayName, voiceCloneId, one to five imageAssetIds, consentBasis: "self" or "authorized", and consentAccepted: true. Images must be JPEG, PNG, or WebP. See avatar and voice sample limits.

Create a voice clone with POST /voice-clones. Supply projectId, displayName, the same consent fields, and sourceType. For "upload", declare filename, mimeType, and sizeBytes, then use the returned signed upload reservation. For "asset", supply a video assetId. Call POST /voice-clones/{resourceId}/run with {} after the sample is ready.

Review the voice preview. Record approval with PUT /avatars/{avatarId}/voiceovers/{voiceoverId}/approval and { "projectId": "UUID", "audioPreviewAcknowledged": true, "approved": true }. An avatar video request then uses presenterProfileId, voiceoverJobId, presenterReferenceImageId, and optional prompt or supported direction settings.

Video and voice jobs require stored media before they report success. Auto-edit jobs require a saved composition. Avatars and voice clones also report mediaAvailable. Missing output returns requires_action; media URL requests return 409 when the stored object is missing.

Was this article helpful?

On this page