> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dally.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# previs.create

> Access: public. Send a JSON body; unknown keys are rejected with 400 invalid_request (inputs are strict). Responses may gain fields additively — never remove or repurpose; ignore unknown response fields.



## OpenAPI

````yaml /api-reference/openapi.json post /v1/previs.create
openapi: 3.1.0
info:
  title: Dally API
  version: v1
  description: >-
    PRIVATE (posture 2026-09-01): the MCP connector is Dally's only supported
    surface; this REST surface serves internal harnesses only, and its keys are
    WorkOS-dashboard-issued, never product-issued (CONTEXT.md § Positions).
    Headless Dally v1 — Slack-shape RPC: every operation is POST
    /v1/<family.verb> with a JSON body. Cursor-only pagination ({items,
    has_more, next_cursor}; next_cursor null is the only end signal).
    Unversioned while private (Jim 2026-09-03): a retired name drops in the
    first migration after the deployed release stops naming it; inputs are
    strict, responses are tolerant.
servers:
  - url: https://dally.ai
    description: The production Headless Dally v1 API.
security: []
paths:
  /v1/previs.create:
    post:
      tags:
        - previs
      summary: >-
        Show four hooks for the creator's idea when they ask for ideas, hooks or
        a previs, or four beats of the picked hook's story. Work in this order.
        1. Find the outliers: query the creator's own reels, and the pool's, for
        the ones whose numbers run above their usual. 2. Watch the openings:
        open each outlier's first four seconds, moments 0 to 3.8 spaced 0.2
        apart where the reel has stored moments, else seconds 0 to 4, beside the
        first lines of its transcript. Never write from transcripts alone. 3.
        Read each hook in the conversation: the move on screen, the words on
        screen, the spoken line, the beat when each lands, and why it works. 4.
        Write four hooks that each borrow one move and none of the words: see
        carries the move as a concrete scene, say the spoken line, on_screen the
        words, and borrowed_from names the reel, its second and the move. 5.
        Give each frame three lines of on-screen words, on_screen and two
        other_words; the card paints the first and offers the rest in its tray.
        6. Dally draws the four frames wordless from see and paints on_screen
        over them; previs.reword changes the words without a redraw and keeps
        every revision. Write the words for the creator alone: read their own
        reels' openings before writing, and write about their own work, their
        own place and their own way of putting things; a voice heard in their
        reels may not be theirs. If a line could be heard in someone else's
        reel, it does not go in this one. Never invent experiences, credentials,
        finances or results; frame an unverified scenario as an idea to film.
        Never copy example hooks, recycle a past post or pick for the person.
        Pass three creator image URLs from open as references and describe their
        actual appearance in character; Dally draws one four-frame sheet with
        GPT Image 2 low through OpenRouter in the approved marker/gouache style,
        about twenty seconds and a few cents. For a storyboard pass the picked
        hooks' parent_id; character, references and format are inherited. Reuse
        request_key on a retry; a new key buys a new drawing. It answers
        immediately: show kind previs with this whole response. Short form is
        9:16; long form is 16:9.
      description: >-
        Access: public. Send a JSON body; unknown keys are rejected with 400
        invalid_request (inputs are strict). Responses may gain fields
        additively — never remove or repurpose; ignore unknown response fields.
      operationId: previs.create
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                request_key:
                  type: string
                  minLength: 1
                  maxLength: 128
                  description: A unique name for this previs. Keep it unchanged on retries.
                kind:
                  type: string
                  enum:
                    - hooks
                    - storyboard
                  description: >-
                    Four alternative openings, or four consecutive beats of the
                    picked opening's story.
                title:
                  type: string
                  minLength: 1
                  maxLength: 160
                  description: A short title for this new idea.
                format:
                  default: '9:16'
                  description: >-
                    Video frame shape: portrait short form or landscape long
                    form. Storyboards inherit their parent.
                  type: string
                  enum:
                    - '9:16'
                    - '16:9'
                character:
                  default: ''
                  description: >-
                    The creator's appearance from their reference images;
                    required for hooks, inherited for storyboards.
                  type: string
                  maxLength: 1500
                references:
                  default: []
                  description: >-
                    Exactly three Dally media image URLs for the real creator
                    and rooms, from open; inherited for a storyboard.
                  maxItems: 3
                  type: array
                  items:
                    type: string
                    format: uri
                frames:
                  minItems: 4
                  maxItems: 4
                  type: array
                  items:
                    type: object
                    properties:
                      say:
                        type: string
                        maxLength: 1000
                        description: The verbatim spoken line, authored for this new idea.
                      see:
                        type: string
                        minLength: 1
                        maxLength: 2000
                        description: >-
                          The shot: the move borrowed from the receipt, then
                          action, setting, framing, expression and props. Write
                          a concrete scene; Dally draws it wordless.
                      on_screen:
                        type: string
                        maxLength: 200
                        description: >-
                          The words the card paints over this frame's drawing,
                          in the creator's caption style; empty means no words.
                          Painted, never drawn, so they can change without a
                          redraw.
                      other_words:
                        default: []
                        description: >-
                          Two more lines of on-screen words for this frame, each
                          one the creator alone could say; the card paints
                          on_screen and offers these in its tray, and
                          previs.reword paints one without a redraw.
                        maxItems: 2
                        type: array
                        items:
                          type: string
                          minLength: 1
                          maxLength: 200
                      seconds:
                        type: number
                        exclusiveMinimum: 0
                        maximum: 300
                        description: >-
                          Planned duration of this hook or story beat in
                          seconds.
                      place:
                        default: lower
                        description: >-
                          Where the painted words sit on the frame: lower, where
                          a reel's captions usually sit; middle; or upper, a
                          title at the top. previs.reword moves them.
                        type: string
                        enum:
                          - lower
                          - middle
                          - upper
                      box:
                        default: none
                        description: >-
                          The label behind the painted words: none is white
                          words with a shadow, black is white words on a black
                          label, white is black words on a white label.
                        type: string
                        enum:
                          - black
                          - white
                          - none
                      subject:
                        description: >-
                          Where the person or object this shot is about will
                          stand in the drawn frame, as left, top, width and
                          height, each a share of the frame from 0 to 1. Give
                          the head and shoulders, not the whole body. Dally
                          places words off this box, so a frame without it gets
                          words guessed over a face.
                        readOnly: true
                        type: array
                        prefixItems:
                          - type: number
                            minimum: 0
                            maximum: 1
                          - type: number
                            minimum: 0
                            maximum: 1
                          - type: number
                            minimum: 0
                            maximum: 1
                          - type: number
                            minimum: 0
                            maximum: 1
                      borrowed_from:
                        default: []
                        description: >-
                          The openings this frame borrows from: at most three
                          reels, the creator's own or the pool's, each with the
                          move you are taking, the spoken line there and its
                          second. Dally shows each under the frame with that
                          reel's frame at that second and keeps them with the
                          pick. Empty when the frame borrows nothing.
                        maxItems: 3
                        type: array
                        items:
                          type: object
                          properties:
                            content_id:
                              type: string
                              format: uuid
                              pattern: >-
                                ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
                              description: >-
                                Dally-stable content id (UUID). Content is
                                always addressed by the composite (content_id,
                                platform); platform-native ids are never primary
                                keys.
                            platform:
                              type: string
                              enum:
                                - instagram
                              description: >-
                                The platform a row belongs to. v1 supports
                                instagram; more platforms will be added to this
                                enum additively — treat unknown values as new
                                platforms, never as errors.
                            quote:
                              default: null
                              description: >-
                                The spoken line at that moment of the reel,
                                verbatim from its transcript; Dally finds its
                                second. Null when nothing is said there.
                              anyOf:
                                - type: string
                                  minLength: 1
                                  maxLength: 200
                                - type: 'null'
                            at:
                              default: null
                              description: >-
                                The second of the opening you are borrowing
                                from, as the moments you watched with open name
                                it. Leave null with a quote and Dally fills it
                                from the words.
                              anyOf:
                                - type: number
                                  minimum: 0
                                  maximum: 3600
                                - type: 'null'
                            move:
                              type: string
                              minLength: 1
                              maxLength: 200
                              description: >-
                                The move you are borrowing, as you saw it in
                                that reel's opening: what is on screen and what
                                happens, such as the phone held up to the lens
                                or a laptop turned to camera with its words
                                showing. Never the words themselves.
                          required:
                            - content_id
                            - platform
                            - move
                          additionalProperties: false
                    required:
                      - say
                      - see
                      - on_screen
                      - seconds
                    additionalProperties: false
                  description: >-
                    Exactly four freshly authored frames in reading order. Hooks
                    are alternatives; storyboard beats form one complete new
                    story.
                parent_id:
                  default: null
                  description: >-
                    The completed hook Previs id for a storyboard; null for
                    hooks.
                  anyOf:
                    - type: string
                      format: uuid
                      pattern: >-
                        ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
                    - type: 'null'
              required:
                - request_key
                - kind
                - title
                - frames
              additionalProperties: false
            example:
              request_key: font-plan-hooks-1
              kind: hooks
              title: The plan that made me stop filming
              format: '9:16'
              character: >-
                Late twenties, black hair past the ears, round glasses, a navy
                fleece.
              references:
                - >-
                  https://media.withdally.com/content/3b1f0c7a-9d24-4e51-b6c8-2f7a90d15e43/frames/1fps/0002.jpg
                - >-
                  https://media.withdally.com/content/3b1f0c7a-9d24-4e51-b6c8-2f7a90d15e43/frames/1fps/0014.jpg
                - >-
                  https://media.withdally.com/content/3b1f0c7a-9d24-4e51-b6c8-2f7a90d15e43/frames/1fps/0031.jpg
              frames:
                - say: I spent longer choosing a font than filming.
                  see: >-
                    The creator closes a laptop at a kitchen table, looking
                    quietly amused.
                  on_screen: Still choosing the font
                  other_words:
                    - Font first, filming second
                    - Day three of the font
                  seconds: 4
                  place: lower
                  box: none
                  borrowed_from: []
                - say: I spent longer choosing a font than filming.
                  see: >-
                    The creator closes a laptop at a kitchen table, looking
                    quietly amused.
                  on_screen: The plan had a font
                  other_words:
                    - I named the font before the reel
                    - Serif, then silence
                  seconds: 4
                  place: lower
                  box: none
                  borrowed_from: []
                - say: I spent longer choosing a font than filming.
                  see: >-
                    The creator closes a laptop at a kitchen table, looking
                    quietly amused.
                  on_screen: Nothing filmed, one font picked
                  other_words:
                    - The font is done
                    - Ask me about the font
                  seconds: 4
                  place: lower
                  box: none
                  borrowed_from: []
                - say: I spent longer choosing a font than filming.
                  see: >-
                    The creator closes a laptop at a kitchen table, looking
                    quietly amused.
                  on_screen: Filming is next week
                  other_words:
                    - The font ships today
                    - Done choosing
                  seconds: 4
                  place: lower
                  box: none
                  borrowed_from: []
              parent_id: null
      responses:
        '200':
          description: Success. request_id is present on every response.
          content:
            application/json:
              schema:
                type: object
                properties:
                  previs:
                    type: object
                    properties:
                      previs_id:
                        type: string
                        format: uuid
                        pattern: >-
                          ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
                        description: >-
                          Durable Dally id of this previs; previs.read,
                          previs.pick and previs.reword take it, and a
                          storyboard names it as parent_id.
                      kind:
                        type: string
                        enum:
                          - hooks
                          - storyboard
                        description: >-
                          hooks: four alternative openings for one idea.
                          storyboard: four consecutive beats of the picked
                          hook's story.
                      title:
                        type: string
                        description: The short title the model gave this idea.
                      format:
                        type: string
                        enum:
                          - '9:16'
                          - '16:9'
                        description: >-
                          The video frame shape: 9:16 short form or 16:9 long
                          form.
                      frames:
                        minItems: 4
                        maxItems: 4
                        type: array
                        items:
                          type: object
                          properties:
                            say:
                              type: string
                              maxLength: 1000
                              description: >-
                                The verbatim spoken line, authored for this new
                                idea.
                            see:
                              type: string
                              minLength: 1
                              maxLength: 2000
                              description: >-
                                The shot: the move borrowed from the receipt,
                                then action, setting, framing, expression and
                                props. Write a concrete scene; Dally draws it
                                wordless.
                            on_screen:
                              type: string
                              maxLength: 200
                              description: >-
                                The words the card paints over this frame's
                                drawing, in the creator's caption style; empty
                                means no words. Painted, never drawn, so they
                                can change without a redraw.
                            other_words:
                              default: []
                              description: >-
                                Two more lines of on-screen words for this
                                frame, each one the creator alone could say; the
                                card paints on_screen and offers these in its
                                tray, and previs.reword paints one without a
                                redraw.
                              maxItems: 2
                              type: array
                              items:
                                type: string
                                minLength: 1
                                maxLength: 200
                            seconds:
                              type: number
                              exclusiveMinimum: 0
                              maximum: 300
                              description: >-
                                Planned duration of this hook or story beat in
                                seconds.
                            place:
                              default: lower
                              description: >-
                                Where the painted words sit on the frame: lower,
                                where a reel's captions usually sit; middle; or
                                upper, a title at the top. previs.reword moves
                                them.
                              type: string
                              enum:
                                - lower
                                - middle
                                - upper
                            box:
                              default: none
                              description: >-
                                The label behind the painted words: none is
                                white words with a shadow, black is white words
                                on a black label, white is black words on a
                                white label.
                              type: string
                              enum:
                                - black
                                - white
                                - none
                            subject:
                              description: >-
                                Where the person or object this shot is about
                                will stand in the drawn frame, as left, top,
                                width and height, each a share of the frame from
                                0 to 1. Give the head and shoulders, not the
                                whole body. Dally places words off this box, so
                                a frame without it gets words guessed over a
                                face.
                              readOnly: true
                              type: array
                              prefixItems:
                                - type: number
                                  minimum: 0
                                  maximum: 1
                                - type: number
                                  minimum: 0
                                  maximum: 1
                                - type: number
                                  minimum: 0
                                  maximum: 1
                                - type: number
                                  minimum: 0
                                  maximum: 1
                            borrowed_from:
                              maxItems: 3
                              type: array
                              items:
                                type: object
                                properties:
                                  content_id:
                                    type: string
                                    format: uuid
                                    pattern: >-
                                      ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
                                    description: >-
                                      Dally-stable content id (UUID). Content is
                                      always addressed by the composite
                                      (content_id, platform); platform-native
                                      ids are never primary keys.
                                  platform:
                                    type: string
                                    enum:
                                      - instagram
                                    description: >-
                                      The platform a row belongs to. v1 supports
                                      instagram; more platforms will be added to
                                      this enum additively — treat unknown
                                      values as new platforms, never as errors.
                                  quote:
                                    default: null
                                    description: >-
                                      The spoken line at that moment of the
                                      reel, verbatim from its transcript; Dally
                                      finds its second. Null when nothing is
                                      said there.
                                    anyOf:
                                      - type: string
                                        minLength: 1
                                        maxLength: 200
                                      - type: 'null'
                                  at:
                                    default: null
                                    description: >-
                                      The second of the opening you are
                                      borrowing from, as the moments you watched
                                      with open name it. Leave null with a quote
                                      and Dally fills it from the words.
                                    anyOf:
                                      - type: number
                                        minimum: 0
                                        maximum: 3600
                                      - type: 'null'
                                  move:
                                    type: string
                                    minLength: 1
                                    maxLength: 200
                                    description: >-
                                      The move you are borrowing, as you saw it
                                      in that reel's opening: what is on screen
                                      and what happens, such as the phone held
                                      up to the lens or a laptop turned to
                                      camera with its words showing. Never the
                                      words themselves.
                                  still:
                                    anyOf:
                                      - type: string
                                        format: uri
                                      - type: 'null'
                                    description: >-
                                      The frame of that reel at the receipt's
                                      second, from Dally's media store; null
                                      when Dally has not cut that reel's frames,
                                      and the card shows the reel's cover
                                      instead.
                                required:
                                  - content_id
                                  - platform
                                  - quote
                                  - at
                                  - move
                                  - still
                              description: >-
                                The openings this frame borrows from: at most
                                three reels, the creator's own or the pool's,
                                each with the move you are taking, the spoken
                                line there and its second. Dally shows each
                                under the frame with that reel's frame at that
                                second and keeps them with the pick. Empty when
                                the frame borrows nothing.
                          required:
                            - say
                            - see
                            - on_screen
                            - other_words
                            - seconds
                            - place
                            - box
                            - borrowed_from
                        description: >-
                          The four frames as authored, in reading order: A, B,
                          C, D.
                      receipts:
                        maxItems: 12
                        type: array
                        items:
                          type: object
                          properties:
                            content_id:
                              type: string
                              format: uuid
                              pattern: >-
                                ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
                              description: >-
                                Dally-stable content id (UUID). Content is
                                always addressed by the composite (content_id,
                                platform); platform-native ids are never primary
                                keys.
                            platform:
                              type: string
                              minLength: 1
                              description: >-
                                The platform of the reel this receipt resolved
                                to.
                          required:
                            - content_id
                            - platform
                          additionalProperties: {}
                        description: >-
                          The reels the receipts name, resolved as content cards
                          inside this caller's scope, one per distinct reel, so
                          the card can stage the reel when its receipt is
                          tapped. A reel this caller cannot read is absent, and
                          its receipt shows as words alone.
                      status:
                        type: string
                        enum:
                          - queued
                          - running
                          - ready
                          - failed
                        description: >-
                          queued (the drawing is ordered), running (the provider
                          is drawing), ready (the sheet is stored), failed
                          (error says why).
                      picked_index:
                        anyOf:
                          - type: integer
                            minimum: 0
                            maximum: 3
                          - type: 'null'
                        description: >-
                          The zero-based frame the person chose, A=0 to D=3;
                          null until previs.pick records one.
                      revision:
                        type: integer
                        minimum: 1
                        description: >-
                          The newest revision; pass it as expected_revision to
                          previs.reword so a stale write is refused.
                      revisions:
                        type: array
                        items:
                          type: object
                          properties:
                            revision:
                              type: integer
                              minimum: 1
                              description: This revision's number.
                            made_by:
                              type: string
                              enum:
                                - chat
                                - card
                                - web
                              description: >-
                                Where it came from: chat (the host from the
                                conversation), card (the person's hand in the
                                frame), web (the Dally web page).
                            what:
                              type: string
                              description: What changed, in the maker's words.
                            forked_from:
                              anyOf:
                                - type: integer
                                - type: 'null'
                              description: >-
                                The earlier revision brought back to make this
                                one; null otherwise.
                            created_at:
                              type: string
                              description: >-
                                When this revision was recorded, as an ISO
                                instant.
                            frames:
                              minItems: 4
                              maxItems: 4
                              type: array
                              items:
                                type: object
                                properties:
                                  on_screen:
                                    type: string
                                    maxLength: 200
                                    description: >-
                                      The words the card paints over this
                                      frame's drawing, in the creator's caption
                                      style; empty means no words. Painted,
                                      never drawn, so they can change without a
                                      redraw.
                                  place:
                                    type: string
                                    enum:
                                      - lower
                                      - middle
                                      - upper
                                    description: Where the words sat.
                                  box:
                                    type: string
                                    enum:
                                      - black
                                      - white
                                      - none
                                    description: The label behind the words.
                                required:
                                  - on_screen
                                  - place
                                  - box
                              description: >-
                                The four frames' painted words, place and label
                                as this revision left them, A to D.
                          required:
                            - revision
                            - made_by
                            - what
                            - forked_from
                            - created_at
                            - frames
                        description: >-
                          Every revision, oldest first: the authoring, each
                          reword and each pick, with who made it and what
                          changed. previs.reword with from_revision brings an
                          earlier one back as a new revision.
                      error:
                        anyOf:
                          - type: string
                          - type: 'null'
                        description: >-
                          Why the drawing failed, in the provider's words; null
                          otherwise.
                      result:
                        anyOf:
                          - type: object
                            properties:
                              image_url:
                                type: string
                                format: uri
                                description: >-
                                  Where the finished four-frame sheet is stored
                                  on Dally's media host.
                              width:
                                type: number
                                description: Pixel width of the stored sheet.
                              height:
                                type: number
                                description: Pixel height of the stored sheet.
                              artist:
                                type: string
                                description: >-
                                  Who drew the sheet, named as the provider
                                  names it.
                              quality:
                                type: string
                                description: The quality tier the drawing was ordered at.
                              provider:
                                type: string
                                description: The provider the drawing went through.
                              cost_usd:
                                anyOf:
                                  - type: number
                                  - type: 'null'
                                description: >-
                                  What the provider charged for this drawing, in
                                  US dollars; null when it did not say.
                              latency_ms:
                                type: number
                                description: >-
                                  Milliseconds from the order to the complete
                                  image.
                              provider_request_id:
                                anyOf:
                                  - type: string
                                  - type: 'null'
                                description: >-
                                  The provider's own id for the drawing; null
                                  when it gave none.
                              usage:
                                type: object
                                propertyNames:
                                  type: string
                                additionalProperties: {}
                                description: >-
                                  The provider's usage record for the drawing,
                                  as it reported it.
                            required:
                              - image_url
                              - width
                              - height
                              - artist
                              - quality
                              - provider
                              - cost_usd
                              - latency_ms
                              - provider_request_id
                              - usage
                          - type: 'null'
                        description: >-
                          The finished drawn sheet and what it cost; null until
                          it is ready.
                      created_at:
                        type: string
                        description: When the previs was made, as an ISO instant.
                    required:
                      - previs_id
                      - kind
                      - title
                      - format
                      - frames
                      - receipts
                      - status
                      - picked_index
                      - revision
                      - revisions
                      - error
                      - result
                      - created_at
                    description: >-
                      The stored previs and its current state; dally_show kind
                      previs takes this whole response.
                  show:
                    type: object
                    properties:
                      kind:
                        type: string
                        const: previs
                        description: The dally_show kind that renders the previs.
                    required:
                      - kind
                    description: >-
                      How it is shown: dally_write renders this kind on this
                      very answer with this whole response as its data, so the
                      creator already sees it; do not render it again.
                  request_id:
                    type: string
                    minLength: 1
                    description: >-
                      Server-minted id for this request. Present on every
                      response, success and error — quote it when reporting a
                      problem.
                required:
                  - previs
                  - show
                  - request_id
              example:
                previs:
                  previs_id: bc3c7b36-7ac7-433d-82ef-58bc2d1fe1d1
                  kind: hooks
                  title: The plan that made me stop filming
                  format: '9:16'
                  frames:
                    - say: I spent longer choosing a font than filming.
                      see: >-
                        The creator closes a laptop at a kitchen table, looking
                        quietly amused.
                      on_screen: Still choosing the font
                      other_words:
                        - Font first, filming second
                        - Day three of the font
                      seconds: 4
                      place: lower
                      box: none
                      borrowed_from: []
                    - say: I spent longer choosing a font than filming.
                      see: >-
                        The creator closes a laptop at a kitchen table, looking
                        quietly amused.
                      on_screen: The plan had a font
                      other_words:
                        - I named the font before the reel
                        - Serif, then silence
                      seconds: 4
                      place: lower
                      box: none
                      borrowed_from: []
                    - say: I spent longer choosing a font than filming.
                      see: >-
                        The creator closes a laptop at a kitchen table, looking
                        quietly amused.
                      on_screen: Nothing filmed, one font picked
                      other_words:
                        - The font is done
                        - Ask me about the font
                      seconds: 4
                      place: lower
                      box: none
                      borrowed_from: []
                    - say: I spent longer choosing a font than filming.
                      see: >-
                        The creator closes a laptop at a kitchen table, looking
                        quietly amused.
                      on_screen: Filming is next week
                      other_words:
                        - The font ships today
                        - Done choosing
                      seconds: 4
                      place: lower
                      box: none
                      borrowed_from: []
                  receipts: []
                  status: queued
                  picked_index: null
                  revision: 1
                  revisions:
                    - revision: 1
                      made_by: chat
                      what: Four hooks authored
                      forked_from: null
                      created_at: '2026-09-10T19:00:00.000Z'
                      frames:
                        - on_screen: Still choosing the font
                          place: lower
                          box: none
                        - on_screen: The plan had a font
                          place: lower
                          box: none
                        - on_screen: Nothing filmed, one font picked
                          place: lower
                          box: none
                        - on_screen: Filming is next week
                          place: lower
                          box: none
                  result: null
                  error: null
                  created_at: '2026-09-10T19:00:00.000Z'
                show:
                  kind: previs
                request_id: req_previs_example
        default:
          description: >-
            Error — the real HTTP status carries the class; the body is always
            the one error envelope. Codes: invalid_request, stale_cursor,
            query_too_broad, unauthorized, forbidden, no_connected_accounts,
            stale_authority, not_found, precondition_failed, method_not_allowed,
            stale_snapshot, stale_revision, execution_payload_erased,
            exhaustiveness_unavailable, rate_limited, internal_error,
            unavailable, search_unavailable.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
      security:
        - bearerAuth: []
        - apiKeyAuth: []
components:
  schemas:
    ErrorEnvelope:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              enum:
                - invalid_request
                - stale_cursor
                - query_too_broad
                - unauthorized
                - forbidden
                - no_connected_accounts
                - stale_authority
                - not_found
                - precondition_failed
                - method_not_allowed
                - stale_snapshot
                - stale_revision
                - execution_payload_erased
                - exhaustiveness_unavailable
                - rate_limited
                - internal_error
                - unavailable
                - search_unavailable
              description: >-
                The machine-readable error code. The set only grows — treat
                unknown codes by falling back to the HTTP status class.
            message:
              type: string
              description: >-
                A human-readable teaching message: what failed and the exact
                fix, never just the symptom.
            details:
              description: >-
                Optional structured context for this code — e.g.
                estimated_matches and ceiling on query_too_broad.
              type: object
              propertyNames:
                type: string
              additionalProperties: {}
          required:
            - code
            - message
          description: The error object — the one shape every failure wears.
        request_id:
          type: string
          minLength: 1
          description: >-
            Server-minted id for this request. Present on every response,
            success and error — quote it when reporting a problem.
      required:
        - error
        - request_id
      description: The ONE error envelope (API-ERR-001).
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: 'A WorkOS-dashboard-issued internal API key on Authorization: Bearer.'
    apiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: The same internal API key, accepted on x-api-key.

````