Config Reference

Every template holds one YAML config. You edit it in the editor, either visually or as text in the YAML tab, and the API reads and writes the same document.

Top-level structure

version: 1

project:   ...
llm:       ...   # optional: override the language model for this config
input:     ...
timeline:  ...
pipeline:  ...
output:    ...   # optional: FCPXML / SRT export targets
outputs:   ...   # optional: named MP4 / FCPXML outputs

version must be 1. llm is optional and names a language-model backend to use for this config (Puffin Ship's default is used when omitted). You use output:, outputs:, or both: see the two sections at the end.


project

project:
  name: "My Project"
  resolution: [1080, 1920]      # [width, height]; portrait = width < height
  fps: 30                       # integer, or [num, den] for fractional e.g. [24000, 1001]
  sample_rate: 48000            # audio sample rate in Hz

Defaults: resolution [1920, 1080], fps 30, sample_rate 48000.


input

Named file references used throughout the pipeline. Values are glob patterns matching files you uploaded to the workspace (folder paths included, e.g. broll/*.mp4).

input:
  - id: speaker-footage
    select: "speaker.MP4"

  - id: broll-clips
    select: "broll/*.mp4"       # matches multiple files

  - id: transcript
    select: "transcript.txt"    # text files are loaded as strings by ai_agent

Steps reference these by id in their input blocks.


timeline

timeline:

  levels:
    - name: music
      order: -1                 # rendered below the backbone
      type: audio
      backbone: false

    - name: background
      order: 0
      type: any
      backbone: false

    - name: main
      order: 1
      type: any
      backbone: true            # exactly one level must be backbone

    - name: broll
      order: 2
      type: video
      backbone: false

    - name: overlay
      order: 3
      type: video
      backbone: false

    - name: captions
      order: 4
      type: video
      backbone: false

  rules:
    gap_fill: black             # how to fill timeline gaps: black | freeze | none
    overflow: error             # what to do if clips exceed timeline: error | trim | warn

Backbone level: drives total timeline duration. All other levels' clips are positioned relative to it in FCPXML. The backbone maps to the FCP <spine>; other levels use FCP lane attributes.

Not supported yet. timeline.duration and timeline.transitions are accepted by the parser but have no effect on the exported timeline: duration always comes from the backbone level, and every cut is hard. They are documented here only so you know not to reach for them.

Level order: lower numbers render first (further back). Use negative values for tracks that should sit below the backbone.

Level types: video, audio, any, title. FCP uses this to determine clip compatibility.


pipeline

An ordered list of steps. Each step runs one processor.

pipeline:
  - id: my_step                 # unique step ID; used by other steps as input
    processor: trim             # processor name (see Processors doc)

    input:                      # what this step reads; every item requires id:
      - id: source              # label for this input (required on every item)
        file: speaker-footage   # reference a project-level input ID
      - id: sources             # multiple project inputs
        files:
          - clip-a
          - clip-b
      - id: transcript          # give each input a meaningful label
        step: transcribe_main   # reference another step's output
      - id: clips
        file: broll-clips

    cache_deps:                 # step IDs that invalidate this step's cache
      - ai_cut                  # re-run when ai_cut changes (even without using its output)

    params:                     # processor-specific settings
      key: value

    prompt: |                   # prompt text for AI processors
      ...

    output:
      timeline: main            # which level this step writes clips to
    level: main                 # short form of output: {timeline: main}; see below

    cache: true                 # save output for reuse inside the run group
    review: false               # pause for human approval before continuing
    mode: ""                    # optional; "plan" enables ai_agent's production-planner mode

Step fields: id, processor, input, cache_deps, params, prompt, output, level, cache (default true), review (default false), and mode (optional; only plan is defined, used by ai_agent). output takes timeline only.

level: main is a short form of output: {timeline: main}. The visual editor writes level:. If a step has both, output.timeline wins. A step needs only one of the two.

Not supported yet. output.placement, output.anchor, and output.workspace parse but are never read: nothing positions a step's clips from them. Where a clip lands is decided by the processor. To pin something to a moment in the transcript, use a processor that takes an anchor of its own.

Input IDs

Every item in input: must have a non-empty id:. This makes YAML configs explicit and validates cleanly at load time. Standard conventions:

ID Meaning
source Primary file or step input (single-input processors)
sources Multiple file inputs (stitch)
transcript Step output containing a transcript
cuts Step output containing edit decisions
backbone Step output defining backbone positions (captions)
clips File input for a directory of media clips (broll_place)
reference Optional text reference/script file

Step output types

Most steps write EditDecisions (clip placements) to a timeline level. Some steps produce other output types that downstream steps consume as inputs:

Output type Produced by Consumed by
Analysis generate_transcript, analyze_footage, workspace_analyze, assemble_transcript, elevenlabs_tts, transcript_aiprep AI processors via step: input
Script write_script transcript_aiprep via step: input
SegmentPlan video_director (primary); footage_assembler (secondary, alongside EditDecisions) broll_place, broll_imagen_generate, broll_screenshot_websource, drawings_ai_placer
TransformPatches reframe, motion_center, speaker_center, scale_transform, volume_adjust Nothing: applied to the clips they target automatically
SourceRemaps chroma_key, noise_reduce Nothing: applied to the clips they target automatically

SegmentPlan is the main inter-step coordination mechanism for the footage-director workflow: footage_assembler produces EditDecisions (placed clips) and a secondary SegmentPlan (unfilled gaps); video_director takes that as input and outputs a refined SegmentPlan as its primary output for downstream broll processors.

Cache deps

Saved output is reused only inside the run group that produced it, and only when nothing the step depends on has changed. A fresh run from the template starts a new group and reuses nothing. See Reusing work between runs.

To invalidate a step when an upstream step changes (even if you don't use its output as data), list the step IDs under cache_deps::

- id: background
  processor: fill_level
  input:
    - id: source
      file: background-image
  cache_deps:
    - ai_cut                     # background re-runs when ai_cut changes
  params:
    duration_step: ai_cut

Review mode

Steps with review: true pause after execution and wait for you in the run view. You can approve the output, approve with edits, reject it (the run ends), or regenerate (re-run the step for new output). See Review Gates.


Variables and secrets

Anywhere in a config, a {{name}} token is replaced with a variable's value, and a {{secret:NAME}} token is replaced with a custom secret. This works in params, prompt, and other string fields:

params:
  voice_id: "{{narrator_voice}}"
  api_key: "{{secret:ELEVENLABS_KEY}}"

If a run starts with a token that has no value, the run stops before it starts.

Where values come from. Variables and custom secrets are set in the editor's Settings slide-over, under Variables & Secrets, or at Workspace Settings > Variables & Keys. Service API keys (OPENAI_API_KEY and the other keys listed in Getting Started) are a separate, curated list in the same Settings slide-over, under Service API Keys.

A variable can be set at more than one scope: workspace, template, run group, and run. When the same name is set at more than one, the more specific scope wins: run beats run group, run group beats template, template beats workspace.

Each variable has a type (string, number, boolean, file, or select) and an optional description. At template scope, a variable can also be marked Required, meaning it must be set before the template can run. Custom secrets are encrypted, write-only, and referenced as {{secret:KEY}}: once saved, a secret's value is never shown again.

Not this syntax. Two other templating syntaxes exist for narrower purposes and are not interchangeable with {{name}}: {{ .Text }} and {{ secret "KEY" }} inside a media processor spec (see Bring your own media service), and {{ params.x }} / {{ loop.item }} / {{ loop.index }} inside a block manifest (see Authoring a block).


output

output:
  - save_finalcut:
      path: "./output/project.fcpxmld"   # FCP X bundle

  - save_srt:
      step: correct_transcript            # which transcript step to export
      path: "./output/project.srt"

The path values are not used. They date from when a pipeline ran on your own machine and wrote files to disk. Runs now happen on the server and you download the results from the run page, so nothing is written to the path you give. path is still required by the config format, so an existing config keeps working, but changing it changes nothing.

Prefer outputs below for new configs: it names the file you download and supports video rendering as well as Final Cut Pro. The .fcpxmld bundle can be opened directly in Final Cut Pro.


outputs

An alternative output declaration that supports both FCPXML and direct video rendering:

outputs:
  - type: fcpxml
    name: my-project           # the Final Cut Pro bundle you download from the run page

  - type: video
    name: my-project-1080p     # the MP4 you download from the run page
    crf: 18                    # H.264 CRF quality (lower = better; default 18)
Field Type Description
type string "fcpxml" or "video"
name string Output filename without extension (.fcpxmld added for fcpxml, .mp4 for video)
crf int H.264 CRF value for type: video (default 18)

Use outputs: when you want to produce an MP4 directly from Puffin Ship, or when you need multiple named output files. Use output: for path-controlled FCPXML or SRT export.