openapi: 3.1.0
info:
  version: 1.4.0
  title: Cloud OpenAPI Spec
  contact:
    name: Native Frame
    email: help@nativeframe.com
  description: |
    ## Introduction
    This API is documented in **OpenAPI format** and can be used to interact with the Native Frame platform.
servers:
  - url: https://platform.nativeframe.com
paths:
  /program/api/v1/projects/{projectID}/programs:
    x-destination:
      - cloud
      - private-cloud
    parameters:
      - name: projectID
        in: path
        description: ID of the project
        required: true
        schema:
          type: string
    post:
      operationId: createProgram
      summary: Create Program
      description: |-
        Create a new program with default composition 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      parameters:
        - name: allow-conflict
          in: query
          description: Allow conflict, if true the existing program will be returned
          required: false
          schema:
            type: boolean
            x-go-type-skip-optional-pointer: false
      requestBody:
        description: Program to create
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Program_ProgramInput'
      responses:
        '200':
          description: Existing program found, returning existing program
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Program'
        '201':
          description: Program created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Program'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_Programs__v1
      x-docs-callouts:
        - private-cloud-warning
  /program/api/v1/program:
    x-destination:
      - cloud
      - private-cloud
    parameters:
      - name: id
        in: query
        description: ID of the program
        required: false
        schema:
          type: string
          x-go-type-skip-optional-pointer: false
      - name: slug
        in: query
        description: Slug of the program
        required: false
        schema:
          type: string
          x-go-type-skip-optional-pointer: false
    get:
      operationId: getProgramBy
      summary: Get program by ID or Slug
      description: |-
        Get program by ID or Slug (either id or slug is required)
        The project ID is extracted from the JWT.
         
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      responses:
        '200':
          description: Get program
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Program'
        '404':
          description: Not Found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - roles:internal-account,service-account
            - prm:MANAGE_PROGRAM
      tags:
        - Program_Programs__v1
      x-docs-callouts:
        - private-cloud-warning
  /program/api/v1/projects/{projectID}/programs/{id}:
    x-destination:
      - cloud
      - private-cloud
    parameters:
      - name: id
        in: path
        description: ID of the program
        required: true
        schema:
          type: string
      - name: projectID
        in: path
        description: ID of the project
        required: true
        schema:
          type: string
    get:
      operationId: getProgram
      summary: Get Program
      description: |-
        Get program by ID 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      responses:
        '200':
          description: Get program
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Program'
        '404':
          description: Not Found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_Programs__v1
      x-docs-callouts:
        - private-cloud-warning
    put:
      operationId: updateProgram
      summary: Update Program
      description: |-
        Update a program 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      requestBody:
        description: Update program
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Program_ProgramInput'
      responses:
        '200':
          description: Program updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Program'
        '404':
          description: Program not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_Programs__v1
      x-docs-callouts:
        - private-cloud-warning
    delete:
      operationId: deleteProgram
      summary: Delete Program
      description: |-
        Delete a program 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      responses:
        '204':
          description: Program deleted
        '404':
          description: Program not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_Programs__v1
      x-docs-callouts:
        - private-cloud-warning
  /program/api/v1/projects/{projectID}/streams:
    x-destination:
      - cloud
      - private-cloud
    parameters:
      - name: projectID
        in: path
        description: ID of the project
        required: true
        schema:
          type: string
    get:
      operationId: getStreams
      summary: Get Streams
      description: |-
        Get all streams by project ID 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      parameters:
        - $ref: '#/components/parameters/Program_PageParam'
        - $ref: '#/components/parameters/Program_LimitParam'
        - name: q
          in: query
          description: Search query, may include stream name or stream ID
          required: false
          schema:
            type: string
            x-go-type-skip-optional-pointer: false
        - name: active
          in: query
          description: Active
          required: false
          schema:
            type: boolean
            x-go-type-skip-optional-pointer: false
      responses:
        '200':
          description: Get streams
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_StreamsResponse'
        '404':
          description: Not Found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_Streams__v1
      x-docs-callouts:
        - private-cloud-warning
    post:
      operationId: createStream
      summary: Create Stream
      description: |-
        Create a stream 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      requestBody:
        description: Stream to create
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Program_CreateStreamRequest'
      responses:
        '201':
          description: Stream created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_StreamResponse'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_Streams__v1
      x-docs-callouts:
        - private-cloud-warning
  /program/api/v2/streams:
    x-destination:
      - cloud
      - private-cloud
    get:
      operationId: getStreamsV2
      summary: Get Streams
      description: |-
        Get all streams for the project (projectID from token) 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      parameters:
        - $ref: '#/components/parameters/Program_PageParam'
        - $ref: '#/components/parameters/Program_LimitParam'
        - name: q
          in: query
          description: Search query, may include stream name or stream ID
          required: false
          schema:
            type: string
            x-go-type-skip-optional-pointer: false
        - name: active
          in: query
          description: Active
          required: false
          schema:
            type: boolean
            x-go-type-skip-optional-pointer: false
        - name: programId
          in: query
          description: Filter by program ID
          required: false
          schema:
            type: string
            x-go-type-skip-optional-pointer: false
        - name: mode
          in: query
          description: Filter by stream mode (e.g., "vf", "v1")
          required: false
          schema:
            type: string
            x-go-type-skip-optional-pointer: false
        - name: authType
          in: query
          description: Filter by auth type (e.g., "public", "private")
          required: false
          schema:
            type: string
            x-go-type-skip-optional-pointer: false
        - name: createdAfter
          in: query
          description: Filter streams created on or after this time (RFC3339)
          required: false
          schema:
            type: string
            format: date-time
            x-go-type-skip-optional-pointer: false
        - name: createdBefore
          in: query
          description: Filter streams created on or before this time (RFC3339)
          required: false
          schema:
            type: string
            format: date-time
            x-go-type-skip-optional-pointer: false
        - name: userId
          in: query
          description: Filter by user ID
          required: false
          schema:
            type: string
            x-go-type-skip-optional-pointer: false
        - name: wasLiveAfter
          in: query
          description: |-
            Filter to streams that had at least one `stream_sessions` row
            overlapping the time window. When set together with
            `wasLiveBefore`, a stream is included if any of its sessions
            satisfies `start <= wasLiveBefore AND (end IS NULL OR end >= wasLiveAfter)`.
            Both boundaries inclusive. V1-mode streams excluded when either
            window param is set.
          required: false
          schema:
            type: string
            format: date-time
            x-go-type-skip-optional-pointer: false
        - name: wasLiveBefore
          in: query
          description: |-
            Upper bound of the historical-liveness window. See `wasLiveAfter`.
            Both inclusive. Required to be >= `wasLiveAfter` when both set,
            otherwise the request fails with 400.
          required: false
          schema:
            type: string
            format: date-time
            x-go-type-skip-optional-pointer: false
        - name: everLive
          in: query
          description: |-
            When `false`, restrict to streams that have NEVER had a
            `stream_sessions` row (i.e. created but never broadcast).
            When `true`, restrict to streams with at least one
            `stream_sessions` row. When absent, no filter.
          required: false
          schema:
            type: boolean
            x-go-type-skip-optional-pointer: false
        - name: derivedFromId
          in: query
          description: |
            Filter by source stream id — return only streams whose
            `derived_from_id` equals this value. Use to list a source
            stream's derivations (e.g. filtergraph overlays).
          required: false
          schema:
            type: string
            format: uuid
            x-go-type-skip-optional-pointer: false
      responses:
        '200':
          description: Get streams
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_StreamsResponse'
        '403':
          description: Forbidden - No project access
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_Streams
      x-docs-callouts:
        - private-cloud-warning
    post:
      operationId: createStreamV2
      summary: Create Stream
      description: |-
        Create a stream (projectID from token) 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      requestBody:
        description: Stream to create
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Program_CreateStreamRequestV2'
      responses:
        '201':
          description: Stream created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_StreamResponseV2'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '403':
          description: Forbidden - No project access
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_Streams
      x-docs-callouts:
        - private-cloud-warning
  /program/api/v1/projects/{projectID}/streams/{id}:
    x-destination:
      - cloud
      - private-cloud
    parameters:
      - name: id
        in: path
        description: ID of the stream
        required: true
        schema:
          type: string
      - name: projectID
        in: path
        description: ID of the project
        required: true
        schema:
          type: string
    get:
      operationId: getStream
      summary: Get Stream
      description: |-
        Get stream by ID 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      responses:
        '200':
          description: Get stream
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_StreamResponse'
        '404':
          description: Not Found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_Streams__v1
      x-docs-callouts:
        - private-cloud-warning
    put:
      operationId: updateStream
      summary: Update Stream
      description: |-
        Update a stream 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      requestBody:
        description: Update stream
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Program_UpdateStreamRequest'
      responses:
        '204':
          description: Stream updated
        '404':
          description: Stream not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_Streams__v1
      x-docs-callouts:
        - private-cloud-warning
    delete:
      operationId: deleteStream
      summary: Delete Stream
      description: |-
        Delete a stream 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      responses:
        '204':
          description: Stream deleted
        '404':
          description: Stream not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_Streams__v1
      x-docs-callouts:
        - private-cloud-warning
  /program/api/v2/streams/{id}:
    x-destination:
      - cloud
      - private-cloud
    parameters:
      - name: id
        in: path
        description: ID of the stream
        required: true
        schema:
          type: string
    get:
      operationId: getStreamV2
      summary: Get Stream
      description: |-
        Get stream by ID (validates stream belongs to token's project) 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      responses:
        '200':
          description: Get stream
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_StreamResponseV2'
        '403':
          description: Forbidden - Stream belongs to different project
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '404':
          description: Not Found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_Streams
      x-docs-callouts:
        - private-cloud-warning
    put:
      operationId: updateStreamV2
      summary: Update Stream
      description: |-
        Update a stream (validates stream belongs to token's project) 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      requestBody:
        description: Update stream
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Program_UpdateStreamRequestV2'
      responses:
        '204':
          description: Stream updated
        '403':
          description: Forbidden - Stream belongs to different project
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '404':
          description: Stream not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_Streams
      x-docs-callouts:
        - private-cloud-warning
    delete:
      operationId: deleteStreamV2
      summary: Delete Stream
      description: |-
        Delete a stream (validates stream belongs to token's project) 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      responses:
        '204':
          description: Stream deleted
        '403':
          description: Forbidden - Stream belongs to different project
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '404':
          description: Stream not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_Streams
      x-docs-callouts:
        - private-cloud-warning
  /program/api/v2/streams/{id}/rtmp-push:
    x-destination:
      - cloud
      - private-cloud
    parameters:
      - name: id
        in: path
        description: ID of the stream
        required: true
        schema:
          type: string
    patch:
      operationId: updateRtmpPushEnabled
      summary: Reconcile RTMP push destinations and enabled state
      description: |-
        Declaratively reconcile the stream's RTMP push destinations against
        the request body. The server upserts each destination in the request
        with that row's `enabled` value, and deletes any stored destination
        not present in the request.

        Each row carries its own `enabled` flag, so a single PATCH can
        express any combination of enabled/disabled destinations.

        The endpoint is idempotent — repeating the same request produces the
        same state.

        Changes apply on the next stream connect. Mid-stream toggling does NOT
        affect a currently-running push (no side-channel to media).

        Maximum 10 destinations per stream.

        Validates the stream belongs to the token's project.
         
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      requestBody:
        description: Desired set of destinations and the enabled flag to apply.
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Program_UpdateRtmpPushEnabledRequest'
      responses:
        '200':
          description: Destinations reconciled
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_UpdateRtmpPushEnabledResponse'
        '400':
          description: Bad request - validation error (unknown type, empty key, cap exceeded, etc.)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '403':
          description: Forbidden - Stream belongs to different project
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '404':
          description: Stream not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '409':
          description: |
            Conflict - one of the proposed enabled destinations is already
            enabled on a related stream in the source/derivation family
            (`rtmp_push_sibling_conflict`). The error payload names the
            offending sibling streamId; the destination key value is NOT
            included. To resolve, use `POST /v2/streams/rtmp-push-bulk` to
            atomically reconcile both streams in one call.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_Streams
      x-docs-callouts:
        - private-cloud-warning
  /program/api/v2/streams/{id}/snapshot-rule:
    x-destination:
      - cloud
      - private-cloud
    parameters:
      - name: id
        in: path
        description: ID of the stream
        required: true
        schema:
          type: string
    post:
      operationId: upsertSnapshotRule
      summary: Create or update the stream's snapshot rule
      description: |-
        Create (201) or update (200) the per-stream snapshot rule. While a
        rule exists and the stream is live, the platform captures an MP4
        clip of up to `maxDurSec` seconds on a cadence (`intervalSec` when
        set, otherwise the platform default — currently 60 seconds) and
        uploads it to the project's configured archiving S3 destination.
        `backfillSec` reads content backwards from the live buffer so each
        capture can include the moments before it fired ("clip the last N
        seconds").

        The request carries capture parameters only — the server assembles
        the full archiver rule (driver, post-processing, S3 destination and
        credentials from the project's archiving configuration) when
        surfacing the rule to orchestration. Changes propagate on the next
        ping cycle (seconds).

        `minDurSec` controls partial clips when the stream ends early:
        clips shorter than it are discarded. Defaults to `maxDurSec`.

        Requires the project to have an archiving configuration (S3
        destination); responds 422 `project_missing_s3_config` otherwise.

        Validates the stream belongs to the token's project. One rule per
        stream.
         
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      requestBody:
        description: Snapshot capture parameters.
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Program_SnapshotRuleRequest'
      responses:
        '200':
          description: Existing rule updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_SnapshotRuleResponse'
        '201':
          description: Rule created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_SnapshotRuleResponse'
        '400':
          description: Bad request - validation error (invalid_duration, invalid_interval, invalid_backfill, etc.)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '403':
          description: Forbidden - Stream belongs to different project
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '404':
          description: Stream not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '422':
          description: Project has no archiving (S3) configuration (project_missing_s3_config)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_Streams
      x-docs-callouts:
        - private-cloud-warning
    get:
      operationId: getSnapshotRule
      summary: Get the stream's snapshot rule
      description: |-
        Returns the stream's snapshot rule, or 404 `snapshot_rule_not_found`
        when none is configured.
         
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      responses:
        '200':
          description: The snapshot rule
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_SnapshotRuleResponse'
        '403':
          description: Forbidden - Stream belongs to different project
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '404':
          description: Stream or rule not found (stream_not_found / snapshot_rule_not_found)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_Streams
      x-docs-callouts:
        - private-cloud-warning
    delete:
      operationId: deleteSnapshotRule
      summary: Delete the stream's snapshot rule
      description: |-
        Removes the stream's snapshot rule. Capture stops on the next ping
        cycle — no out-of-band signal is sent to orchestration. Responds
        404 `snapshot_rule_not_found` when no rule exists.
         
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      responses:
        '204':
          description: Rule deleted
        '403':
          description: Forbidden - Stream belongs to different project
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '404':
          description: Stream or rule not found (stream_not_found / snapshot_rule_not_found)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_Streams
      x-docs-callouts:
        - private-cloud-warning
  /program/api/v2/streams/{id}/snapshots:
    x-destination:
      - cloud
      - private-cloud
    parameters:
      - name: id
        in: path
        description: ID of the stream
        required: true
        schema:
          type: string
    get:
      operationId: listStreamSnapshots
      summary: List a stream's captured snapshot objects (managed storage)
      description: |-
        Lists the snapshot objects captured for the stream on the project's
        **managed** snapshots storage, each with a time-limited presigned
        download URL — the platform-mediated way to view/download managed
        objects without exposing member credentials or a Backblaze login
        (M6 Task 012). Paginated via `limit` + opaque `cursor`.

        Managed snapshots only: if the project's snapshots storage is BYO,
        the customer accesses their own bucket directly (no platform
        surface), and this returns an empty list. 404 if the stream is
        unknown to the token's project.
         
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      parameters:
        - name: limit
          in: query
          description: Max objects to return (default 100, max 1000).
          required: false
          schema:
            type: integer
            x-go-type-skip-optional-pointer: false
        - name: cursor
          in: query
          description: Opaque pagination cursor from a previous page's nextCursor.
          required: false
          schema:
            type: string
            x-go-type-skip-optional-pointer: false
      responses:
        '200':
          description: A page of snapshot objects with presigned download URLs
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_StorageObjectListResponse'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '404':
          description: Stream not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_Streams
      x-docs-callouts:
        - private-cloud-warning
  /program/api/v2/storage-profiles:
    x-destination:
      - cloud
      - private-cloud
    get:
      operationId: listStorageProfiles
      summary: List the project's storage profiles across all surfaces
      description: |-
        Returns the project's configured storage profiles across all
        surfaces (archive, assets, snapshots, clips). Unconfigured
        surfaces are omitted. Credentials are never included.
         
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      responses:
        '200':
          description: The project's storage profiles
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_StorageProfileListResponse'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_Storage
      x-docs-callouts:
        - private-cloud-warning
  /program/api/v2/storage-profiles/{surface}:
    x-destination:
      - cloud
      - private-cloud
    parameters:
      - name: surface
        in: path
        description: Storage surface (archive | assets | snapshots | clips)
        required: true
        schema:
          type: string
          enum:
            - archive
            - assets
            - snapshots
            - clips
    get:
      operationId: getStorageProfile
      summary: Get the project's storage profile for a surface
      description: |-
        Returns the project's storage profile for the surface (managed or
        byo), or 404 `storage_profile_not_found` when the surface has no
        configured storage. M7: each surface configures its own storage —
        there is no archive fallback.
         
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      responses:
        '200':
          description: The storage profile
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_StorageProfileResponse'
        '404':
          description: No managed profile for this surface
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_Storage
      x-docs-callouts:
        - private-cloud-warning
    put:
      operationId: setStorageProfile
      summary: Enable managed storage for a surface
      description: |-
        Sets the surface's storage mode. `mode: managed` provisions a
        per-tenant Backblaze bucket lazily — the first call may take a few
        seconds (mirrors managed assets). Idempotent: repeat calls return
        the current profile. `mode: byo` records the customer's own
        destination. M7: a surface resolves to its own profile only — there
        is no archive fallback. (To copy the archiving config into a byo
        profile without re-entering creds, use POST …/{surface}/from-archive.)
         
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Program_SetStorageProfileRequest'
      responses:
        '200':
          description: Profile (provisioned or already present)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_StorageProfileResponse'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '503':
          description: Managed storage not configured for this deployment, or provisioning failed previously
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_Storage
      x-docs-callouts:
        - private-cloud-warning
    delete:
      operationId: deleteStorageProfile
      summary: Disable / release a surface's storage
      description: |-
        Releases the surface's storage — the inverse of the enabling PUT
        (M7). For a **managed** surface this tears down the managed storage
        (empties the surface's prefix, removes its key); the shared
        per-project account/bucket is removed only when the last managed
        surface is released. For a **BYO** surface it removes the stored
        destination + its Vault secret (the customer's own bucket/objects
        are never touched). Idempotent — releasing an unconfigured surface
        also succeeds. After release, GET returns 404 and the feature
        returns 422 until re-enabled.
         
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      responses:
        '204':
          description: Released (or already absent)
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_Storage
      x-docs-callouts:
        - private-cloud-warning
  /program/api/v2/storage-profiles/{surface}/download-key:
    x-destination:
      - cloud
      - private-cloud
    parameters:
      - name: surface
        in: path
        description: Storage surface (archive | assets | snapshots | clips)
        required: true
        schema:
          type: string
          enum:
            - archive
            - assets
            - snapshots
            - clips
    post:
      operationId: createDownloadKey
      summary: Mint a scoped read-only download key for managed storage
      description: |-
        Mints a Backblaze application key **scoped to the tenant's managed
        bucket** for this surface with **read-only** capabilities
        (listBuckets/listFiles/readFiles) — for programmatic tenant access
        (e.g. `aws s3 ls/cp`) without the dashboard (M6 Task 014).

        The `applicationKey` is returned **once** (B2/AWS semantics — not
        retrievable later). The per-tenant member MASTER key is never
        returned. Managed surfaces only: BYO surfaces respond 422 (the
        tenant already holds their own credentials).
         
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      responses:
        '201':
          description: A freshly-minted scoped read-only key (shown once)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_DownloadKeyResponse'
        '422':
          description: Surface is BYO or has no managed bucket
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_Storage
      x-docs-callouts:
        - private-cloud-warning
  /program/api/v2/storage-profiles/{surface}/download-key/{keyId}:
    x-destination:
      - cloud
      - private-cloud
    parameters:
      - name: surface
        in: path
        description: Storage surface (archive | assets | snapshots | clips)
        required: true
        schema:
          type: string
          enum:
            - archive
            - assets
            - snapshots
            - clips
      - name: keyId
        in: path
        description: The application key id to revoke.
        required: true
        schema:
          type: string
    delete:
      operationId: revokeDownloadKey
      summary: Revoke a previously-minted download key
      description: |-
        Revokes a scoped read-only key minted by createDownloadKey, so a
        leaked or stale key can be killed (M6 Task 014). Idempotent.
         
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      responses:
        '204':
          description: Revoked (or already gone)
        '422':
          description: Surface is BYO or has no managed bucket
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_Storage
      x-docs-callouts:
        - private-cloud-warning
  /program/api/v2/storage-profiles/{surface}/from-archive:
    x-destination:
      - cloud
      - private-cloud
    parameters:
      - name: surface
        in: path
        description: Storage surface to configure (snapshots | clips)
        required: true
        schema:
          type: string
          enum:
            - archive
            - assets
            - snapshots
            - clips
    post:
      operationId: createStorageProfileFromArchive
      summary: Configure a surface's BYO storage by copying the project's archiving config
      description: |-
        Materializes a **BYO** storage profile for the surface from the
        project's existing **archiving (recording) config** — so a customer
        who already configured S3 for recording doesn't re-enter the same
        destination + credentials for snapshots/clips (M7 Task 013).

        This is a **server-side** action because the archiving config's
        secret key is write-only (redacted on GET): only the server can read
        it from Vault and copy it into the surface profile. The copy happens
        **at call time** — it is not a live link; later changes to the
        archiving config do not propagate (re-POST to re-sync).

        After a 200, `GET /v2/storage-profiles/{surface}` returns a ready
        `byo` profile and the feature's writes (e.g. snapshot-rule create)
        no longer return 422. No request body — the source is always the
        project's archiving config.

        Promotable surfaces: `snapshots`, `clips`. Other surfaces respond
        422. Requires a BYO archiving config with a non-empty bucket; a
        project with no archiving config (or a managed archive) responds
        422 (nothing to promote from).
         
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      responses:
        '200':
          description: The resulting BYO storage profile (credentials never echoed)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_StorageProfileResponse'
        '422':
          description: Surface not promotable, or no BYO archiving config to promote from
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '503':
          description: Storage profiles not configured for this deployment
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_Storage
      x-docs-callouts:
        - private-cloud-warning
  /program/api/v2/streams/rtmp-push-bulk:
    x-destination:
      - cloud
      - private-cloud
    post:
      operationId: bulkUpdateRtmpPush
      summary: Atomically reconcile RTMP push destinations across multiple streams
      description: |-
        Reconcile destinations for multiple streams in a single transaction.
        The request body lists one entry per target stream with that stream's
        complete desired destination set. The server applies all per-stream
        reconciles and the cross-stream sibling-collision check (`(type, key)`
        uniqueness within a source/derivation family) against the **final
        state** of the request. Either all per-stream reconciles commit or
        none do.

        The intended use is the source-vs-overlay flip-flop: clear the
        previous streamId and set the new one in a single call, with no
        ordering hazard between two separate PATCHes.

        Validations applied per stream entry:
        - Maximum 10 destinations per stream
        - `type` must be `yt`
        - `key` must be non-empty and ≤256 characters
        - Stream must belong to the token's project

        The response mirrors the request shape, returning the post-reconcile
        destination set for each stream.

        Idempotent. Replaying the same request body produces the same state.
         
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      requestBody:
        description: Per-stream desired destination sets to apply atomically.
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Program_BulkUpdateRtmpPushRequest'
      responses:
        '200':
          description: All destinations reconciled
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_BulkUpdateRtmpPushResponse'
        '400':
          description: |
            Bad request - validation error on one or more entries (unknown
            type, empty key, cap exceeded, duplicate streamID in request,
            empty `streams` array, etc.)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '403':
          description: Forbidden - one of the streams belongs to a different project
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '404':
          description: One of the streams not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '409':
          description: |
            Conflict - the proposed final state would leave the same
            `(type, key)` enabled on multiple streams within a source/
            derivation family. Error payload names the conflicting streamIds.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_Streams
      x-docs-callouts:
        - private-cloud-warning
  /program/api/v2/streams/{id}/session:
    x-destination:
      - cloud
      - private-cloud
    parameters:
      - name: id
        in: path
        description: ID of the stream
        required: true
        schema:
          type: string
    get:
      operationId: getStreamSessionV2
      summary: Get Active Stream Session
      description: |-
        Get the active stream session for a stream by stream ID. Returns 404 if no active session exists. 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      responses:
        '200':
          description: Active stream session found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_StreamSessionResponse'
        '403':
          description: Forbidden - Stream belongs to different project
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '404':
          description: No active session found for stream
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_Streams
      x-docs-callouts:
        - private-cloud-warning
  /program/api/v2/streams/{id}/stream-sessions:
    x-destination:
      - cloud
      - private-cloud
    parameters:
      - name: id
        in: path
        description: ID of the stream
        required: true
        schema:
          type: string
    get:
      operationId: listStreamSessionsV2
      summary: List Stream Sessions
      description: |-
        List `stream_sessions` rows for a single stream, ordered by `start DESC`.
        Optional `after`/`before` (RFC3339) restrict the result to sessions that
        overlap the window (`start <= before AND (end IS NULL OR end >= after)`).
        Pagination via `page` (1-indexed, default 1) and `limit` (default 10, max 100).
        Returns an empty list for V1-mode streams (V1 has no `stream_sessions`).
        404 if the stream does not exist or belongs to a different project. 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      parameters:
        - name: after
          in: query
          description: Lower bound (inclusive) of the session-overlap window
          required: false
          schema:
            type: string
            format: date-time
            x-go-type-skip-optional-pointer: false
        - name: before
          in: query
          description: Upper bound (inclusive) of the session-overlap window
          required: false
          schema:
            type: string
            format: date-time
            x-go-type-skip-optional-pointer: false
        - name: page
          in: query
          description: Page number (1-indexed)
          required: false
          schema:
            type: integer
            x-go-type-skip-optional-pointer: false
        - name: limit
          in: query
          description: Number of results per page (default 10, max 100)
          required: false
          schema:
            type: integer
            x-go-type-skip-optional-pointer: false
      responses:
        '200':
          description: List of stream sessions
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_StreamSessionsListResponse'
        '400':
          description: Bad Request (e.g., before < after)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '404':
          description: Stream not found or belongs to different project
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_Streams
      x-docs-callouts:
        - private-cloud-warning
  /program/api/v2/streams/{id}/stream-sessions/summary:
    x-destination:
      - cloud
      - private-cloud
    parameters:
      - name: id
        in: path
        description: ID of the stream
        required: true
        schema:
          type: string
    get:
      operationId: getStreamSessionsSummaryV2
      summary: Per-Stream Stream Sessions Summary
      description: |-
        Aggregate `stream_sessions` durations for one stream over a required
        time window. Durations are clipped to `[after, before]` so values
        sum coherently. Open sessions are clipped using server `now()`.
        V1-mode streams return zero summary. 90-day max window (400 on
        larger). 404 cross-tenant.

        Response always includes `cleanupArtifactSessionCount` so callers
        can judge whether the totals may be inflated by janitor-closed
        sessions. Pass `excludeCleanupArtifacts=true` to exclude those
        from the duration aggregates entirely. 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      parameters:
        - name: after
          in: query
          description: Window lower bound (RFC3339, inclusive). Required.
          required: true
          schema:
            type: string
            format: date-time
        - name: before
          in: query
          description: Window upper bound (RFC3339, inclusive). Required.
          required: true
          schema:
            type: string
            format: date-time
        - name: excludeCleanupArtifacts
          in: query
          description: |-
            When true, sessions with `closed_by_cleanup = true` are excluded
            from `totalSeconds`, `sessionCount`, `longestSeconds`,
            `shortestSeconds`, and the bounds.
          required: false
          schema:
            type: boolean
            x-go-type-skip-optional-pointer: false
      responses:
        '200':
          description: Per-stream summary
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_StreamSessionsSummaryResponse'
        '400':
          description: Bad Request (missing window, inverted, or > 90 days)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '404':
          description: Stream not found or belongs to different project
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_Streams
      x-docs-callouts:
        - private-cloud-warning
  /program/api/v2/project/stream-sessions/summary:
    x-destination:
      - cloud
      - private-cloud
    get:
      operationId: getProjectStreamSessionsSummaryV2
      summary: Project-Wide Stream Sessions Summary
      description: |-
        Project-scoped rollup of `stream_sessions` durations within a window.
        Clipping rules match the per-stream endpoint. Optional `programId`
        restricts the rollup to one program (404 if it does not belong to
        the caller's project). V1-mode streams excluded. 90-day max window. 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      parameters:
        - name: after
          in: query
          description: Window lower bound (RFC3339, inclusive). Required.
          required: true
          schema:
            type: string
            format: date-time
        - name: before
          in: query
          description: Window upper bound (RFC3339, inclusive). Required.
          required: true
          schema:
            type: string
            format: date-time
        - name: programId
          in: query
          description: Restrict the rollup to a single program in the caller's project.
          required: false
          schema:
            type: string
            x-go-type-skip-optional-pointer: false
        - name: excludeCleanupArtifacts
          in: query
          description: |-
            When true, sessions with `closed_by_cleanup = true` are excluded
            from all aggregates.
          required: false
          schema:
            type: boolean
            x-go-type-skip-optional-pointer: false
      responses:
        '200':
          description: Project-wide summary
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_ProjectStreamSessionsSummaryResponse'
        '400':
          description: Bad Request (missing window, inverted, > 90 days)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '404':
          description: programId does not belong to caller's project
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_Streams
      x-docs-callouts:
        - private-cloud-warning
  /program/api/v2/project/stream-sessions/concurrent-peak:
    x-destination:
      - cloud
      - private-cloud
    get:
      operationId: getProjectConcurrentPeakV2
      summary: Project-Wide Concurrent Peak
      description: |-
        Maximum number of simultaneously-open `stream_sessions` in the
        window for the caller's project (or one program inside it).
        Computed by sweep-line over start/end events. V1 streams
        excluded. Window must be <= 7 days (tighter than other summary
        endpoints; this query scales worse). `Cache-Control: max-age=60`. 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      parameters:
        - name: after
          in: query
          description: Window lower bound (RFC3339, inclusive). Required.
          required: true
          schema:
            type: string
            format: date-time
        - name: before
          in: query
          description: Window upper bound (RFC3339, inclusive). Required.
          required: true
          schema:
            type: string
            format: date-time
        - name: programId
          in: query
          description: Restrict to one program in the caller's project.
          required: false
          schema:
            type: string
            x-go-type-skip-optional-pointer: false
      responses:
        '200':
          description: Concurrent-peak result
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_ConcurrentPeakResponse'
        '400':
          description: Bad Request (missing window, inverted, or > 7 days)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '404':
          description: programId does not belong to caller's project
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_Streams
      x-docs-callouts:
        - private-cloud-warning
  /program/api/v2/programs:
    x-destination:
      - cloud
      - private-cloud
    get:
      operationId: getProgramsV2
      summary: List Programs
      description: |-
        Get all programs for the project (projectID from token) 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      parameters:
        - $ref: '#/components/parameters/Program_PageParam'
        - $ref: '#/components/parameters/Program_LimitParam'
        - name: q
          in: query
          description: Search by program name or slug
          required: false
          schema:
            type: string
            x-go-type-skip-optional-pointer: false
        - name: active
          in: query
          description: |-
            When true, restrict to programs with at least one stream currently
            broadcasting (open `stream_sessions` row, V2-mode streams only).
            When false or absent, no liveness filter.
          required: false
          schema:
            type: boolean
            x-go-type-skip-optional-pointer: false
        - name: wasLiveAfter
          in: query
          description: |-
            Filter to programs that had at least one V2 stream broadcasting
            during the window. Overlap semantics match `GET /v2/streams`.
            V1 programs (programs whose streams are V1-mode) excluded when
            this param is set.
          required: false
          schema:
            type: string
            format: date-time
            x-go-type-skip-optional-pointer: false
        - name: wasLiveBefore
          in: query
          description: Upper bound of the historical-liveness window. Inclusive.
          required: false
          schema:
            type: string
            format: date-time
            x-go-type-skip-optional-pointer: false
        - name: createdAfter
          in: query
          description: Filter programs created on or after this time (RFC3339)
          required: false
          schema:
            type: string
            format: date-time
            x-go-type-skip-optional-pointer: false
        - name: createdBefore
          in: query
          description: Filter programs created on or before this time (RFC3339)
          required: false
          schema:
            type: string
            format: date-time
            x-go-type-skip-optional-pointer: false
        - name: everBroadcast
          in: query
          description: |-
            When `false`, restrict to programs that have NEVER had a
            `sessions` row (programs created but never broadcast).
            When `true`, restrict to programs with at least one `sessions`
            row in their lifetime. When absent, no filter.
          required: false
          schema:
            type: boolean
            x-go-type-skip-optional-pointer: false
      responses:
        '200':
          description: List of programs
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_ProgramsResponse'
        '403':
          description: Forbidden - No project access
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_Programs
      x-docs-callouts:
        - private-cloud-warning
    post:
      operationId: createProgramV2
      summary: Create Program
      description: |-
        Create a program (projectID from token) 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      parameters:
        - name: allow-conflict
          in: query
          description: If true, return existing program on conflict
          required: false
          schema:
            type: boolean
            x-go-type-skip-optional-pointer: false
      requestBody:
        description: Program to create
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Program_CreateProgramRequestV2'
      responses:
        '200':
          description: Existing program returned (allow-conflict=true)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Program'
        '201':
          description: Program created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Program'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '403':
          description: Forbidden - No project access
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_Programs
      x-docs-callouts:
        - private-cloud-warning
  /program/api/v2/programs/{id}:
    x-destination:
      - cloud
      - private-cloud
    parameters:
      - name: id
        in: path
        description: Program ID or slug
        required: true
        schema:
          type: string
    get:
      operationId: getProgramV2
      summary: Get Program
      description: |-
        Get program by ID or slug (validates project ownership) 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      responses:
        '200':
          description: Program found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Program'
        '403':
          description: Forbidden - Program belongs to different project
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '404':
          description: Program not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_Programs
      x-docs-callouts:
        - private-cloud-warning
    put:
      operationId: updateProgramV2
      summary: Update Program
      description: |-
        Update a program (validates project ownership) 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      requestBody:
        description: Program to update
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Program_ProgramInput'
      responses:
        '200':
          description: Program updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Program'
        '403':
          description: Forbidden - Program belongs to different project
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '404':
          description: Program not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_Programs
      x-docs-callouts:
        - private-cloud-warning
    delete:
      operationId: deleteProgramV2
      summary: Delete Program
      description: |-
        Delete a program (validates project ownership) 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      responses:
        '204':
          description: Program deleted
        '403':
          description: Forbidden - Program belongs to different project
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '404':
          description: Program not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_Programs
      x-docs-callouts:
        - private-cloud-warning
  /program/api/v2/programs/{id}/join-session:
    x-destination:
      - cloud
      - private-cloud
    parameters:
      - name: id
        in: path
        description: Program ID
        required: true
        schema:
          type: string
    post:
      operationId: joinSessionV2
      summary: Join Session
      description: |-
        Join a program session (projectID from token) 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      responses:
        '200':
          description: Session joined
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_JoinSessionResponse'
        '403':
          description: Forbidden - Program belongs to different project
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '404':
          description: Program not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_Sessions
      x-docs-callouts:
        - private-cloud-warning
  /program/api/v2/programs/{id}/end-session:
    x-destination:
      - cloud
      - private-cloud
    parameters:
      - name: id
        in: path
        description: Program ID
        required: true
        schema:
          type: string
    post:
      operationId: endSessionV2
      summary: End Session
      description: |-
        End a session (projectID from token) 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      requestBody:
        description: Session to end
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Program_EndSessionRequest'
      responses:
        '204':
          description: Session ended
        '403':
          description: Forbidden - Program belongs to different project
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '404':
          description: Program not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_Sessions
      x-docs-callouts:
        - private-cloud-warning
  /program/api/v2/archiving-config:
    x-destination:
      - cloud
      - private-cloud
    get:
      operationId: getArchivingConfigV2
      summary: Get Archiving Config
      description: |-
        Get archiving config (projectID from token) 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      responses:
        '200':
          description: Archiving config
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_ArchivingConfig'
        '403':
          description: Forbidden - No project access
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '404':
          description: Archiving config not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_Archiving
      x-docs-callouts:
        - private-cloud-warning
    post:
      operationId: upsertArchivingConfigV2
      summary: Upsert Archiving Config
      description: |-
        Upsert archiving config (projectID from token) 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      requestBody:
        description: Archiving config to upsert
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Program_ArchivingConfig'
      responses:
        '201':
          description: Archiving config upserted
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_ArchivingConfig'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '403':
          description: Forbidden - No project access
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_Archiving
      x-docs-callouts:
        - private-cloud-warning
    delete:
      operationId: deleteArchivingConfigV2
      summary: Delete Archiving Config
      description: |-
        Delete archiving config (projectID from token) 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      responses:
        '204':
          description: Archiving config deleted
        '403':
          description: Forbidden - No project access
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '404':
          description: Archiving config not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_Archiving
      x-docs-callouts:
        - private-cloud-warning
  /program/api/v2/archiving-config/test:
    x-destination:
      - cloud
      - private-cloud
    get:
      operationId: testArchivingConfigV2
      summary: Test Archiving Config
      description: |-
        Test archiving config S3 connection (projectID from token) 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      responses:
        '200':
          description: Test archiving config success
        '403':
          description: Forbidden - No project access
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '404':
          description: Archiving config not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '424':
          description: Failed to test S3 connection
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_Archiving
      x-docs-callouts:
        - private-cloud-warning
  /program/api/v2/archive/hls-playlist:
    x-destination:
      - cloud
      - private-cloud
    get:
      operationId: getArchiverHLSPlaylistV2
      summary: Get Archived HLS Playlist
      description: |-
        Generate a unified HLS (m3u8) playlist across multiple archived stream sessions in S3. Merges segments from all sessions within the requested time range into a single VOD playlist.
         
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      parameters:
        - name: stream_key
          in: query
          description: Stream ID (PublicKey)
          required: true
          schema:
            type: string
        - name: start_datetime
          in: query
          description: Start of time range (ISO 8601 / RFC 3339)
          required: true
          schema:
            type: string
            format: date-time
        - name: end_datetime
          in: query
          description: End of time range (ISO 8601 / RFC 3339)
          required: true
          schema:
            type: string
            format: date-time
        - name: url_rewrite_match
          in: query
          description: |
            Regex pattern to match against the full segment URL. Used with url_rewrite_replace for flexible URL rewriting (e.g. rewrite S3 URLs to CDN). Uses Go regexp syntax.
          required: false
          schema:
            type: string
            x-go-type-skip-optional-pointer: false
        - name: url_rewrite_replace
          in: query
          description: |
            Replacement string for matched URLs. Supports capture group references ($1, $2, etc.). Must be provided together with url_rewrite_match.
          required: false
          schema:
            type: string
            x-go-type-skip-optional-pointer: false
        - name: output_path
          in: query
          description: |
            Optional S3 path (relative to the archive bucket root) where the generated index.m3u8 will be saved. If provided and non-empty, the handler creates the path if needed and saves the playlist as index.m3u8, overwriting any existing file.
          required: false
          schema:
            type: string
            x-go-type-skip-optional-pointer: false
        - name: response
          in: query
          description: |
            Response-shape selector. `body` (the default) returns the m3u8 inline. `metadata` returns an ArchiveAssetMetadata JSON about the S3 write — requires `output_path` to be set, otherwise rejected with 400.
          required: false
          schema:
            type: string
            enum:
              - body
              - metadata
            x-go-type-skip-optional-pointer: false
      responses:
        '200':
          description: |
            Merged HLS playlist. Content type depends on the `response` query param — `application/vnd.apple.mpegurl` for `body`, `application/json` (ArchiveAssetMetadata) for `metadata`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_ArchiveAssetMetadata'
            application/vnd.apple.mpegurl:
              schema:
                type: string
        '400':
          description: Bad request (invalid params, bad regex, or fileType not HLS)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '403':
          description: Forbidden - No project access
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '404':
          description: Archiving config not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_Archiving
      x-docs-callouts:
        - private-cloud-warning
  /program/api/v2/archive/thumbnail:
    x-destination:
      - cloud
      - private-cloud
    get:
      operationId: getArchiverThumbnail
      summary: Get an archived-stream thumbnail
      description: |-
        Seeks into an archived HLS stream at the given timestamp and returns a single encoded image (jpg/png/webp). The program service looks up the project's archiving-config (including the public playback base URL) in vault and delegates the actual frame extraction and encoding to the foundation-mediaassets service. When the timestamp falls in a gap between archive sessions, the closest session by time is used; ties prefer the session before.
         
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      parameters:
        - name: stream_key
          in: query
          description: Stream ID (PublicKey).
          required: true
          schema:
            type: string
        - name: datetime
          in: query
          description: Timestamp to extract a frame at (ISO 8601 / RFC 3339).
          required: true
          schema:
            type: string
            format: date-time
        - name: format
          in: query
          description: Output image format. Defaults to `jpg` when omitted.
          required: false
          schema:
            type: string
            enum:
              - jpg
              - png
              - webp
            x-go-type-skip-optional-pointer: false
        - name: quality
          in: query
          description: |
            Encoder quality 0–100. For jpg/webp this is perceptual quality (higher = better). For png this maps to `compression_level` — PNG is lossless either way. Defaults to `63` when omitted.
          required: false
          schema:
            type: integer
            maximum: 100
            minimum: 0
            x-go-type-skip-optional-pointer: false
        - name: width
          in: query
          description: |
            Output width in pixels (1–4096). When only one of width/height is provided, the other is computed from the source to preserve aspect ratio. When both are omitted, the image is returned at the source variant's natural resolution.
          required: false
          schema:
            type: integer
            maximum: 4096
            minimum: 1
            x-go-type-skip-optional-pointer: false
        - name: height
          in: query
          description: Output height in pixels (1–4096). See `width` for semantics.
          required: false
          schema:
            type: integer
            maximum: 4096
            minimum: 1
            x-go-type-skip-optional-pointer: false
        - name: aspect_method
          in: query
          description: |
            How to reconcile source aspect ratio with the target box when both `width` and `height` are provided. Defaults to `center-cut`.
          required: false
          schema:
            type: string
            enum:
              - center-cut
              - pillar-box
            x-go-type-skip-optional-pointer: false
        - name: output_path
          in: query
          description: |
            Optional S3 path (relative to the archive bucket root). When set, the generated image is also written to `{output_path}/thumb{unixMillisOfDatetime}.{ext}` in addition to being returned in the response body.
          required: false
          schema:
            type: string
            x-go-type-skip-optional-pointer: false
        - name: playback_url
          in: query
          description: |
            Per-request override of the vault-stored `s3BaseUrl` on the project's archiving config. Useful when the vault entry hasn't been backfilled with a playback URL. When omitted, the vault value is used; when neither is set, mediaassets falls back to downloading the matching .ts segment via S3.
          required: false
          schema:
            type: string
            x-go-type-skip-optional-pointer: false
        - name: response
          in: query
          description: |
            Response-shape selector. `body` (the default) returns the encoded image inline. `metadata` returns an ArchiveAssetMetadata JSON about the S3 write — requires `output_path` to be set, otherwise rejected with 400.
          required: false
          schema:
            type: string
            enum:
              - body
              - metadata
            x-go-type-skip-optional-pointer: false
      responses:
        '200':
          description: |
            Encoded thumbnail image. Content type depends on the `response` query param — `image/{jpeg,png,webp}` for `body`, `application/json` (ArchiveAssetMetadata) for `metadata`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_ArchiveAssetMetadata'
            image/jpeg:
              schema:
                type: string
                format: binary
            image/png:
              schema:
                type: string
                format: binary
            image/webp:
              schema:
                type: string
                format: binary
        '400':
          description: Bad request (invalid params, fileType not HLS)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '403':
          description: Forbidden - No project access
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '404':
          description: Archiving config not found, or no archive sessions for the stream key
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_Archiving
      x-docs-callouts:
        - private-cloud-warning
  /program/api/v2/archive/mp4-clip:
    x-destination:
      - cloud
      - private-cloud
    get:
      operationId: getArchiverMP4Clip
      summary: Generate a remuxed MP4 clip from an archived stream
      description: |-
        Produces a single MP4 file by remuxing (not transcoding) the archived HLS segments that fall within the requested time range into an MP4 container. Source is assumed to be H.264 video + AAC audio; the clip is written with the `+faststart` flag so the moov atom precedes the mdat box for progressive playback. The program service looks up the project's archiving-config in vault and delegates clip generation to the foundation-mediaassets service.
        Always writes to S3 and always returns metadata — there is no body-response mode, and `output_path` is required.
        Max clip duration is enforced server-side (default 3 minutes). Requests whose `end_datetime - start_datetime` exceeds the cap are rejected with 400 before any S3 lookup.
        **Clip boundary precision:** because this is a pure remux (no transcode), the start of the produced MP4 snaps back to the nearest keyframe at-or-before the requested `start_datetime`. With the typical 2-second keyframe interval in our archives this adds up to ~2 seconds of leading content (head-padding) before the requested start. The end is frame-accurate at the requested `end_datetime`. Net effect: the actual MP4 may be up to one keyframe interval longer than `end_datetime - start_datetime`; the extra is at the head, never at the tail. The actual produced duration is returned in `mp4.durationSeconds`; callers that need exact-frame starts should consume the metadata and skip the head-padding client-side.
         
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      parameters:
        - name: stream_key
          in: query
          description: Stream ID (PublicKey).
          required: true
          schema:
            type: string
        - name: start_datetime
          in: query
          description: Start of the clip range (ISO 8601 / RFC 3339).
          required: true
          schema:
            type: string
            format: date-time
        - name: end_datetime
          in: query
          description: |
            End of the clip range (ISO 8601 / RFC 3339). `end_datetime - start_datetime` must be greater than zero and must not exceed the configured max clip duration (default 3 minutes); requests outside that range are rejected with 400.
          required: true
          schema:
            type: string
            format: date-time
        - name: output_path
          in: query
          description: |
            S3 path (relative to the archive bucket root) where the generated MP4 will be written. The final object key is `{output_path}/clip{startUnixMs}-{endUnixMs}.mp4`.
          required: true
          schema:
            type: string
        - name: kf_accurate
          in: query
          description: |
            When true, trim the clip start to the nearest GOP keyframe rather than the archive segment boundary — giving up to ~one keyframe interval of leading head-padding instead of up to ~one full segment. Still a pure remux (no transcode); the end stays frame-accurate at `end_datetime`. Honored only for single-session ranges; a range spanning multiple archive sessions falls back to segment-granular trimming. Defaults to false.
          required: false
          schema:
            type: boolean
            x-go-type-skip-optional-pointer: false
      responses:
        '200':
          description: |
            MP4 clip generated successfully. Returns ArchiveAssetMetadata describing the S3 write, with MP4-specific fields under the `mp4` sub-object.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_ArchiveAssetMetadata'
        '400':
          description: |
            Bad request — missing/invalid params, duration exceeds the configured cap, or `output_path` not provided.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '403':
          description: Forbidden - No project access
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '404':
          description: Archiving config not found, or no archive sessions for the stream key + range
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_Archiving
      x-docs-callouts:
        - private-cloud-warning
  /program/api/v2/cdn:
    x-destination:
      - cloud
      - private-cloud
    get:
      operationId: getCDNConfigV2
      summary: Get CDN Config
      description: |-
        Get CDN config (projectID from token) 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      responses:
        '200':
          description: CDN config
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_CDN'
        '403':
          description: Forbidden - No project access
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '404':
          description: CDN config not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_CDN
      x-docs-callouts:
        - private-cloud-warning
    post:
      operationId: upsertCDNConfigV2
      summary: Upsert CDN Config
      description: |-
        Upsert CDN config (projectID from token) 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      requestBody:
        description: CDN config to upsert
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Program_CDN'
      responses:
        '201':
          description: CDN config upserted
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_CDN'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '403':
          description: Forbidden - No project access
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_CDN
      x-docs-callouts:
        - private-cloud-warning
    delete:
      operationId: deleteCDNConfigV2
      summary: Delete CDN Config
      description: |-
        Delete CDN config (projectID from token) 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      responses:
        '204':
          description: CDN config deleted
        '403':
          description: Forbidden - No project access
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '404':
          description: CDN config not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_CDN
      x-docs-callouts:
        - private-cloud-warning
  /program/api/v2/projects/{projectID}/assets:
    x-destination:
      - cloud
      - private-cloud
    parameters:
      - name: projectID
        in: path
        description: UUID of the project
        required: true
        schema:
          type: string
    get:
      operationId: listAssets
      summary: List assets in a project
      description: |-
        Returns every asset in the project ordered by `createdOn` ASC for
        deterministic dashboard rendering. Optional `storageMode` query
        narrows the result.
         
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      parameters:
        - name: storageMode
          in: query
          description: Narrow the result to managed or BYO assets only.
          required: false
          schema:
            type: string
            enum:
              - managed
              - byo
            x-go-type-skip-optional-pointer: false
      responses:
        '200':
          description: List of assets
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_AssetsResponse'
        '403':
          description: Forbidden — no project access
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:user,service-account,internal-account
            - roles:user,service-account,internal-account
      tags:
        - Program_Assets
      x-docs-callouts:
        - private-cloud-warning
    post:
      operationId: createAsset
      summary: Create an asset (managed upload or BYO URL)
      description: |-
        Creates a new project-scoped asset row. Two modes:

        **`storageMode=managed`** — bytes are uploaded server-side to
        Backblaze (program receives the multipart body and streams it
        to B2). On first managed asset per project, this request also
        lazy-provisions the project's B2 storage account (D10b),
        adding ~1-3s to the response time. Subsequent uploads skip
        provisioning. Upload ceiling is configurable per deployment
        (default 10 MiB per design.md C8).

        **`storageMode=byo`** — caller supplies `publicUrl` in the
        metadata JSON; program issues an opportunistic HEAD against
        the URL to seed `contentType` and `sizeBytes` (per Q7). The
        `file` part is ignored for BYO mode. HEAD failures (404,
        timeout, HEAD-disallowed CDNs) do NOT block the create.

        Request body is `multipart/form-data` with two parts:
        - `metadata`: JSON-encoded `CreateAssetMetadata`
        - `file`: the asset bytes (managed mode only)
         
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                metadata:
                  description: JSON-encoded CreateAssetMetadata
                  type: string
                file:
                  description: Asset bytes (managed mode only; ≤ max_upload_bytes)
                  type: string
                  format: binary
              required:
                - metadata
      responses:
        '201':
          description: Asset created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_AssetResponse'
        '400':
          description: Validation failure (invalid id charset, missing field, bad URL, etc.)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '403':
          description: Forbidden — no project access
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '409':
          description: Asset id already exists in this project
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '413':
          description: Upload exceeds max_upload_bytes
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '503':
          description: Managed storage not configured / not ready for this deployment
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:user,service-account,internal-account
            - roles:user,service-account,internal-account
      tags:
        - Program_Assets
      x-docs-callouts:
        - private-cloud-warning
  /program/api/v2/projects/{projectID}/assets/{assetID}:
    x-destination:
      - cloud
      - private-cloud
    parameters:
      - name: projectID
        in: path
        description: UUID of the project
        required: true
        schema:
          type: string
      - name: assetID
        in: path
        description: Customer-supplied asset id (^[a-zA-Z0-9._-]{1,128}$)
        required: true
        schema:
          type: string
    get:
      operationId: getAsset
      summary: Get a single asset's metadata
      description: |-
        Returns the full asset row including type, properties, content
        metadata, and most recent fetch status. The actual bytes are
        served via `GET /assets/{assetID}/file` (302 redirect).
         
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      responses:
        '200':
          description: Asset metadata
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_AssetResponse'
        '403':
          description: Forbidden — no project access
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '404':
          description: Asset not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:user,service-account,internal-account
            - roles:user,service-account,internal-account
      tags:
        - Program_Assets
      x-docs-callouts:
        - private-cloud-warning
    patch:
      operationId: updateAsset
      summary: Update an asset's mutable fields
      description: |-
        Updates `type`, `properties`, `publicUrl` (BYO only),
        `contentType`, or `sizeBytes`. Identity columns (id, projectId,
        storageMode, storageKey) are immutable post-create. Bytes
        themselves cannot be updated — delete and re-create the asset
        for that.
         
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Program_UpdateAssetRequest'
      responses:
        '200':
          description: Asset updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_AssetResponse'
        '400':
          description: Validation failure
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '403':
          description: Forbidden — no project access
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '404':
          description: Asset not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:user,service-account,internal-account
            - roles:user,service-account,internal-account
      tags:
        - Program_Assets
      x-docs-callouts:
        - private-cloud-warning
    delete:
      operationId: deleteAsset
      summary: Delete an asset (and its bytes, if managed)
      description: |-
        For managed assets, the B2 object is deleted FIRST. Only if
        that succeeds is the DB row removed — leaves the row intact
        on B2 delete failure so the user can retry rather than
        discovering an orphan B2 object later. For BYO assets, only
        the row is removed (program never owned the bytes).

        FK CASCADE removes any `stream_assets` join rows referencing
        this asset across all streams.

        Idempotent on already-absent.
         
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      responses:
        '204':
          description: Asset deleted (or already absent)
        '403':
          description: Forbidden — no project access
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error (e.g. B2 delete failed; row was NOT deleted)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:user,service-account,internal-account
            - roles:user,service-account,internal-account
      tags:
        - Program_Assets
      x-docs-callouts:
        - private-cloud-warning
  /program/api/v2/projects/{projectID}/assets/{assetID}/file:
    x-destination:
      - cloud
      - private-cloud
    parameters:
      - name: projectID
        in: path
        required: true
        schema:
          type: string
      - name: assetID
        in: path
        required: true
        schema:
          type: string
    get:
      operationId: getAssetFile
      summary: Download the asset bytes (via 302 redirect)
      description: |-
        Returns a 302 redirect to the bytes. For managed assets, a
        short-TTL presigned Backblaze GET URL (default 5 min); for
        BYO, the stored `publicUrl`. Program is never in the byte
        path for downloads (D5).
         
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      responses:
        '302':
          description: Redirect to the asset bytes
          headers:
            Location:
              schema:
                type: string
              description: Presigned B2 GET URL (managed) or stored publicUrl (BYO)
        '403':
          description: Forbidden — no project access
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '404':
          description: Asset not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:user,service-account,internal-account
            - roles:user,service-account,internal-account
      tags:
        - Program_Assets
      x-docs-callouts:
        - private-cloud-warning
  /program/api/v2/projects/{projectID}/assets/{assetID}/streams:
    x-destination:
      - cloud
      - private-cloud
    parameters:
      - name: projectID
        in: path
        required: true
        schema:
          type: string
      - name: assetID
        in: path
        required: true
        schema:
          type: string
    get:
      operationId: listStreamsForAsset
      summary: List streams using this asset (reverse lookup)
      description: |-
        Returns the IDs of streams currently attached to this asset.
        Used by dashboard's "where is this used?" view to warn before
        delete or rename.
         
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      responses:
        '200':
          description: Stream IDs in attachment order
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_AssetStreamsResponse'
        '403':
          description: Forbidden — no project access
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '404':
          description: Asset not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:user,service-account,internal-account
            - roles:user,service-account,internal-account
      tags:
        - Program_Assets
      x-docs-callouts:
        - private-cloud-warning
  /program/api/v2/streams/{streamID}/assets:
    x-destination:
      - cloud
      - private-cloud
    parameters:
      - name: streamID
        in: path
        description: UUID of the stream
        required: true
        schema:
          type: string
    get:
      operationId: listStreamAssets
      summary: List assets attached to a stream
      description: '<a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>'
      responses:
        '200':
          description: Asset rows attached to the stream
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_StreamAssetsResponse'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '404':
          description: Stream not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:user,service-account,internal-account
            - roles:user,service-account,internal-account
      tags:
        - Program_Assets
      x-docs-callouts:
        - private-cloud-warning
    put:
      operationId: reconcileStreamAssets
      summary: Declarative reconcile of the stream's attached asset set
      description: |-
        Replaces the stream's attached asset set with the supplied
        `assetIds`. Atomic — either every add/remove lands or none do.
        Asset ids that don't belong to the stream's project are
        rejected by FK at the DB layer (400). The response is the
        post-reconcile asset rows so callers don't need a follow-up
        GET.
         
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Program_ReconcileStreamAssetsRequest'
      responses:
        '200':
          description: Reconciled — returns post-mutation asset set
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_StreamAssetsResponse'
        '400':
          description: Cross-project attach attempt or invalid asset id
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '404':
          description: Stream not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:user,service-account,internal-account
            - roles:user,service-account,internal-account
      tags:
        - Program_Assets
      x-docs-callouts:
        - private-cloud-warning
  /program/api/v2/streams/{streamID}/assets/{assetID}:
    x-destination:
      - cloud
      - private-cloud
    parameters:
      - name: streamID
        in: path
        required: true
        schema:
          type: string
      - name: assetID
        in: path
        required: true
        schema:
          type: string
    post:
      operationId: attachStreamAsset
      summary: Attach one asset to a stream (additive)
      description: |-
        Idempotent — re-attaching the same (stream, asset) pair is a
        no-op success. Cross-project attach is rejected by FK at the
        DB layer.
         
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      responses:
        '204':
          description: Attached (or already attached)
        '400':
          description: Cross-project attach or unknown asset
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '404':
          description: Stream not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:user,service-account,internal-account
            - roles:user,service-account,internal-account
      tags:
        - Program_Assets
      x-docs-callouts:
        - private-cloud-warning
    delete:
      operationId: detachStreamAsset
      summary: Detach one asset from a stream
      description: |-
        Idempotent on already-detached. 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      responses:
        '204':
          description: Detached (or was not attached)
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '404':
          description: Stream not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:user,service-account,internal-account
            - roles:user,service-account,internal-account
      tags:
        - Program_Assets
      x-docs-callouts:
        - private-cloud-warning
  /program/api/v1/projects/{projectID}/archiving-config/test:
    x-destination:
      - cloud
      - private-cloud
    parameters:
      - name: projectID
        in: path
        description: ID of the project
        required: true
        schema:
          type: string
    get:
      operationId: testArchivingConfig
      summary: Test Archiving Config
      description: |-
        Test archiving config by ID 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      responses:
        '200':
          description: Test archiving config success
        '404':
          description: Archiving config not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '424':
          description: Failed to test S3 connection
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_Archiving__v1
      x-docs-callouts:
        - private-cloud-warning
  /program/api/v1/projects/{projectID}/archiving-config:
    x-destination:
      - cloud
      - private-cloud
    parameters:
      - name: projectID
        in: path
        description: ID of the project
        required: true
        schema:
          type: string
    get:
      operationId: getArchivingConfig
      summary: Get Archiving Config
      description: |-
        Get archiving config 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      responses:
        '200':
          description: Get all archiving configs
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_ArchivingConfig'
        '404':
          description: Project not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_Archiving__v1
      x-docs-callouts:
        - private-cloud-warning
    post:
      operationId: upsertArchivingConfig
      summary: Upsert Archiving Config
      description: |-
        Upsert archiving config 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      requestBody:
        description: Archiving config to upsert
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Program_ArchivingConfig'
      responses:
        '201':
          description: Archiving config upserted
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_ArchivingConfig'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_Archiving__v1
      x-docs-callouts:
        - private-cloud-warning
    delete:
      operationId: deleteArchivingConfig
      summary: Delete Archiving Config
      description: |-
        Delete archiving config 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      responses:
        '204':
          description: Archiving config deleted
        '404':
          description: Archiving config not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_Archiving__v1
      x-docs-callouts:
        - private-cloud-warning
  /program/api/v1/projects/{projectID}/cdn:
    x-destination:
      - cloud
      - private-cloud
    parameters:
      - name: projectID
        in: path
        description: ID of the project
        required: true
        schema:
          type: string
    get:
      operationId: getCDNConfig
      summary: Get CDN config
      description: |-
        Get CDN config 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      responses:
        '200':
          description: Get CDN
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_CDN'
        '404':
          description: Project not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_CDN__v1
      x-docs-callouts:
        - private-cloud-warning
    post:
      operationId: upsertCDNConfig
      summary: Upsert CDN
      description: |-
        Upsert CDN 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      requestBody:
        description: CDN to upsert
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Program_CDN'
      responses:
        '201':
          description: CDN upserted
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_CDN'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_CDN__v1
      x-docs-callouts:
        - private-cloud-warning
    delete:
      operationId: deleteCDNConfig
      summary: Delete CDN
      description: |-
        Delete CDN 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      responses:
        '204':
          description: CDN deleted
        '404':
          description: CDN not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_CDN__v1
      x-docs-callouts:
        - private-cloud-warning
  /program/api/v2/streams/search:
    x-destination:
      - cloud
      - private-cloud
    post:
      operationId: searchStreamsV2
      summary: Search Streams
      description: |-
        Search streams with advanced filtering options using a request body.
        This endpoint provides the same functionality as GET /v2/streams but accepts
        a JSON body for more complex query scenarios. Use this when you need to:
        - Pass complex filter criteria
        - Avoid URL length limitations
        - Use clients that don't support query parameters on GET requests
         
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      requestBody:
        description: Search criteria for streams
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Program_SearchStreamsRequest'
      responses:
        '200':
          description: Search results
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_StreamsResponse'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '403':
          description: Forbidden - No project access
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_Streams
      x-docs-callouts:
        - private-cloud-warning
  /program/api/v2/streams/{id}/rtsp-source:
    x-destination:
      - cloud
      - private-cloud
    parameters:
      - name: id
        in: path
        description: ID of the stream
        required: true
        schema:
          type: string
          format: uuid
    get:
      operationId: getRTSPSource
      summary: Get RTSP Source
      description: |-
        Get RTSP source configuration for a stream 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      responses:
        '200':
          description: RTSP source configuration
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_RTSPSourceResponse'
        '403':
          description: Forbidden - Stream belongs to different project
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '404':
          description: RTSP source not configured for stream
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_RTSP
      x-docs-callouts:
        - private-cloud-warning
    put:
      operationId: configureRTSPSource
      summary: Configure RTSP Source
      description: |-
        Configure or update RTSP source for a stream. Creates if not exists, updates if exists. 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      requestBody:
        description: RTSP source configuration
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Program_RTSPSourceConfigRequest'
      responses:
        '200':
          description: RTSP source configured
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_RTSPSourceResponse'
        '400':
          description: Bad Request - Invalid configuration
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '403':
          description: Forbidden - Stream belongs to different project
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '404':
          description: Stream not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_RTSP
      x-docs-callouts:
        - private-cloud-warning
    delete:
      operationId: deleteRTSPSource
      summary: Delete RTSP Source
      description: |-
        Delete RTSP source configuration for a stream. Stops any active pull first. 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      responses:
        '204':
          description: RTSP source deleted
        '403':
          description: Forbidden - Stream belongs to different project
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '404':
          description: RTSP source not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_RTSP
      x-docs-callouts:
        - private-cloud-warning
  /program/api/v2/streams/{id}/rtsp-source/start:
    x-destination:
      - cloud
      - private-cloud
    parameters:
      - name: id
        in: path
        description: ID of the stream
        required: true
        schema:
          type: string
          format: uuid
    post:
      operationId: startRTSPPull
      summary: Start RTSP Pull
      description: |-
        Manually start RTSP pull for a stream. Creates a stream session and begins pulling from the configured RTSP source. 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      responses:
        '200':
          description: RTSP pull started
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_RTSPSourceStatusResponse'
        '400':
          description: Bad Request - Source already running or not configured
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '403':
          description: Forbidden - Stream belongs to different project
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '404':
          description: RTSP source not configured
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_RTSP
      x-docs-callouts:
        - private-cloud-warning
  /program/api/v2/streams/{id}/rtsp-source/stop:
    x-destination:
      - cloud
      - private-cloud
    parameters:
      - name: id
        in: path
        description: ID of the stream
        required: true
        schema:
          type: string
          format: uuid
    post:
      operationId: stopRTSPPull
      summary: Stop RTSP Pull
      description: |-
        Manually stop RTSP pull for a stream. Ends the current stream session. 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      responses:
        '200':
          description: RTSP pull stopped
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_RTSPSourceStatusResponse'
        '400':
          description: Bad Request - Source not running
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '403':
          description: Forbidden - Stream belongs to different project
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '404':
          description: RTSP source not configured
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_RTSP
      x-docs-callouts:
        - private-cloud-warning
  /program/api/v2/streams/{id}/rtsp-source/status:
    x-destination:
      - cloud
      - private-cloud
    parameters:
      - name: id
        in: path
        description: ID of the stream
        required: true
        schema:
          type: string
          format: uuid
    get:
      operationId: getRTSPSourceStatus
      summary: Get RTSP Source Status
      description: |-
        Get current status of RTSP source including running state, error information, and schedule status 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      responses:
        '200':
          description: RTSP source status
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_RTSPSourceStatusResponse'
        '403':
          description: Forbidden - Stream belongs to different project
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '404':
          description: RTSP source not configured
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_RTSP
      x-docs-callouts:
        - private-cloud-warning
  /program/api/v2/streams/{id}/rtsp-schedules:
    x-destination:
      - cloud
      - private-cloud
    parameters:
      - name: id
        in: path
        description: ID of the stream
        required: true
        schema:
          type: string
          format: uuid
    get:
      operationId: getRTSPSchedules
      summary: Get RTSP Schedules
      description: |-
        Get all RTSP schedules for a stream 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      responses:
        '200':
          description: List of RTSP schedules
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_RTSPSchedulesResponse'
        '403':
          description: Forbidden - Stream belongs to different project
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_RTSP
      x-docs-callouts:
        - private-cloud-warning
    post:
      operationId: createRTSPSchedule
      summary: Create RTSP Schedule
      description: |-
        Create a new RTSP schedule for a stream 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      requestBody:
        description: Schedule configuration
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Program_RTSPScheduleRequest'
      responses:
        '201':
          description: Schedule created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_RTSPScheduleResponse'
        '400':
          description: Bad Request - Invalid schedule or RTSP source not configured
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '403':
          description: Forbidden - Stream belongs to different project
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '404':
          description: Stream not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '409':
          description: Conflict - Schedule already exists for stream (V1 limitation)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_RTSP
      x-docs-callouts:
        - private-cloud-warning
  /program/api/v2/streams/{id}/rtsp-schedules/{scheduleId}:
    x-destination:
      - cloud
      - private-cloud
    parameters:
      - name: id
        in: path
        description: ID of the stream
        required: true
        schema:
          type: string
          format: uuid
      - name: scheduleId
        in: path
        description: ID of the schedule
        required: true
        schema:
          type: string
          format: uuid
    get:
      operationId: getRTSPScheduleByID
      summary: Get RTSP Schedule
      description: |-
        Get a specific RTSP schedule by ID 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      responses:
        '200':
          description: RTSP schedule
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_RTSPScheduleResponse'
        '403':
          description: Forbidden - Schedule belongs to different project
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '404':
          description: Schedule not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_RTSP
      x-docs-callouts:
        - private-cloud-warning
    put:
      operationId: updateRTSPSchedule
      summary: Update RTSP Schedule
      description: |-
        Update an existing RTSP schedule 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      requestBody:
        description: Schedule configuration
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Program_RTSPScheduleRequest'
      responses:
        '200':
          description: Schedule updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_RTSPScheduleResponse'
        '400':
          description: Bad Request - Invalid schedule
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '403':
          description: Forbidden - Schedule belongs to different project
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '404':
          description: Schedule not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_RTSP
      x-docs-callouts:
        - private-cloud-warning
    delete:
      operationId: deleteRTSPSchedule
      summary: Delete RTSP Schedule
      description: |-
        Delete an RTSP schedule. Stops any active pull if the schedule is currently active. 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      responses:
        '204':
          description: Schedule deleted
        '403':
          description: Forbidden - Schedule belongs to different project
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '404':
          description: Schedule not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Program_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Program_RTSP
      x-docs-callouts:
        - private-cloud-warning
  /auth/v1/jwks:
    get:
      operationId: getJWKs
      summary: Returns a list of JSON Web Keys
      description: '<a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>'
      parameters:
        - name: kc
          in: query
          description: Include JWKs from KeyCloak
          required: false
          schema:
            type: boolean
        - name: iss
          in: query
          description: Filter JWKs by issuer
          required: false
          schema:
            type: string
        - name: Cache-Control
          in: header
          description: Cache-Control header, only 'no-cache' is supported if you also include a valid JWT
          schema:
            type: string
      responses:
        '200':
          description: Array of JWKs
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Auth_JWKs'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Auth_Error'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Auth_Error'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Auth_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Auth_Error'
      tags:
        - Auth_JSON Web Keys
      x-destination:
        - cloud
        - private-cloud
      x-docs-callouts:
        - private-cloud-warning
  /auth/v1/jwt:
    x-destination:
      - cloud
      - private-cloud
    post:
      operationId: createJWT
      summary: Create JWT
      description: |-
        To create a JWT use your project's Service Account JWT to authenticate and authorize the request.

        The 'kid' you supply must exist and will be used to sign the JWT. You can create a new KID by creating a new JWK in your dashboard.

        Do not use the 'kid' of your project's Service Account JWT unless you want to give the JWT created access to your project.
         
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      requestBody:
        description: JWT options
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Auth_CreateJWT'
      responses:
        '201':
          description: JWT
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Auth_JWTResponse'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Auth_Error'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Auth_Error'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Auth_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Auth_Error'
      security:
        - JWT:
            - roles:internal-account,service-account
            - aud:internal-account,service-account
      tags:
        - Auth_JSON Web Tokens
      x-docs-callouts:
        - private-cloud-warning
  /auth/v1/video-jwt:
    x-destination:
      - cloud
      - private-cloud
    post:
      operationId: createVideoJWT
      summary: Create Video JWT
      description: |-
        Create a JWT with a video token claim.

        This can be used to start or view a video stream.
         
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      requestBody:
        description: JWT options
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Auth_CreateVideoJWT'
      responses:
        '201':
          description: JWT
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Auth_JWTResponse'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Auth_Error'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Auth_Error'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Auth_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Auth_Error'
      security:
        - JWT:
            - roles:internal-account,service-account
            - aud:internal-account,service-account
      tags:
        - Auth_JSON Web Tokens
      x-docs-callouts:
        - private-cloud-warning
  /auth/v1/issuers:
    x-destination:
      - cloud
      - private-cloud
    post:
      operationId: CreateIssuer
      summary: Create Issuer
      description: '<a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Auth_Issuer'
      responses:
        '201':
          description: Issuer
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Auth_Issuer'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Auth_Error'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Auth_Error'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Auth_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Auth_Error'
      security:
        - JWT:
            - roles:service-account,internal-account
            - aud:internal-account
      tags:
        - Auth_JWT Issuers
      x-docs-callouts:
        - private-cloud-warning
  /auth/v1/issuers/{iss}:
    x-destination:
      - cloud
      - private-cloud
    get:
      operationId: GetIssuer
      summary: Get Issuer
      description: '<a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>'
      parameters:
        - name: iss
          in: path
          description: Issuer ID
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Issuer
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Auth_Issuer'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Auth_Error'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Auth_Error'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Auth_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Auth_Error'
      security:
        - JWT:
            - roles:service-account,internal-account
            - aud:internal-account
      tags:
        - Auth_JWT Issuers
      x-docs-callouts:
        - private-cloud-warning
    put:
      operationId: UpdateIssuer
      summary: Update Issuer
      description: '<a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>'
      parameters:
        - name: iss
          in: path
          description: Issuer ID
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Auth_Issuer'
      responses:
        '200':
          description: Issuer
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Auth_Issuer'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Auth_Error'
        '401':
          description: JWT
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Auth_Error'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Auth_Error'
      security:
        - JWT:
            - roles:service-account,internal-account
            - aud:service-account,internal-account
      tags:
        - Auth_JWT Issuers
      x-docs-callouts:
        - private-cloud-warning
    delete:
      operationId: RemoveIssuer
      summary: Remove Issuer
      description: |-
        Remove an issuer by the `iss` claim, this will also remove all the keys associated with the issuer.

        *Note* there is a cache running on each service so it can take a few minutes to see your changes
         
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      parameters:
        - name: iss
          in: path
          description: Issuer ID
          required: true
          schema:
            type: string
      responses:
        '204':
          description: Issuer removed
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Auth_Error'
        '401':
          description: JWT
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Auth_Error'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Auth_Error'
      security:
        - JWT:
            - roles:service-account,internal-account
            - aud:internal-account
      tags:
        - Auth_JWT Issuers
      x-docs-callouts:
        - private-cloud-warning
  /dashboard/api/v1/public-config:
    x-destination:
      - cloud
      - private-cloud
    get:
      operationId: getPublicConfig
      summary: Public config endpoint
      description: '<a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>'
      responses:
        '200':
          description: Returns the public config of the service
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Dashboard_PublicConfig'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Dashboard_Error'
      tags:
        - Dashboard_Config
      x-docs-callouts:
        - private-cloud-warning
      x-eov-operation-handler: routes/publicConfig
  /dashboard/api/v1/organizations/{organizationSlug}/projects:
    x-destination:
      - cloud
      - private-cloud
    post:
      operationId: createProject
      summary: Create Project
      description: '<a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>'
      parameters:
        - name: organizationSlug
          in: path
          required: true
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Dashboard_CreateProjectBody'
      responses:
        '200':
          description: Returns the created project information
          content:
            application/json:
              schema:
                type: object
                properties:
                  project:
                    $ref: '#/components/schemas/Dashboard_Project'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Dashboard_Error'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Dashboard_Error'
        '404':
          description: Organization not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Dashboard_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Dashboard_Error'
      security:
        - JWT: []
      tags:
        - Dashboard_Projects
      x-docs-callouts:
        - private-cloud-warning
      x-eov-operation-handler: routes/projects/createProject
    get:
      operationId: getProjects
      summary: Get Projects
      description: |-
        Returns all of the projects for an organization 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      parameters:
        - name: organizationSlug
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Returns the projects information
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Dashboard_Project'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Dashboard_Error'
        '404':
          description: Organization not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Dashboard_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Dashboard_Error'
      security:
        - JWT: []
      tags:
        - Dashboard_Projects
      x-docs-callouts:
        - private-cloud-warning
      x-eov-operation-handler: routes/projects/getProjects
  /dashboard/api/v1/organizations/{organizationSlug}/projects/{projectId}:
    get:
      operationId: getProject
      summary: Get Project
      description: '<a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>'
      parameters:
        - name: organizationSlug
          in: path
          required: true
          schema:
            type: string
        - name: projectId
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Returns the project information
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Dashboard_Project'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Dashboard_Error'
        '404':
          description: Project not found or organization not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Dashboard_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Dashboard_Error'
      security:
        - JWT: []
      tags:
        - Dashboard_Projects
      x-destination:
        - cloud
        - private-cloud
      x-docs-callouts:
        - private-cloud-warning
      x-eov-operation-handler: routes/projects/getProject
    put:
      operationId: updateProject
      summary: Update Project
      description: '<a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>'
      parameters:
        - name: organizationSlug
          in: path
          required: true
          schema:
            type: string
        - name: projectId
          in: path
          required: true
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Dashboard_UpdateProjectBody'
      responses:
        '200':
          description: Returns the updated project information
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Dashboard_Project'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Dashboard_Error'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Dashboard_Error'
        '404':
          description: Project not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Dashboard_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Dashboard_Error'
      security:
        - JWT: []
      tags:
        - Dashboard_Projects
      x-destination:
        - cloud
        - private-cloud
      x-docs-callouts:
        - private-cloud-warning
      x-eov-operation-handler: routes/projects/updateProject
  /dashboard/api/v1/organizations/{organizationSlug}/invoices/dates:
    get:
      operationId: getInvoicesDates
      summary: Get Invoice Dates
      description: '<a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>'
      parameters:
        - name: organizationSlug
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Returns the dates of the invoices including current month
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Dashboard_InvoiceDatesResponse'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Dashboard_Error'
        '404':
          description: Project not found or organization not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Dashboard_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Dashboard_Error'
      security:
        - JWT: []
      tags:
        - Dashboard_Projects
      x-destination:
        - cloud
        - private-cloud
      x-docs-callouts:
        - private-cloud-warning
      x-eov-operation-handler: routes/invoices/getInvoicesDates
  /dashboard/api/v1/organizations/{organizationSlug}/invoices/{date}:
    get:
      operationId: getInvoice
      summary: Get Invoice
      description: '<a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>'
      parameters:
        - name: organizationSlug
          in: path
          required: true
          schema:
            type: string
        - name: date
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Returns the dates of the invoices including current month
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Dashboard_InvoiceResponse'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Dashboard_Error'
        '404':
          description: Project not found or organization not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Dashboard_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Dashboard_Error'
      security:
        - JWT: []
      tags:
        - Dashboard_Projects
      x-destination:
        - cloud
        - private-cloud
      x-docs-callouts:
        - private-cloud-warning
      x-eov-operation-handler: routes/invoices/getInvoice
  /dashboard/api/v1/organizations/{organizationSlug}/invoices/{date}/totals:
    get:
      operationId: getInvoiceTotals
      summary: Get Invoice Dates
      description: '<a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>'
      parameters:
        - name: organizationSlug
          in: path
          required: true
          schema:
            type: string
        - name: date
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Returns the dates of the invoices including current month
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Dashboard_InvoiceTotalsResponse'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Dashboard_Error'
        '404':
          description: Project not found or organization not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Dashboard_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Dashboard_Error'
      security:
        - JWT: []
      tags:
        - Dashboard_Projects
      x-destination:
        - cloud
        - private-cloud
      x-docs-callouts:
        - private-cloud-warning
      x-eov-operation-handler: routes/invoices/getInvoiceTotals
  /dashboard/api/v1/organizations/{organizationSlug}/invoices/history:
    get:
      operationId: getInvoiceHistory
      summary: Get Invoice History
      description: '<a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>'
      parameters:
        - name: organizationSlug
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Invoice history
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Dashboard_Invoice'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Dashboard_Error'
        '404':
          description: Project not found or organization not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Dashboard_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Dashboard_Error'
      security:
        - JWT: []
      tags:
        - Dashboard_Projects
      x-destination:
        - cloud
        - private-cloud
      x-docs-callouts:
        - private-cloud-warning
      x-eov-operation-handler: routes/invoices/getInvoiceHistory
  /dashboard/api/v1/organizations/{organizationSlug}/invoices/download-all:
    get:
      operationId: downloadAllInvoices
      summary: Download All Invoices
      description: '<a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>'
      parameters:
        - name: organizationSlug
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Invoice history
          content:
            application/zip:
              schema:
                $ref: '#/components/schemas/Dashboard_Binary'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Dashboard_Error'
        '404':
          description: Project not found or organization not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Dashboard_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Dashboard_Error'
      security:
        - JWT: []
      tags:
        - Dashboard_Projects
      x-destination:
        - cloud
        - private-cloud
      x-docs-callouts:
        - private-cloud-warning
      x-eov-operation-handler: routes/invoices/downloadAllInvoices
  /dashboard/api/v1/organizations/{organizationSlug}/projects/{projectId}/issuers:
    get:
      operationId: getExternalIssuer
      summary: External Issuer Handler
      description: '<a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>'
      parameters:
        - name: organizationSlug
          in: path
          description: Slug of the organization
          required: true
          schema:
            type: string
        - name: projectId
          in: path
          description: The ID of the project
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Success response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Dashboard_Issuer'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Dashboard_Error'
        '404':
          description: Not Found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Dashboard_Error'
      security:
        - JWT: []
      tags:
        - Dashboard_External Issuer
      x-destination:
        - cloud
        - private-cloud
      x-docs-callouts:
        - private-cloud-warning
      x-eov-operation-handler: routes/externalIssuers/getExternalIssuer
    post:
      operationId: createExternalIssuer
      summary: External Issuer Handler
      description: '<a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>'
      parameters:
        - name: organizationSlug
          in: path
          description: Slug of the organization
          required: true
          schema:
            type: string
        - name: projectId
          in: path
          description: The ID of the project
          required: true
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Dashboard_IssuerBody'
      responses:
        '204':
          description: Success response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Dashboard_Issuer'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Dashboard_Error'
        '404':
          description: Not Found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Dashboard_Error'
      security:
        - JWT: []
      tags:
        - Dashboard_External Issuer
      x-destination:
        - cloud
        - private-cloud
      x-docs-callouts:
        - private-cloud-warning
      x-eov-operation-handler: routes/externalIssuers/createExternalIssuer
  /events/v2/config:
    x-destination:
      - cloud
      - private-cloud
    get:
      operationId: GetConfig
      summary: Get Events Config
      description: |-
        Get configured events config 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      responses:
        '200':
          description: Returns all registerd project configs
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Events_EventsDefinitions'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Events_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Events_Project
      x-docs-callouts:
        - private-cloud-warning
  /events/v2/webhook:
    x-destination:
      - cloud
      - private-cloud
    get:
      operationId: GetAllWebhooks
      summary: Get All Webhooks
      description: |-
        Get all configured webhooks 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      responses:
        '200':
          description: Returns all configured webhooks webhook on success
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Events_Webhook'
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Events_Error'
        '404':
          description: Not Found Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Events_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Events_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Events_Webhook
      x-docs-callouts:
        - private-cloud-warning
  /events/v2/webhook/{name}:
    x-destination:
      - cloud
      - private-cloud
    parameters:
      - $ref: '#/components/parameters/Events_nameParam'
    get:
      operationId: GetWebhook
      summary: Get Webhook
      description: |-
        Get the specified webhook 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      responses:
        '200':
          description: Returns the specified webhook on success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Events_Webhook'
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Events_Error'
        '404':
          description: Not Found Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Events_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Events_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Events_Webhook
      x-docs-callouts:
        - private-cloud-warning
    delete:
      operationId: DeleteWebhook
      summary: Delete Webhook
      description: |-
        Delete the specific webhook 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      responses:
        '200':
          description: Returns the deleted webhook on success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Events_Webhook'
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Events_Error'
        '404':
          description: Not Found Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Events_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Events_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Events_Webhook
      x-docs-callouts:
        - private-cloud-warning
    put:
      operationId: CookWebhook
      summary: Prepare Webhook
      description: '<a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Events_Webhook'
      responses:
        '200':
          description: Returns on success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Events_Webhook'
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Events_Error'
        '404':
          description: Not Found Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Events_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Events_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Events_Webhook
      x-docs-callouts:
        - private-cloud-warning
  /events/v2/history/webhooks/{name}:
    x-destination:
      - cloud
      - private-cloud
    parameters:
      - $ref: '#/components/parameters/Events_nameParam'
      - $ref: '#/components/parameters/Events_eventQuery'
      - $ref: '#/components/parameters/Events_fromQuery'
      - $ref: '#/components/parameters/Events_toQuery'
      - $ref: '#/components/parameters/Events_limitQuery'
      - $ref: '#/components/parameters/Events_offsetQuery'
      - $ref: '#/components/parameters/Events_responseCodeQuery'
      - $ref: '#/components/parameters/Events_minAttemptsQuery'
      - $ref: '#/components/parameters/Events_statusQuery'
    get:
      operationId: QueryEvents
      summary: Past Events
      description: |-
        Search handled events by specified params 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      responses:
        '200':
          description: Returns on success
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Events_DestinationEvent'
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Events_Error'
        '404':
          description: Not Found Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Events_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Events_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Events_History
      x-docs-callouts:
        - private-cloud-warning
  /events/v2/history:
    x-destination:
      - cloud
      - private-cloud
    parameters:
      - $ref: '#/components/parameters/Events_eventQuery'
      - $ref: '#/components/parameters/Events_fromQuery'
      - $ref: '#/components/parameters/Events_toQuery'
      - $ref: '#/components/parameters/Events_limitQuery'
      - $ref: '#/components/parameters/Events_offsetQuery'
      - $ref: '#/components/parameters/Events_responseCodeQuery'
      - $ref: '#/components/parameters/Events_minAttemptsQuery'
      - $ref: '#/components/parameters/Events_statusQuery'
    get:
      operationId: QueryAllEvents
      summary: All Past Events
      description: |-
        Search handled events across all webhooks 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      responses:
        '200':
          description: Returns on success
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Events_DestinationEvent'
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Events_Error'
        '404':
          description: Not Found Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Events_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Events_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Events_History
      x-docs-callouts:
        - private-cloud-warning
  /events/v2/events/sync:
    x-destination:
      - cloud
      - private-cloud
    post:
      operationId: TriggerEventSync
      summary: Trigger Event Sync
      description: |-
        Trigger specified event synchronously 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Events_SourceEvent'
        x-go-type-skip-optional-pointer: true
      responses:
        '200':
          description: Returns on success
          content:
            '*':
              schema:
                type: string
                format: binary
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Events_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Events_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Events_Event
      x-docs-callouts:
        - private-cloud-warning
  /events/v2/events:
    x-destination:
      - cloud
      - private-cloud
    post:
      operationId: TriggerEvent
      summary: Trigger Event
      description: |-
        Trigger specified event 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Events_SourceEvent'
      responses:
        '204':
          description: Returns on success
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Events_Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Events_Error'
      security:
        - JWT:
            - aud:internal-account,service-account
            - roles:internal-account,service-account
      tags:
        - Events_Event
      x-docs-callouts:
        - private-cloud-warning
  /manifest/live/{streamKey}:
    x-destination:
      - cloud
      - private-cloud
    get:
      summary: Get Media Player Manifest
      description: |-
        Retrieve the media player manifest including various formats and encodings. This endpoint is also available with a `.json` suffix 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      parameters:
        - name: streamKey
          in: path
          description: The unique key identifying the stream.
          required: true
          schema:
            type: string
        - name: accessToken
          in: query
          description: Optional access token for authorization.
          required: false
          schema:
            type: string
      responses:
        '200':
          description: Successful response with media manifest
          content:
            application/json:
              schema:
                type: object
                properties:
                  self:
                    description: URL to the manifest itself
                    type: string
                    format: uri
                  formats:
                    type: object
                    properties:
                      mp4-hls:
                        type: object
                        properties:
                          manifest:
                            description: URL to the HLS manifest
                            type: string
                            format: uri
                          videoCodec:
                            description: Video codec used
                            type: string
                          audioCodec:
                            description: Audio codec used
                            type: string
                          encodings:
                            type: array
                            items:
                              type: object
                              properties:
                                videoWidth:
                                  description: Video width in pixels
                                  type: integer
                                videoHeight:
                                  description: Video height in pixels
                                  type: integer
                                videoKbps:
                                  description: Video bitrate in Kbps
                                  type: integer
                                audioKbps:
                                  description: Audio bitrate in Kbps
                                  type: integer
                                videoPts:
                                  description: Video presentation timestamp
                                  type: integer
                                audioPts:
                                  description: Audio presentation timestamp
                                  type: integer
                                collected:
                                  description: Timestamp when the data was collected
                                  type: integer
                                location:
                                  description: URL to the specific encoding
                                  type: string
                                  format: uri
                      jpeg:
                        type: object
                        properties:
                          encodings:
                            type: array
                            items:
                              type: object
                              properties:
                                videoWidth:
                                  description: Image width in pixels
                                  type: integer
                                videoHeight:
                                  description: Image height in pixels
                                  type: integer
                                location:
                                  description: URL to the JPEG image
                                  type: string
                                  format: uri
                      webrtc:
                        type: object
                        properties:
                          origin:
                            type: object
                            properties:
                              token:
                                description: Access token for WebRTC
                                type: string
                              rsrc:
                                description: Resource identifier
                                type: string
                              location:
                                description: URL to the WebRTC call join endpoint
                                type: string
                                format: uri
                              callId:
                                description: Unique call identifier
                                type: string
                              peerId:
                                description: Peer identifier
                                type: string
                              streamNames:
                                type: array
                                items:
                                  type: string
                                  description: Names of the streams
                              publicKey:
                                description: Public key associated with the stream
                                type: string
                              uri:
                                description: WebSocket URI for WebRTC connection
                                type: string
                                format: uri
                              httpUri:
                                description: HTTP URI for WebRTC connection
                                type: string
                                format: uri
                              region:
                                description: Region of the WebRTC server
                                type: string
                              version:
                                description: Version of the WebRTC protocol
                                type: integer
                              turn:
                                type: object
                                properties:
                                  servers:
                                    type: array
                                    items:
                                      type: object
                                      properties:
                                        urls:
                                          type: array
                                          items:
                                            type: string
                                            format: uri
                                            description: TURN server URL
                                        username:
                                          description: Username for TURN server authentication
                                          type: string
                                        credential:
                                          description: Credential for TURN server authentication
                                          type: string
                                        credentialType:
                                          description: Type of credential (e.g., password)
                                          type: string
                  atr:
                    description: Assigned transcode region
                    type: string
                  aor:
                    description: Assigned origin region
                    type: string
                  abr:
                    description: Assigned order region
                    type: string
                  rep:
                    description: Replication status
                    type: boolean
                  clientEncoder:
                    description: Information about the client encoder
                    type: string
        '404':
          description: Not Found - The specified stream key is offline.
        '500':
          description: Internal Server Error - A server error occurred.
      tags:
        - Playback_Manifest
      x-docs-callouts:
        - private-cloud-warning
  /manifest/live/{streamKey}/viewers:
    x-destination:
      - cloud
      - private-cloud
    get:
      summary: Get Viewer Count
      description: |-
        Retrieve the current viewer count for the stream identified by the stream key. 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      parameters:
        - name: streamKey
          in: path
          description: The unique key identifying the stream.
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Successful response with viewer count
          content:
            application/json:
              schema:
                type: object
                properties:
                  viewCount:
                    description: The number of current viewers
                    type: integer
        '404':
          description: Not Found - The specified stream key is offline.
        '500':
          description: Internal Server Error - A server error occurred.
      tags:
        - Playback_Manifest
      x-docs-callouts:
        - private-cloud-warning
  /manifest/state/{streamKey}:
    x-destination:
      - cloud
      - private-cloud
    get:
      summary: Get Stream State
      description: |-
        Retrieve the current state of the stream identified by the stream key. 
                    
        <a href="https://platform.nativeframe.com/generate-jwt" target="_blank" style={{{{display: "inline-block", padding: "0.5rem 2rem", backgroundColor: "#1e40af", color: "white", textAlign: "center", textDecoration: "none", borderRadius: "4px", fontSize: "16px", marginBottom: "2rem"}}}}>Generate JWT</a>
      parameters:
        - name: streamKey
          in: path
          description: The unique key identifying the stream.
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Successful response with stream state
          content:
            application/json:
              schema:
                type: object
                properties:
                  active:
                    description: Indicates if the stream is currently active
                    type: boolean
                  needAuth:
                    description: Indicates if the stream requires authentication
                    type: boolean
                  viewCount:
                    description: The number of current viewers
                    type: integer
        '404':
          description: Not Found - The specified stream key does not exist.
        '500':
          description: Internal Server Error - A server error occurred.
      tags:
        - Playback_Manifest
      x-docs-callouts:
        - private-cloud-warning
components:
  parameters:
    Events_eventQuery:
      in: query
      name: event
      required: false
      schema:
        type: string
    Events_fromQuery:
      in: query
      name: from
      required: false
      schema:
        description: From specified date in ISO-8601 format
        type: string
        format: date-time
    Events_limitQuery:
      in: query
      name: limit
      required: false
      schema:
        description: Limit of returned items
        type: integer
        default: 100
        maximum: 100
        minimum: 1
    Events_minAttemptsQuery:
      in: query
      name: minAttempts
      required: false
      schema:
        description: Minimum attempts
        type: integer
        minimum: 0
    Events_nameParam:
      in: path
      name: name
      required: true
      schema:
        type: string
        example: pvc-broadcast-events
        maxLength: 64
        minLength: 1
        pattern: ^[a-zA-Z0-9_-]+$
    Events_offsetQuery:
      in: query
      name: offset
      required: false
      schema:
        description: Offset of returned items
        type: integer
        default: 0
        minimum: 0
    Events_responseCodeQuery:
      in: query
      name: responseCode
      required: false
      schema:
        description: HTTP response code
        type: integer
        maximum: 599
        minimum: 100
    Events_statusQuery:
      in: query
      name: status
      required: false
      schema:
        description: Current status of this task
        type: string
        enum:
          - NEW
          - IN_PROCESS
          - DELIVERED
          - CANCELED
          - FAILED
    Events_toQuery:
      in: query
      name: to
      required: false
      schema:
        description: To specified date in ISO-8601 format
        type: string
        format: date-time
    Program_LimitParam:
      name: limit
      in: query
      description: Limit
      required: false
      schema:
        type: integer
        x-go-type-skip-optional-pointer: false
    Program_PageParam:
      name: page
      in: query
      description: Page number
      required: false
      schema:
        type: integer
        x-go-type-skip-optional-pointer: false
  schemas:
    Program_ProgramInput:
      description: |-
        #ProgramInput is the create/update request body — the client-suppliable fields
        only, so the server-computed fields on #Program (streamCount, liveStreamCount)
        are NOT demanded on input. Keep the shared fields in sync with #Program below.
        (Defined separately rather than via a shared base: CUE's openapi encoder panics
        on hidden-field references, and `&`-extending a closed #def is disallowed.)
      type: object
      properties:
        id:
          type: string
        projectID:
          type: string
        programName:
          type: string
        programSlug:
          type: string
        clientReferrer:
          type: string
        defaultComposition:
          type: string
        mode:
          type: string
        createdBy:
          type: string
        updatedBy:
          type: string
        createdOn:
          type: string
        updatedOn:
          type: string
        locked:
          description: Whether the project is locked (prevents certain operations)
          type: boolean
      required:
        - programSlug
    Program_Program:
      type: object
      properties:
        id:
          type: string
        projectID:
          type: string
        programName:
          type: string
        programSlug:
          type: string
        clientReferrer:
          type: string
        defaultComposition:
          type: string
        mode:
          type: string
        createdBy:
          type: string
        updatedBy:
          type: string
        createdOn:
          type: string
        updatedOn:
          type: string
        locked:
          description: Whether the project is locked (prevents certain operations)
          type: boolean
        streamCount:
          description: |-
            Count of streams under this program. Always present (zero is a
            meaningful answer). Computed from `streams.program_id = programs.id`.
          type: integer
        liveStreamCount:
          description: |-
            Count of streams under this program that are currently broadcasting
            (have an open `stream_sessions` row). V1-mode streams are excluded.
            `liveStreamCount <= streamCount` always.
          type: integer
      required:
        - programSlug
        - streamCount
        - liveStreamCount
    Program_Error:
      type: object
      properties:
        message:
          description: Error message for the end user
          type: string
        errorCode:
          description: Code that can be set that supplies a specific reason for why a request failed
          type: string
        invalidFields:
          description: Specific error scoped to a field
          type: array
          items:
            $ref: '#/components/schemas/Program_InvalidField'
        internal:
          description: Internal user only
          type: string
      required:
        - message
      x-go-type: apperrors.Error
      x-go-type-import:
        path: github.com/LivelyVideo/service-definitions/errors
        name: apperrors
    Program_InvalidField:
      type: object
      properties:
        name:
          type: string
        reason:
          type: string
        errorCode:
          type: string
      required:
        - name
        - reason
      x-go-type: apperrors.InvalidField
      x-go-type-import:
        path: github.com/LivelyVideo/service-definitions/errors
        name: apperrors
    Program_StreamsResponse:
      type: object
      properties:
        streams:
          type: array
          items:
            $ref: '#/components/schemas/Program_StreamResponse'
        totalCount:
          type: integer
    Program_CreateStreamRequest:
      type: object
      properties:
        authKey:
          type: string
        streamName:
          type: string
        authType:
          $ref: '#/components/schemas/Program_AuthType'
        transcode:
          type: boolean
        deleteExisting:
          type: boolean
        allowAppDataOverride:
          type: boolean
      required:
        - authKey
        - streamName
    Program_StreamResponse:
      type: object
      properties:
        id:
          type: string
        programId:
          type: string
        streamName:
          type: string
        ingress:
          $ref: '#/components/schemas/Program_Ingress'
        manifestUrl:
          type: string
        streamKey:
          type: string
        authKey:
          type: string
        active:
          type: boolean
        transcode:
          type: boolean
        authType:
          $ref: '#/components/schemas/Program_AuthType'
        appData:
          description: The app data
          type: string
          example: '{"foo":"bar"}'
        rtmpPush:
          description: |-
            Configured RTMP push destinations. Empty when none configured.
            `key` is returned as-is on reads.
          type: array
          items:
            $ref: '#/components/schemas/Program_RtmpPushDestination'
          example: '{"enabled":true,"destinations":[{"name":"foo","enabled":true,"platform":"youtube","rtmpUrl":"rtmp://a.rtmp.youtube.com/live2","streamKey":"key"}]}'
        mode:
          description: Stream mode (e.g., "vf" for video foundation)
          type: string
        kind:
          description: |-
            Stream role. `source` is a normal ingest stream; `filtergraph` is a
            derived stream produced by composition (e.g. an overlay applied to a
            source). Defaults to `source` for streams created without an explicit
            kind.
          type: string
          enum:
            - source
            - filtergraph
        derivedFromId:
          description: |-
            derivedFromId is the streamId of the source this stream is derived
            from when kind != "source". Absent or empty for source streams.
          type: string
        vfIngress:
          $ref: '#/components/schemas/Program_Ingress'
        vfManifestUrl:
          description: Video Foundation manifest URL
          type: string
        createdOn:
          description: |-
            Timestamp the stream row was created in the program service (RFC3339).
            Sourced from `streams.created_on`. Omitted on the rare legacy row
            with no recorded creation time.
          type: string
        lastLiveAt:
          description: |-
            The most recent moment this stream was live (RFC3339). For a stream
            currently broadcasting, this is `now()`; for an ended broadcast it
            is the most recent `stream_sessions.end`. Omitted if the stream has
            never had a `stream_sessions` row, or for V1-mode streams (V1 has a
            different liveness model not surfaced here).
          type: string
        currentLiveSince:
          description: |-
            The `start` timestamp of the stream's currently-open `stream_sessions`
            row, if any (RFC3339). Omitted if the stream is not currently
            broadcasting, or for V1-mode streams.
          type: string
    Program_CreateStreamRequestV2:
      type: object
      properties:
        streamName:
          type: string
        streamID:
          type: string
        appData:
          type: string
        transcode:
          type: boolean
        authKey:
          type: string
        authType:
          $ref: '#/components/schemas/Program_AuthType'
        programID:
          type: string
        programSlug:
          type: string
        mode:
          description: Stream mode (e.g., "vf" for video foundation)
          type: string
        rtmpPush:
          description: |-
            Optional create-time push destinations. Each entry sets its own
            `enabled` flag explicitly; the dedicated PATCH endpoint accepts the
            same shape post-create. Maximum 10 destinations enforced at the
            application layer.
          type: array
          items:
            $ref: '#/components/schemas/Program_RtmpPushDestination'
        kind:
          description: |-
            Stream role. `source` is a normal ingest stream; `filtergraph` is a
            derived stream produced by composition (e.g. an overlay applied to a
            source). When omitted, defaults to `source`.
          type: string
          enum:
            - source
            - filtergraph
        derivedFromId:
          description: |-
            derivedFromId is the streamId of the source this stream is derived
            from. REQUIRED when kind is `filtergraph`; MUST be empty when kind
            is `source`. The referenced source stream must exist in the same
            project.
          type: string
    Program_StreamResponseV2:
      type: object
      properties:
        appData:
          description: The app data
          type: string
          example: '{"foo":"bar"}'
      allOf:
        - $ref: '#/components/schemas/Program_StreamResponse'
    Program_UpdateStreamRequest:
      type: object
      properties:
        authKey:
          type: string
        streamName:
          type: string
        authType:
          $ref: '#/components/schemas/Program_AuthType'
        transcode:
          type: boolean
      required:
        - authKey
        - streamName
        - authType
        - transcode
    Program_UpdateStreamRequestV2:
      type: object
      properties:
        authKey:
          type: string
        streamName:
          type: string
        authType:
          $ref: '#/components/schemas/Program_AuthType'
        transcode:
          type: boolean
        appData:
          description: The app data
          type: string
          example: '{"foo":"bar"}'
        mode:
          description: Stream mode (e.g., "vf" for video foundation)
          type: string
        rtmpPush:
          example: '{"enabled":true,"destinations":[{"name":"foo","enabled":true,"platform":"youtube","rtmpUrl":"rtmp://a.rtmp.youtube.com/live2","streamKey":"key"}]}'
      required:
        - authKey
        - streamName
        - authType
        - transcode
    Program_UpdateRtmpPushEnabledRequest:
      description: |-
        Declarative reconcile: server upserts every entry in `destinations` with
        the `enabled` value carried on each row, and deletes any stored
        destination not present in the request. Idempotent — repeating the same
        payload produces the same state.

        Each row's `enabled` flag is independent, so a single PATCH can express
        any combination of enabled/disabled destinations.

        Note: changes apply on next stream connect; mid-stream toggling does
        NOT affect a running push (no side-channel to media in this milestone).

        Maximum 10 destinations enforced at the application layer.
      type: object
      properties:
        destinations:
          description: |-
            Full set of push destinations to reconcile against stored state. Each
            entry's `enabled` value is applied as-is.
          type: array
          items:
            $ref: '#/components/schemas/Program_RtmpPushDestination'
      required:
        - destinations
    Program_UpdateRtmpPushEnabledResponse:
      type: object
      properties:
        message:
          description: Status message
          type: string
        rtmpPush:
          description: The reconciled set of destinations. Reflects post-reconcile state.
          type: array
          items:
            $ref: '#/components/schemas/Program_RtmpPushDestination'
    Program_SnapshotRuleResponse:
      type: object
      properties:
        id:
          description: ID of the snapshot rule row.
          type: string
        streamId:
          description: ID of the stream the rule applies to.
          type: string
        projectId:
          description: ID of the project owning the stream.
          type: string
        maxDurSec:
          description: Clip length in seconds.
          type: integer
        intervalSec:
          description: |-
            Capture cadence in seconds. Omitted when the rule has no explicit
            cadence (platform default applies).
          type: integer
        backfillSec:
          description: |-
            Seconds of pre-trigger content read backwards from the live buffer.
            Omitted when zero.
          type: integer
        minDurSec:
          description: |-
            Minimum clip length kept when the stream ends early. Reflects the
            applied default (= maxDurSec) when the caller omitted it.
          type: integer
        formats:
          description: |-
            Rendition selectors. Empty when the rule falls back to the project's
            archiving formats.
          type: array
          items:
            type: string
        oneShot:
          description: One-shot mode flag, echoed from create.
          type: boolean
        expiresAt:
          description: |-
            When a one-shot rule stops being surfaced to orchestration
            (RFC3339). Absent for recurring rules. An expired rule still
            reads via GET until deleted.
          type: string
        createdAt:
          description: Timestamp the rule was created (RFC3339).
          type: string
        updatedAt:
          description: Timestamp the rule was last updated (RFC3339).
          type: string
      required:
        - id
        - streamId
        - projectId
        - maxDurSec
        - minDurSec
    Program_SnapshotRuleRequest:
      description: |-
        Per-stream snapshot rule (VIDEO-206 / milestone-4). The integrator-facing
        contract is deliberately thin: capture parameters only. The server builds
        the full archiver rule (driver, post-process commands, S3 destination from
        the project's archiving config) when surfacing the rule to orchestration
        in ping responses — integrators never see or control those.
      type: object
      properties:
        maxDurSec:
          description: Clip length in seconds.
          type: integer
        intervalSec:
          description: |-
            Capture cadence in seconds — "a maxDurSec-second clip every
            intervalSec seconds" while the stream is live. Optional: when
            omitted, the platform's default snapshot cadence applies (currently
            60 seconds); dedicated one-shot trigger semantics are planned.
          type: integer
        backfillSec:
          description: |-
            Seconds of pre-trigger content to read backwards from the live
            buffer ("clip the LAST n seconds"). Optional; 0/omitted captures
            forward from task start. Accuracy is keyframe-bound and the
            practical maximum depends on the source's buffer sizing — reliable
            on transcoded streams.
          type: integer
        minDurSec:
          description: |-
            Minimum clip length in seconds to keep when the stream ends before a
            full clip accumulated. Defaults to maxDurSec (partial clips are
            discarded) when omitted.
          type: integer
        formats:
          description: |-
            Rendition (bitrate) selectors, e.g. ["2300"]. Not container formats —
            output container is MP4. Defaults to the project's archiving formats
            when omitted.
          type: array
          items:
            type: string
        oneShot:
          description: |-
            One-shot mode: capture exactly one clip, then the rule expires
            server-side (stops being surfaced to orchestration) after
            maxDurSec seconds — the ICF-proven pattern. Mutually exclusive
            with intervalSec (400 invalid_interval when both are set); the
            server forces the one-shot interval itself.
          type: boolean
      required:
        - maxDurSec
    Program_StorageObjectListResponse:
      description: |-
        #StorageObjectListResponse is a paginated page of managed objects for a
        surface (M6 Task 012). `nextCursor` is absent on the last page.
      type: object
      properties:
        objects:
          type: array
          items:
            $ref: '#/components/schemas/Program_StorageObject'
        nextCursor:
          type: string
      required:
        - objects
    Program_StorageProfileListResponse:
      description: |-
        List of the project's storage profiles across all configured
        surfaces (M6 Task 003). Unconfigured surfaces are omitted.
        Credentials are never included (same redaction as the single GET).
      type: object
      properties:
        profiles:
          type: array
          items:
            $ref: '#/components/schemas/Program_StorageProfileResponse'
      required:
        - profiles
    Program_StorageProfileResponse:
      description: |-
        Per-(project, surface) storage profile (milestone-5 / §6 convergence).
        Surfaces: "archive" | "assets" | "snapshots" | "clips". Each can be
        "managed" (NF-provisioned per-tenant Backblaze B2) or "byo"
        (customer-supplied destination + credentials).
      type: object
      properties:
        projectId:
          description: UUID of the project.
          type: string
        surface:
          description: Storage surface this profile configures.
          type: string
          enum:
            - archive
            - assets
            - snapshots
            - clips
        mode:
          description: |-
            "managed" — NF-provisioned per-tenant Backblaze B2.
            "byo"     — customer-supplied destination + credentials.
          type: string
          enum:
            - managed
            - byo
        status:
          description: |-
            Provisioning lifecycle. BYO profiles are "ready" immediately
            (no partner-API provisioning step).
          type: string
          enum:
            - provisioning
            - ready
            - failed
            - tearing_down
        provider:
          description: |-
            Destination summary. Never includes credentials — secrets live in
            Vault and only ride the orchestration ping payload.
          type: string
        bucketName:
          type: string
        region:
          type: string
        endpoint:
          type: string
        publicUrlBase:
          description: |-
            For a BYO `assets` profile: the public URL base new uploads inherit
            when they omit an explicit per-upload publicUrl (M6 Task 009).
          type: string
        statusError:
          description: Error message from the last failed provisioning attempt.
          type: string
        createdAt:
          type: string
        updatedAt:
          type: string
      required:
        - projectId
        - surface
        - mode
        - status
    Program_SetStorageProfileRequest:
      description: |-
        PUT body. mode=managed provisions lazily (first call may take a few
        seconds, mirroring managed assets). mode=byo records the supplied
        destination with no partner-API call; the destination is required
        when mode=byo and ignored for managed.
      type: object
      properties:
        mode:
          type: string
          enum:
            - managed
            - byo
        destination:
          $ref: '#/components/schemas/Program_StorageDestination'
      required:
        - mode
    Program_DownloadKeyResponse:
      description: |-
        #DownloadKeyResponse is a freshly-minted, bucket-scoped, READ-ONLY
        Backblaze application key for programmatic tenant access to managed
        storage (M6 Task 014). `applicationKey` is shown ONCE (B2/AWS
        semantics — not retrievable later). The per-tenant member MASTER key
        is never returned.
      type: object
      properties:
        keyId:
          type: string
        applicationKey:
          type: string
        bucketName:
          type: string
        s3Endpoint:
          type: string
        region:
          type: string
        expiresAt:
          type: string
      required:
        - keyId
        - applicationKey
        - bucketName
        - s3Endpoint
        - region
    Program_BulkUpdateRtmpPushRequest:
      description: |-
        Atomic multi-stream reconcile request. All entries are applied in a
        single transaction; either every per-stream reconcile commits or none do.
        The cross-stream sibling-collision check (`(type, key)` uniqueness within
        a source/derivation family) is evaluated against the FINAL state described
        by the request — so a "clear A, set B" flip-flop succeeds in one call.
      type: object
      properties:
        streams:
          description: |-
            One entry per target stream. Must be non-empty; streamIDs must be
            unique within the request.
          type: array
          items:
            $ref: '#/components/schemas/Program_BulkUpdateRtmpPushEntry'
      required:
        - streams
    Program_BulkUpdateRtmpPushResponse:
      type: object
      properties:
        streams:
          description: Per-stream results, one per entry in the request.
          type: array
          items:
            $ref: '#/components/schemas/Program_BulkUpdateRtmpPushResultEntry'
      required:
        - streams
    Program_StreamSessionResponse:
      type: object
      properties:
        streamSessionID:
          description: The unique ID of the stream session
          type: string
        streamID:
          description: The stream ID
          type: string
        sessionID:
          description: The parent session ID
          type: string
        sourceType:
          description: The source type (rtmp or rtp)
          type: string
        start:
          description: When the session started
          type: string
          format: date-time
        end:
          description: When the session ended (RFC3339). Omitted while the session is open.
          type: string
        durationSeconds:
          description: |-
            Duration of the session in seconds. For an open session, computed
            from `start` to the server's current time.
          type: integer
        closedByCleanup:
          description: |-
            True when the session was closed by the 24h cleanup janitor rather
            than the normal end-session lifecycle. Durations near 86400 may be
            janitor artifacts; callers can exclude such sessions from totals
            via the `excludeCleanupArtifacts` query param on summary endpoints.
          type: boolean
      required:
        - streamSessionID
        - streamID
        - sessionID
    Program_StreamSessionsListResponse:
      description: Paginated list response for stream sessions.
      type: object
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/Program_StreamSessionResponse'
        totalCount:
          type: integer
        page:
          type: integer
        limit:
          type: integer
    Program_StreamSessionsSummaryResponse:
      description: |-
        Per-stream aggregation over `stream_sessions` within a window. All
        durations are clipped to the window so they sum coherently. For an
        open session, `end` is treated as `now()` for clipping purposes.
      type: object
      properties:
        totalSeconds:
          type: integer
        sessionCount:
          type: integer
        longestSeconds:
          type: integer
        shortestSeconds:
          type: integer
        firstStartedAt:
          type: string
        lastEndedAt:
          type: string
        cleanupArtifactSessionCount:
          description: |-
            Count of sessions in the window that were closed by the 24h cleanup
            janitor. Always present; informs whether the totals may be inflated.
            0 when the summary excluded artifacts.
          type: integer
      required:
        - totalSeconds
        - sessionCount
        - longestSeconds
        - shortestSeconds
        - cleanupArtifactSessionCount
    Program_ProjectStreamSessionsSummaryResponse:
      description: Project-wide aggregation over `stream_sessions`. Same clipping rules.
      type: object
      properties:
        totalSeconds:
          type: integer
        sessionCount:
          type: integer
        distinctStreamCount:
          type: integer
        distinctProgramCount:
          type: integer
        firstStartedAt:
          type: string
        lastEndedAt:
          type: string
        cleanupArtifactSessionCount:
          description: Same semantics as the per-stream summary; always present.
          type: integer
      required:
        - totalSeconds
        - sessionCount
        - distinctStreamCount
        - distinctProgramCount
        - cleanupArtifactSessionCount
    Program_ConcurrentPeakResponse:
      description: |-
        Peak concurrency aggregation. `peak` is the maximum number of
        simultaneously-open stream_sessions in the window; `peakAt` is the
        first instant the peak was reached.
      type: object
      properties:
        peak:
          type: integer
        peakAt:
          type: string
        totalSessionCount:
          type: integer
      required:
        - peak
        - totalSessionCount
    Program_ProgramsResponse:
      type: object
      properties:
        programs:
          type: array
          items:
            $ref: '#/components/schemas/Program_Program'
        totalCount:
          type: integer
    Program_CreateProgramRequestV2:
      type: object
      properties:
        programName:
          type: string
        programSlug:
          type: string
        clientReferrer:
          type: string
        defaultComposition:
          type: string
        mode:
          type: string
      required:
        - programName
        - programSlug
    Program_JoinSessionResponse:
      type: object
      properties:
        sessionID:
          description: The session ID
          type: string
          example: aec387b2-5588-438d-a423-d9b5be602ed5
        details:
          description: JSON data for the session
          type: string
          example: '{"foo":"bar"}'
    Program_EndSessionRequest:
      type: object
      properties:
        sessionID:
          description: The session ID to end
          type: string
          example: aec387b2-5588-438d-a423-d9b5be602ed5
      required:
        - sessionID
    Program_ArchivingConfig:
      type: object
      properties:
        provider:
          description: Name of the storage provider
          type: string
          example: AWS S3
        id:
          description: ID of the archiving config
          type: string
          example: aec387b2-5588-438d-a423-d9b5be602ed5
        projectId:
          description: ID of the project
          type: string
          example: aec387b2-5588-438d-a423-d9b5be602ed5
        formats:
          description: Formats to archive
          type: array
          items:
            type: string
          example:
            - mp4
            - hls
        fileType:
          description: File type to archive
          type: string
          example: mp4
        path:
          description: Path to archive
          type: string
          example: s3://my-bucket/my-path
        pathTemplate:
          $ref: '#/components/schemas/Program_PathTemplate'
        s3Bucket:
          description: S3 bucket to archive
          type: string
          example: my-bucket
        s3AccessKeyId:
          description: S3 access key ID. Always returned in full in responses.
          type: string
          example: my-access-key-id
        s3SecretKey:
          description: 'S3 secret key. Write-only: never returned in GET responses (always empty string). On upsert, an empty string preserves the existing secret key; a non-empty value replaces it.'
          type: string
          example: my-secret-key
        s3Region:
          description: S3 region
          type: string
          example: us-east-1
        s3Url:
          description: S3 URL
          type: string
          example: https://s3.amazonaws.com
        continuousUploadIndex:
          description: Whether to continuously upload archive segment indexes. Defaults to true.
          type: boolean
        s3BaseUrl:
          description: |-
            Public HTTP/CDN base URL from which archived m3u8s and segments are
            served. Required for liveDvr (used to form the playback URL written into
            manifest.json). Distinct from s3Url (the upload endpoint).
          type: string
        liveDvr:
          description: |-
            Enable live-DVR: inject a link to the archive master.m3u8 into the live
            manifest.json so the player can rewind into the archive. Only valid when
            s3BaseUrl is set.
          type: boolean
      required:
        - provider
        - projectId
        - formats
        - fileType
        - path
        - s3Bucket
        - s3AccessKeyId
        - s3SecretKey
        - s3Region
        - continuousUploadIndex
    Program_ArchiveAssetMetadata:
      description: |
        Metadata about an archive-asset write, returned when the request sets `response=metadata`. Shared shape across the HLS playlist and thumbnail endpoints; format-specific extras sit under the `hls`/`image` sub-objects.
      type: object
      properties:
        s3Bucket:
          description: S3 bucket the asset was written to.
          type: string
        s3ObjectKey:
          description: Object key within the bucket. Named to avoid confusion with credential fields.
          type: string
          example: thumbs/stream1/thumb1777204805250.jpg
        s3Uri:
          description: Canonical `s3://bucket/key` URI.
          type: string
          example: s3://my-bucket/thumbs/stream1/thumb1777204805250.jpg
        contentType:
          description: MIME type of the uploaded asset.
          type: string
          example: image/jpeg
        bytes:
          description: Size of the uploaded asset in bytes.
          type: integer
          format: int64
        etag:
          description: |
            S3 ETag from the PutObject response. Useful for cache validation (If-None-Match) and upload integrity checks.
          type: string
        playbackUrl:
          description: |
            Public HTTP(S) URL for the asset, constructed by joining the project's `s3BaseUrl` with the object key. Omitted when no playback URL is configured for the project.
          type: string
        image:
          $ref: '#/components/schemas/Program_ArchiveImageMetadata'
        hls:
          $ref: '#/components/schemas/Program_ArchiveHLSMetadata'
        mp4:
          $ref: '#/components/schemas/Program_ArchiveMP4Metadata'
      required:
        - s3Bucket
        - s3ObjectKey
        - s3Uri
        - contentType
        - bytes
    Program_ArchiveImageMetadata:
      description: Image-specific metadata, included for thumbnail responses.
      type: object
      properties:
        width:
          description: Actual width of the encoded image in pixels.
          type: integer
        height:
          description: Actual height of the encoded image in pixels.
          type: integer
        format:
          description: Image format that was encoded.
          type: string
          enum:
            - jpg
            - png
            - webp
      required:
        - width
        - height
        - format
    Program_ArchiveHLSMetadata:
      description: HLS-specific metadata, included for playlist responses.
      type: object
      properties:
        totalDurationSeconds:
          description: Sum of all segment durations in the merged playlist.
          type: number
          format: double
        sessionCount:
          description: Number of archive sessions merged into the playlist.
          type: integer
      required:
        - totalDurationSeconds
        - sessionCount
    Program_ArchiveMP4Metadata:
      description: MP4-specific metadata, included for MP4 clip responses.
      type: object
      properties:
        durationSeconds:
          description: |
            Actual duration of the produced MP4 clip in seconds. May be slightly longer than `end_datetime - start_datetime` due to the start-side keyframe snap (head-padding up to one keyframe interval, typically ~2 s). The end is frame-accurate at the requested `end_datetime`.
          type: number
          format: double
        width:
          description: Video width in pixels.
          type: integer
        height:
          description: Video height in pixels.
          type: integer
        fps:
          description: |
            Video frame rate (frames per second). Omitted when the source does not expose a stable frame rate.
          type: number
          format: double
        videoCodec:
          description: Video codec name (e.g. "h264").
          type: string
        audioCodec:
          description: Audio codec name (e.g. "aac").
          type: string
        bitrateKbps:
          description: Overall bitrate of the produced MP4 in kilobits per second.
          type: integer
      required:
        - durationSeconds
        - width
        - height
        - videoCodec
        - audioCodec
    Program_CDN:
      type: object
      properties:
        id:
          description: ID of the CDN
          type: string
          example: aec387b2-5588-438d-a423-d9b5be602ed5
        name:
          description: Name of the CDN
          type: string
          example: my-cdn
        projectId:
          description: ID of the project
          type: string
          example: aec387b2-5588-438d-a423-d9b5be602ed5
        url:
          description: URL of the CDN
          type: string
          example: https://cdn.example.com
      required:
        - projectId
        - url
    Program_AssetsResponse:
      description: AssetsResponse is the list shape returned by `GET /assets`.
      type: object
      properties:
        assets:
          type: array
          items:
            $ref: '#/components/schemas/Program_Asset'
      required:
        - assets
    Program_AssetResponse:
      description: |-
        AssetResponse wraps a single asset, used by POST/GET/PATCH/file-URL
        responses.
      type: object
      properties:
        asset:
          $ref: '#/components/schemas/Program_Asset'
      required:
        - asset
    Program_UpdateAssetRequest:
      description: |-
        UpdateAssetRequest is the PATCH body. Identity columns (id,
        projectId, storageMode, storageKey) are immutable post-create.
      type: object
      properties:
        type:
          description: |-
            Opaque render dispatch — caller can change without breaking
            existing assets since the media server interprets by type.
          type: string
        properties:
          description: Opaque properties blob — replaces the existing value.
          type: object
        publicUrl:
          description: |-
            BYO mode only — change which URL the asset points at. Triggers
            the same Q7 opportunistic HEAD as create.
          type: string
        contentType:
          description: Both modes — caller-supplied overrides for content metadata.
          type: string
        sizeBytes:
          type: integer
    Program_AssetStreamsResponse:
      description: |-
        AssetStreamsResponse is the reverse-lookup result for
        `GET /projects/{p}/assets/{id}/streams` — "which streams use this
        asset?". UUIDs of streams in attachment order.
      type: object
      properties:
        streamIds:
          type: array
          items:
            type: string
      required:
        - streamIds
    Program_StreamAssetsResponse:
      description: |-
        StreamAssetsResponse is the list shape returned by
        `GET /streams/{id}/assets` and `PUT /streams/{id}/assets`. The
        response is the post-mutation asset set so callers don't need a
        follow-up GET.
      type: object
      properties:
        assets:
          type: array
          items:
            $ref: '#/components/schemas/Program_Asset'
      required:
        - assets
    Program_ReconcileStreamAssetsRequest:
      description: |-
        ReconcileStreamAssetsRequest is the PUT body for declarative
        reconcile — replaces the stream's full attached set.
      type: object
      properties:
        assetIds:
          description: |-
            Asset ids to attach to the stream. Order does NOT determine
            render order (C9 — composition is the media server's concern;
            stream_assets carries no ordering).
          type: array
          items:
            type: string
      required:
        - assetIds
    Program_SearchStreamsRequest:
      description: Search criteria for streams (POST alternative to GET with query params)
      type: object
      properties:
        q:
          description: Search query, may include stream name or stream ID
          type: string
        active:
          description: Filter by active status
          type: boolean
        page:
          description: Page number (1-indexed)
          type: integer
        limit:
          description: Number of results per page
          type: integer
        programId:
          description: Filter by program ID
          type: string
        mode:
          description: Filter by stream mode (e.g., "vf", "v1")
          type: string
        authType:
          description: Filter by auth type (e.g., "public", "private")
          type: string
        createdAfter:
          description: Filter streams created on or after this time (RFC3339)
          type: string
        createdBefore:
          description: Filter streams created on or before this time (RFC3339)
          type: string
        userId:
          description: Filter by user ID
          type: string
        derivedFromId:
          description: |-
            Filter by source stream id — return only streams whose
            `derived_from_id` equals this value. Empty when not filtering.
          type: string
    Program_RTSPSourceResponse:
      type: object
      properties:
        id:
          description: Unique identifier for the RTSP source
          type: string
          format: uuid
          x-go-name: ID
          x-go-type-skip-optional-pointer: true
        streamID:
          description: ID of the associated stream
          type: string
          format: uuid
          x-go-type-skip-optional-pointer: true
        projectID:
          description: ID of the project
          type: string
          format: uuid
          x-go-type-skip-optional-pointer: true
        sourceUrl:
          description: RTSP source URL
          type: string
          x-go-type-skip-optional-pointer: true
        authType:
          $ref: '#/components/schemas/Program_RTSPAuthType'
        authUsername:
          description: Username for RTSP authentication (password is never returned)
          type: string
          x-go-type-skip-optional-pointer: true
        region:
          description: Preferred region for the RTSP broker
          type: string
          x-go-type-skip-optional-pointer: true
        status:
          $ref: '#/components/schemas/Program_RTSPSourceStatus'
        createdAt:
          description: When the RTSP source was created
          type: string
          format: date-time
          x-go-type-skip-optional-pointer: true
        updatedAt:
          description: When the RTSP source was last updated
          type: string
          format: date-time
          x-go-type-skip-optional-pointer: true
        viewable:
          description: Whether the pulled source is viewable by end-viewers in the manifest
          type: boolean
          x-go-type-skip-optional-pointer: false
    Program_RTSPAuthType:
      description: Authentication type for RTSP source
      type: string
      enum:
        - basic
        - digest
      x-go-type-skip-optional-pointer: true
    Program_RTSPSourceStatus:
      description: Current status of the RTSP source
      type: string
      enum:
        - idle
        - running
        - failed
        - stopped
      x-go-type-skip-optional-pointer: true
    Program_RTSPSourceConfigRequest:
      type: object
      properties:
        sourceUrl:
          description: RTSP source URL to pull from
          type: string
          example: rtsp://192.168.1.100:554/stream1
          x-go-type-skip-optional-pointer: true
        authType:
          $ref: '#/components/schemas/Program_RTSPAuthType'
        authUsername:
          description: Username for RTSP authentication
          type: string
          x-go-type-skip-optional-pointer: true
        authPassword:
          description: Password for RTSP authentication (write-only, not returned in responses)
          type: string
          x-go-type-skip-optional-pointer: true
        region:
          description: Preferred region for the RTSP broker
          type: string
          example: us-east-1
          x-go-type-skip-optional-pointer: true
        viewable:
          description: |-
            Whether the pulled source is viewable by end-viewers in the manifest.
            Optional; defaults to true when omitted. Set false to hide the raw source
            (e.g. when it is only an input to a composed program). Relayed to the broker.
          type: boolean
          x-go-type-skip-optional-pointer: false
      required:
        - sourceUrl
    Program_RTSPSourceStatusResponse:
      type: object
      properties:
        id:
          description: Unique identifier for the RTSP source
          type: string
          format: uuid
          x-go-name: ID
          x-go-type-skip-optional-pointer: true
        streamID:
          description: ID of the associated stream
          type: string
          format: uuid
          x-go-type-skip-optional-pointer: true
        projectID:
          description: ID of the project
          type: string
          format: uuid
          x-go-type-skip-optional-pointer: true
        sourceUrl:
          description: RTSP source URL
          type: string
          x-go-type-skip-optional-pointer: true
        status:
          $ref: '#/components/schemas/Program_RTSPSourceStatus'
        currentSessionID:
          description: Current stream session ID if running
          type: string
          format: uuid
          x-go-type-skip-optional-pointer: true
        lastError:
          description: Last error message if status is failed
          type: string
          x-go-type-skip-optional-pointer: true
        lastCheck:
          description: Last health check timestamp
          type: string
          format: date-time
          x-go-type-skip-optional-pointer: true
        startedAt:
          description: When the current pull session started
          type: string
          format: date-time
          x-go-type-skip-optional-pointer: true
        retryCount:
          description: Number of retry attempts
          type: integer
          x-go-type-skip-optional-pointer: true
        consecutiveFailures:
          description: Number of consecutive failures
          type: integer
          x-go-type-skip-optional-pointer: true
        activeSchedule:
          description: Currently active schedule, or null if none
          allOf:
            - $ref: '#/components/schemas/Program_RTSPScheduleResponse'
          x-go-type-skip-optional-pointer: false
        nextSchedule:
          description: Next pending schedule, or null if none
          allOf:
            - $ref: '#/components/schemas/Program_RTSPScheduleResponse'
          x-go-type-skip-optional-pointer: false
        error:
          description: Integrator-friendly detail for the last error. Present only when status is failed; null/omitted otherwise. The raw lastError string remains for debugging.
          allOf:
            - $ref: '#/components/schemas/Program_RTSPErrorDetail'
          x-go-type-skip-optional-pointer: false
    Program_RTSPScheduleResponse:
      type: object
      properties:
        id:
          description: Unique identifier for the schedule
          type: string
          format: uuid
          x-go-name: ID
          x-go-type-skip-optional-pointer: true
        sourceID:
          description: ID of the associated RTSP source
          type: string
          format: uuid
          x-go-type-skip-optional-pointer: true
        streamID:
          description: ID of the associated stream
          type: string
          format: uuid
          x-go-type-skip-optional-pointer: true
        projectID:
          description: ID of the project
          type: string
          format: uuid
          x-go-type-skip-optional-pointer: true
        name:
          description: Human-readable name for the schedule
          type: string
          x-go-type-skip-optional-pointer: true
        startTime:
          description: When the scheduled pull should start (UTC)
          type: string
          format: date-time
          x-go-type-skip-optional-pointer: true
        endTime:
          description: When the scheduled pull should stop (UTC)
          type: string
          format: date-time
          x-go-type-skip-optional-pointer: true
        enabled:
          description: Whether the schedule is enabled
          type: boolean
          x-go-type-skip-optional-pointer: true
        status:
          $ref: '#/components/schemas/Program_RTSPScheduleStatus'
        createdAt:
          description: When the schedule was created
          type: string
          format: date-time
          x-go-type-skip-optional-pointer: true
        updatedAt:
          description: When the schedule was last updated
          type: string
          format: date-time
          x-go-type-skip-optional-pointer: true
    Program_RTSPScheduleStatus:
      description: Current status of the RTSP schedule
      type: string
      enum:
        - pending
        - active
        - completed
        - cancelled
      x-go-type-skip-optional-pointer: true
    Program_RTSPErrorDetail:
      description: Structured, integrator-friendly representation of the last RTSP error. `message` is display-ready; `category` is a stable enum for programmatic handling; `code` is the upstream status code when the error carried one.
      type: object
      properties:
        message:
          description: Human-readable, display-ready error message intended for the integrator's end user.
          type: string
          example: The media host rejected the pull request.
          x-go-type-skip-optional-pointer: true
        category:
          description: Stable category for programmatic handling. New values may be added over time; treat unknown values as `internal`.
          type: string
          enum:
            - media_host_rejected
            - broker_unreachable
            - auth_failed
            - source_unreachable
            - internal
          x-go-type-skip-optional-pointer: true
        code:
          description: Upstream status code when the error carried one (e.g. the broker's HTTP status). Omitted when no status code applies (e.g. a connection timeout).
          type: integer
          example: 502
          x-go-type-skip-optional-pointer: true
    Program_RTSPSchedulesResponse:
      type: object
      properties:
        schedules:
          description: List of RTSP schedules
          type: array
          items:
            $ref: '#/components/schemas/Program_RTSPScheduleResponse'
          x-go-type-skip-optional-pointer: true
        totalCount:
          description: Total number of schedules
          type: integer
          x-go-type-skip-optional-pointer: true
    Program_RTSPScheduleRequest:
      type: object
      properties:
        name:
          description: Human-readable name for the schedule
          type: string
          example: Morning News Feed
          x-go-type-skip-optional-pointer: true
        startTime:
          description: When the scheduled pull should start (UTC)
          type: string
          format: date-time
          x-go-type-skip-optional-pointer: true
        endTime:
          description: When the scheduled pull should stop (UTC)
          type: string
          format: date-time
          x-go-type-skip-optional-pointer: true
        enabled:
          description: Whether the schedule is enabled
          type: boolean
          default: true
          x-go-type-skip-optional-pointer: false
      required:
        - name
        - startTime
        - endTime
    Program_Ingress:
      type: object
      properties:
        rtmp:
          type: string
        webrtc:
          type: string
    Program_AuthType:
      description: |-
        The type of authentication used for a program or stream.
        - `public` will allow anyone to view the stream.
        - `private` will require a JWT to start or view a stream.
        - `private+program-states` will work with both JWTs and integrator custom tokens.
      type: string
      enum:
        - private
        - public
        - private+program-states
    Program_RtmpPushDestination:
      description: |-
        RtmpPushDestination — single shape used in both request and response
        contexts. `enabled` is required: callers express the intended state of
        each destination explicitly, so a single PATCH can express mixed
        enabled/disabled states across multiple rows.

        `key` is the destination credential (e.g., a YouTube stream key).
        Treat it as a secret in caller logs and storage; the server returns it
        as-is on read responses (no masking, per D5).
      type: object
      properties:
        type:
          description: Destination type. Only "yt" is supported in this milestone.
          type: string
          enum:
            - yt
        key:
          description: |-
            Destination credential (e.g., the YouTube stream key from YT Studio).
            Returned as-is on reads.
          type: string
        enabled:
          description: |-
            Whether this destination is included when the streamKey is assembled.
            Disabled destinations are stored but skipped.
          type: boolean
      required:
        - type
        - key
        - enabled
    Program_StorageObject:
      description: |-
        #StorageObject is one stored object on a managed surface (M6 Task 012)
        with a time-limited presigned download URL — the platform-mediated way
        to view/download managed objects without exposing member credentials
        or requiring a Backblaze login.
      type: object
      properties:
        key:
          type: string
        sizeBytes:
          type: integer
        lastModified:
          type: string
        downloadUrl:
          description: Time-limited presigned GET URL (minutes). Re-list to refresh.
          type: string
        expiresAt:
          type: string
      required:
        - key
        - sizeBytes
        - downloadUrl
        - expiresAt
    Program_StorageDestination:
      description: |-
        #StorageDestination is the customer-supplied destination on a BYO
        PUT. S3-family surfaces (archive/snapshots/clips) use
        provider+bucket+region+endpoint+credentials; assets uses
        publicUrlBase. Credentials are write-only — accepted here, persisted
        to Vault, and NEVER echoed in any response. Per-surface required
        fields are enforced server-side (the endpoint is optional only for
        Amazon S3, where the region derives it).
      type: object
      properties:
        provider:
          type: string
        bucket:
          type: string
        region:
          type: string
        endpoint:
          type: string
        accessKey:
          type: string
        secretKey:
          type: string
        pathTemplate:
          type: string
        publicUrlBase:
          type: string
    Program_BulkUpdateRtmpPushEntry:
      description: |-
        One stream's complete desired destination set inside a bulk reconcile
        request. Mirrors the per-stream PATCH semantics: the server upserts each
        destination with that row's `enabled` value, deletes any stored
        destination not in the entry. Maximum 10 destinations per stream.
      type: object
      properties:
        streamID:
          description: The stream id whose destinations this entry describes.
          type: string
        destinations:
          description: Desired set of destinations for this stream. Empty array clears the set.
          type: array
          items:
            $ref: '#/components/schemas/Program_RtmpPushDestination'
      required:
        - streamID
        - destinations
    Program_BulkUpdateRtmpPushResultEntry:
      description: |-
        Per-stream post-reconcile state, returned in the same order as the
        request's streams.
      type: object
      properties:
        streamID:
          description: The stream id this result corresponds to.
          type: string
        rtmpPush:
          description: |-
            The reconciled set of destinations for this stream. Reflects
            post-reconcile state.
          type: array
          items:
            $ref: '#/components/schemas/Program_RtmpPushDestination'
      required:
        - streamID
        - rtmpPush
    Program_PathTemplate:
      description: Path template to archive
      type: string
      example: key/start/height
      enum:
        - key/start/height
        - key/session/height
        - start/key/height
        - key/start_key
        - start_key/key
    Program_Asset:
      description: |-
        Asset is the read shape returned by `GET /assets/{id}` and
        `GET /assets`. Carries everything the dashboard or media server
        needs to render an asset entry — no separate "summary" vs "detail"
        distinction (the row is small enough that one shape works).

        Notes on opaque fields:
          - `type` is a free-form string identifying the mediaassets
            renderer plugin. The only plugin registered in mediaassets
            today is "html2img"; additional plugins each get their own
            `type` value. Program does not validate.
          - `properties` is a JSON object of render-time parameters keyed
            by `type`. Program does not validate; round-trips verbatim.
            For the current "html2img" plugin the shape is
            {"args": [...string]} — a html2img CLI argument array. See
            the program-assets openspec design D11 for the integration
            contract with mediaassets.
      type: object
      properties:
        id:
          description: Project-scoped customer handle. ^[a-zA-Z0-9._-]{1,128}$.
          type: string
        projectId:
          description: UUID of the project this asset belongs to.
          type: string
        storageMode:
          $ref: '#/components/schemas/Program_StorageMode'
        publicUrl:
          description: |-
            Publicly resolvable URL serving the bytes. For managed assets,
            program writes the constructed B2 URL at upload time. For BYO,
            the caller supplies it.
          type: string
        type:
          description: Renderer/schema selector. Opaque to program.
          type: string
        properties:
          description: |-
            Render-time parameters keyed by `type`. Opaque to program.
            Defaults to {} when omitted on create.
          type: object
        contentType:
          description: |-
            Content metadata, populated on managed upload or from
            opportunistic HEAD on BYO create.
          type: string
        sizeBytes:
          type: integer
        etag:
          type: string
        fetchStatus:
          $ref: '#/components/schemas/Program_FetchStatus'
        lastCheck:
          description: Timestamp of the last status report.
          type: string
        lastError:
          description: |-
            Error message from the last failed render attempt; cleared on
            recovery.
          type: string
        startedAt:
          description: When the asset was first rendered (managed lifecycle hook).
          type: string
        createdOn:
          type: string
        createdBy:
          type: string
        updatedOn:
          type: string
        updatedBy:
          type: string
      required:
        - id
        - projectId
        - storageMode
        - publicUrl
        - type
        - properties
        - createdOn
        - updatedOn
    Program_StorageMode:
      description: |-
        StorageMode discriminates between managed and BYO storage. CHECK
        constraint at the DB layer couples this with storage_key /
        public_url presence; the API rejects mismatched inputs before
        reaching the DB.
      type: string
      enum:
        - managed
        - byo
    Program_FetchStatus:
      description: |-
        FetchStatus is the most recent media-server render result for this
        asset. NULL when never rendered; set by `POST /assets/{id}/status`.
      type: string
      enum:
        - ready
        - fetch_failed
    Auth_JWKs:
      type: object
      properties:
        issuer:
          $ref: '#/components/schemas/Auth_Issuer'
        keys:
          description: Keys maybe empty if the 'iss' param was set, in this case the keys will be under the `issuer` object
          type: array
          x-go-type: jwk.Set
          x-go-type-import:
            name: jwk
            path: github.com/lestrrat-go/jwx/v2/jwk
      required:
        - keys
    Auth_Issuer:
      type: object
      properties:
        iss:
          description: Issuer of the JWT
          type: string
        project:
          $ref: '#/components/schemas/Auth_Project'
        JWKsURL:
          description: URL to the JWKs public keys, if no URL is provided you must include 'keys', if both are provided the keys fetched from the URL are merged with the supplied keys
          type: string
          x-go-type-skip-optional-pointer: true
          x-oapi-codegen-extra-tags:
            yaml: jwks-url
        aud:
          description: An array of audiences that are valid for this issuer, an empty array is allowed
          type: array
          items:
            type: string
          x-go-type-skip-optional-pointer: true
        roles:
          description: An array of roles that are allowed for this issuer, an empty permmits all roles
          type: array
          items:
            type: string
          x-go-type-skip-optional-pointer: true
        prm:
          description: An uint64 bitmask representing the permissions valid for this issuser, an empty value permits all permissions
          type: number
          format: uint64
          x-go-type: uint64
          x-go-type-skip-optional-pointer: true
        internal:
          description: 'Indicates that this issuer is an internal issuer (NOTE: this field can not be set via the API)'
          type: boolean
          x-go-type-skip-optional-pointer: true
        static:
          description: 'Indicates that this issuer was added via a configuration, (NOTE: this field can not set via the API)'
          type: boolean
          x-go-type-skip-optional-pointer: true
        keys:
          description: JWK public keys used for this issuer, an emtpy array is allowed if a JWKsURL is also provided
          type: array
          x-go-type: jwk.Set
          x-go-type-import:
            name: jwk
            path: github.com/lestrrat-go/jwx/v2/jwk
          x-go-type-skip-optional-pointer: true
      required:
        - iss
        - project
    Auth_Project:
      type: object
      properties:
        id:
          type: string
      required:
        - id
    Auth_Error:
      type: object
      properties:
        message:
          description: Error message for the end user
          type: string
        errorCode:
          description: Code that can be set that supplies a specific reason for why a request failed
          type: string
        invalidFields:
          description: Specific error scoped to a field
          type: array
          items:
            $ref: '#/components/schemas/Auth_InvalidField'
        internal:
          description: Internal user only
          type: string
      required:
        - message
      x-go-type: apperrors.Error
      x-go-type-import:
        path: github.com/LivelyVideo/service-definitions/errors
        name: apperrors
    Auth_InvalidField:
      type: object
      properties:
        name:
          type: string
        reason:
          type: string
        errorCode:
          type: string
      required:
        - name
        - reason
      x-go-type: apperrors.InvalidField
      x-go-type-import:
        path: github.com/LivelyVideo/service-definitions/errors
        name: apperrors
    Auth_CreateJWT:
      description: JSON Web Token (JWT) create request body
      type: object
      properties:
        kid:
          description: Key ID of the JWK
          type: string
        ttl:
          description: |
            ttl stands for time to live, a ttl of 300 will expire in 300 seconds. Either ttl or exp should be used but not both
          type: integer
          example: 600
          x-go-type-skip-optional-pointer: true
        exp:
          description: |
            The JWT will no longer be valid after this date. Either ttl or expire should be used but not both
          type: integer
          format: timestamp (Unix epoch)
          x-go-type: int64
          x-go-type-skip-optional-pointer: true
        nbf:
          description: |
            The JWT will not be valid before this date
          type: integer
          format: timestamp (Unix epoch)
          x-go-type: int64
          x-go-type-skip-optional-pointer: true
        sub:
          description: |
            The subject of the JWT (the user id)
          type: string
          x-go-type-skip-optional-pointer: true
        roles:
          description: |
            An array of roles that will be applied to the JWT. This will apper in the JWT as the claim `roles`
          type: array
          items:
            type: string
            default: []
          x-go-type-skip-optional-pointer: true
        permissions:
          description: |
            An array of permissions that will be applied to the JWT. 
            The permissions are a string representation of a uint64 bitmask.
            This will appear in the JWT as the claim `prm`
          type: array
          items:
            type: string
            default: []
          x-go-type-skip-optional-pointer: true
        claims:
          description: |
            Additional claims to be stored with the JWT
          type: object
          default: {}
          additionalProperties: true
          x-go-type-skip-optional-pointer: true
      required:
        - kid
    Auth_JWTResponse:
      description: JWT response
      type: object
      properties:
        token:
          type: string
      required:
        - token
    Auth_CreateVideoJWT:
      description: JSON Web Token (JWT) create request body
      type: object
      properties:
        kid:
          description: Key ID of the JWK
          type: string
        roles:
          description: |
            An array of roles that will be applied to the JWT. This will apper in the JWT as the claim `roles`
          type: array
          items:
            type: string
            default: []
          x-go-type-skip-optional-pointer: true
        videoToken:
          description: |
            This is a namespaced claim used to store the legacy version of the access token

            This will appear in the JWT as the claim `@video/token`
          $ref: '#/components/schemas/Auth_AccessToken'
      required:
        - kid
        - videoToken
    Auth_AccessToken:
      description: |
        AccessToken is used to authenticate a user across the Lively Video services.
      type: object
      properties:
        token:
          description: |
            Unique authentication token for use by the end user client to authenticate against Lively Video APIs
            If present, the token is echoed back in the response. 
            If not, a newly generated token is returned on the response.
          type: string
          example: cb069d2d-724e-402f-9724-4910fe3604d7
          x-go-type: types.TokenUnion
          x-go-type-import:
            path: github.com/LivelyVideo/service-definitions/video-foundation/business/auth/shared/go/types
        scopes:
          description: |
            Array of scopes for which the token is valid

            ### Available scopes:
            - broadcaster
            - private-broadcaster
            - viewer
            - private-viewer
            - admin
          type: array
          items:
            type: string
          example:
            - broadcaster
          minItems: 1
        accessIds:
          description: |
            Array of ids for which the token is valid
          type: array
          items:
            type: string
            format: uuid
          example:
            - e0d9d6d6-9977-4a13-97e2-e66b122390df
            - bbaedb37-0e3e-47c0-933e-5f20b308b58a
          default: []
        ttl:
          description: |
            Users of the access token lose access to Lively Video services after the ttl. Defaults to 300 seconds.
          type: integer
          example: 600
        expire:
          description: |
            Users of the access token lose access to Lively Video services after the expiration time. 
            Can be specified instead of TTL.
          type: string
          format: date-time
          example: '2023-01-01T00:00:00.000Z'
        userId:
          description: |
            Unique ID used to identify the user in the client organization's system
          example: '1234567890'
          nullable: true
          oneOf:
            - type: string
              format: number
            - type: integer
            - type: 'null'
          x-go-type: interface{}
        admin:
          description: |
            If true, the user has admin privilege for the lifetime of the user token
          type: boolean
          example: false
          default: false
        data:
          description: |
            Additional data to be stored with the access token
          type: object
          example:
            foo: bar
          default: {}
          additionalProperties: true
      additionalProperties: false
      required:
        - scopes
    Dashboard_PublicConfig:
      type: object
      additionalProperties:
        anyOf:
          - type: string
          - type: number
          - type: boolean
    Dashboard_Error:
      type: object
      properties:
        message:
          description: Error message for the end user
          type: string
        errorCode:
          description: Code that can be set that supplies a specific reason for why a request failed
          type: string
        invalidFields:
          description: Specific error scoped to a field
          type: array
          items:
            $ref: '#/components/schemas/Dashboard_InvalidField'
        internal:
          description: Internal user only
          type: string
      required:
        - message
      x-go-type: apperrors.Error
      x-go-type-import:
        path: github.com/LivelyVideo/service-definitions/errors
        name: apperrors
    Dashboard_InvalidField:
      type: object
      properties:
        name:
          type: string
        reason:
          type: string
        errorCode:
          type: string
      required:
        - name
        - reason
      x-go-type: apperrors.InvalidField
      x-go-type-import:
        path: github.com/LivelyVideo/service-definitions/errors
        name: apperrors
    Dashboard_Project:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        slug:
          type: string
        isLegacyProjectPrivateCloud:
          type: boolean
        organizationId:
          type: string
        configuration:
          type: object
          additionalProperties: false
          properties:
            privateViewing:
              type: boolean
            cdn:
              type: boolean
            recording:
              type: boolean
        description:
          type: string
        configured:
          type: boolean
        createdAt:
          type: string
          nullable: true
        projectConfiguration:
          $ref: '#/components/schemas/Dashboard_ProjectConfiguration'
      additionalProperties: false
      required:
        - id
        - name
        - slug
        - organizationId
        - configuration
        - configured
    Dashboard_ProjectConfiguration:
      allOf:
        - $ref: '#/components/schemas/Dashboard_ProjectConfigurationProperties'
        - type: object
          properties:
            projectId:
              type: string
          required:
            - projectId
            - preferredAuth
    Dashboard_ProjectConfigurationProperties:
      type: object
      properties:
        preferredAuth:
          type: string
      additionalProperties: true
    Dashboard_CreateProjectBody:
      type: object
      properties:
        name:
          type: string
        slug:
          type: string
        configuration:
          type: object
          additionalProperties: false
          properties:
            privateViewing:
              type: boolean
            cdn:
              type: boolean
            recording:
              type: boolean
        description:
          type: string
        preferredAuth:
          type: string
          enum:
            - jwtAuth
            - webhookAuth
            - public
      required:
        - configuration
        - name
    Dashboard_UpdateProjectBody:
      type: object
      properties:
        name:
          type: string
        slug:
          type: string
        description:
          type: string
        configured:
          type: boolean
        projectConfiguration:
          $ref: '#/components/schemas/Dashboard_ProjectConfigurationProperties'
    Dashboard_InvoiceDatesResponse:
      type: array
      items:
        type: object
        properties:
          date:
            type: string
        required:
          - date
    Dashboard_InvoiceResponse:
      type: array
      items:
        type: object
        properties:
          projectId:
            type: string
            format: uuid
          projectName:
            type: string
          minutesStreamed:
            type: integer
            example: 10
          streamPrice:
            type: number
            format: float
            example: 0.03
          minutesViewed:
            type: integer
            example: 6
          viewPrice:
            type: number
            format: float
            example: 0.001
          totalCost:
            type: number
            format: float
            example: 0.31
        required:
          - projectId
          - projectName
          - minutesStreamed
          - streamPrice
          - minutesViewed
          - viewPrice
          - totalCost
    Dashboard_InvoiceTotalsResponse:
      type: object
      properties:
        stream:
          type: number
        view:
          type: number
        cost:
          type: number
      required:
        - stream
        - view
        - cost
    Dashboard_Invoice:
      type: object
      properties:
        id:
          type: string
        date:
          type: string
          format: date-time
        paid:
          type: integer
        stripeInvoiceId:
          type: string
        organizationId:
          type: string
        invoicePdf:
          type: string
          format: uri
        stripeStatus:
          type: string
        subtotalCents:
          type: number
        taxCents:
          type: number
        totalCents:
          type: number
      required:
        - id
        - date
        - paid
        - stripeInvoiceId
        - organizationId
        - invoicePdf
        - stripeStatus
        - subtotalCents
        - taxCents
        - totalCents
    Dashboard_Binary:
      description: Binary data (Blob)
      type: string
      format: binary
    Dashboard_Issuer:
      type: object
      properties:
        JWKsURL:
          type: string
          format: uri
        iss:
          type: string
          format: uri
        project:
          type: object
          properties:
            id:
              type: string
        keys:
          type: array
          items:
            type: object
            additionalProperties: true
          nullable: true
      required:
        - iss
        - JWKsURL
        - project
        - keys
    Dashboard_IssuerBody:
      type: object
      properties:
        iss:
          type: string
        jwksUrl:
          type: string
      required:
        - iss
        - jwksUrl
    Events_EventsDefinitions:
      description: Project which combines events
      type: object
      properties:
        spec:
          description: Complete list of event
          type: array
          items:
            $ref: '#/components/schemas/Events_EventDefinition'
          x-isnullable: false
          x-oapi-codegen-extra-tags:
            yaml: spec
      additionalProperties: false
      required:
        - name
        - events
        - null
      title: EventsDefinitions
    Events_EventDefinition:
      description: Description of single event
      type: object
      properties:
        name:
          $ref: '#/components/schemas/Events_EventName'
        description:
          description: Event description
          type: string
          example: Start of a broadcast
          x-oapi-codegen-extra-tags:
            yaml: description
        kind:
          type: string
          example: async
          default: async
          enum:
            - async
            - sync
          x-oapi-codegen-extra-tags:
            yaml: kind
        schemas:
          $ref: '#/components/schemas/Events_EventDefinitionSchemas'
      additionalProperties: false
      required:
        - name
        - kind
      title: Project Event
    Events_EventName:
      description: Event name
      type: string
      example: broadcast-start
      maxLength: 64
      minLength: 1
      pattern: ^[a-zA-Z0-9_-]+$
      x-oapi-codegen-extra-tags:
        yaml: name
    Events_EventDefinitionSchemas:
      type: object
      properties:
        request:
          type: object
          additionalProperties: true
          x-go-type: any
          x-go-type-skip-optional-pointer: true
          x-oapi-codegen-extra-tags:
            yaml: request
        responses:
          additionalProperties: true
          type: object
          x-go-type: any
          x-go-type-skip-optional-pointer: true
          x-oapi-codegen-extra-tags:
            yaml: responses
    Events_Error:
      type: object
      properties:
        message:
          description: Error message for the end user
          type: string
        errorCode:
          description: Code that can be set that supplies a specific reason for why a request failed
          type: string
        invalidFields:
          description: Specific error scoped to a field
          type: array
          items:
            $ref: '#/components/schemas/Events_InvalidField'
        internal:
          description: Internal user only
          type: string
      required:
        - message
      x-go-type: apperrors.Error
      x-go-type-import:
        path: github.com/LivelyVideo/service-definitions/errors
        name: apperrors
    Events_InvalidField:
      type: object
      properties:
        name:
          type: string
        reason:
          type: string
        errorCode:
          type: string
      required:
        - name
        - reason
      x-go-type: apperrors.InvalidField
      x-go-type-import:
        path: github.com/LivelyVideo/service-definitions/errors
        name: apperrors
    Events_Webhook:
      description: Describes a webhook for handling events
      type: object
      properties:
        project:
          $ref: '#/components/schemas/Events_ProjectName'
        name:
          $ref: '#/components/schemas/Events_WebhookName'
        description:
          type: string
          example: Handle broadcast events of pvc
        maxAttempts:
          type: integer
          default: 10
          maximum: 20
          minimum: 1
        disabled:
          type: boolean
          default: false
        request:
          $ref: '#/components/schemas/Events_WebhookRequest'
        response:
          $ref: '#/components/schemas/Events_WebhookResponse'
        event:
          $ref: '#/components/schemas/Events_EventName'
      required:
        - name
        - request
        - event
    Events_ProjectName:
      description: Project name
      type: string
      example: pvc
      maxLength: 64
      minLength: 1
      pattern: ^[a-zA-Z0-9_-]+$
      x-oapi-codegen-extra-tags:
        validate: required,min=1,max=256
    Events_WebhookName:
      description: Webhook name
      type: string
      example: pvc-broadcast-events
      maxLength: 64
      minLength: 1
      pattern: ^[a-zA-Z0-9_-]+$
    Events_WebhookRequest:
      type: object
      properties:
        url:
          type: string
          example: http://exampple.com/event/{{.Source.Event}}
        method:
          type: string
          default: POST
          enum:
            - GET
            - POST
            - PUT
            - PATCH
            - HEAD
            - OPTION
            - DELETE
        headers:
          type: object
          additionalProperties:
            type: string
    Events_WebhookResponse:
      type: object
      properties:
        codes:
          type: array
          items:
            type: integer
            minimum: 100
            maximum: 599
        headers:
          type: object
          additionalProperties:
            type: string
        bodyRegex:
          type: string
          example: /^OK$/
        timeout:
          type: integer
          default: 5
          maximum: 600
          minimum: 1
      x-go-type-skip-optional-pointer: true
    Events_DestinationEvent:
      description: Destination event to certan webhook
      type: object
      properties:
        id:
          description: UUIDv1 of current event. It's different with source event id
          type: string
          format: uuid
          example: 413f13e3-684e-223f-2247-0963feaa3351
        source:
          $ref: '#/components/schemas/Events_SourceEvent'
        attempts:
          description: How many attempts it already made
          type: integer
          example: 3
        lastResponseCode:
          description: Last HTTP code returned from webhook endpoint
          type: integer
          example: 200
        lastResponseTime:
          description: How long was las response (ms)
          type: number
          example: 25
        status:
          description: Current status of this task
          type: string
          enum:
            - NEW
            - IN_PROCESS
            - DELIVERED
            - CANCELED
            - FAILED
        lastError:
          description: Last error was occurred
          type: string
          example: Remote endpoint returned 500 HTTP code
        created:
          description: Timestamp when the task was started
          type: string
          format: date-time
          example: '2019-07-21T17:32:28.000Z'
        webhookName:
          $ref: '#/components/schemas/Events_WebhookName'
      additionalProperties: false
    Events_SourceEvent:
      description: Source event from an application
      type: object
      properties:
        id:
          description: UUIDv1 of incomming event. Can be generated on client side or automatically server side
          type: string
          format: uuid
          example: 166ae306-50ff-11e9-8647-d663bd873d93
        project:
          $ref: '#/components/schemas/Events_ProjectName'
        event:
          $ref: '#/components/schemas/Events_EventName'
        payload:
          description: Payload which described in project config. HTTP method must be POST, PUT, PATCH or DELETE
          type: object
          example:
            foo: bar
          x-go-type: any
          x-go-type-skip-optional-pointer: true
      additionalProperties: false
      required:
        - event
    Events_ProgramStatesRequestV2:
      type: object
      properties:
        programs:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/Events_ProgramRequestV2'
      required:
        - programs
    Events_ProgramRequestV2:
      type: object
      properties:
        streams:
          description: Streams in the program
          type: object
          additionalProperties:
            $ref: '#/components/schemas/Events_StreamRequestV2'
      required:
        - streams
    Events_StreamRequestV2:
      type: object
      properties:
        token:
          description: The token of the producer of the stream, may be empty if only viewTokens are being sent
          $ref: '#/components/schemas/Events_TokenRequestV2'
        viewTokens:
          description: The view tokens of the consumers
          type: array
          items:
            $ref: '#/components/schemas/Events_TokenRequestV2'
          x-go-type-skip-optional-pointer: true
    Events_TokenRequestV2:
      type: object
      properties:
        action:
          description: The action being performed by the token
          type: string
          enum:
            - hls-auth
            - joining
            - creating
            - polling
        type:
          description: The type of the token
          type: string
          default: token
          enum:
            - token
            - sub
        value:
          description: Either a token or a sub claim depending on the type
          type: string
      required:
        - value
        - type
        - action
    Events_ProgramStatesResponseV2:
      type: object
      properties:
        programs:
          description: |-
            The programs from the requests, all programs sent in the request should be returned in the resposne
            if programs are missing, they will be stopped
          type: object
          additionalProperties:
            $ref: '#/components/schemas/Events_ProgramResponseV2'
      required:
        - programs
    Events_ProgramResponseV2:
      type: object
      properties:
        stop:
          description: If stop is true all streams in the program should be stopped
          type: boolean
          default: false
        stopReason:
          description: stopReason that will be logged
          type: string
        needAuth:
          type: boolean
          default: false
        streams:
          description: Streams in the program
          type: object
          additionalProperties:
            $ref: '#/components/schemas/Events_StreamResponseV2'
      required:
        - stop
        - needAuth
        - streams
    Events_StreamResponseV2:
      type: object
      properties:
        stop:
          description: If stop is true the stream should be stopped
          type: boolean
          default: false
        stopReason:
          description: stopReason that will be logged
          type: string
        needAuth:
          type: boolean
          default: false
        token:
          description: The auth token of the producer of the stream
          type: string
          minLength: 4
        appData:
          $ref: '#/components/schemas/Events_AppData'
          x-go-type-skip-optional-pointer: true
        viewTokens:
          description: The view tokens of the consumers
          type: object
          additionalProperties:
            $ref: '#/components/schemas/Events_ViewTokenResponseV2'
          x-go-type-skip-optional-pointer: true
      required:
        - stop
        - token
        - needAuth
        - appData
    Events_AppData:
      description: |
        AppData is used to store additional data in the stream or view tokens

        Fields that need to be retured in the appData for the current SFU and LB

        - `user.id` - The user id that belongs to the token
        - `user.name` - The user name that belongs to the token
        - `user.scope` - The user's scope, some scopes are `broadcaster`, `viewer`, `admin`, `private-broadcaster`, `private-viewer`

        NOTE: `$sys.` is reserved for system use only and should not be returned by the integration system

        The client will use for UI puposes and the server will log this data 

        If a `user.scope` is not provided the backend will infer the scope from the token based on the auth state of the stream
      type: object
      additionalProperties:
        type: string
    Events_ViewTokenResponseV2:
      type: object
      properties:
        stop:
          description: If stop is true the consumer/producer is stopped
          type: boolean
          default: false
        stopReason:
          description: stopReason that will be logged
          type: string
        appData:
          $ref: '#/components/schemas/Events_AppData'
          x-go-type-skip-optional-pointer: true
      required:
        - stop
        - appData
    Webhook_Event:
      type: object
      properties:
        id:
          description: The unique identifier for the event. Should be used to deduplicate events in case of retries.
          type: string
        event:
          description: |-
            -> The type of event.
            - `program-states-v2` is the nested format. The payload contains the `ProgramStatesRequestV3` schema.
            - `events` is the flat event-based alternative. The payload contains the `EventWebhookRequest` schema — a flat list of typed events with server-generated IDs for response correlation.
          type: string
          enum:
            - program-states-v2
            - events
        payload:
          type: object
          oneOf:
            - $ref: '#/components/schemas/Webhook_ProgramStatesRequestV3'
            - $ref: '#/components/schemas/Webhook_EventWebhookRequest'
    Webhook_Error:
      type: object
      properties:
        message:
          description: Error message for the end user
          type: string
        errorCode:
          description: Code that can be set that supplies a specific reason for why a request failed
          type: string
        invalidFields:
          description: Specific error scoped to a field
          type: array
          items:
            $ref: '#/components/schemas/Webhook_InvalidField'
        internal:
          description: Internal user only
          type: string
      required:
        - message
    Webhook_InvalidField:
      type: object
      properties:
        name:
          type: string
        reason:
          type: string
        errorCode:
          type: string
      required:
        - name
        - reason
    Webhook_ProgramStatesRequestV3:
      description: ProgramStatesRequestV3 contains tokens and programs that require authentication
      type: object
      properties:
        tokens:
          description: Tokens at this level have not yet been associated with a program and could be requesting access to create a program
          type: array
          items:
            $ref: '#/components/schemas/Webhook_TokenLevelTokenRequestV3'
        programs:
          description: Programs that have already been created, contains tokens and streams that are associated with the program
          type: object
          additionalProperties:
            $ref: '#/components/schemas/Webhook_ProgramRequestV3'
      required:
        - tokens
        - programs
    Webhook_TokenLevelTokenRequestV3:
      description: TokenLevelTokenRequestV3 is a token request for orphan or program-level tokens (not associated with a stream)
      type: object
      properties:
        type:
          type: string
          enum:
            - token
            - sub
        value:
          type: string
        event:
          $ref: '#/components/schemas/Webhook_TokenLevelEvents'
        payload: {}
      required:
        - type
        - value
        - event
    Webhook_TokenLevelEvents:
      description: |-
        TokenLevelEvents are events valid for orphan or program-level tokens.
        A program-level user token mirrors the user's lifecycle state on the gateway.
        Beyond the original orphan-token events, it also carries the user-state events the
        gateway reports at the program level for a user not tied to a stream:
        polling (heartbeat / still-authorized), creating-send-transport (capability gate),
        and webrtc-manifest-ready. Stream-only events (creating, manifest-ready, closed,
        starting, format-started/ended) stay out — they only occur under a stream.
      type: string
      enum:
        - joining
        - hls-auth
        - auth-manifest
        - disconnected
        - polling
        - creating-send-transport
        - webrtc-manifest-ready
    Webhook_ProgramRequestV3:
      description: ProgramRequestV3 contains tokens and streams that are associated with the program
      type: object
      properties:
        tokens:
          description: Tokens that are associated with the program
          type: array
          items:
            $ref: '#/components/schemas/Webhook_TokenLevelTokenRequestV3'
        streams:
          description: Streams that are associated with the program
          type: object
          additionalProperties:
            $ref: '#/components/schemas/Webhook_StreamRequestV3'
      required:
        - tokens
        - streams
    Webhook_StreamRequestV3:
      description: |-
        StreamRequestV3 represents a stream and contains the tokens that are producing and consuming the stream.
        A stream can contain multiple producing tokens that are producing different tracks (webcam, screen share, etc...)
      type: object
      properties:
        producing:
          description: Producing contains all the tokens that are producing tracks on the stream. Each track is identified by the streamName and appData can be updated individually for each track.
          type: array
          items:
            $ref: '#/components/schemas/Webhook_ProducingStreamRequestV3'
        consuming:
          description: Consuming contains all the tokens that are consuming the stream, IE viewers of the stream or individual tracks on the stream.
          type: array
          items:
            $ref: '#/components/schemas/Webhook_ConsumingStreamRequestV3'
        alias:
          description: |-
            alias can be returned as an alias for the stream, this can be used later to lookup the stream
            Using an alias is a good practice to survive stream disconnections where a reconnect can result in a new stream ID.
          type: string
      required:
        - producing
        - consuming
    Webhook_ProducingStreamRequestV3:
      description: |-
        ProducingStreamRequestV3 contains the token that is producing the stream and the streamName
        Multiple streams can be produced by a single stream ID, streamName+streamID is unique
      type: object
      properties:
        streamName:
          description: StreamName is assigned to the stream by the client and is used to identify the track (webcam, screen share, etc...)
          type: string
        authKey:
          description: Auth key is used to authenticate the stream, if not provided the stream will be authenticated using the provided token
          type: string
        token:
          $ref: '#/components/schemas/Webhook_ProducerTokenRequestV3'
      required:
        - streamName
        - token
    Webhook_ProducerTokenRequestV3:
      description: ProducerTokenRequestV3 is a token request for producing stream tokens
      type: object
      properties:
        type:
          type: string
          enum:
            - token
            - sub
        value:
          type: string
        event:
          $ref: '#/components/schemas/Webhook_ProducerEvents'
        payload: {}
      required:
        - type
        - value
        - event
    Webhook_ProducerEvents:
      description: ProducerEvents are events valid for producing stream tokens
      type: string
      enum:
        - creating
        - creating-send-transport
        - polling
        - manifest-ready
        - webrtc-manifest-ready
        - closed
        - disconnected
        - starting
        - connected
        - format-started
        - format-ended
    Webhook_ConsumingStreamRequestV3:
      description: ConsumingStreamRequestV3 contains the token that is consuming the stream and the streamName, streamName+streamID is unique
      type: object
      properties:
        streamName:
          description: StreamName is assigned to the stream by the client and is used to identify the track (webcam, screen share, etc...) being consumed (viewed)
          type: string
        token:
          $ref: '#/components/schemas/Webhook_ConsumerTokenRequestV3'
      required:
        - streamName
        - token
    Webhook_ConsumerTokenRequestV3:
      description: ConsumerTokenRequestV3 is a token request for consuming stream tokens
      type: object
      properties:
        type:
          type: string
          enum:
            - token
            - sub
        value:
          type: string
        event:
          $ref: '#/components/schemas/Webhook_ConsumerEvents'
        payload: {}
      required:
        - type
        - value
        - event
    Webhook_ConsumerEvents:
      description: ConsumerEvents are events valid for consuming stream tokens
      type: string
      enum:
        - joining
        - polling
        - closed
        - disconnected
    Webhook_EventWebhookRequest:
      description: |-
        EventWebhookRequest is the event-based webhook request sent to integrators.
        Contains a flat list of typed events — no nesting or hierarchy.
      type: object
      properties:
        events:
          description: Events is the list of events in this webhook call
          type: array
          items:
            $ref: '#/components/schemas/Webhook_WebhookEvent'
      required:
        - events
    Webhook_WebhookEvent:
      description: |-
        WebhookEvent is a single event in the webhook request.
        Each event has a server-generated ID for response correlation,
        a type that identifies the kind of event, and a type-specific payload.
      type: object
      properties:
        id:
          description: ID is a server-generated unique identifier for response correlation
          type: string
        type:
          $ref: '#/components/schemas/Webhook_WebhookEventType'
        payload:
          description: Payload contains event-specific data, varies by type
      required:
        - id
        - type
        - payload
    Webhook_WebhookEventType:
      description: |-
        WebhookEventType defines all possible event types in the webhook system.
        Respondable events: integrator can set stop, appData (and needAuth for control surfaces) in the response.
        Notification events: informational only, no response expected.
      type: string
      enum:
        - token-joining
        - token-hls-auth
        - token-auth-manifest
        - token-polling
        - token-creating-send-transport
        - token-webrtc-manifest-ready
        - producer-creating
        - producer-creating-send-transport
        - producer-polling
        - consumer-joining
        - consumer-polling
        - stream-state
        - program-state
        - producer-starting
        - producer-manifest-ready
        - producer-webrtc-manifest-ready
        - producer-closed
        - producer-connected
        - consumer-closed
        - token-disconnected
        - producer-disconnected
        - consumer-disconnected
        - program-closed
        - producer-format-started
        - producer-format-ended
    Webhook_ProgramStatesResponseV3:
      description: ProgramStatesResponseV3 contains the response for the program states request
      type: object
      properties:
        tokens:
          description: Tokens at this level have not yet been associated with a program and could be requesting access to create a program
          type: array
          items:
            $ref: '#/components/schemas/Webhook_TokenLevelTokenResponseV3'
        programs:
          description: Programs that have already been created, contains tokens and streams that are associated with the program
          type: object
          additionalProperties:
            $ref: '#/components/schemas/Webhook_ProgramResponseV3'
      required:
        - tokens
        - programs
    Webhook_TokenLevelTokenResponseV3:
      description: TokenLevelTokenResponseV3 is a token response for orphan or program-level tokens
      type: object
      properties:
        value:
          type: string
        event:
          $ref: '#/components/schemas/Webhook_TokenLevelEvents'
        stop:
          type: boolean
        stopReason:
          type: string
        appData:
          type: object
          additionalProperties:
            type: string
      required:
        - value
        - event
        - stop
    Webhook_ProgramResponseV3:
      type: object
      properties:
        needAuth:
          description: NeedAuth indicates that the program requires authentication, if false consuming tokens will not be sent in the request for this program
          type: boolean
        stop:
          description: Stop indicates that the program and all associated streams should be stopped
          type: boolean
        stopReason:
          description: StopReason is an optional reason for stopping the program, should only be set if stop is true
          type: string
        streams:
          description: Streams that are associated with the program
          type: object
          additionalProperties:
            $ref: '#/components/schemas/Webhook_StreamResponseV3'
        tokens:
          description: Tokens that are associated with the program
          type: array
          items:
            $ref: '#/components/schemas/Webhook_TokenLevelTokenResponseV3'
      required:
        - needAuth
        - stop
        - streams
        - tokens
    Webhook_StreamResponseV3:
      type: object
      properties:
        alias:
          description: Alias is the alias that was provided in the request, if no alias was provided, this will not be set
          type: string
        needAuth:
          description: NeedAuth indicates that the stream requires authentication, if false consuming tokens will not be sent in the request for this stream
          type: boolean
        stop:
          description: Stop indicates that the stream should be stopped - this will stop all associated producing and consuming tokens
          type: boolean
        stopReason:
          description: StopReason is an optional reason for stopping the stream, should only be set if stop is true
          type: string
        producing:
          description: Producing represents the producing tokens and their associated stream names
          type: array
          items:
            $ref: '#/components/schemas/Webhook_ProducingStreamResponseV3'
        consuming:
          description: Consuming represents the consuming tokens and their associated stream names
          type: array
          items:
            $ref: '#/components/schemas/Webhook_ConsumingStreamResponseV3'
      required:
        - needAuth
        - stop
        - producing
        - consuming
    Webhook_ProducingStreamResponseV3:
      description: ProducingStreamResponseV3 contains the response for a producing stream
      type: object
      properties:
        streamName:
          description: StreamName is the name of the stream
          type: string
        authKey:
          description: AuthKey is the auth key that was provided in the request, if no auth key was provided this should not be set
          type: string
        token:
          $ref: '#/components/schemas/Webhook_ProducerTokenResponseV3'
      required:
        - streamName
        - token
    Webhook_ProducerTokenResponseV3:
      description: ProducerTokenResponseV3 is a token response for producing stream tokens
      type: object
      properties:
        value:
          type: string
        event:
          $ref: '#/components/schemas/Webhook_ProducerEvents'
        stop:
          type: boolean
        stopReason:
          type: string
        appData:
          type: object
          additionalProperties:
            type: string
      required:
        - value
        - event
        - stop
    Webhook_ConsumingStreamResponseV3:
      description: ConsumingStreamResponseV3 contains the response for a consuming stream
      type: object
      properties:
        streamName:
          description: StreamName is the name of the stream
          type: string
        token:
          $ref: '#/components/schemas/Webhook_ConsumerTokenResponseV3'
      required:
        - streamName
        - token
    Webhook_ConsumerTokenResponseV3:
      description: ConsumerTokenResponseV3 is a token response for consuming stream tokens
      type: object
      properties:
        value:
          type: string
        event:
          $ref: '#/components/schemas/Webhook_ConsumerEvents'
        stop:
          type: boolean
        stopReason:
          type: string
        appData:
          type: object
          additionalProperties:
            type: string
      required:
        - value
        - event
        - stop
    Webhook_EventWebhookResponse:
      description: |-
        EventWebhookResponse is the integrator's response to an EventWebhookRequest.
        Control surface events (stream-state, program-state) are sparse — omitting them accepts defaults (stop=false, needAuth=false).
        Token, producer, and consumer events MUST be returned to allow the token to continue — omitting them will stop the token.
        An empty response {} will stop all tokens.
      type: object
      properties:
        events:
          description: Events are responses for individual events. Only include events you want to modify.
          type: array
          items:
            $ref: '#/components/schemas/Webhook_EventResponse'
    Webhook_EventResponse:
      description: |-
        EventResponse is the integrator's response for a single event.
        Only the id is required. All other fields are optional — omitted fields default to false/unset.
        Integrators must return responses for all token/producer/consumer events they want to allow.
        Omitting a token/producer/consumer event from the response will stop that token.
        Control surface events (stream-state, program-state) can be safely omitted — they default to needAuth=false, stop=false.
      type: object
      properties:
        id:
          description: ID references the event from the request
          type: string
        needAuth:
          description: NeedAuth indicates that auth is required. Only meaningful for stream-state and program-state events.
          type: boolean
        stop:
          description: Stop is set to true to stop the token/stream/program. Defaults to false if omitted.
          type: boolean
        stopReason:
          description: StopReason is an optional reason for stopping
          type: string
        appData:
          description: AppData is additional data to attach to the token/stream
          type: object
          additionalProperties:
            type: string
      required:
        - id
  responses: {}
  securitySchemes:
    JWT:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: Bearer Token authentication for applications
tags:
  - name: Auth_JSON Web Keys
    description: |
      JSON Web Keys (JWKs) are used to sign and verify JWTs.

      JWKs can be used to create JWTs to interact with the video services by creating a
      JWK with an included role of `service-account` and then creating
      a JWT using the Key ID (kid) of the JWK that has the role of `service-account`.
    x-displayName: JSON Web Keys
  - name: Auth_JSON Web Tokens
    description: |
      JSON Web Tokens (JWTs) are used to authenticate users and services across the video services.
    x-displayName: JSON Web Tokens
  - name: Auth_JWT Issuers
    description: |
      A JWT Issuer can be added to to your project to enable external JWKs to be used to sign JWTs.

      This enables services like Auth0 to be used to sign JWTs for your project.
    x-displayName: JWT Issuers
  - name: Dashboard_Config
    description: Config endpoints
    x-displayName: Config
  - name: Dashboard_External Issuer
    description: External Issuer endpoints
    x-displayName: External Issuer
  - name: Dashboard_Projects
    description: Project endpoints
    x-displayName: Projects
  - name: Events_Event
    description: Event
    x-displayName: Event
  - name: Events_History
    description: History of events
    x-displayName: History
  - name: Events_Project
    description: Project
    x-displayName: Project
  - name: Events_Webhook
    description: Webhook
    x-displayName: Webhook
  - name: Playback_Manifest
    description: Manifest endpoints
    x-displayName: Manifest
  - name: Program_Archiving
    x-displayName: Archiving
    description: ''
  - name: Program_Archiving__v1
    x-displayName: Archiving
    description: ''
  - name: Program_Assets
    description: |
      Project-scoped asset metadata + stream→asset attachment surface
      (program-assets feature). Replaces the removed v1/v2 `mediaasset`
      endpoints. Assets can be managed (Native Frame hosts the bytes
      in Backblaze) or BYO (caller supplies a publicly-resolvable
      URL). Stream→asset attachment is m:n via the `stream_assets`
      join.
    x-displayName: Assets
  - name: Program_CDN
    x-displayName: CDN
    description: ''
  - name: Program_CDN__v1
    x-displayName: CDN
    description: ''
  - name: Program_Programs
    description: Endpoints for managing programs
    x-displayName: Programs
  - name: Program_Programs__v1
    x-displayName: Programs
    description: Endpoints for managing programs
  - name: Program_RTSP
    description: Endpoints for managing RTSP sources and schedules
    x-displayName: RTSP
  - name: Program_Sessions
    x-displayName: Sessions
    description: ''
  - name: Program_Storage
    x-displayName: Storage
    description: ''
  - name: Program_Streams
    description: Endpoints for managing streams
    x-displayName: Streams
  - name: Program_Streams__v1
    x-displayName: Streams
    description: Endpoints for managing streams
x-tagGroups:
  - name: Program
    tags:
      - Program_Archiving
      - Program_Assets
      - Program_CDN
      - Program_Programs
      - Program_RTSP
      - Program_Sessions
      - Program_Storage
      - Program_Streams
  - name: Program - Legacy (v1)
    tags:
      - Program_Archiving__v1
      - Program_CDN__v1
      - Program_Programs__v1
      - Program_Streams__v1
  - name: Auth
    tags:
      - Auth_JSON Web Keys
      - Auth_JSON Web Tokens
      - Auth_JWT Issuers
  - name: Dashboard
    tags:
      - Dashboard_Config
      - Dashboard_External Issuer
      - Dashboard_Projects
  - name: Events
    tags:
      - Events_Event
      - Events_History
      - Events_Project
      - Events_Webhook
  - name: Playback
    tags:
      - Playback_Manifest
x-specs:
  program:
    version: 1.24.0
  auth:
    version: 1.7.0
  dashboard:
    version: 1.1.0
  events:
    version: 2.0.0
  manifest:
    version: 1.0.1
  webhooks:
    version: 1.1.0
