---
title: "List briefs (optionally scoped to a project)"
method: GET
path: "/v1/briefs"
tags: ["briefs"]
---

# List briefs (optionally scoped to a project)

`GET /v1/briefs`

## Request

- Base URL: `https://api.cueframe.ai`
- URL: `https://api.cueframe.ai/v1/briefs`
- Auth: one of:
  - HTTP bearer
  - OAuth 2 (authorization code, authorization URL `https://api.cueframe.ai/api/auth/mcp/authorize`, token URL `https://api.cueframe.ai/api/auth/mcp/token`, scopes: `projects:read`)
  - API key in header `PAYMENT-SIGNATURE`

DEFAULT lists human-authored briefs only. Machine-minted clip briefs (suggest_briefs output) are opt-in: ?kind=clip lists just them, ?kind=all lists everything. Any other kind value is a 400, never silently empty.

## Query parameters

- `limit` integer
- `after` string
- `projectId` string
- `kind` 'authored' | 'clip' | 'all'

## Response `200`

Paginated briefs.

- BriefListResponse
  - `data` BriefResponse[], required
    - `id` string, required
    - `projectId` string, required
    - `kind` 'authored' | 'clip', required: authored = create_brief; clip = minted by suggest_briefs from an AI clip suggestion.
    - `sourceSuggestionId` string: kind:'clip' provenance — the suggestion this Brief was minted from.
    - `name` string
    - `goal` string, required: What the video must accomplish.
    - `audience` string
    - `platform` string
    - `format` Format
      - `aspectRatio` '16:9' | '9:16' | '1:1' | '4:5', required
      - `fps` union
        - 24
        - 25
        - 30
        - 60
      - `resolution` 'hd' | 'fhd' | '4k'
      - `platform` string
    - `durationSec` number: Target output duration. HONOR-OR-REFUSE: compose validates it against the beat-source window (±1.5s) and refuses a brief it cannot honor.
    - `tone` string
    - `cta` string
    - `locale` string: Output language (BCP-47 tag, e.g. 'es-419'): ALL on-screen copy + captions.
    - `hook` string
    - `caption` string
    - `beats` BriefBeat[]
      - `id` string, required
      - `intent` string, required: What this beat DOES editorially (hook the claim, prove it, CTA…).
      - `durationSec` number
      - `source` object: MOMENT PINNING: this beat uses EXACTLY this window of this media item — honored to-the-frame or refused. v1: every sourced beat must reference the SAME mediaId (multi-source briefs are refused loudly, not silently merged).
        - `mediaId` string, required
        - `startSec` number, required
        - `endSec` number, required
      - `graphic` object: GRAPHICS MANDATE: the plan MUST carry a graphics request of this role overlapping this beat's window — enforced at the plan gate (honor-or-refuse, like moment pinning). Prose mustIncludes reaches only the judge; this is the checkable form.
        - `role` 'title-card' | 'stat' | 'lower-third' | 'pull-quote' | 'hero' | 'logo-tag' | 'enumeration' | 'sequence' | 'comparison', required: The mandated graphic's editorial role (the graphics-plan GraphicRole vocabulary).
        - `items` string[]: Mandated list items (enumeration/sequence) — carried VERBATIM into the plan's copy.items.
    - `mustIncludes` string[]
    - `references` string[]
    - `captions` object
      - `styleId` string: Caption style id (e.g. 'serif-emphasis@1').
      - `emphasisPhrases` string[]: Phrases rendered in the caption EMPHASIS style (the big-serif treatment). Matched against the transcript; drives CaptionWord.emphasis.
    - `motionStyle` object
      - `textAnimation` string
      - `transitions` string
      - `colorMood` string
      - `captionStyle` string
    - `seededGraphics` TimelineClip[]: Client-authored graphic clips the Director must carry VERBATIM: seeded into the design loop's base composition as LOCKED clips (never re-authored, never discarded).
      - `id` string, required
      - `startTime` number, required
      - `duration` number, required
      - `source` union, required
        - object
          - `kind` 'media', required
          - `mediaId` string, required
          - `trim` object
            - `start` number, required
            - `end` number, required
          - `excludedRanges` object[]
            - `start` number, required
            - `end` number, required
            - `reason` string
          - `volume` number
          - `muted` boolean
          - `playbackRate` number
          - `sync` 'video' | 'independent'
          - `kenBurns` 'in' | 'out' | 'pan-l' | 'pan-r' | 'none'
          - `volumeDb` number
          - `fadeInMs` number
          - `fadeOutMs` number
          - `loop` boolean
          - `audioRole` 'sfx' | 'music' | 'vo' | 'ambience'
          - `duck` object
            - `duckDb` number, required
            - `attackMs` number, required
            - `releaseMs` number, required
            - `windows` object[]
              - …
          - `anchor` object
            - `clipId` string, required
            - `offsetMs` number, required
          - `reframe` object
            - `segments` object[], required
              - …
        - object
          - `kind` 'component', required
          - `componentId` string, required
          - `props` object, required
          - `zPlane` 'front' | 'behind-subject'
          - `execution` union
            - object
              - …
            - object
              - …
          - `placement` union
            - object
              - …
            - object
              - …
          - `retired` object
        - object
          - `kind` 'overlay', required
          - `primitiveId` string, required
          - `params` object, required
          - `zPlane` 'front' | 'behind-subject'
          - `anchor` object
            - `space` 'scene', required
            - `x` number, required
            - `y` number, required
          - `parallax` number
        - object
          - `kind` 'effect', required
          - `component` union
            - object
              - …
            - object
              - …
          - `targetTrackIds` string[]
          - `wrapperOrder` integer
          - `primitiveId` string
          - `params` object
        - object
          - `kind` 'card', required
          - `html` string, required
          - `tokens` object
          - `zPlane` 'front'
        - object
          - `kind` 'composition', required
          - `compositionId` string, required
          - `trim` object
            - `start` number, required
            - `end` number, required
      - `kind` 'video' | 'audio' | 'image' | 'overlay' | 'effect'
      - `opacity` number
      - `scale` number
      - `rotation` number
      - `position` object: Clip CENTRE as a fraction of the frame: {x:0.5,y:0.5} is dead centre, 0 to 1 is inside the frame, and a little overshoot (down to -1, up to 2) is how an entrance starts off-canvas. NOT pixels: the renderer maps x to `left: x*100%`, so `x: 180` sits 180 frame-widths away and draws nothing.
        - `x` number, required
        - `y` number, required
      - `region` object
        - `x` number, required
        - `y` number, required
        - `w` number, required
        - `h` number, required
      - `fit` 'cover' | 'contain'
      - `captionVisibility` 'visible' | 'hidden': Video media clip only. Hide native captions while this clip is topmost and covers the lower picture, or when an opaque, effect-free clip has an explicitly full-frame region, even with fit:contain. Caption words and timings remain stored and resume when another visible clip takes over.
      - `effects` object[]
        - `id` string
        - `component` union
          - object
            - `version` 3, required
            - `componentId` string, required
            - `sourceVersionId` string, required
            - `params` object, required
            - `seed` string, required
            - `assets` object
            - `mediaBindings` object
          - object
            - `version` 4, required
            - `componentId` string, required
            - `sourceVersionId` string, required
            - `params` object, required
            - `seed` string, required
            - `assets` object
            - `mediaBindings` object
        - `window` object
          - `startTime` number, required
          - `duration` number, required
        - `primitiveId` string
        - `params` object
      - `transitionIn` object
        - `type` string, required
        - `duration` number, required
        - `id` string
        - `component` union
          - object
            - `version` 3, required
            - `componentId` string, required
            - `sourceVersionId` string, required
            - `params` object, required
            - `seed` string, required
            - `assets` object
            - `mediaBindings` object
          - object
            - `version` 4, required
            - `componentId` string, required
            - `sourceVersionId` string, required
            - `params` object, required
            - `seed` string, required
            - `assets` object
            - `mediaBindings` object
        - `fromClipId` string
        - `toClipId` string
        - `handlePolicy` 'outgoing-overrun-at-cut-v1'
      - `linkGroupId` string
      - `tweens` object[]
        - `id` string, required
        - `propertyGroup` 'visual' | 'scale' | 'rotation' | 'position', required
        - `position` number, required
        - `duration` number, required
        - `keyframes` object, required
          - `format` 'percentage', required
          - `easeEach` 'none', required
          - `keyframes` object[], required
            - `percentage` number, required
            - `properties` object, required
            - `ease` string
      - `automation` object
        - `version` 1, required
        - `lanes` object[], required
          - `target` 'volume', required
          - `points` object[], required
            - `t` number, required
            - `v` number, required
      - `legacyKeyframes` object
        - `needsUpgrade` true, required
        - `channels` string[], required
        - `record` unknown, required
    - `exclusions` BriefExclusion[]
    - `gates` BriefGates
      - `holdAt` string[]: Checkpoint gates — the compose pauses at each named stage for review via resume. DEFAULT (gates absent): the compose holds at EVERY stage — your agent reviews and resumes each one; an unreviewed checkpoint times out loudly after 60min. Auto-progression is the opt-in (gates.autoApprove: true).
      - `autoApprove` boolean: true = fully autonomous (compose runs with NO gates — the headless opt-in; without it a brief holds at every stage by default). Mutually exclusive with a non-empty holdAt.
      - `reviewMode` 'agent' | 'hosted': Who captures the review decision. Default 'agent': you relay the packet and call resume. 'hosted': every checkpoint mints a review-page URL (checkpoint.ready payload + get_checkpoint's reviewUrl) where a human approves/revises from the browser — no account, no agent session; the recorded decision rides the SAME resume rail and you learn of it via checkpoint webhooks / wait_job.
    - `audio` BriefAudio
      - `music` object
        - `enabled` boolean, required: Whether the compose carries a music bed.
        - `mood` string: Freeform mood/genre prompt for the GENERATED bed (e.g. 'understated editorial, warm'). Ignored when mediaId pins a track.
        - `mediaId` string: Pin a client-imported track as the bed. HONOR-OR-REFUSE: must be an org-owned kind:'audio' media item, else 422 — never accept-and-ignore. Absent ⇒ generate from mood.
      - `sfx` object
        - `intensity` 'off' | 'light' | 'standard' | 'dense', required: SFX placement density. Real-footage content keeps restraint caps regardless ('dense' is the explicit opt-out); generated/graphic-led content unlocks the standard tier.
    - `quote` BriefQuote, required
      - `composeUsd` number, required
      - `renderUsdPerExport` number, required
      - `estimatedJourneyUsd` number, required: compose + expected renders — relay this BEFORE composing.
      - `revisionCyclesIncluded` integer, required: Revise cycles the compose price includes per gate (A1). Beyond this, resume(revise) is refused with `revision_cycles_exhausted` — saying no never silently charges.
    - `createdAt` number, required
    - `updatedAt` number, required
  - `pagination` PaginationMeta, required: Cursor pagination metadata.
    - `hasMore` boolean, required
    - `nextCursor` string, nullable, required
    - `prevCursor` string, nullable, required

## Other responses

- `400`: Bad request — validation_error / invalid_cursor / invalid_query.
- `401`: Missing or invalid Authorization header.
- `402`: Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).
- `403`: Forbidden — permission insufficient.
- `404`: Resource not found.
- `429`: Rate limited. Retry-After header present.
- `500`: Internal error.

---

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