{
  "swagger": "2.0",
  "info": {
    "title": "Video service",
    "version": "0.1507.0",
    "description": "Send your API key as a bearer token: `Authorization: Bearer <api key>`."
  },
  "consumes": [
    "application/json"
  ],
  "produces": [
    "application/json"
  ],
  "securityDefinitions": {
    "ApiKey": {
      "type": "apiKey",
      "in": "header",
      "name": "Authorization",
      "description": "Your API key as a bearer token: `Authorization: Bearer <api key>`."
    }
  },
  "security": [
    {
      "ApiKey": []
    }
  ],
  "paths": {
    "/video/v1/videos/{videoRid}": {
      "get": {
        "operationId": "VideoService_get",
        "summary": "Get",
        "tags": [
          "Video Service"
        ],
        "description": "Returns video metadata associated with a video rid.",
        "deprecated": true,
        "x-deprecated": "Legacy Video-entity API. Videos are now channels on datasets; list a channel's files with listVideoChannelDatasetFiles and read dataset metadata from CatalogService.",
        "parameters": [
          {
            "name": "videoRid",
            "in": "path",
            "type": "string",
            "format": "rid",
            "x-alias": "VideoRid",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "$ref": "#/definitions/Video"
            },
            "x-example": {
              "rid": "<video rid>",
              "title": "<title>",
              "description": "<description>",
              "labels": [
                "<label>"
              ],
              "properties": {
                "<key>": "<property value>"
              },
              "createdBy": "<created by>",
              "createdAt": "2026-01-01T00:00:00Z",
              "isArchived": true,
              "originMetadata": {
                "videoSources": [
                  {
                    "type": "s3",
                    "s3": "<s3 path>"
                  }
                ],
                "timestampManifest": {
                  "type": "mcap",
                  "mcap": {
                    "mcapChannelLocator": {
                      "type": "topic",
                      "topic": "<mcap channel topic>"
                    }
                  }
                }
              },
              "allSegmentsMetadata": {
                "rid": "<video rid>",
                "numFrames": 1,
                "numSegments": 1,
                "scaleFactor": 1,
                "minAbsoluteTimestamp": {
                  "seconds": 1,
                  "nanos": 1
                },
                "maxAbsoluteTimestamp": {
                  "seconds": 1,
                  "nanos": 1
                },
                "mediaDurationSeconds": 1,
                "mediaFrameRate": 1,
                "minTimestamp": {
                  "seconds": 1,
                  "nanos": 1
                },
                "maxTimestamp": {
                  "seconds": 1,
                  "nanos": 1
                },
                "durationSeconds": 1,
                "frameRate": 1
              }
            }
          }
        }
      },
      "put": {
        "operationId": "VideoService_updateMetadata",
        "summary": "Update metadata",
        "tags": [
          "Video Service"
        ],
        "description": "Updates the metadata for a video associated with the given video rid.",
        "deprecated": true,
        "x-deprecated": "Legacy Video-entity API. Videos are now channels on datasets; update dataset metadata with CatalogService#updateDatasetMetadata and per-file titles with batchUpdateVideoChannelDatasetFiles.",
        "parameters": [
          {
            "name": "videoRid",
            "in": "path",
            "type": "string",
            "format": "rid",
            "x-alias": "VideoRid",
            "required": true
          },
          {
            "name": "request",
            "in": "body",
            "schema": {
              "$ref": "#/definitions/UpdateVideoMetadataRequest"
            },
            "required": true,
            "x-example": {
              "title": "<title>",
              "description": "<description>",
              "labels": [
                "<label>"
              ],
              "properties": {
                "<key>": "<property value>"
              },
              "startingTimestamp": {
                "seconds": 1,
                "nanos": 1
              },
              "scaleParameter": {
                "type": "trueFrameRate",
                "trueFrameRate": 1
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "$ref": "#/definitions/Video"
            },
            "x-example": {
              "rid": "<video rid>",
              "title": "<title>",
              "description": "<description>",
              "labels": [
                "<label>"
              ],
              "properties": {
                "<key>": "<property value>"
              },
              "createdBy": "<created by>",
              "createdAt": "2026-01-01T00:00:00Z",
              "isArchived": true,
              "originMetadata": {
                "videoSources": [
                  {
                    "type": "s3",
                    "s3": "<s3 path>"
                  }
                ],
                "timestampManifest": {
                  "type": "mcap",
                  "mcap": {
                    "mcapChannelLocator": {
                      "type": "topic",
                      "topic": "<mcap channel topic>"
                    }
                  }
                }
              },
              "allSegmentsMetadata": {
                "rid": "<video rid>",
                "numFrames": 1,
                "numSegments": 1,
                "scaleFactor": 1,
                "minAbsoluteTimestamp": {
                  "seconds": 1,
                  "nanos": 1
                },
                "maxAbsoluteTimestamp": {
                  "seconds": 1,
                  "nanos": 1
                },
                "mediaDurationSeconds": 1,
                "mediaFrameRate": 1,
                "minTimestamp": {
                  "seconds": 1,
                  "nanos": 1
                },
                "maxTimestamp": {
                  "seconds": 1,
                  "nanos": 1
                },
                "durationSeconds": 1,
                "frameRate": 1
              }
            }
          }
        }
      }
    },
    "/video/v1/videos/batchGet": {
      "post": {
        "operationId": "VideoService_batchGet",
        "summary": "Batch get",
        "tags": [
          "Video Service"
        ],
        "description": "Returns video metadata about each video given a set of video rids.",
        "deprecated": true,
        "x-deprecated": "Legacy Video-entity API. Videos are now channels on datasets; list a channel's files with listVideoChannelDatasetFiles and read dataset metadata from CatalogService.",
        "parameters": [
          {
            "name": "request",
            "in": "body",
            "schema": {
              "$ref": "#/definitions/GetVideosRequest"
            },
            "required": true,
            "x-example": {
              "videoRids": [
                "<video rid>"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "$ref": "#/definitions/GetVideosResponse"
            },
            "x-example": {
              "responses": [
                {
                  "rid": "<video rid>",
                  "title": "<title>",
                  "description": "<description>",
                  "labels": [
                    "<label>"
                  ],
                  "properties": {
                    "<key>": "<property value>"
                  },
                  "createdBy": "<created by>",
                  "createdAt": "2026-01-01T00:00:00Z",
                  "isArchived": true,
                  "originMetadata": {
                    "videoSources": [
                      {
                        "type": "s3",
                        "s3": "<s3 path>"
                      }
                    ],
                    "timestampManifest": {
                      "type": "mcap",
                      "mcap": {
                        "mcapChannelLocator": {
                          "type": "topic",
                          "topic": "<mcap channel topic>"
                        }
                      }
                    }
                  },
                  "allSegmentsMetadata": {
                    "rid": "<video rid>",
                    "numFrames": 1,
                    "numSegments": 1,
                    "scaleFactor": 1,
                    "minAbsoluteTimestamp": {
                      "seconds": 1,
                      "nanos": 1
                    },
                    "maxAbsoluteTimestamp": {
                      "seconds": 1,
                      "nanos": 1
                    },
                    "mediaDurationSeconds": 1,
                    "mediaFrameRate": 1,
                    "minTimestamp": {
                      "seconds": 1,
                      "nanos": 1
                    },
                    "maxTimestamp": {
                      "seconds": 1,
                      "nanos": 1
                    },
                    "durationSeconds": 1,
                    "frameRate": 1
                  }
                }
              ]
            }
          }
        }
      }
    },
    "/video/v1/videos/search": {
      "post": {
        "operationId": "VideoService_search",
        "summary": "Search",
        "tags": [
          "Video Service"
        ],
        "description": "Returns metadata about videos that match a given query.",
        "deprecated": true,
        "x-deprecated": "Legacy Video-entity API. Videos are now channels on datasets; search datasets with CatalogService#searchDatasets.",
        "parameters": [
          {
            "name": "request",
            "in": "body",
            "schema": {
              "$ref": "#/definitions/SearchVideosRequest"
            },
            "required": true,
            "x-example": {
              "query": {
                "type": "searchText",
                "searchText": "<search text>"
              },
              "sortOptions": {
                "isDescending": true,
                "field": "CREATED_AT"
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "$ref": "#/definitions/SearchVideosResponse"
            },
            "x-example": {
              "results": [
                {
                  "rid": "<video rid>",
                  "title": "<title>",
                  "description": "<description>",
                  "labels": [
                    "<label>"
                  ],
                  "properties": {
                    "<key>": "<property value>"
                  },
                  "createdBy": "<created by>",
                  "createdAt": "2026-01-01T00:00:00Z",
                  "isArchived": true,
                  "originMetadata": {
                    "videoSources": [
                      {
                        "type": "s3",
                        "s3": "<s3 path>"
                      }
                    ],
                    "timestampManifest": {
                      "type": "mcap",
                      "mcap": {
                        "mcapChannelLocator": {
                          "type": "topic",
                          "topic": "<mcap channel topic>"
                        }
                      }
                    }
                  },
                  "allSegmentsMetadata": {
                    "rid": "<video rid>",
                    "numFrames": 1,
                    "numSegments": 1,
                    "scaleFactor": 1,
                    "minAbsoluteTimestamp": {
                      "seconds": 1,
                      "nanos": 1
                    },
                    "maxAbsoluteTimestamp": {
                      "seconds": 1,
                      "nanos": 1
                    },
                    "mediaDurationSeconds": 1,
                    "mediaFrameRate": 1,
                    "minTimestamp": {
                      "seconds": 1,
                      "nanos": 1
                    },
                    "maxTimestamp": {
                      "seconds": 1,
                      "nanos": 1
                    },
                    "durationSeconds": 1,
                    "frameRate": 1
                  }
                }
              ],
              "nextPageToken": "<token>"
            }
          }
        }
      }
    },
    "/video/v1/videos": {
      "post": {
        "operationId": "VideoService_create",
        "summary": "Create",
        "tags": [
          "Video Service"
        ],
        "description": "Creates and persists a video entity with the given metadata.",
        "deprecated": true,
        "x-deprecated": "Legacy Video-entity API. Videos are now channels on datasets; ingest with videoV2 options targeting a dataset channel instead of creating a Video.",
        "parameters": [
          {
            "name": "request",
            "in": "body",
            "schema": {
              "$ref": "#/definitions/CreateVideoRequest"
            },
            "required": true,
            "x-example": {
              "title": "<title>"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "$ref": "#/definitions/Video"
            },
            "x-example": {
              "rid": "<video rid>",
              "title": "<title>",
              "description": "<description>",
              "labels": [
                "<label>"
              ],
              "properties": {
                "<key>": "<property value>"
              },
              "createdBy": "<created by>",
              "createdAt": "2026-01-01T00:00:00Z",
              "isArchived": true,
              "originMetadata": {
                "videoSources": [
                  {
                    "type": "s3",
                    "s3": "<s3 path>"
                  }
                ],
                "timestampManifest": {
                  "type": "mcap",
                  "mcap": {
                    "mcapChannelLocator": {
                      "type": "topic",
                      "topic": "<mcap channel topic>"
                    }
                  }
                }
              },
              "allSegmentsMetadata": {
                "rid": "<video rid>",
                "numFrames": 1,
                "numSegments": 1,
                "scaleFactor": 1,
                "minAbsoluteTimestamp": {
                  "seconds": 1,
                  "nanos": 1
                },
                "maxAbsoluteTimestamp": {
                  "seconds": 1,
                  "nanos": 1
                },
                "mediaDurationSeconds": 1,
                "mediaFrameRate": 1,
                "minTimestamp": {
                  "seconds": 1,
                  "nanos": 1
                },
                "maxTimestamp": {
                  "seconds": 1,
                  "nanos": 1
                },
                "durationSeconds": 1,
                "frameRate": 1
              }
            }
          }
        }
      }
    },
    "/video/v1/videos/{videoRid}/ingest-status": {
      "get": {
        "operationId": "VideoService_getIngestStatus",
        "summary": "Get ingest status",
        "tags": [
          "Video Service"
        ],
        "deprecated": true,
        "x-deprecated": "Legacy Video-entity API. Videos are now channels on datasets; ingest status is tracked per file on the Catalog dataset file (CatalogService#getDatasetFile).",
        "parameters": [
          {
            "name": "videoRid",
            "in": "path",
            "type": "string",
            "format": "rid",
            "x-alias": "VideoRid",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "$ref": "#/definitions/DetailedIngestStatus"
            },
            "x-example": {
              "type": "success",
              "success": {}
            }
          }
        }
      }
    },
    "/video/v1/videos/batch-get-ingest-status": {
      "post": {
        "operationId": "VideoService_batchGetIngestStatus",
        "summary": "Batch get ingest status",
        "tags": [
          "Video Service"
        ],
        "deprecated": true,
        "x-deprecated": "Legacy Video-entity API. Videos are now channels on datasets; ingest status is tracked per file on the Catalog dataset file (CatalogService#batchGetDatasetFiles).",
        "parameters": [
          {
            "name": "videoRids",
            "in": "body",
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "format": "rid",
                "x-alias": "VideoRid"
              },
              "uniqueItems": true,
              "example": [
                "<video rid>"
              ]
            },
            "required": false,
            "x-example": [
              "<video rid>"
            ]
          }
        ],
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "type": "object",
              "additionalProperties": {
                "$ref": "#/definitions/DetailedIngestStatus"
              },
              "x-map-key": "VideoRid"
            },
            "x-example": {
              "<key>": {
                "type": "success",
                "success": {}
              }
            }
          }
        }
      }
    },
    "/video/v1/videos/enriched-ingest-status": {
      "post": {
        "operationId": "VideoService_getEnrichedIngestStatus",
        "summary": "Get enriched ingest status",
        "tags": [
          "Video Service"
        ],
        "deprecated": true,
        "x-deprecated": "Legacy Video-entity API. Videos are now channels on datasets; ingest status is tracked per file on the Catalog dataset file (CatalogService#getDatasetFile).",
        "parameters": [
          {
            "name": "request",
            "in": "body",
            "schema": {
              "$ref": "#/definitions/GetEnrichedVideoIngestStatusRequest"
            },
            "required": true,
            "x-example": {
              "videoRid": "<video rid>"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "$ref": "#/definitions/EnrichedVideoIngestStatus"
            },
            "x-example": {
              "status": {
                "type": "ready",
                "ready": {}
              },
              "fileIngestStatus": {
                "<key>": {
                  "type": "success",
                  "success": {}
                }
              },
              "nextPageToken": "<token>"
            }
          },
          "204": {
            "description": "No content, when there is nothing to return."
          }
        }
      }
    },
    "/video/v1/videos/{videoRid}/archive": {
      "put": {
        "operationId": "VideoService_archive",
        "summary": "Archive",
        "tags": [
          "Video Service"
        ],
        "description": "Archives a video, which excludes it from search and hides it from being publicly visible, but does not permanently delete it. Archived videos can be unarchived.",
        "deprecated": true,
        "x-deprecated": "Legacy Video-entity API. Videos are now channels on datasets; archive the backing dataset with CatalogService#archiveDataset, or delete individual files with IngestService#deleteFile.",
        "parameters": [
          {
            "name": "videoRid",
            "in": "path",
            "type": "string",
            "format": "rid",
            "x-alias": "VideoRid",
            "required": true
          }
        ],
        "responses": {
          "204": {
            "description": "No content."
          }
        }
      }
    },
    "/video/v1/videos/{videoRid}/unarchive": {
      "put": {
        "operationId": "VideoService_unarchive",
        "summary": "Unarchive",
        "tags": [
          "Video Service"
        ],
        "description": "Unarchives a previously archived video.",
        "deprecated": true,
        "x-deprecated": "Legacy Video-entity API. Videos are now channels on datasets; unarchive the backing dataset with CatalogService#unarchiveDataset.",
        "parameters": [
          {
            "name": "videoRid",
            "in": "path",
            "type": "string",
            "format": "rid",
            "x-alias": "VideoRid",
            "required": true
          }
        ],
        "responses": {
          "204": {
            "description": "No content."
          }
        }
      }
    },
    "/video/v1/videos/{videoRid}/playlist": {
      "get": {
        "operationId": "VideoService_getPlaylist",
        "summary": "Get playlist",
        "tags": [
          "Video Service"
        ],
        "description": "Generates an HLS playlist for a video within optional time bounds. Uses GET with query parameters for HLS.js compatibility. The HLS playlist will contain links to all of the segments in the video that overlap with the given bounds, or all segments if no bounds are provided.\n\nNote: The start and end parameters must either both be provided or both be omitted. Providing only one will result in a MissingTimestampBoundPair error.",
        "deprecated": true,
        "x-deprecated": "Replaced by getPlaylistV2, which addresses the video channel series (channel + tags) instead of a Video rid.",
        "parameters": [
          {
            "name": "videoRid",
            "in": "path",
            "type": "string",
            "format": "rid",
            "x-alias": "VideoRid",
            "required": true
          },
          {
            "name": "start",
            "in": "query",
            "type": "string",
            "required": false,
            "description": "Start bound as ISO-8601 timestamp (e.g., \"2024-01-01T00:00:00Z\"). Must be provided together with end, or neither."
          },
          {
            "name": "end",
            "in": "query",
            "type": "string",
            "required": false,
            "description": "End bound as ISO-8601 timestamp (e.g., \"2024-01-01T01:00:00Z\"). Must be provided together with start, or neither."
          }
        ],
        "produces": [
          "application/octet-stream"
        ],
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "type": "string",
              "format": "binary"
            }
          }
        }
      }
    },
    "/video/v1/videos/{videoRid}/segment-summaries": {
      "get": {
        "operationId": "VideoService_getSegmentSummaries",
        "summary": "Get segment summaries",
        "tags": [
          "Video Service"
        ],
        "description": "Returns the min and max absolute and media timestamps for each segment in a video. To be used during frame-timestamp mapping.",
        "deprecated": true,
        "x-deprecated": "Replaced by getSegmentSummariesInBounds. Will be removed after April 15th.",
        "parameters": [
          {
            "name": "videoRid",
            "in": "path",
            "type": "string",
            "format": "rid",
            "x-alias": "VideoRid",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "type": "array",
              "items": {
                "$ref": "#/definitions/SegmentSummary"
              }
            },
            "x-example": [
              {
                "minAbsoluteTimestamp": {
                  "seconds": 1,
                  "nanos": 1
                },
                "maxAbsoluteTimestamp": {
                  "seconds": 1,
                  "nanos": 1
                },
                "minMediaTimestamp": 1,
                "maxMediaTimestamp": 1
              }
            ]
          }
        }
      }
    },
    "/video/v1/videos/{videoRid}/playlist-in-bounds": {
      "post": {
        "operationId": "VideoService_getPlaylistInBounds",
        "summary": "Get playlist in bounds",
        "tags": [
          "Video Service"
        ],
        "description": "Generates an HLS playlist for a video with the given video rid to enable playback within an optional set of bounds. The HLS playlist will contain links to all of the segments in the video that overlap with the given bounds. playlist will be limited to the given bounds.",
        "deprecated": true,
        "x-deprecated": "Use getPlaylist (GET) for HLS.js compatibility.",
        "parameters": [
          {
            "name": "videoRid",
            "in": "path",
            "type": "string",
            "format": "rid",
            "x-alias": "VideoRid",
            "required": true
          },
          {
            "name": "request",
            "in": "body",
            "schema": {
              "$ref": "#/definitions/GetPlaylistInBoundsRequest"
            },
            "required": true,
            "x-example": {
              "bounds": {
                "start": {
                  "seconds": 1,
                  "nanos": 1
                },
                "end": {
                  "seconds": 1,
                  "nanos": 1
                }
              }
            }
          }
        ],
        "produces": [
          "application/octet-stream"
        ],
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "type": "string",
              "format": "binary"
            }
          }
        }
      }
    },
    "/video/v2/videos/playlist-in-bounds": {
      "post": {
        "operationId": "VideoService_getPlaylistInBoundsV2",
        "summary": "Get playlist in bounds v2",
        "tags": [
          "Video Service"
        ],
        "description": "Generates an HLS playlist for a video series (identified by channel + tags) within bounds.",
        "deprecated": true,
        "x-deprecated": "Use getPlaylistV2 (GET) for HLS.js compatibility.",
        "parameters": [
          {
            "name": "request",
            "in": "body",
            "schema": {
              "$ref": "#/definitions/GetPlaylistInBoundsForChannelRequest"
            },
            "required": true,
            "x-example": {
              "channelSeries": {
                "type": "dataSource",
                "dataSource": {
                  "dataSourceRid": "<data source rid>",
                  "channel": "<channel>"
                }
              },
              "bounds": {
                "start": {
                  "seconds": 1,
                  "nanos": 1
                },
                "end": {
                  "seconds": 1,
                  "nanos": 1
                }
              }
            }
          }
        ],
        "produces": [
          "application/octet-stream"
        ],
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "type": "string",
              "format": "binary"
            }
          }
        }
      }
    },
    "/video/v2/videos/playlist": {
      "get": {
        "operationId": "VideoService_getPlaylistV2",
        "summary": "Get playlist v2",
        "tags": [
          "Video Service"
        ],
        "description": "Generates an HLS playlist for a video series within time bounds. Specify either dataSourceRid OR (assetRid + dataScopeName) to identify the series source.\n\nNote: Both start and end parameters are required and must be provided together.",
        "parameters": [
          {
            "name": "dataSourceRid",
            "in": "query",
            "type": "string",
            "format": "rid",
            "x-alias": "DataSourceRid",
            "required": false,
            "description": "Data source RID (mutually exclusive with assetRid)"
          },
          {
            "name": "assetRid",
            "in": "query",
            "type": "string",
            "format": "rid",
            "x-alias": "AssetRid",
            "required": false,
            "description": "Asset RID (mutually exclusive with dataSourceRid, requires dataScopeName)"
          },
          {
            "name": "dataScopeName",
            "in": "query",
            "type": "string",
            "required": false,
            "description": "Data scope name (required when using assetRid)"
          },
          {
            "name": "channel",
            "in": "query",
            "type": "string",
            "required": true,
            "description": "Channel name"
          },
          {
            "name": "tags",
            "in": "query",
            "type": "string",
            "required": false,
            "description": "Tags as JSON-encoded map (e.g., {\"vehicle\":\"car1\"})"
          },
          {
            "name": "start",
            "in": "query",
            "type": "string",
            "required": true,
            "description": "Required start bound as ISO-8601 timestamp (e.g., \"2024-01-01T00:00:00Z\"). Must be provided with end."
          },
          {
            "name": "end",
            "in": "query",
            "type": "string",
            "required": true,
            "description": "Required end bound as ISO-8601 timestamp (e.g., \"2024-01-01T01:00:00Z\"). Must be provided with start."
          }
        ],
        "produces": [
          "application/octet-stream"
        ],
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "type": "string",
              "format": "binary"
            }
          }
        }
      }
    },
    "/video/v1/videos/{videoRid}/segment-summaries-in-bounds": {
      "post": {
        "operationId": "VideoService_getSegmentSummariesInBounds",
        "summary": "Get segment summaries in bounds",
        "tags": [
          "Video Service"
        ],
        "description": "Returns the min and max absolute and media timestamps for each segment in a video that overlap with an optional set of bounds.",
        "deprecated": true,
        "x-deprecated": "Replaced by getSegmentSummariesInBoundsV2, which addresses the video channel series (channel + tags) instead of a Video rid.",
        "parameters": [
          {
            "name": "videoRid",
            "in": "path",
            "type": "string",
            "format": "rid",
            "x-alias": "VideoRid",
            "required": true
          },
          {
            "name": "request",
            "in": "body",
            "schema": {
              "$ref": "#/definitions/GetSegmentSummariesInBoundsRequest"
            },
            "required": true,
            "x-example": {
              "bounds": {
                "start": {
                  "seconds": 1,
                  "nanos": 1
                },
                "end": {
                  "seconds": 1,
                  "nanos": 1
                }
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "type": "array",
              "items": {
                "$ref": "#/definitions/SegmentSummary"
              }
            },
            "x-example": [
              {
                "minAbsoluteTimestamp": {
                  "seconds": 1,
                  "nanos": 1
                },
                "maxAbsoluteTimestamp": {
                  "seconds": 1,
                  "nanos": 1
                },
                "minMediaTimestamp": 1,
                "maxMediaTimestamp": 1
              }
            ]
          }
        }
      }
    },
    "/video/v2/videos/segment-summaries-in-bounds": {
      "post": {
        "operationId": "VideoService_getSegmentSummariesInBoundsV2",
        "summary": "Get segment summaries in bounds v2",
        "tags": [
          "Video Service"
        ],
        "description": "Returns the min and max absolute and media timestamps for each segment matching a video series (identified by channel + tags) within the specified bounds.",
        "parameters": [
          {
            "name": "request",
            "in": "body",
            "schema": {
              "$ref": "#/definitions/GetSegmentSummariesInBoundsForChannelRequest"
            },
            "required": true,
            "x-example": {
              "channelSeries": {
                "type": "dataSource",
                "dataSource": {
                  "dataSourceRid": "<data source rid>",
                  "channel": "<channel>"
                }
              },
              "bounds": {
                "start": {
                  "seconds": 1,
                  "nanos": 1
                },
                "end": {
                  "seconds": 1,
                  "nanos": 1
                }
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "type": "array",
              "items": {
                "$ref": "#/definitions/SegmentSummaryV2"
              }
            },
            "x-example": [
              {
                "datasetFileId": "<dataset file id>",
                "minAbsoluteTimestamp": {
                  "seconds": 1,
                  "nanos": 1
                },
                "maxAbsoluteTimestamp": {
                  "seconds": 1,
                  "nanos": 1
                },
                "minMediaTimestamp": 1,
                "maxMediaTimestamp": 1
              }
            ]
          }
        }
      }
    },
    "/video/v2/videos/segment-metadata": {
      "post": {
        "operationId": "VideoService_getSegmentMetadataV2",
        "summary": "Get segment metadata v2",
        "tags": [
          "Video Service"
        ],
        "description": "Returns aggregated segment metadata for a video channel series, including total frames, segment count, min/max timestamps, and average frame rate. Optionally filter by time bounds.",
        "parameters": [
          {
            "name": "request",
            "in": "body",
            "schema": {
              "$ref": "#/definitions/GetSegmentMetadataForChannelRequest"
            },
            "required": true,
            "x-example": {
              "channelSeries": {
                "type": "dataSource",
                "dataSource": {
                  "dataSourceRid": "<data source rid>",
                  "channel": "<channel>"
                }
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "$ref": "#/definitions/VideoChannelSegmentsMetadata"
            },
            "x-example": {
              "numFrames": 1,
              "numSegments": 1,
              "minAbsoluteTimestamp": {
                "seconds": 1,
                "nanos": 1
              },
              "maxAbsoluteTimestamp": {
                "seconds": 1,
                "nanos": 1
              },
              "mediaDurationSeconds": 1,
              "mediaFrameRate": 1
            }
          },
          "204": {
            "description": "No content, when there is nothing to return."
          }
        }
      }
    },
    "/video/v2/videos/get-segment-by-timestamp": {
      "post": {
        "operationId": "VideoService_getSegmentByTimestampV2",
        "summary": "Get segment by timestamp v2",
        "tags": [
          "Video Service"
        ],
        "description": "Returns metadata for the segment within a video series containing the requested absolute timestamp.",
        "parameters": [
          {
            "name": "request",
            "in": "body",
            "schema": {
              "$ref": "#/definitions/GetSegmentByTimestampV2Request"
            },
            "required": true,
            "x-example": {
              "channelSeries": {
                "type": "dataSource",
                "dataSource": {
                  "dataSourceRid": "<data source rid>",
                  "channel": "<channel>"
                }
              },
              "timestamp": {
                "seconds": 1,
                "nanos": 1
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "$ref": "#/definitions/SegmentV2"
            },
            "x-example": {
              "rid": "<segment rid>",
              "datasetFileId": "<dataset file id>",
              "dataHandle": {
                "type": "s3",
                "s3": "<s3 path>"
              },
              "frameRate": 1,
              "durationSeconds": 1,
              "timestamps": {
                "type": "timestampMappings",
                "timestampMappings": {
                  "mediaTimestamps": [
                    1
                  ],
                  "absoluteTimestamps": [
                    {
                      "seconds": 1,
                      "nanos": 1
                    }
                  ]
                }
              }
            }
          },
          "204": {
            "description": "No content, when there is nothing to return."
          }
        }
      }
    },
    "/video/v1/videos/{videoRid}/get-segment-at-or-after-timestamp": {
      "post": {
        "operationId": "VideoService_getSegmentAtOrAfterTimestamp",
        "summary": "Get segment at or after timestamp",
        "tags": [
          "Video Service"
        ],
        "description": "Returns metadata for the segment containing the requested absolute timestamp. If no segment contains the timestamp, returns the closest segment starting after the timestamp. Returns empty if no segment is found at or after the timestamp.",
        "deprecated": true,
        "x-deprecated": "Replaced by getSegmentAtOrAfterTimestampV2, which addresses the video channel series (channel + tags) instead of a Video rid.",
        "parameters": [
          {
            "name": "videoRid",
            "in": "path",
            "type": "string",
            "format": "rid",
            "x-alias": "VideoRid",
            "required": true
          },
          {
            "name": "request",
            "in": "body",
            "schema": {
              "$ref": "#/definitions/GetSegmentAtOrAfterTimestampRequest"
            },
            "required": true,
            "x-example": {
              "timestamp": {
                "seconds": 1,
                "nanos": 1
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "$ref": "#/definitions/Segment"
            },
            "x-example": {
              "rid": "<segment rid>",
              "videoRid": "<video rid>",
              "dataHandle": {
                "type": "s3",
                "s3": "<s3 path>"
              },
              "frameRate": 1,
              "durationSeconds": 1,
              "timestamps": {
                "type": "timestampMappings",
                "timestampMappings": {
                  "mediaTimestamps": [
                    1
                  ],
                  "absoluteTimestamps": [
                    {
                      "seconds": 1,
                      "nanos": 1
                    }
                  ]
                }
              }
            }
          },
          "204": {
            "description": "No content, when there is nothing to return."
          }
        }
      }
    },
    "/video/v2/videos/get-segment-at-or-after-timestamp": {
      "post": {
        "operationId": "VideoService_getSegmentAtOrAfterTimestampV2",
        "summary": "Get segment at or after timestamp v2",
        "tags": [
          "Video Service"
        ],
        "description": "Returns metadata for the segment containing the requested absolute timestamp for a video series (identified by channel + tags). If no segment contains the timestamp, returns the closest segment starting after the timestamp. Returns empty if no segment is found at or after the timestamp.",
        "parameters": [
          {
            "name": "request",
            "in": "body",
            "schema": {
              "$ref": "#/definitions/GetSegmentAtOrAfterTimestampV2Request"
            },
            "required": true,
            "x-example": {
              "channelSeries": {
                "type": "dataSource",
                "dataSource": {
                  "dataSourceRid": "<data source rid>",
                  "channel": "<channel>"
                }
              },
              "timestamp": {
                "seconds": 1,
                "nanos": 1
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "$ref": "#/definitions/SegmentV2"
            },
            "x-example": {
              "rid": "<segment rid>",
              "datasetFileId": "<dataset file id>",
              "dataHandle": {
                "type": "s3",
                "s3": "<s3 path>"
              },
              "frameRate": 1,
              "durationSeconds": 1,
              "timestamps": {
                "type": "timestampMappings",
                "timestampMappings": {
                  "mediaTimestamps": [
                    1
                  ],
                  "absoluteTimestamps": [
                    {
                      "seconds": 1,
                      "nanos": 1
                    }
                  ]
                }
              }
            }
          },
          "204": {
            "description": "No content, when there is nothing to return."
          }
        }
      }
    },
    "/video/v1/videos/{videoRid}/get-ranges-with-existing-segment-data": {
      "post": {
        "operationId": "VideoService_getFileSummaries",
        "summary": "Get file summaries",
        "tags": [
          "Video Service"
        ],
        "description": "Returns the min and max absolute timestamps from non-archived video files associated with a given video that overlap with an optional set of bounds. The files on the edges of the bounds will be truncated to segments that are inside or overlap with the bounds.",
        "deprecated": true,
        "x-deprecated": "Replaced by listVideoChannelDatasetFiles, which returns the dataset files backing a video channel together with the bounds each file contributes.",
        "parameters": [
          {
            "name": "videoRid",
            "in": "path",
            "type": "string",
            "format": "rid",
            "x-alias": "VideoRid",
            "required": true
          },
          {
            "name": "request",
            "in": "body",
            "schema": {
              "$ref": "#/definitions/GetFileSummariesRequest"
            },
            "required": true,
            "x-example": {
              "bounds": {
                "start": {
                  "seconds": 1,
                  "nanos": 1
                },
                "end": {
                  "seconds": 1,
                  "nanos": 1
                }
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "$ref": "#/definitions/GetFileSummariesResponse"
            },
            "x-example": {
              "fileSummaries": [
                {
                  "fileRid": "<video file rid>",
                  "bounds": {
                    "start": {
                      "seconds": 1,
                      "nanos": 1
                    },
                    "end": {
                      "seconds": 1,
                      "nanos": 1
                    }
                  }
                }
              ]
            }
          }
        }
      }
    },
    "/video/v1/videos/{videoRid}/streaming/whip": {
      "post": {
        "operationId": "VideoService_generateWhipStream",
        "summary": "Generate WHIP stream",
        "tags": [
          "Video Service"
        ],
        "description": "Generates a stream ID scoped to a video and returns a WHIP URL with a MediaMTX JWT and ICE servers. Enforces write permission on the video.",
        "deprecated": true,
        "x-deprecated": "Replaced by generateWhipStreamV2, which addresses a channel-backed live video series instead of a Video rid.",
        "parameters": [
          {
            "name": "videoRid",
            "in": "path",
            "type": "string",
            "format": "rid",
            "x-alias": "VideoRid",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "$ref": "#/definitions/GenerateWhipStreamResponse"
            },
            "x-example": {
              "streamId": "<stream id>",
              "whipUrl": "<whip url>",
              "iceServers": [
                {
                  "urls": [
                    "<urls>"
                  ],
                  "username": "<username>",
                  "credential": "<credential>"
                }
              ]
            }
          }
        }
      }
    },
    "/video/v2/videos/streaming/whip": {
      "post": {
        "operationId": "VideoService_generateWhipStreamV2",
        "summary": "Generate WHIP stream v2",
        "tags": [
          "Video Service"
        ],
        "description": "Generates a stream ID scoped to a channel-backed live video series and returns a WHIP URL with a MediaMTX JWT and ICE servers. Currently only datasource-backed dataset channels are supported.",
        "parameters": [
          {
            "name": "request",
            "in": "body",
            "schema": {
              "$ref": "#/definitions/GenerateWhipStreamV2Request"
            },
            "required": true,
            "x-example": {
              "channelSeries": {
                "type": "dataSource",
                "dataSource": {
                  "dataSourceRid": "<data source rid>",
                  "channel": "<channel>"
                }
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "$ref": "#/definitions/GenerateWhipStreamResponse"
            },
            "x-example": {
              "streamId": "<stream id>",
              "whipUrl": "<whip url>",
              "iceServers": [
                {
                  "urls": [
                    "<urls>"
                  ],
                  "username": "<username>",
                  "credential": "<credential>"
                }
              ]
            }
          }
        }
      }
    },
    "/video/v1/videos/{videoRid}/streaming/whep": {
      "post": {
        "operationId": "VideoService_generateWhepStream",
        "summary": "Generate WHEP stream",
        "tags": [
          "Video Service"
        ],
        "description": "Returns WHEP URL, ICE servers, and token for playing back the active stream. Returns empty if there is no active stream. Enforces read permission on the video.",
        "deprecated": true,
        "x-deprecated": "Replaced by generateWhepStreamV2, which addresses a channel-backed live video series instead of a Video rid.",
        "parameters": [
          {
            "name": "videoRid",
            "in": "path",
            "type": "string",
            "format": "rid",
            "x-alias": "VideoRid",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "$ref": "#/definitions/GenerateWhepStreamResponse"
            },
            "x-example": {
              "whepUrl": "<whep url>",
              "iceServers": [
                {
                  "urls": [
                    "<urls>"
                  ],
                  "username": "<username>",
                  "credential": "<credential>"
                }
              ],
              "token": "<token>"
            }
          },
          "204": {
            "description": "No content, when there is nothing to return."
          }
        }
      }
    },
    "/video/v2/videos/streaming/whep": {
      "post": {
        "operationId": "VideoService_generateWhepStreamV2",
        "summary": "Generate WHEP stream v2",
        "tags": [
          "Video Service"
        ],
        "description": "Returns WHEP URL, ICE servers, and token for playing back the active channel-backed live video stream. Returns empty if there is no active stream. Currently only datasource-backed dataset channels are supported.",
        "parameters": [
          {
            "name": "request",
            "in": "body",
            "schema": {
              "$ref": "#/definitions/GenerateWhepStreamV2Request"
            },
            "required": true,
            "x-example": {
              "channelSeries": {
                "type": "dataSource",
                "dataSource": {
                  "dataSourceRid": "<data source rid>",
                  "channel": "<channel>"
                }
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "$ref": "#/definitions/GenerateWhepStreamResponse"
            },
            "x-example": {
              "whepUrl": "<whep url>",
              "iceServers": [
                {
                  "urls": [
                    "<urls>"
                  ],
                  "username": "<username>",
                  "credential": "<credential>"
                }
              ],
              "token": "<token>"
            }
          },
          "204": {
            "description": "No content, when there is nothing to return."
          }
        }
      }
    },
    "/video/v1/videos/{videoRid}/streaming/streams/{streamId}": {
      "get": {
        "operationId": "VideoService_getStream",
        "summary": "Get stream",
        "tags": [
          "Video Service"
        ],
        "description": "Returns stream session metadata for a given stream ID scoped to the video. Enforces read permission on the video.",
        "parameters": [
          {
            "name": "videoRid",
            "in": "path",
            "type": "string",
            "format": "rid",
            "x-alias": "VideoRid",
            "required": true
          },
          {
            "name": "streamId",
            "in": "path",
            "type": "string",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "$ref": "#/definitions/VideoStream"
            },
            "x-example": {
              "streamId": "<stream id>",
              "videoRid": "<video rid>",
              "streamStatus": "<stream status>",
              "start": "2026-01-01T00:00:00Z",
              "end": "2026-01-01T00:00:00Z",
              "createdAt": "2026-01-01T00:00:00Z",
              "updatedAt": "2026-01-01T00:00:00Z"
            }
          },
          "204": {
            "description": "No content, when there is nothing to return."
          }
        }
      }
    },
    "/video/v1/videos/{videoRid}/streaming/streams-in-bounds": {
      "post": {
        "operationId": "VideoService_getStreamsInBounds",
        "summary": "Get streams in bounds",
        "tags": [
          "Video Service"
        ],
        "description": "Returns all stream sessions for a video that overlap with the specified time bounds. A stream overlaps if there is any intersection between its [start, end] interval and the provided bounds. Enforces read permission on the video.",
        "deprecated": true,
        "x-deprecated": "Replaced by getStreamsInBoundsV2, which addresses a channel-backed live video series instead of a Video rid.",
        "parameters": [
          {
            "name": "videoRid",
            "in": "path",
            "type": "string",
            "format": "rid",
            "x-alias": "VideoRid",
            "required": true
          },
          {
            "name": "request",
            "in": "body",
            "schema": {
              "$ref": "#/definitions/GetStreamsInBoundsRequest"
            },
            "required": true,
            "x-example": {
              "bounds": {
                "start": {
                  "seconds": 1,
                  "nanos": 1
                },
                "end": {
                  "seconds": 1,
                  "nanos": 1
                }
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "$ref": "#/definitions/GetStreamsInBoundsResponse"
            },
            "x-example": {
              "streams": [
                {
                  "streamId": "<stream id>",
                  "videoRid": "<video rid>",
                  "streamStatus": "<stream status>",
                  "start": "2026-01-01T00:00:00Z",
                  "end": "2026-01-01T00:00:00Z",
                  "createdAt": "2026-01-01T00:00:00Z",
                  "updatedAt": "2026-01-01T00:00:00Z"
                }
              ],
              "nextPageToken": "<token>"
            }
          }
        }
      }
    },
    "/video/v2/videos/streaming/streams-in-bounds": {
      "post": {
        "operationId": "VideoService_getStreamsInBoundsV2",
        "summary": "Get streams in bounds v2",
        "tags": [
          "Video Service"
        ],
        "description": "Returns all channel-backed stream sessions for a dataset/channel that overlap with the specified time bounds. A stream overlaps if there is any intersection between its [start, end] interval and the provided bounds. Enforces read metadata permission on the dataset.",
        "parameters": [
          {
            "name": "request",
            "in": "body",
            "schema": {
              "$ref": "#/definitions/GetStreamsInBoundsForChannelRequest"
            },
            "required": true,
            "x-example": {
              "channelSeries": {
                "type": "dataSource",
                "dataSource": {
                  "dataSourceRid": "<data source rid>",
                  "channel": "<channel>"
                }
              },
              "bounds": {
                "start": {
                  "seconds": 1,
                  "nanos": 1
                },
                "end": {
                  "seconds": 1,
                  "nanos": 1
                }
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "$ref": "#/definitions/GetStreamsInBoundsV2Response"
            },
            "x-example": {
              "streams": [
                {
                  "streamId": "<stream id>",
                  "streamStatus": "<stream status>",
                  "createdAt": "2026-01-01T00:00:00Z",
                  "updatedAt": "2026-01-01T00:00:00Z",
                  "start": "2026-01-01T00:00:00Z",
                  "end": "2026-01-01T00:00:00Z"
                }
              ],
              "nextPageToken": "<token>"
            }
          }
        }
      }
    },
    "/video/v2/videos/channel-dataset-files": {
      "post": {
        "operationId": "VideoService_listVideoChannelDatasetFiles",
        "summary": "List video channel dataset files",
        "tags": [
          "Video Service"
        ],
        "description": "Returns the dataset files backing a video channel (identified by channel + tags), ordered by start timestamp ascending and paginated. Each entry carries the min/max absolute timestamps the file contributes to the channel. Optionally filtered by time bounds. Streamed sessions are not included; use getStreamsInBoundsV2 for those. Enforces read metadata permission on the datasource.",
        "parameters": [
          {
            "name": "request",
            "in": "body",
            "schema": {
              "$ref": "#/definitions/ListVideoChannelDatasetFilesRequest"
            },
            "required": true,
            "x-example": {
              "channelSeries": {
                "type": "dataSource",
                "dataSource": {
                  "dataSourceRid": "<data source rid>",
                  "channel": "<channel>"
                }
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "$ref": "#/definitions/ListVideoChannelDatasetFilesResponse"
            },
            "x-example": {
              "datasetFiles": [
                {
                  "datasetFileId": "<dataset file id>",
                  "start": {
                    "seconds": 1,
                    "nanos": 1
                  },
                  "end": {
                    "seconds": 1,
                    "nanos": 1
                  }
                }
              ],
              "nextPageToken": "<token>"
            }
          }
        }
      }
    },
    "/video/v2/videos/channel-dataset-files/batch-update": {
      "post": {
        "operationId": "VideoService_batchUpdateVideoChannelDatasetFiles",
        "summary": "Batch update video channel dataset files",
        "tags": [
          "Video Service"
        ],
        "description": "Updates one or more video dataset files in a channel in a single transaction. Each update may set a new absolute start timestamp (segments shifted so the earliest starts at the given timestamp), a scale parameter (frame timestamps rescaled around the file's start), and/or a new title (file name). If a resulting layout would overlap segments of another file in the channel, no files are updated and VIDEO_SEGMENT_CONFLICT is thrown (all-or-nothing). Returns the updated files with their new bounds and persists those bounds to the corresponding Catalog DatasetFile. Currently only datasource-backed dataset channels are supported. Enforces write data permission on the datasource.",
        "parameters": [
          {
            "name": "request",
            "in": "body",
            "schema": {
              "$ref": "#/definitions/BatchUpdateVideoChannelDatasetFilesRequest"
            },
            "required": true,
            "x-example": {
              "channelSeries": {
                "type": "dataSource",
                "dataSource": {
                  "dataSourceRid": "<data source rid>",
                  "channel": "<channel>"
                }
              },
              "datasetRid": "<dataset rid>",
              "updates": [
                {
                  "datasetFileId": "<dataset file id>"
                }
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "$ref": "#/definitions/BatchUpdateVideoChannelDatasetFilesResponse"
            },
            "x-example": {
              "datasetFiles": [
                {
                  "datasetFileId": "<dataset file id>",
                  "start": {
                    "seconds": 1,
                    "nanos": 1
                  },
                  "end": {
                    "seconds": 1,
                    "nanos": 1
                  }
                }
              ]
            }
          }
        }
      }
    },
    "/video/v1/videos/{videoRid}/streaming/end": {
      "post": {
        "operationId": "VideoService_endStream",
        "summary": "End stream",
        "tags": [
          "Video Service"
        ],
        "description": "Marks the active stream session as ended for the video. Throws VIDEO_NOT_FOUND if no active stream exists. Enforces write permission on the video.",
        "deprecated": true,
        "x-deprecated": "Replaced by endStreamV2, which addresses a channel-backed live video series instead of a Video rid.",
        "parameters": [
          {
            "name": "videoRid",
            "in": "path",
            "type": "string",
            "format": "rid",
            "x-alias": "VideoRid",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "$ref": "#/definitions/EndStreamResponse"
            },
            "x-example": {
              "streamId": "<stream id>",
              "endedAt": {
                "seconds": 1,
                "nanos": 1
              }
            }
          }
        }
      }
    },
    "/video/v2/videos/streaming/end": {
      "post": {
        "operationId": "VideoService_endStreamV2",
        "summary": "End stream v2",
        "tags": [
          "Video Service"
        ],
        "description": "Marks the active stream session as ended for a channel-backed live video series. Returns empty when no active stream exists, so a publisher-disconnect hook that fires more than once — or races the reaper — is a no-op rather than an error. Currently only datasource-backed dataset channels are supported. Enforces write permission on the data source.",
        "parameters": [
          {
            "name": "request",
            "in": "body",
            "schema": {
              "$ref": "#/definitions/EndStreamV2Request"
            },
            "required": true,
            "x-example": {
              "channelSeries": {
                "type": "dataSource",
                "dataSource": {
                  "dataSourceRid": "<data source rid>",
                  "channel": "<channel>"
                }
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "$ref": "#/definitions/EndStreamResponse"
            },
            "x-example": {
              "streamId": "<stream id>",
              "endedAt": {
                "seconds": 1,
                "nanos": 1
              }
            }
          },
          "204": {
            "description": "No content, when there is nothing to return."
          }
        }
      }
    },
    "/video/v1/segment/upload": {
      "post": {
        "operationId": "VideoService_uploadSegmentFromMediaMtx",
        "summary": "Upload segment from media mtx",
        "tags": [
          "Video Service"
        ],
        "description": "MediaMTX segment upload endpoint. Receives video segments from MediaMTX hooks. Validates JWT and logs session. Future: create video segments from uploaded files.",
        "consumes": [
          "application/octet-stream"
        ],
        "parameters": [
          {
            "name": "streamPath",
            "in": "query",
            "type": "string",
            "required": true,
            "description": "MTX_PATH from MediaMTX indicating the stream path"
          },
          {
            "name": "filePath",
            "in": "query",
            "type": "string",
            "required": true,
            "description": "File path of the uploaded segment"
          },
          {
            "name": "duration",
            "in": "query",
            "type": "string",
            "required": true,
            "description": "MTX_SEGMENT_DURATION from MediaMTX in seconds"
          },
          {
            "name": "minTimestampSeconds",
            "in": "query",
            "type": "integer",
            "format": "int64",
            "required": true,
            "description": "Minimum timestamp seconds since epoch"
          },
          {
            "name": "minTimestampNanos",
            "in": "query",
            "type": "integer",
            "format": "int64",
            "required": true,
            "description": "Nanosecond offset (0-999999999)"
          },
          {
            "name": "Content-Length",
            "in": "header",
            "type": "integer",
            "format": "int64",
            "required": true,
            "description": "Size of the segment in bytes from Content-Length header"
          },
          {
            "name": "body",
            "in": "body",
            "schema": {
              "type": "string",
              "format": "binary",
              "example": "string"
            },
            "required": true,
            "x-example": "string"
          }
        ],
        "responses": {
          "204": {
            "description": "No content."
          }
        }
      }
    }
  },
  "definitions": {
    "ArchivedStatus": {
      "type": "string",
      "enum": [
        "NOT_ARCHIVED",
        "ARCHIVED"
      ]
    },
    "Empty": {
      "type": "object",
      "properties": {}
    },
    "Handle": {
      "type": "object",
      "x-union": true,
      "properties": {
        "type": {
          "type": "string",
          "enum": [
            "s3"
          ]
        },
        "s3": {
          "type": "string",
          "x-alias": "S3Path"
        }
      },
      "required": [
        "type"
      ],
      "description": "Set `type` to the name of one of the other fields, and set only that field.",
      "example": {
        "type": "s3",
        "s3": "string"
      }
    },
    "IngestStatus": {
      "type": "string",
      "enum": [
        "SUCCEEDED",
        "FAILED",
        "IN_PROGRESS"
      ]
    },
    "McapChannelLocator": {
      "description": "Locator for a channel in an mcap file. Channel name is not guaranteed to be unique, so channel ID should be used for mcap files with duplicate channel names.\n\nSet `type` to the name of one of the other fields, and set only that field.",
      "type": "object",
      "x-union": true,
      "properties": {
        "type": {
          "type": "string",
          "enum": [
            "topic",
            "id"
          ]
        },
        "topic": {
          "type": "string",
          "x-alias": "McapChannelTopic"
        },
        "id": {
          "type": "integer",
          "format": "int32",
          "x-alias": "McapChannelId"
        }
      },
      "required": [
        "type"
      ],
      "example": {
        "type": "topic",
        "topic": "string"
      }
    },
    "Property": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string",
          "x-alias": "PropertyName"
        },
        "value": {
          "type": "string",
          "x-alias": "PropertyValue"
        }
      },
      "required": [
        "name",
        "value"
      ]
    },
    "Timestamp": {
      "description": "Deprecated for new APIs. Use google.protobuf.Timestamp for absolute instants in proto APIs.\n\nThis legacy nanosecond precision timestamp type is represented by an epoch time in seconds and a nanosecond offset. The nanosecond offset is from the start of the epoch second, so must be less than 1 billion.",
      "type": "object",
      "properties": {
        "seconds": {
          "type": "integer",
          "format": "int64"
        },
        "nanos": {
          "type": "integer",
          "format": "int64"
        }
      },
      "required": [
        "seconds",
        "nanos"
      ]
    },
    "BatchUpdateVideoChannelDatasetFilesRequest": {
      "description": "Request to update one or more video dataset files (start-time alignment, rescaling, and/or title). Exactly one of datasetRid or channelSeries must be set. Prefer datasetRid: it addresses the files directly, deriving each file's backing series from its own segments, so callers never resupply channel identity. channelSeries remains supported for backwards compatibility and additionally validates that every file backs the given channel. At most 100 files may be updated per request.",
      "type": "object",
      "properties": {
        "channelSeries": {
          "$ref": "#/definitions/VideoChannelSeries"
        },
        "datasetRid": {
          "type": "string",
          "format": "rid",
          "x-alias": "DatasetRid",
          "description": "The dataset owning the files to update. Every requested file must belong to this dataset and be a video file (back a video series); enforces write data permission on the dataset."
        },
        "updates": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/VideoChannelDatasetFileUpdate"
          }
        }
      },
      "example": {
        "channelSeries": {
          "type": "dataSource",
          "dataSource": {
            "dataSourceRid": "<data source rid>",
            "channel": "<channel>"
          }
        },
        "datasetRid": "<dataset rid>",
        "updates": [
          {
            "datasetFileId": "<dataset file id>"
          }
        ]
      }
    },
    "BatchUpdateVideoChannelDatasetFilesResponse": {
      "type": "object",
      "properties": {
        "datasetFiles": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/VideoChannelDatasetFile"
          }
        }
      }
    },
    "Bounds": {
      "type": "object",
      "properties": {
        "start": {
          "$ref": "#/definitions/Timestamp"
        },
        "end": {
          "$ref": "#/definitions/Timestamp"
        }
      },
      "required": [
        "start",
        "end"
      ]
    },
    "CreateVideoRequest": {
      "type": "object",
      "properties": {
        "title": {
          "type": "string"
        },
        "description": {
          "type": "string"
        },
        "labels": {
          "type": "array",
          "items": {
            "type": "string",
            "x-alias": "Label"
          },
          "uniqueItems": true
        },
        "properties": {
          "type": "object",
          "additionalProperties": {
            "type": "string",
            "x-alias": "PropertyValue"
          },
          "x-map-key": "PropertyName"
        },
        "originMetadata": {
          "allOf": [
            {
              "$ref": "#/definitions/VideoOriginMetadata"
            }
          ],
          "x-deprecated": "deprecated in favor of per-file VideoFileOriginMetadata. Will be removed after April 15th."
        },
        "workspace": {
          "type": "string",
          "format": "rid",
          "x-alias": "WorkspaceRid",
          "description": "The workspace in which to create the video. If not provided, the video will be created in the default workspace for the user's organization, if the default workspace for the organization is configured."
        },
        "markingRids": {
          "type": "array",
          "items": {
            "type": "string",
            "format": "rid",
            "x-alias": "MarkingRid"
          },
          "uniqueItems": true,
          "description": "The markings to apply to the created video. If not provided, the video will be visible to all users in the same workspace."
        }
      },
      "required": [
        "title"
      ],
      "example": {
        "title": "<title>"
      }
    },
    "DetailedIngestStatus": {
      "type": "object",
      "x-union": true,
      "properties": {
        "type": {
          "type": "string",
          "enum": [
            "success",
            "error",
            "inProgress"
          ]
        },
        "success": {
          "$ref": "#/definitions/SuccessIngestStatus"
        },
        "error": {
          "$ref": "#/definitions/ErrorIngestStatus"
        },
        "inProgress": {
          "type": "number",
          "format": "double",
          "description": "A number between 0 and 1 representing percentage progress."
        }
      },
      "required": [
        "type"
      ],
      "description": "Set `type` to the name of one of the other fields, and set only that field.",
      "example": {
        "type": "success",
        "success": {}
      }
    },
    "EndStreamResponse": {
      "description": "Response payload for ending an active stream session.",
      "type": "object",
      "properties": {
        "streamId": {
          "type": "string"
        },
        "endedAt": {
          "$ref": "#/definitions/Timestamp"
        }
      },
      "required": [
        "streamId",
        "endedAt"
      ]
    },
    "EndStreamV2Request": {
      "description": "Request to end the active stream session for a channel-backed live video series.",
      "type": "object",
      "properties": {
        "channelSeries": {
          "$ref": "#/definitions/VideoChannelSeries"
        }
      },
      "required": [
        "channelSeries"
      ],
      "example": {
        "channelSeries": {
          "type": "dataSource",
          "dataSource": {
            "dataSourceRid": "<data source rid>",
            "channel": "<channel>"
          }
        }
      }
    },
    "EnrichedVideoIngestStatus": {
      "type": "object",
      "properties": {
        "status": {
          "$ref": "#/definitions/VideoIngestStatus"
        },
        "fileIngestStatus": {
          "type": "object",
          "additionalProperties": {
            "$ref": "#/definitions/VideoFileIngestStatus"
          },
          "x-map-key": "VideoFileRid"
        },
        "nextPageToken": {
          "type": "string",
          "x-alias": "Token"
        }
      },
      "required": [
        "status"
      ]
    },
    "ErrorIngestStatus": {
      "type": "object",
      "properties": {
        "errors": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/IngestError"
          }
        }
      }
    },
    "FileSummary": {
      "type": "object",
      "properties": {
        "fileRid": {
          "type": "string",
          "format": "rid",
          "x-alias": "VideoFileRid"
        },
        "bounds": {
          "$ref": "#/definitions/Bounds"
        }
      },
      "required": [
        "fileRid",
        "bounds"
      ]
    },
    "GenerateWhepStreamResponse": {
      "description": "Response with WHEP URL, ICE servers, and token for playback",
      "type": "object",
      "properties": {
        "whepUrl": {
          "type": "string"
        },
        "iceServers": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/IceServer"
          }
        },
        "token": {
          "type": "string"
        }
      },
      "required": [
        "whepUrl",
        "token"
      ]
    },
    "GenerateWhepStreamV2Request": {
      "description": "Request to generate a WHEP stream for a channel-backed live video series.",
      "type": "object",
      "properties": {
        "channelSeries": {
          "$ref": "#/definitions/VideoChannelSeries"
        }
      },
      "required": [
        "channelSeries"
      ],
      "example": {
        "channelSeries": {
          "type": "dataSource",
          "dataSource": {
            "dataSourceRid": "<data source rid>",
            "channel": "<channel>"
          }
        }
      }
    },
    "GenerateWhipStreamResponse": {
      "description": "Response with WHIP URL and ICE servers for publishing",
      "type": "object",
      "properties": {
        "streamId": {
          "type": "string"
        },
        "whipUrl": {
          "type": "string"
        },
        "iceServers": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/IceServer"
          }
        }
      },
      "required": [
        "streamId",
        "whipUrl"
      ]
    },
    "GenerateWhipStreamV2Request": {
      "description": "Request to generate a WHIP stream for a channel-backed live video series.",
      "type": "object",
      "properties": {
        "channelSeries": {
          "$ref": "#/definitions/VideoChannelSeries"
        }
      },
      "required": [
        "channelSeries"
      ],
      "example": {
        "channelSeries": {
          "type": "dataSource",
          "dataSource": {
            "dataSourceRid": "<data source rid>",
            "channel": "<channel>"
          }
        }
      }
    },
    "GetEnrichedVideoIngestStatusRequest": {
      "type": "object",
      "properties": {
        "videoRid": {
          "type": "string",
          "format": "rid",
          "x-alias": "VideoRid"
        },
        "token": {
          "type": "string",
          "x-alias": "Token"
        }
      },
      "required": [
        "videoRid"
      ],
      "example": {
        "videoRid": "<video rid>"
      }
    },
    "GetFileSummariesRequest": {
      "type": "object",
      "properties": {
        "bounds": {
          "$ref": "#/definitions/Bounds"
        }
      },
      "example": {
        "bounds": {
          "start": {
            "seconds": 1,
            "nanos": 1
          },
          "end": {
            "seconds": 1,
            "nanos": 1
          }
        }
      }
    },
    "GetFileSummariesResponse": {
      "type": "object",
      "properties": {
        "fileSummaries": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/FileSummary"
          }
        }
      }
    },
    "GetPlaylistInBoundsForChannelRequest": {
      "description": "Request to get playlist for a video channel series. Uses channel + tags to resolve to video series metadata within the specified video.",
      "type": "object",
      "properties": {
        "channelSeries": {
          "$ref": "#/definitions/VideoChannelSeries"
        },
        "bounds": {
          "$ref": "#/definitions/Bounds"
        }
      },
      "required": [
        "channelSeries",
        "bounds"
      ],
      "example": {
        "channelSeries": {
          "type": "dataSource",
          "dataSource": {
            "dataSourceRid": "<data source rid>",
            "channel": "<channel>"
          }
        },
        "bounds": {
          "start": {
            "seconds": 1,
            "nanos": 1
          },
          "end": {
            "seconds": 1,
            "nanos": 1
          }
        }
      }
    },
    "GetPlaylistInBoundsRequest": {
      "type": "object",
      "properties": {
        "bounds": {
          "$ref": "#/definitions/Bounds"
        }
      },
      "example": {
        "bounds": {
          "start": {
            "seconds": 1,
            "nanos": 1
          },
          "end": {
            "seconds": 1,
            "nanos": 1
          }
        }
      }
    },
    "GetSegmentAtOrAfterTimestampRequest": {
      "description": "Request to get a segment containing the given timestamp, or the closest segment starting after it.",
      "type": "object",
      "properties": {
        "timestamp": {
          "$ref": "#/definitions/Timestamp"
        }
      },
      "required": [
        "timestamp"
      ],
      "example": {
        "timestamp": {
          "seconds": 1,
          "nanos": 1
        }
      }
    },
    "GetSegmentAtOrAfterTimestampV2Request": {
      "description": "Request to get a segment containing the given timestamp, or the closest segment starting after it, for a video channel series (identified by channel + tags).",
      "type": "object",
      "properties": {
        "channelSeries": {
          "$ref": "#/definitions/VideoChannelSeries"
        },
        "timestamp": {
          "$ref": "#/definitions/Timestamp"
        }
      },
      "required": [
        "channelSeries",
        "timestamp"
      ],
      "example": {
        "channelSeries": {
          "type": "dataSource",
          "dataSource": {
            "dataSourceRid": "<data source rid>",
            "channel": "<channel>"
          }
        },
        "timestamp": {
          "seconds": 1,
          "nanos": 1
        }
      }
    },
    "GetSegmentByTimestampV2Request": {
      "description": "Request to get a segment by timestamp for a video series.",
      "type": "object",
      "properties": {
        "channelSeries": {
          "$ref": "#/definitions/VideoChannelSeries"
        },
        "timestamp": {
          "$ref": "#/definitions/Timestamp"
        },
        "viewRangeStart": {
          "allOf": [
            {
              "$ref": "#/definitions/Timestamp"
            }
          ],
          "description": "The start of the view range used to dynamically calculate media timestamps. The first segment with an overlap with the time bounds will have its minimum media timestamp set to 0, with every subsequent segment building media time cumulatively from that offset."
        }
      },
      "required": [
        "channelSeries",
        "timestamp"
      ],
      "example": {
        "channelSeries": {
          "type": "dataSource",
          "dataSource": {
            "dataSourceRid": "<data source rid>",
            "channel": "<channel>"
          }
        },
        "timestamp": {
          "seconds": 1,
          "nanos": 1
        }
      }
    },
    "GetSegmentMetadataForChannelRequest": {
      "description": "Request to get aggregated segment metadata for a video channel series. Uses channel + tags to resolve to video series metadata. Optionally filter by time bounds.",
      "type": "object",
      "properties": {
        "channelSeries": {
          "$ref": "#/definitions/VideoChannelSeries"
        },
        "bounds": {
          "$ref": "#/definitions/Bounds"
        }
      },
      "required": [
        "channelSeries"
      ],
      "example": {
        "channelSeries": {
          "type": "dataSource",
          "dataSource": {
            "dataSourceRid": "<data source rid>",
            "channel": "<channel>"
          }
        }
      }
    },
    "GetSegmentSummariesInBoundsForChannelRequest": {
      "description": "Request to get segment summaries for a video channel series. Uses channel + tags to resolve to video series metadata within the specified bounds.",
      "type": "object",
      "properties": {
        "channelSeries": {
          "$ref": "#/definitions/VideoChannelSeries"
        },
        "bounds": {
          "$ref": "#/definitions/Bounds"
        }
      },
      "required": [
        "channelSeries",
        "bounds"
      ],
      "example": {
        "channelSeries": {
          "type": "dataSource",
          "dataSource": {
            "dataSourceRid": "<data source rid>",
            "channel": "<channel>"
          }
        },
        "bounds": {
          "start": {
            "seconds": 1,
            "nanos": 1
          },
          "end": {
            "seconds": 1,
            "nanos": 1
          }
        }
      }
    },
    "GetSegmentSummariesInBoundsRequest": {
      "type": "object",
      "properties": {
        "bounds": {
          "$ref": "#/definitions/Bounds"
        }
      },
      "example": {
        "bounds": {
          "start": {
            "seconds": 1,
            "nanos": 1
          },
          "end": {
            "seconds": 1,
            "nanos": 1
          }
        }
      }
    },
    "GetStreamsInBoundsForChannelRequest": {
      "description": "Request to get channel-backed video stream sessions within bounds.",
      "type": "object",
      "properties": {
        "channelSeries": {
          "$ref": "#/definitions/VideoChannelSeries"
        },
        "bounds": {
          "$ref": "#/definitions/Bounds"
        },
        "pageSize": {
          "type": "integer",
          "format": "int32",
          "description": "Defaults to 100. Will throw if larger than 1_000."
        },
        "token": {
          "type": "string",
          "x-alias": "Token"
        }
      },
      "required": [
        "channelSeries",
        "bounds"
      ],
      "example": {
        "channelSeries": {
          "type": "dataSource",
          "dataSource": {
            "dataSourceRid": "<data source rid>",
            "channel": "<channel>"
          }
        },
        "bounds": {
          "start": {
            "seconds": 1,
            "nanos": 1
          },
          "end": {
            "seconds": 1,
            "nanos": 1
          }
        }
      }
    },
    "GetStreamsInBoundsRequest": {
      "type": "object",
      "properties": {
        "bounds": {
          "$ref": "#/definitions/Bounds"
        },
        "pageSize": {
          "type": "integer",
          "format": "int32",
          "description": "Defaults to 100. Will throw if larger than 1_000."
        },
        "token": {
          "type": "string",
          "x-alias": "Token"
        }
      },
      "required": [
        "bounds"
      ],
      "example": {
        "bounds": {
          "start": {
            "seconds": 1,
            "nanos": 1
          },
          "end": {
            "seconds": 1,
            "nanos": 1
          }
        }
      }
    },
    "GetStreamsInBoundsResponse": {
      "type": "object",
      "properties": {
        "streams": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/VideoStream"
          }
        },
        "nextPageToken": {
          "type": "string",
          "x-alias": "Token"
        }
      }
    },
    "GetStreamsInBoundsV2Response": {
      "type": "object",
      "properties": {
        "streams": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/VideoStreamV2"
          }
        },
        "nextPageToken": {
          "type": "string",
          "x-alias": "Token"
        }
      }
    },
    "GetVideosRequest": {
      "type": "object",
      "properties": {
        "videoRids": {
          "type": "array",
          "items": {
            "type": "string",
            "format": "rid",
            "x-alias": "VideoRid"
          },
          "uniqueItems": true
        }
      },
      "example": {
        "videoRids": [
          "<video rid>"
        ]
      }
    },
    "GetVideosResponse": {
      "type": "object",
      "properties": {
        "responses": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/Video"
          },
          "uniqueItems": true
        }
      }
    },
    "IceServer": {
      "description": "WebRTC ICE server configuration",
      "type": "object",
      "properties": {
        "urls": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "username": {
          "type": "string"
        },
        "credential": {
          "type": "string"
        }
      }
    },
    "IngestError": {
      "type": "object",
      "properties": {
        "errorType": {
          "type": "string",
          "x-alias": "ErrorType"
        },
        "message": {
          "type": "string"
        },
        "errorInstanceId": {
          "type": "string"
        }
      },
      "required": [
        "errorType",
        "message"
      ]
    },
    "ListVideoChannelDatasetFilesRequest": {
      "description": "Request to list the dataset files backing a video channel series. Uses channel + tags to resolve to video series metadata. Bounds are optional; when omitted all dataset files for the channel are returned.",
      "type": "object",
      "properties": {
        "channelSeries": {
          "$ref": "#/definitions/VideoChannelSeries"
        },
        "bounds": {
          "$ref": "#/definitions/Bounds"
        },
        "pageSize": {
          "type": "integer",
          "format": "int32",
          "description": "Defaults to 100. Will throw if larger than 1_000."
        },
        "token": {
          "type": "string",
          "x-alias": "Token"
        }
      },
      "required": [
        "channelSeries"
      ],
      "example": {
        "channelSeries": {
          "type": "dataSource",
          "dataSource": {
            "dataSourceRid": "<data source rid>",
            "channel": "<channel>"
          }
        }
      }
    },
    "ListVideoChannelDatasetFilesResponse": {
      "type": "object",
      "properties": {
        "datasetFiles": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/VideoChannelDatasetFile"
          }
        },
        "nextPageToken": {
          "type": "string",
          "x-alias": "Token"
        }
      }
    },
    "McapTimestampManifest": {
      "description": "Timestamps are derived from the mcap file containing the video frames.",
      "type": "object",
      "properties": {
        "mcapChannelLocator": {
          "$ref": "#/definitions/McapChannelLocator"
        }
      },
      "required": [
        "mcapChannelLocator"
      ]
    },
    "NoTimestampManifest": {
      "description": "these values will not be updated after ingest time, to allow for resetting. The updated values are stored implicitly through the segment timestamps.",
      "type": "object",
      "properties": {
        "startingTimestamp": {
          "allOf": [
            {
              "$ref": "#/definitions/Timestamp"
            }
          ],
          "description": "Specifies the original starting timestamp of the video."
        },
        "scaleParameter": {
          "allOf": [
            {
              "$ref": "#/definitions/ScaleParameter"
            }
          ],
          "description": "A field that specifies that the frame rate of the video does not match the frame rate of the camera | i.e. a slowed down or sped up video. Can specify either the camera frame rate or the absolute end time."
        }
      },
      "required": [
        "startingTimestamp"
      ]
    },
    "ScaleParameter": {
      "type": "object",
      "x-union": true,
      "properties": {
        "type": {
          "type": "string",
          "enum": [
            "trueFrameRate",
            "endingTimestamp",
            "scaleFactor"
          ]
        },
        "trueFrameRate": {
          "type": "number",
          "format": "double"
        },
        "endingTimestamp": {
          "$ref": "#/definitions/Timestamp"
        },
        "scaleFactor": {
          "type": "number",
          "format": "double",
          "description": "the scale factor can be used to calculate whether media duration differs from a video's | real duration, and if so, the true frame rate of the camera. The video time will thus be scaled | by the ratio of the real duration to media duration, or media frame rate to true frame rate."
        }
      },
      "required": [
        "type"
      ],
      "description": "Set `type` to the name of one of the other fields, and set only that field.",
      "example": {
        "type": "trueFrameRate",
        "trueFrameRate": 1
      }
    },
    "SearchVideosQuery": {
      "type": "object",
      "x-union": true,
      "properties": {
        "type": {
          "type": "string",
          "enum": [
            "searchText",
            "label",
            "property",
            "and",
            "or",
            "ingestStatus",
            "workspace"
          ]
        },
        "searchText": {
          "type": "string"
        },
        "label": {
          "type": "string",
          "x-alias": "Label"
        },
        "property": {
          "$ref": "#/definitions/Property"
        },
        "and": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/SearchVideosQuery"
          },
          "uniqueItems": true
        },
        "or": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/SearchVideosQuery"
          },
          "uniqueItems": true
        },
        "ingestStatus": {
          "$ref": "#/definitions/IngestStatus"
        },
        "workspace": {
          "type": "string",
          "format": "rid",
          "x-alias": "WorkspaceRid"
        }
      },
      "required": [
        "type"
      ],
      "description": "Set `type` to the name of one of the other fields, and set only that field.",
      "example": {
        "type": "searchText",
        "searchText": "string"
      }
    },
    "SearchVideosRequest": {
      "type": "object",
      "properties": {
        "query": {
          "$ref": "#/definitions/SearchVideosQuery"
        },
        "pageSize": {
          "type": "integer",
          "format": "int32",
          "description": "Defaults to 100. Will throw if larger than 1_000."
        },
        "token": {
          "type": "string",
          "x-alias": "Token"
        },
        "sortOptions": {
          "$ref": "#/definitions/SortOptions"
        },
        "archivedStatuses": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/ArchivedStatus"
          },
          "uniqueItems": true,
          "description": "Default search status is NOT_ARCHIVED if none are provided. Allows for including archived videos in search."
        }
      },
      "required": [
        "query",
        "sortOptions"
      ],
      "example": {
        "query": {
          "type": "searchText",
          "searchText": "<search text>"
        },
        "sortOptions": {
          "isDescending": true,
          "field": "CREATED_AT"
        }
      }
    },
    "SearchVideosResponse": {
      "type": "object",
      "properties": {
        "results": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/Video"
          }
        },
        "nextPageToken": {
          "type": "string",
          "x-alias": "Token"
        }
      }
    },
    "Segment": {
      "type": "object",
      "properties": {
        "rid": {
          "type": "string",
          "format": "rid",
          "x-alias": "SegmentRid"
        },
        "videoRid": {
          "type": "string",
          "format": "rid",
          "x-alias": "VideoRid"
        },
        "dataHandle": {
          "$ref": "#/definitions/Handle"
        },
        "frameRate": {
          "type": "number",
          "format": "double",
          "description": "The average frame rate (FPS) of the segment calculated as total frames / duration in seconds."
        },
        "durationSeconds": {
          "type": "number",
          "format": "double",
          "description": "The duration of a segment in media time."
        },
        "timestamps": {
          "allOf": [
            {
              "$ref": "#/definitions/SegmentTimestamps"
            }
          ],
          "description": "for videos with frame-level timestamps, we provide mappings, otherwise we just include a single list of timestamps."
        }
      },
      "required": [
        "rid",
        "videoRid",
        "dataHandle",
        "frameRate",
        "durationSeconds",
        "timestamps"
      ]
    },
    "SegmentSummary": {
      "description": "Bounding timestamps for the frames within a segment. For non-frame-mapped videos, the min and max media timestamps will be empty.",
      "type": "object",
      "properties": {
        "minAbsoluteTimestamp": {
          "$ref": "#/definitions/Timestamp"
        },
        "maxAbsoluteTimestamp": {
          "$ref": "#/definitions/Timestamp"
        },
        "minMediaTimestamp": {
          "type": "number",
          "format": "double"
        },
        "maxMediaTimestamp": {
          "type": "number",
          "format": "double"
        }
      },
      "required": [
        "minAbsoluteTimestamp",
        "maxAbsoluteTimestamp",
        "minMediaTimestamp",
        "maxMediaTimestamp"
      ]
    },
    "SegmentSummaryV2": {
      "description": "Bounding timestamps for the frames within a segment. Includes datasetFileId for V2 channel-based API.",
      "type": "object",
      "properties": {
        "datasetFileId": {
          "type": "string",
          "format": "uuid",
          "description": "The dataset file ID that this segment belongs to."
        },
        "minAbsoluteTimestamp": {
          "$ref": "#/definitions/Timestamp"
        },
        "maxAbsoluteTimestamp": {
          "$ref": "#/definitions/Timestamp"
        },
        "minMediaTimestamp": {
          "type": "number",
          "format": "double"
        },
        "maxMediaTimestamp": {
          "type": "number",
          "format": "double"
        }
      },
      "required": [
        "minAbsoluteTimestamp",
        "maxAbsoluteTimestamp",
        "minMediaTimestamp",
        "maxMediaTimestamp"
      ]
    },
    "SegmentTimestamps": {
      "description": "A video segment will either contain timestamps or timestamp mappings depending on whether it is intended to be frame-mapped. Without a frame-timestamp mapping manifest file, a list of absolute timestamps will be automatically assigned to each segment based on media timestamps.. Otherwise, media timestamps will be extracted and mapped to those in the provided manifest.\n\nSet `type` to the name of one of the other fields, and set only that field.",
      "type": "object",
      "x-union": true,
      "properties": {
        "type": {
          "type": "string",
          "enum": [
            "timestampMappings"
          ]
        },
        "timestampMappings": {
          "$ref": "#/definitions/TimestampMappings"
        }
      },
      "required": [
        "type"
      ],
      "example": {
        "type": "timestampMappings",
        "timestampMappings": {
          "mediaTimestamps": [
            1
          ],
          "absoluteTimestamps": [
            {
              "seconds": 1,
              "nanos": 1
            }
          ]
        }
      }
    },
    "SegmentV2": {
      "description": "Segment for V2 channel-based video API (without videoRid).",
      "type": "object",
      "properties": {
        "rid": {
          "type": "string",
          "format": "rid",
          "x-alias": "SegmentRid"
        },
        "datasetFileId": {
          "type": "string",
          "format": "uuid",
          "description": "The dataset file ID that this segment belongs to."
        },
        "dataHandle": {
          "$ref": "#/definitions/Handle"
        },
        "frameRate": {
          "type": "number",
          "format": "double",
          "description": "The average frame rate (FPS) of the segment calculated as total frames / duration in seconds."
        },
        "durationSeconds": {
          "type": "number",
          "format": "double",
          "description": "The duration of a segment in media time."
        },
        "timestamps": {
          "allOf": [
            {
              "$ref": "#/definitions/SegmentTimestamps"
            }
          ],
          "description": "for videos with frame-level timestamps, we provide mappings, otherwise we just include a single list of timestamps."
        }
      },
      "required": [
        "rid",
        "dataHandle",
        "frameRate",
        "durationSeconds",
        "timestamps"
      ]
    },
    "SortField": {
      "type": "string",
      "enum": [
        "CREATED_AT"
      ]
    },
    "SortOptions": {
      "type": "object",
      "properties": {
        "isDescending": {
          "type": "boolean"
        },
        "field": {
          "$ref": "#/definitions/SortField"
        }
      },
      "required": [
        "isDescending",
        "field"
      ]
    },
    "SuccessIngestStatus": {
      "type": "object",
      "properties": {}
    },
    "TimestampMappings": {
      "description": "contains 2 equal-length lists, which contain the video media time and user-provided absolute time for the frame at each index. Enables frame-mapping on the front-end.",
      "type": "object",
      "properties": {
        "mediaTimestamps": {
          "type": "array",
          "items": {
            "type": "number",
            "format": "double"
          }
        },
        "absoluteTimestamps": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/Timestamp"
          }
        }
      }
    },
    "UpdateVideoMetadataRequest": {
      "type": "object",
      "properties": {
        "title": {
          "type": "string"
        },
        "description": {
          "type": "string"
        },
        "labels": {
          "type": "array",
          "items": {
            "type": "string",
            "x-alias": "Label"
          },
          "uniqueItems": true
        },
        "properties": {
          "type": "object",
          "additionalProperties": {
            "type": "string",
            "x-alias": "PropertyValue"
          },
          "x-map-key": "PropertyName"
        },
        "startingTimestamp": {
          "$ref": "#/definitions/Timestamp"
        },
        "scaleParameter": {
          "allOf": [
            {
              "$ref": "#/definitions/ScaleParameter"
            }
          ],
          "x-deprecated": "deprecated in favor of updating scaleParameter per-file. Will fail if set on a video with multiple files. Will be removed after April 15th."
        }
      },
      "example": {
        "title": "<title>",
        "description": "<description>",
        "labels": [
          "<label>"
        ],
        "properties": {
          "<key>": "<property value>"
        },
        "startingTimestamp": {
          "seconds": 1,
          "nanos": 1
        },
        "scaleParameter": {
          "type": "trueFrameRate",
          "trueFrameRate": 1
        }
      }
    },
    "Video": {
      "type": "object",
      "properties": {
        "rid": {
          "type": "string",
          "format": "rid",
          "x-alias": "VideoRid"
        },
        "title": {
          "type": "string"
        },
        "description": {
          "type": "string"
        },
        "labels": {
          "type": "array",
          "items": {
            "type": "string",
            "x-alias": "Label"
          },
          "uniqueItems": true
        },
        "properties": {
          "type": "object",
          "additionalProperties": {
            "type": "string",
            "x-alias": "PropertyValue"
          },
          "x-map-key": "PropertyName"
        },
        "createdBy": {
          "type": "string",
          "format": "rid"
        },
        "createdAt": {
          "type": "string",
          "format": "date-time"
        },
        "isArchived": {
          "type": "boolean"
        },
        "originMetadata": {
          "allOf": [
            {
              "$ref": "#/definitions/VideoOriginMetadata"
            }
          ],
          "x-deprecated": "deprecated in favor of per-file VideoFileOriginMetadata. Will be removed after April 15th."
        },
        "allSegmentsMetadata": {
          "$ref": "#/definitions/VideoAllSegmentsMetadata"
        }
      },
      "required": [
        "rid",
        "title",
        "createdBy",
        "createdAt",
        "isArchived"
      ]
    },
    "VideoAllSegmentsMetadata": {
      "type": "object",
      "properties": {
        "rid": {
          "type": "string",
          "format": "rid",
          "x-alias": "VideoRid"
        },
        "numFrames": {
          "type": "integer",
          "format": "int32"
        },
        "numSegments": {
          "type": "integer",
          "format": "int32"
        },
        "scaleFactor": {
          "type": "number",
          "format": "double",
          "description": "deprecated, in favor of per-file VideoFileSegmentsMetadata scaleFactor. Will be removed after April 15th."
        },
        "minAbsoluteTimestamp": {
          "$ref": "#/definitions/Timestamp"
        },
        "maxAbsoluteTimestamp": {
          "allOf": [
            {
              "$ref": "#/definitions/Timestamp"
            }
          ],
          "description": "the timestamp corresponding to absolute starting timestamp plus absolute duration of the video."
        },
        "mediaDurationSeconds": {
          "type": "number",
          "format": "double"
        },
        "mediaFrameRate": {
          "type": "number",
          "format": "double",
          "description": "The average media frame rate (FPS) of the video calculated as total frames / duration in seconds."
        },
        "minTimestamp": {
          "allOf": [
            {
              "$ref": "#/definitions/Timestamp"
            }
          ],
          "description": "deprecated. Will be removed after April 15th."
        },
        "maxTimestamp": {
          "allOf": [
            {
              "$ref": "#/definitions/Timestamp"
            }
          ],
          "description": "deprecated. Will be removed after April 15th."
        },
        "durationSeconds": {
          "type": "number",
          "format": "double",
          "description": "deprecated. Will be removed after April 15th."
        },
        "frameRate": {
          "type": "number",
          "format": "double",
          "description": "deprecated. Will be removed after April 15th."
        }
      },
      "required": [
        "rid",
        "numFrames",
        "numSegments",
        "minAbsoluteTimestamp",
        "maxAbsoluteTimestamp",
        "mediaDurationSeconds",
        "mediaFrameRate"
      ]
    },
    "VideoAssetChannel": {
      "description": "Reference a video channel via an Asset's data scope",
      "type": "object",
      "properties": {
        "assetRid": {
          "type": "string"
        },
        "dataScopeName": {
          "type": "string"
        },
        "channel": {
          "type": "string"
        },
        "tags": {
          "type": "object",
          "additionalProperties": {
            "type": "string",
            "x-alias": "TagValue"
          },
          "x-map-key": "TagName"
        }
      },
      "required": [
        "assetRid",
        "dataScopeName",
        "channel"
      ]
    },
    "VideoChannelDatasetFile": {
      "description": "A dataset file backing a video channel, with the min and max absolute timestamps of the segments it contributes to the channel.",
      "type": "object",
      "properties": {
        "datasetFileId": {
          "type": "string",
          "format": "uuid"
        },
        "start": {
          "$ref": "#/definitions/Timestamp"
        },
        "end": {
          "$ref": "#/definitions/Timestamp"
        }
      },
      "required": [
        "datasetFileId",
        "start",
        "end"
      ]
    },
    "VideoChannelDatasetFileUpdate": {
      "description": "An update to apply to a single video dataset file backing a channel. Only the provided fields are changed; at least one must be set. When both start and scaleParameter are set, the file is rescaled first (around its current start) and then shifted to the new start.",
      "type": "object",
      "properties": {
        "datasetFileId": {
          "type": "string",
          "format": "uuid"
        },
        "start": {
          "allOf": [
            {
              "$ref": "#/definitions/Timestamp"
            }
          ],
          "description": "New absolute start timestamp for the file. The file's earliest segment is shifted to this timestamp and every other segment in the file is shifted by the same offset."
        },
        "title": {
          "type": "string",
          "description": "New name (title) for the dataset file."
        },
        "scaleParameter": {
          "allOf": [
            {
              "$ref": "#/definitions/ScaleParameter"
            }
          ],
          "description": "Rescales the file's frame timestamps around its start (e.g. a corrected true frame rate, an absolute ending timestamp, or a direct scale factor). The file's cached segment metadata (scale factor, frame rate) is recomputed."
        }
      },
      "required": [
        "datasetFileId"
      ]
    },
    "VideoChannelSegmentsMetadata": {
      "description": "Aggregated segment metadata for a video channel series",
      "type": "object",
      "properties": {
        "numFrames": {
          "type": "integer",
          "format": "int32"
        },
        "numSegments": {
          "type": "integer",
          "format": "int32"
        },
        "minAbsoluteTimestamp": {
          "$ref": "#/definitions/Timestamp"
        },
        "maxAbsoluteTimestamp": {
          "$ref": "#/definitions/Timestamp"
        },
        "mediaDurationSeconds": {
          "type": "number",
          "format": "double"
        },
        "mediaFrameRate": {
          "type": "number",
          "format": "double",
          "description": "The average media frame rate (FPS) calculated as total frames / duration in seconds."
        }
      },
      "required": [
        "numFrames",
        "numSegments",
        "minAbsoluteTimestamp",
        "maxAbsoluteTimestamp",
        "mediaDurationSeconds",
        "mediaFrameRate"
      ]
    },
    "VideoChannelSeries": {
      "description": "Union type for referencing a video channel. Allows querying video data via datasource/channel, asset data scopes, or run data scopes.\n\nSet `type` to the name of one of the other fields, and set only that field.",
      "type": "object",
      "x-union": true,
      "properties": {
        "type": {
          "type": "string",
          "enum": [
            "dataSource",
            "asset"
          ]
        },
        "dataSource": {
          "$ref": "#/definitions/VideoDataSourceChannel"
        },
        "asset": {
          "$ref": "#/definitions/VideoAssetChannel"
        }
      },
      "required": [
        "type"
      ],
      "example": {
        "type": "dataSource",
        "dataSource": {
          "dataSourceRid": "string",
          "channel": "string",
          "tags": {
            "key": "string"
          }
        }
      }
    },
    "VideoDataSourceChannel": {
      "description": "Reference a video channel directly from a datasource/dataset",
      "type": "object",
      "properties": {
        "dataSourceRid": {
          "type": "string"
        },
        "channel": {
          "type": "string"
        },
        "tags": {
          "type": "object",
          "additionalProperties": {
            "type": "string",
            "x-alias": "TagValue"
          },
          "x-map-key": "TagName"
        }
      },
      "required": [
        "dataSourceRid",
        "channel"
      ]
    },
    "VideoFileIngestStatus": {
      "type": "object",
      "x-union": true,
      "properties": {
        "type": {
          "type": "string",
          "enum": [
            "success",
            "error",
            "inProgress"
          ]
        },
        "success": {
          "$ref": "#/definitions/SuccessIngestStatus"
        },
        "error": {
          "$ref": "#/definitions/IngestError"
        },
        "inProgress": {
          "$ref": "#/definitions/Empty"
        }
      },
      "required": [
        "type"
      ],
      "description": "Set `type` to the name of one of the other fields, and set only that field.",
      "example": {
        "type": "success",
        "success": {}
      }
    },
    "VideoIngestStatus": {
      "type": "object",
      "x-union": true,
      "properties": {
        "type": {
          "type": "string",
          "enum": [
            "ready",
            "inProgress",
            "error"
          ]
        },
        "ready": {
          "$ref": "#/definitions/Empty"
        },
        "inProgress": {
          "$ref": "#/definitions/Empty"
        },
        "error": {
          "$ref": "#/definitions/Empty"
        }
      },
      "required": [
        "type"
      ],
      "description": "Set `type` to the name of one of the other fields, and set only that field.",
      "example": {
        "type": "ready",
        "ready": {}
      }
    },
    "VideoOriginMetadata": {
      "type": "object",
      "properties": {
        "videoSources": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/Handle"
          },
          "x-deprecated": "deprecated in favor of per-file VideoFileOriginMetadata. Will be removed after April 15th."
        },
        "timestampManifest": {
          "allOf": [
            {
              "$ref": "#/definitions/VideoTimestampManifest"
            }
          ],
          "x-deprecated": "deprecated in favor of per-file VideoFileOriginMetadata. Will be removed after April 15th."
        }
      },
      "required": [
        "timestampManifest"
      ]
    },
    "VideoStream": {
      "description": "Metadata for a single video stream session.",
      "type": "object",
      "properties": {
        "streamId": {
          "type": "string"
        },
        "videoRid": {
          "type": "string",
          "format": "rid",
          "x-alias": "VideoRid"
        },
        "streamStatus": {
          "type": "string"
        },
        "start": {
          "type": "string",
          "format": "date-time"
        },
        "end": {
          "type": "string",
          "format": "date-time"
        },
        "createdAt": {
          "type": "string",
          "format": "date-time"
        },
        "updatedAt": {
          "type": "string",
          "format": "date-time"
        }
      },
      "required": [
        "streamId",
        "videoRid",
        "streamStatus",
        "createdAt",
        "updatedAt"
      ]
    },
    "VideoStreamV2": {
      "description": "Metadata for a single channel-backed video stream session.",
      "type": "object",
      "properties": {
        "streamId": {
          "type": "string"
        },
        "streamStatus": {
          "type": "string"
        },
        "createdAt": {
          "type": "string",
          "format": "date-time"
        },
        "updatedAt": {
          "type": "string",
          "format": "date-time"
        },
        "start": {
          "type": "string",
          "format": "date-time"
        },
        "end": {
          "type": "string",
          "format": "date-time"
        }
      },
      "required": [
        "streamId",
        "streamStatus",
        "createdAt",
        "updatedAt"
      ]
    },
    "VideoTimestampManifest": {
      "type": "object",
      "x-union": true,
      "properties": {
        "type": {
          "type": "string",
          "enum": [
            "mcap",
            "s3paths",
            "noManifest"
          ]
        },
        "mcap": {
          "$ref": "#/definitions/McapTimestampManifest"
        },
        "s3paths": {
          "type": "array",
          "items": {
            "type": "string",
            "x-alias": "S3Path"
          }
        },
        "noManifest": {
          "$ref": "#/definitions/NoTimestampManifest"
        }
      },
      "required": [
        "type"
      ],
      "description": "Set `type` to the name of one of the other fields, and set only that field.",
      "example": {
        "type": "mcap",
        "mcap": {
          "mcapChannelLocator": {
            "type": "topic",
            "topic": "string"
          }
        }
      }
    }
  },
  "tags": [
    {
      "name": "Video Service",
      "x-displayName": "Video service",
      "description": "The video service manages videos and video metadata."
    }
  ]
}
