> ## 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.pick

> 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.pick
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.pick:
    post:
      tags:
        - previs
      summary: >-
        Remember the hook the person chose. Call only after their explicit pick,
        or from the frame they tapped. This buys nothing and records a revision.
        Author its four-beat storyboard and call previs.create with this
        previs_id as parent_id when the person asks for the storyboard.
      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.pick
      requestBody:
        required: true
        content:
          application/json:
            schema:
              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: The completed hooks' Previs id.
                index:
                  type: integer
                  minimum: 0
                  maximum: 3
                  description: 'Zero-based frame: A=0, B=1, C=2, D=3.'
              required:
                - previs_id
                - index
              additionalProperties: false
            example:
              previs_id: bc3c7b36-7ac7-433d-82ef-58bc2d1fe1d1
              index: 1
      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:
                request_id: req_previs_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: ready
                  picked_index: 1
                  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:
                    image_url: >-
                      https://media.withdally.com/generated/previs/7d3f2a1b-4c5e-4f6a-8b9c-0d1e2f3a4b5c/bc3c7b36-7ac7-433d-82ef-58bc2d1fe1d1.png
                    width: 864
                    height: 1536
                    artist: openai/gpt-image-2
                    quality: low
                    provider: openrouter
                    cost_usd: 0.04
                    latency_ms: 21000
                    provider_request_id: null
                    usage: {}
                  error: null
                  created_at: '2026-09-10T19:00:00.000Z'
                show:
                  kind: previs
        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.

````