---
title: "Cut the finished video"
method: POST
path: "/marketing/projects/{id}/exports"
tags: ["marketing"]
---

# Cut the finished video

`POST /marketing/projects/{id}/exports`

## Request

- Base URL: `https://api.gogoscreen.com/api/v1`
- URL: `https://api.gogoscreen.com/api/v1/marketing/projects/{id}/exports`
- Auth: one of:
  - HTTP bearer
  - HTTP bearer

Render one revision into a finished file, with cover, captions and transcript. THIS IS THE MARKETING OPERATION THAT SPENDS: time is reserved at the DELIVERED length (authored ÷ the revision's speed) and settled when the file is made; a cancelled or failed export is charged nothing. `expectedRevisionId` must be the current revision, or 409 `revision_conflict` with nothing reserved. Ask `marketing.exports.quote` first. Answers 202; at most three exports in flight.

## Path parameters

- `id` string, uuid, required

## Headers

- `Idempotency-Key` string, required

## Request body

- object
  - `audioMode` 'music' | 'silent' | 'voice' | 'voice-music': Defaults to `music`.
  - `coverText` string, nullable: Words for the cover image, for THIS export only. Blank means none; it is never written back to the revision.
  - `durationSeconds` integer, required: One the design offers at this format, and the one the named revision was saved with. The six-second edition is retired and is refused here.
  - `expectedRevisionId` string, uuid, required: The revision you are exporting. It must still be the project's current one.
  - `format` string, required: One the design offers: landscape | portrait | square | four-five.

## Response `200`

The work was already known — the service recognised this key on its own record and queued nothing new. Answered when the 24-hour idempotency claim has expired but the work has not.

- object
  - `created` boolean, required
  - `export` object, required
    - `audioMode` string, required
    - `durationSeconds` number, required
    - `failureCode` string, nullable, required
    - `format` string, required
    - `hasCaptions` boolean, required
    - `hasCover` boolean, required
    - `hasTranscript` boolean, required
    - `id` string, required
    - `progress` object, nullable, required: The last progress reading while the export runs: the current step and a whole percent. null once it has settled, and null when no reading was recorded.
      - `at` string, nullable, required
      - `percent` integer, required
      - `stage` string, required
    - `projectId` string, required
    - `qa` object, nullable, required: The outcome of the automated checks, once they have run; null before. Why an export failed is `failureCode`.
      - `notes` string[], required: What the export did that a person may want to know, as codes: `font_missing`, `cover_drawn`, `cover_not_drawn`, `narration_fitted`, `transcript_written`, `transcript_not_written`. A note is not a failure.
      - `ok` boolean, required: Whether the automated checks on the finished file passed.
    - `revisionId` string, required
    - `secondsCharged` number, nullable, required
    - `secondsReserved` number, required
    - `state` 'queued' | 'running' | 'succeeded' | 'failed' | 'cancelled', required
    - `status` string, required
    - `watermark` string, required
  - `resource` object, required
    - `artifactsExpired` boolean, required: The work succeeded but its files were deleted at the end of the retention period.
    - `cancellable` boolean, required
    - `cost` object, required
      - `secondsCharged` number, nullable, required
      - `secondsReserved` number, required
      - `watermark` boolean, required
    - `createdAt` string, date-time, nullable, required
    - `error` object, nullable, required
      - `code` string, required
      - `reason` string, nullable, required
      - `retryable` boolean, required
      - `terminal` boolean, required
    - `expiresAt` string, date-time, nullable, required
    - `finishedAt` string, date-time, nullable, required
    - `id` string, required
    - `idempotencyKey` string, nullable, required
    - `internalStatus` string, required: A finer-grained status word. Informational; branch on `state`.
    - `kind` string, required: walkthrough.render | walkthrough.storyboard | marketing.export | marketing.generation | marketing.source_scan | marketing.source_operation
    - `pollAfterMs` number, nullable, required: Wait this long before polling again; null once the state is terminal.
    - `progress` object, nullable, required: HOW FAR THE WORK HAS GOT, as last reported, or null — null while nothing has been recorded yet and null for every terminal state, because a finished job is 100 by definition and a failed one has no bar to draw.
      - `at` string, nullable, required: When it was reported. A reading that has stopped moving means the work has, not that the bar is broken.
      - `percent` number, required: 0 to 100, as last reported for this job. It never goes backwards. Draw exactly this number: nothing here is interpolated and a client that animates between readings is inventing progress.
      - `stage` string, required: A short label for the current step. Show it; do not branch on it.
    - `requestId` string, nullable, required
    - `result` object, nullable, required
      - `artifacts` object[], required
        - `bytes` number, nullable, required
        - `expiresAt` string, date-time, nullable, required
        - `sha256` string, nullable, required
        - `type` string, required
        - `url` string, nullable, required
      - `durationSeconds` number, nullable, required
    - `stage` string, nullable, required
    - `startedAt` string, date-time, nullable, required
    - `state` 'queued' | 'running' | 'succeeded' | 'failed' | 'cancelled', required: The five public states. Poll until one of succeeded/failed/cancelled.

## Other responses

- `202`: The work was queued. Poll the resource at `Location`. A retry with the same Idempotency-Key answers this again, with the same body and the same `Location`, plus `Idempotent-Replayed: true`.
- `400`: `validation_failed` — That request is not valid. · `idempotency_key_required` — This operation needs an Idempotency-Key header: a string of up to 128 characters, unique to this request, so a retry cannot do the work twice. · `unknown_template` — No such design. The catalogue is at GET /api/v1/catalog/marketing/templates. · `unsupported_format` — That design does not offer that shape. `details.formats` lists what it does. · `unsupported_duration` — That design does not offer that length. `details.durations` lists what it does. · `unsupported_audio_mode` — That design does not offer that audio mode. `details.audioModes` lists what it does. · `invalid_cover_text` — Those cover words are not valid for this design and shape. · `expected_revision_required` — Name the revision you are changing, so a save cannot land on words you never saw.
- `401`: `unauthorized` — Authentication is required.
- `402`: `insufficient_seconds` — You do not have enough video time left. Buy more time to keep going.
- `403`: `forbidden_scope` — This credential does not carry the scope this operation needs.
- `404`: `not_found` — No such resource.
- `409`: `idempotency_conflict` — That idempotency key was already used with a different request. · `idempotency_in_progress` — That idempotency key is still being processed. · `conflict` — That request conflicts with the current state. · `no_revision` — That project has no revision to export yet. `details.missing` says what to put right. · `revision_conflict` — That revision is no longer the project's current one. · `revision_configuration_mismatch` — That export does not match the revision's own shape, length or audio. `details.missing` says what to put right. · `too_many_in_flight` — Too many operations are already running on this account. · `already_settled` — That operation has already finished.
- `410`: `source_expired` — That source is past its retention window.
- `413`: `payload_too_large` — That request body is too large.
- `415`: `unsupported_media_type` — That content type is not supported.
- `422`: `campaign_speed_not_offered` — That version is saved at a speed we do not offer. `details.missing` says what to put right. · `campaign_speed_breaks_music_ending` — At that version's saved speed the music would not end with the film. `details.missing` says what to put right. · `campaign_speed_breaks_narration_fit` — At that version's saved speed a spoken line would no longer fit its shot. `details.missing` says what to put right.
- `429`: `rate_limited` — Too many requests. Try again shortly.
- `500`: `internal_error` — Something went wrong. Try again.
- `503`: `reservation_failed` — Video time could not be reserved. Try again shortly. · `queue_unavailable` — That work cannot be queued right now. Try again shortly.

---

[API](https://skmtc.dev/gogoscreen/apis/gogoscreen-api.md) · [All operations](https://skmtc.dev/gogoscreen/apis/gogoscreen-api/llms.txt) · [OpenAPI document](https://skmtc.dev/gogoscreen/apis/gogoscreen-api/revisions/2fd812319d75?raw)
