# Video service

The video service manages videos and video metadata.

OpenAPI file: [`VideoService.json`](https://dev.nominal.io/api/_downloads/7143d12daf3f946119d98f17be092172/VideoService.json)

## Endpoints

### Get

GET `/video/v1/videos/{videoRid}`

**Deprecated:** Legacy Video-entity API. Videos are now channels on datasets; list a channel’s files with listVideoChannelDatasetFiles and read dataset metadata from CatalogService.

Returns video metadata associated with a video rid.

Path parameters

`videoRid` string (RID) required
:   ​

Response

`rid` string (RID)
:   ​

`title` string
:   ​

`description` string
:   ​

`labels` array of string
:   ​

`properties` map of `PropertyName` to string
:   ​

`createdBy` string (RID)
:   ​

`createdAt` string (date-time)
:   ​

`isArchived` boolean
:   ​

`originMetadata` [`VideoOriginMetadata`](https://dev.nominal.io/api/rest/video-service.md#videooriginmetadata) deprecated
:   **Deprecated:** deprecated in favor of per-file VideoFileOriginMetadata. Will be removed after April 15th.

    Fields of `VideoOriginMetadata`

    `videoSources` array of [`Handle`](https://dev.nominal.io/api/rest/video-service.md#handle) deprecated
    :   **Deprecated:** deprecated in favor of per-file VideoFileOriginMetadata. Will be removed after April 15th.

        **s3**

        Set `type` to `"s3"`.

        `s3` string
        :   ​

    `timestampManifest` [`VideoTimestampManifest`](https://dev.nominal.io/api/rest/video-service.md#videotimestampmanifest) deprecated
    :   **Deprecated:** deprecated in favor of per-file VideoFileOriginMetadata. Will be removed after April 15th.

        **mcap**

        Set `type` to `"mcap"`.

        `mcap` [`McapTimestampManifest`](https://dev.nominal.io/api/rest/video-service.md#mcaptimestampmanifest)
        :   ​

            Fields of `McapTimestampManifest`

            `mcapChannelLocator` [`McapChannelLocator`](https://dev.nominal.io/api/rest/video-service.md#mcapchannellocator)
            :   ​

                **topic**

                Set `type` to `"topic"`.

                `topic` string
                :   ​

                **id**

                Set `type` to `"id"`.

                `id` integer
                :   ​

        **s3paths**

        Set `type` to `"s3paths"`.

        `s3paths` array of string
        :   ​

        **noManifest**

        Set `type` to `"noManifest"`.

        `noManifest` [`NoTimestampManifest`](https://dev.nominal.io/api/rest/video-service.md#notimestampmanifest)
        :   ​

            Fields of `NoTimestampManifest`

            `startingTimestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
            :   Specifies the original starting timestamp of the video.

                Fields of `Timestamp`

                `seconds` integer (int64)
                :   ​

                `nanos` integer (int64)
                :   ​

            `scaleParameter` [`ScaleParameter`](https://dev.nominal.io/api/rest/video-service.md#scaleparameter)
            :   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.

                **trueFrameRate**

                Set `type` to `"trueFrameRate"`.

                `trueFrameRate` number
                :   ​

                **endingTimestamp**

                Set `type` to `"endingTimestamp"`.

                `endingTimestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
                :   ​

                **scaleFactor**

                Set `type` to `"scaleFactor"`.

                `scaleFactor` number
                :   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.

`allSegmentsMetadata` [`VideoAllSegmentsMetadata`](https://dev.nominal.io/api/rest/video-service.md#videoallsegmentsmetadata)
:   ​

    Fields of `VideoAllSegmentsMetadata`

    `rid` string (RID)
    :   ​

    `numFrames` integer
    :   ​

    `numSegments` integer
    :   ​

    `scaleFactor` number
    :   deprecated, in favor of per-file VideoFileSegmentsMetadata scaleFactor. Will be removed after April 15th.

    `minAbsoluteTimestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
    :   ​

    `maxAbsoluteTimestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
    :   the timestamp corresponding to absolute starting timestamp plus absolute duration of the video.

    `mediaDurationSeconds` number
    :   ​

    `mediaFrameRate` number
    :   The average media frame rate (FPS) of the video calculated as total frames / duration in seconds.

    `minTimestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
    :   deprecated. Will be removed after April 15th.

    `maxTimestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
    :   deprecated. Will be removed after April 15th.

    `durationSeconds` number
    :   deprecated. Will be removed after April 15th.

    `frameRate` number
    :   deprecated. Will be removed after April 15th.

Request

**curl**

```shell
curl "https://api.gov.nominal.io/api/video/v1/videos/<video rid>" \
  -H "Authorization: Bearer <api key>"
```

**requests**

```python
import requests

response = requests.get(
    "https://api.gov.nominal.io/api/video/v1/videos/<video rid>",
    headers={"Authorization": "Bearer <api key>"},
)
response.raise_for_status()
print(response.json())
```

**httpx**

```python
import httpx

response = httpx.get(
    "https://api.gov.nominal.io/api/video/v1/videos/<video rid>",
    headers={"Authorization": "Bearer <api key>"},
)
response.raise_for_status()
print(response.json())
```

**aiohttp**

```python
import asyncio

import aiohttp

async def main() -> None:
    async with aiohttp.ClientSession() as session:
        async with session.get(
            "https://api.gov.nominal.io/api/video/v1/videos/<video rid>",
            headers={"Authorization": "Bearer <api key>"},
        ) as response:
            response.raise_for_status()
            print(await response.json())

asyncio.run(main())
```

Response: `200`

```json
{
  "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
  }
}
```

### Update metadata

PUT `/video/v1/videos/{videoRid}`

**Deprecated:** Legacy Video-entity API. Videos are now channels on datasets; update dataset metadata with CatalogService#updateDatasetMetadata and per-file titles with batchUpdateVideoChannelDatasetFiles.

Updates the metadata for a video associated with the given video rid.

Path parameters

`videoRid` string (RID) required
:   ​

Body

`title` string
:   ​

`description` string
:   ​

`labels` array of string
:   ​

`properties` map of `PropertyName` to string
:   ​

`startingTimestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
:   ​

    Fields of `Timestamp`

    `seconds` integer (int64) required
    :   ​

    `nanos` integer (int64) required
    :   ​

`scaleParameter` [`ScaleParameter`](https://dev.nominal.io/api/rest/video-service.md#scaleparameter) deprecated
:   **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.

    **trueFrameRate**

    Set `type` to `"trueFrameRate"`.

    `trueFrameRate` number
    :   ​

    **endingTimestamp**

    Set `type` to `"endingTimestamp"`.

    `endingTimestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
    :   ​

    **scaleFactor**

    Set `type` to `"scaleFactor"`.

    `scaleFactor` number
    :   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.

Response

`rid` string (RID)
:   ​

`title` string
:   ​

`description` string
:   ​

`labels` array of string
:   ​

`properties` map of `PropertyName` to string
:   ​

`createdBy` string (RID)
:   ​

`createdAt` string (date-time)
:   ​

`isArchived` boolean
:   ​

`originMetadata` [`VideoOriginMetadata`](https://dev.nominal.io/api/rest/video-service.md#videooriginmetadata) deprecated
:   **Deprecated:** deprecated in favor of per-file VideoFileOriginMetadata. Will be removed after April 15th.

    Fields of `VideoOriginMetadata`

    `videoSources` array of [`Handle`](https://dev.nominal.io/api/rest/video-service.md#handle) deprecated
    :   **Deprecated:** deprecated in favor of per-file VideoFileOriginMetadata. Will be removed after April 15th.

        **s3**

        Set `type` to `"s3"`.

        `s3` string
        :   ​

    `timestampManifest` [`VideoTimestampManifest`](https://dev.nominal.io/api/rest/video-service.md#videotimestampmanifest) deprecated
    :   **Deprecated:** deprecated in favor of per-file VideoFileOriginMetadata. Will be removed after April 15th.

        **mcap**

        Set `type` to `"mcap"`.

        `mcap` [`McapTimestampManifest`](https://dev.nominal.io/api/rest/video-service.md#mcaptimestampmanifest)
        :   ​

            Fields of `McapTimestampManifest`

            `mcapChannelLocator` [`McapChannelLocator`](https://dev.nominal.io/api/rest/video-service.md#mcapchannellocator)
            :   ​

                **topic**

                Set `type` to `"topic"`.

                `topic` string
                :   ​

                **id**

                Set `type` to `"id"`.

                `id` integer
                :   ​

        **s3paths**

        Set `type` to `"s3paths"`.

        `s3paths` array of string
        :   ​

        **noManifest**

        Set `type` to `"noManifest"`.

        `noManifest` [`NoTimestampManifest`](https://dev.nominal.io/api/rest/video-service.md#notimestampmanifest)
        :   ​

            Fields of `NoTimestampManifest`

            `startingTimestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
            :   Specifies the original starting timestamp of the video.

                Fields of `Timestamp`

                `seconds` integer (int64)
                :   ​

                `nanos` integer (int64)
                :   ​

            `scaleParameter` [`ScaleParameter`](https://dev.nominal.io/api/rest/video-service.md#scaleparameter)
            :   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.

                **trueFrameRate**

                Set `type` to `"trueFrameRate"`.

                `trueFrameRate` number
                :   ​

                **endingTimestamp**

                Set `type` to `"endingTimestamp"`.

                `endingTimestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
                :   ​

                **scaleFactor**

                Set `type` to `"scaleFactor"`.

                `scaleFactor` number
                :   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.

`allSegmentsMetadata` [`VideoAllSegmentsMetadata`](https://dev.nominal.io/api/rest/video-service.md#videoallsegmentsmetadata)
:   ​

    Fields of `VideoAllSegmentsMetadata`

    `rid` string (RID)
    :   ​

    `numFrames` integer
    :   ​

    `numSegments` integer
    :   ​

    `scaleFactor` number
    :   deprecated, in favor of per-file VideoFileSegmentsMetadata scaleFactor. Will be removed after April 15th.

    `minAbsoluteTimestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
    :   ​

    `maxAbsoluteTimestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
    :   the timestamp corresponding to absolute starting timestamp plus absolute duration of the video.

    `mediaDurationSeconds` number
    :   ​

    `mediaFrameRate` number
    :   The average media frame rate (FPS) of the video calculated as total frames / duration in seconds.

    `minTimestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
    :   deprecated. Will be removed after April 15th.

    `maxTimestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
    :   deprecated. Will be removed after April 15th.

    `durationSeconds` number
    :   deprecated. Will be removed after April 15th.

    `frameRate` number
    :   deprecated. Will be removed after April 15th.

Request

**curl**

```shell
curl -X PUT "https://api.gov.nominal.io/api/video/v1/videos/<video rid>" \
  -H "Authorization: Bearer <api key>" \
  -H "Content-Type: application/json" \
  --data '{
  "title": "<title>",
  "description": "<description>",
  "labels": [
    "<label>"
  ],
  "properties": {
    "<key>": "<property value>"
  },
  "startingTimestamp": {
    "seconds": 1,
    "nanos": 1
  },
  "scaleParameter": {
    "type": "trueFrameRate",
    "trueFrameRate": 1
  }
}'
```

**requests**

```python
import requests

response = requests.put(
    "https://api.gov.nominal.io/api/video/v1/videos/<video rid>",
    headers={"Authorization": "Bearer <api key>"},
    json={
        "title": "<title>",
        "description": "<description>",
        "labels": ["<label>"],
        "properties": {"<key>": "<property value>"},
        "startingTimestamp": {"seconds": 1, "nanos": 1},
        "scaleParameter": {"type": "trueFrameRate", "trueFrameRate": 1},
    },
)
response.raise_for_status()
print(response.json())
```

**httpx**

```python
import httpx

response = httpx.put(
    "https://api.gov.nominal.io/api/video/v1/videos/<video rid>",
    headers={"Authorization": "Bearer <api key>"},
    json={
        "title": "<title>",
        "description": "<description>",
        "labels": ["<label>"],
        "properties": {"<key>": "<property value>"},
        "startingTimestamp": {"seconds": 1, "nanos": 1},
        "scaleParameter": {"type": "trueFrameRate", "trueFrameRate": 1},
    },
)
response.raise_for_status()
print(response.json())
```

**aiohttp**

```python
import asyncio

import aiohttp

async def main() -> None:
    async with aiohttp.ClientSession() as session:
        async with session.put(
            "https://api.gov.nominal.io/api/video/v1/videos/<video rid>",
            headers={"Authorization": "Bearer <api key>"},
            json={
                "title": "<title>",
                "description": "<description>",
                "labels": ["<label>"],
                "properties": {"<key>": "<property value>"},
                "startingTimestamp": {"seconds": 1, "nanos": 1},
                "scaleParameter": {"type": "trueFrameRate", "trueFrameRate": 1},
            },
        ) as response:
            response.raise_for_status()
            print(await response.json())

asyncio.run(main())
```

Response: `200`

```json
{
  "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
  }
}
```

### Batch get

POST `/video/v1/videos/batchGet`

**Deprecated:** Legacy Video-entity API. Videos are now channels on datasets; list a channel’s files with listVideoChannelDatasetFiles and read dataset metadata from CatalogService.

Returns video metadata about each video given a set of video rids.

Body

`videoRids` array of string (RID)
:   ​

Response

`responses` array of [`Video`](https://dev.nominal.io/api/rest/video-service.md#video)
:   ​

    Fields of `Video`

    `rid` string (RID)
    :   ​

    `title` string
    :   ​

    `description` string
    :   ​

    `labels` array of string
    :   ​

    `properties` map of `PropertyName` to string
    :   ​

    `createdBy` string (RID)
    :   ​

    `createdAt` string (date-time)
    :   ​

    `isArchived` boolean
    :   ​

    `originMetadata` [`VideoOriginMetadata`](https://dev.nominal.io/api/rest/video-service.md#videooriginmetadata) deprecated
    :   **Deprecated:** deprecated in favor of per-file VideoFileOriginMetadata. Will be removed after April 15th.

        Fields of `VideoOriginMetadata`

        `videoSources` array of [`Handle`](https://dev.nominal.io/api/rest/video-service.md#handle) deprecated
        :   **Deprecated:** deprecated in favor of per-file VideoFileOriginMetadata. Will be removed after April 15th.

            **s3**

            Set `type` to `"s3"`.

            `s3` string
            :   ​

        `timestampManifest` [`VideoTimestampManifest`](https://dev.nominal.io/api/rest/video-service.md#videotimestampmanifest) deprecated
        :   **Deprecated:** deprecated in favor of per-file VideoFileOriginMetadata. Will be removed after April 15th.

            **mcap**

            Set `type` to `"mcap"`.

            `mcap` [`McapTimestampManifest`](https://dev.nominal.io/api/rest/video-service.md#mcaptimestampmanifest)
            :   ​

                Fields of `McapTimestampManifest`

                `mcapChannelLocator` [`McapChannelLocator`](https://dev.nominal.io/api/rest/video-service.md#mcapchannellocator)
                :   ​

                    **topic**

                    Set `type` to `"topic"`.

                    `topic` string
                    :   ​

                    **id**

                    Set `type` to `"id"`.

                    `id` integer
                    :   ​

            **s3paths**

            Set `type` to `"s3paths"`.

            `s3paths` array of string
            :   ​

            **noManifest**

            Set `type` to `"noManifest"`.

            `noManifest` [`NoTimestampManifest`](https://dev.nominal.io/api/rest/video-service.md#notimestampmanifest)
            :   ​

                Fields of `NoTimestampManifest`

                `startingTimestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
                :   Specifies the original starting timestamp of the video.

                    Fields of `Timestamp`

                    `seconds` integer (int64)
                    :   ​

                    `nanos` integer (int64)
                    :   ​

                `scaleParameter` [`ScaleParameter`](https://dev.nominal.io/api/rest/video-service.md#scaleparameter)
                :   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.

                    **trueFrameRate**

                    Set `type` to `"trueFrameRate"`.

                    `trueFrameRate` number
                    :   ​

                    **endingTimestamp**

                    Set `type` to `"endingTimestamp"`.

                    `endingTimestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
                    :   ​

                    **scaleFactor**

                    Set `type` to `"scaleFactor"`.

                    `scaleFactor` number
                    :   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.

    `allSegmentsMetadata` [`VideoAllSegmentsMetadata`](https://dev.nominal.io/api/rest/video-service.md#videoallsegmentsmetadata)
    :   ​

        Fields of `VideoAllSegmentsMetadata`

        `rid` string (RID)
        :   ​

        `numFrames` integer
        :   ​

        `numSegments` integer
        :   ​

        `scaleFactor` number
        :   deprecated, in favor of per-file VideoFileSegmentsMetadata scaleFactor. Will be removed after April 15th.

        `minAbsoluteTimestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
        :   ​

        `maxAbsoluteTimestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
        :   the timestamp corresponding to absolute starting timestamp plus absolute duration of the video.

        `mediaDurationSeconds` number
        :   ​

        `mediaFrameRate` number
        :   The average media frame rate (FPS) of the video calculated as total frames / duration in seconds.

        `minTimestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
        :   deprecated. Will be removed after April 15th.

        `maxTimestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
        :   deprecated. Will be removed after April 15th.

        `durationSeconds` number
        :   deprecated. Will be removed after April 15th.

        `frameRate` number
        :   deprecated. Will be removed after April 15th.

Request

**curl**

```shell
curl -X POST "https://api.gov.nominal.io/api/video/v1/videos/batchGet" \
  -H "Authorization: Bearer <api key>" \
  -H "Content-Type: application/json" \
  --data '{
  "videoRids": [
    "<video rid>"
  ]
}'
```

**requests**

```python
import requests

response = requests.post(
    "https://api.gov.nominal.io/api/video/v1/videos/batchGet",
    headers={"Authorization": "Bearer <api key>"},
    json={"videoRids": ["<video rid>"]},
)
response.raise_for_status()
print(response.json())
```

**httpx**

```python
import httpx

response = httpx.post(
    "https://api.gov.nominal.io/api/video/v1/videos/batchGet",
    headers={"Authorization": "Bearer <api key>"},
    json={"videoRids": ["<video rid>"]},
)
response.raise_for_status()
print(response.json())
```

**aiohttp**

```python
import asyncio

import aiohttp

async def main() -> None:
    async with aiohttp.ClientSession() as session:
        async with session.post(
            "https://api.gov.nominal.io/api/video/v1/videos/batchGet",
            headers={"Authorization": "Bearer <api key>"},
            json={"videoRids": ["<video rid>"]},
        ) as response:
            response.raise_for_status()
            print(await response.json())

asyncio.run(main())
```

Response: `200`

```json
{
  "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
      }
    }
  ]
}
```

### Search

POST `/video/v1/videos/search`

**Deprecated:** Legacy Video-entity API. Videos are now channels on datasets; search datasets with CatalogService#searchDatasets.

Returns metadata about videos that match a given query.

Body

`query` [`SearchVideosQuery`](https://dev.nominal.io/api/rest/video-service.md#searchvideosquery) required
:   ​

    **searchText**

    Set `type` to `"searchText"`.

    `searchText` string
    :   ​

    **label**

    Set `type` to `"label"`.

    `label` string
    :   ​

    **property**

    Set `type` to `"property"`.

    `property` [`Property`](https://dev.nominal.io/api/rest/video-service.md#property)
    :   ​

        Fields of `Property`

        `name` string required
        :   ​

        `value` string required
        :   ​

    **and**

    Set `type` to `"and"`.

    `and` array of [`SearchVideosQuery`](https://dev.nominal.io/api/rest/video-service.md#searchvideosquery)
    :   ​

    **or**

    Set `type` to `"or"`.

    `or` array of [`SearchVideosQuery`](https://dev.nominal.io/api/rest/video-service.md#searchvideosquery)
    :   ​

    **ingestStatus**

    Set `type` to `"ingestStatus"`.

    `ingestStatus` [`IngestStatus`](https://dev.nominal.io/api/rest/video-service.md#ingeststatus)
    :   ​

        Values of `IngestStatus`

        `SUCCEEDED`
        :   ​

        `FAILED`
        :   ​

        `IN_PROGRESS`
        :   ​

    **workspace**

    Set `type` to `"workspace"`.

    `workspace` string (RID)
    :   ​

`pageSize` integer
:   Defaults to 100. Will throw if larger than 1_000.

`token` string
:   ​

`sortOptions` [`SortOptions`](https://dev.nominal.io/api/rest/video-service.md#sortoptions) required
:   ​

    Fields of `SortOptions`

    `isDescending` boolean required
    :   ​

    `field` [`SortField`](https://dev.nominal.io/api/rest/video-service.md#sortfield) required
    :   ​

        Values of `SortField`

        `CREATED_AT`
        :   ​

`archivedStatuses` array of [`ArchivedStatus`](https://dev.nominal.io/api/rest/video-service.md#archivedstatus)
:   Default search status is NOT_ARCHIVED if none are provided. Allows for including archived videos in search.

    Values of `ArchivedStatus`

    `NOT_ARCHIVED`
    :   ​

    `ARCHIVED`
    :   ​

Response

`results` array of [`Video`](https://dev.nominal.io/api/rest/video-service.md#video)
:   ​

    Fields of `Video`

    `rid` string (RID)
    :   ​

    `title` string
    :   ​

    `description` string
    :   ​

    `labels` array of string
    :   ​

    `properties` map of `PropertyName` to string
    :   ​

    `createdBy` string (RID)
    :   ​

    `createdAt` string (date-time)
    :   ​

    `isArchived` boolean
    :   ​

    `originMetadata` [`VideoOriginMetadata`](https://dev.nominal.io/api/rest/video-service.md#videooriginmetadata) deprecated
    :   **Deprecated:** deprecated in favor of per-file VideoFileOriginMetadata. Will be removed after April 15th.

        Fields of `VideoOriginMetadata`

        `videoSources` array of [`Handle`](https://dev.nominal.io/api/rest/video-service.md#handle) deprecated
        :   **Deprecated:** deprecated in favor of per-file VideoFileOriginMetadata. Will be removed after April 15th.

            **s3**

            Set `type` to `"s3"`.

            `s3` string
            :   ​

        `timestampManifest` [`VideoTimestampManifest`](https://dev.nominal.io/api/rest/video-service.md#videotimestampmanifest) deprecated
        :   **Deprecated:** deprecated in favor of per-file VideoFileOriginMetadata. Will be removed after April 15th.

            **mcap**

            Set `type` to `"mcap"`.

            `mcap` [`McapTimestampManifest`](https://dev.nominal.io/api/rest/video-service.md#mcaptimestampmanifest)
            :   ​

                Fields of `McapTimestampManifest`

                `mcapChannelLocator` [`McapChannelLocator`](https://dev.nominal.io/api/rest/video-service.md#mcapchannellocator)
                :   ​

                    **topic**

                    Set `type` to `"topic"`.

                    `topic` string
                    :   ​

                    **id**

                    Set `type` to `"id"`.

                    `id` integer
                    :   ​

            **s3paths**

            Set `type` to `"s3paths"`.

            `s3paths` array of string
            :   ​

            **noManifest**

            Set `type` to `"noManifest"`.

            `noManifest` [`NoTimestampManifest`](https://dev.nominal.io/api/rest/video-service.md#notimestampmanifest)
            :   ​

                Fields of `NoTimestampManifest`

                `startingTimestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
                :   Specifies the original starting timestamp of the video.

                    Fields of `Timestamp`

                    `seconds` integer (int64)
                    :   ​

                    `nanos` integer (int64)
                    :   ​

                `scaleParameter` [`ScaleParameter`](https://dev.nominal.io/api/rest/video-service.md#scaleparameter)
                :   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.

                    **trueFrameRate**

                    Set `type` to `"trueFrameRate"`.

                    `trueFrameRate` number
                    :   ​

                    **endingTimestamp**

                    Set `type` to `"endingTimestamp"`.

                    `endingTimestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
                    :   ​

                    **scaleFactor**

                    Set `type` to `"scaleFactor"`.

                    `scaleFactor` number
                    :   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.

    `allSegmentsMetadata` [`VideoAllSegmentsMetadata`](https://dev.nominal.io/api/rest/video-service.md#videoallsegmentsmetadata)
    :   ​

        Fields of `VideoAllSegmentsMetadata`

        `rid` string (RID)
        :   ​

        `numFrames` integer
        :   ​

        `numSegments` integer
        :   ​

        `scaleFactor` number
        :   deprecated, in favor of per-file VideoFileSegmentsMetadata scaleFactor. Will be removed after April 15th.

        `minAbsoluteTimestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
        :   ​

        `maxAbsoluteTimestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
        :   the timestamp corresponding to absolute starting timestamp plus absolute duration of the video.

        `mediaDurationSeconds` number
        :   ​

        `mediaFrameRate` number
        :   The average media frame rate (FPS) of the video calculated as total frames / duration in seconds.

        `minTimestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
        :   deprecated. Will be removed after April 15th.

        `maxTimestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
        :   deprecated. Will be removed after April 15th.

        `durationSeconds` number
        :   deprecated. Will be removed after April 15th.

        `frameRate` number
        :   deprecated. Will be removed after April 15th.

`nextPageToken` string
:   ​

Request

**curl**

```shell
curl -X POST "https://api.gov.nominal.io/api/video/v1/videos/search" \
  -H "Authorization: Bearer <api key>" \
  -H "Content-Type: application/json" \
  --data '{
  "query": {
    "type": "searchText",
    "searchText": "<search text>"
  },
  "sortOptions": {
    "isDescending": true,
    "field": "CREATED_AT"
  }
}'
```

**requests**

```python
import requests

response = requests.post(
    "https://api.gov.nominal.io/api/video/v1/videos/search",
    headers={"Authorization": "Bearer <api key>"},
    json={
        "query": {"type": "searchText", "searchText": "<search text>"},
        "sortOptions": {"isDescending": True, "field": "CREATED_AT"},
    },
)
response.raise_for_status()
print(response.json())
```

**httpx**

```python
import httpx

response = httpx.post(
    "https://api.gov.nominal.io/api/video/v1/videos/search",
    headers={"Authorization": "Bearer <api key>"},
    json={
        "query": {"type": "searchText", "searchText": "<search text>"},
        "sortOptions": {"isDescending": True, "field": "CREATED_AT"},
    },
)
response.raise_for_status()
print(response.json())
```

**aiohttp**

```python
import asyncio

import aiohttp

async def main() -> None:
    async with aiohttp.ClientSession() as session:
        async with session.post(
            "https://api.gov.nominal.io/api/video/v1/videos/search",
            headers={"Authorization": "Bearer <api key>"},
            json={
                "query": {"type": "searchText", "searchText": "<search text>"},
                "sortOptions": {"isDescending": True, "field": "CREATED_AT"},
            },
        ) as response:
            response.raise_for_status()
            print(await response.json())

asyncio.run(main())
```

Response: `200`

```json
{
  "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>"
}
```

### Create

POST `/video/v1/videos`

**Deprecated:** Legacy Video-entity API. Videos are now channels on datasets; ingest with videoV2 options targeting a dataset channel instead of creating a Video.

Creates and persists a video entity with the given metadata.

Body

`title` string required
:   ​

`description` string
:   ​

`labels` array of string
:   ​

`properties` map of `PropertyName` to string
:   ​

`originMetadata` [`VideoOriginMetadata`](https://dev.nominal.io/api/rest/video-service.md#videooriginmetadata) deprecated
:   **Deprecated:** deprecated in favor of per-file VideoFileOriginMetadata. Will be removed after April 15th.

    Fields of `VideoOriginMetadata`

    `videoSources` array of [`Handle`](https://dev.nominal.io/api/rest/video-service.md#handle) deprecated
    :   **Deprecated:** deprecated in favor of per-file VideoFileOriginMetadata. Will be removed after April 15th.

        **s3**

        Set `type` to `"s3"`.

        `s3` string
        :   ​

    `timestampManifest` [`VideoTimestampManifest`](https://dev.nominal.io/api/rest/video-service.md#videotimestampmanifest) required deprecated
    :   **Deprecated:** deprecated in favor of per-file VideoFileOriginMetadata. Will be removed after April 15th.

        **mcap**

        Set `type` to `"mcap"`.

        `mcap` [`McapTimestampManifest`](https://dev.nominal.io/api/rest/video-service.md#mcaptimestampmanifest)
        :   ​

            Fields of `McapTimestampManifest`

            `mcapChannelLocator` [`McapChannelLocator`](https://dev.nominal.io/api/rest/video-service.md#mcapchannellocator) required
            :   ​

                **topic**

                Set `type` to `"topic"`.

                `topic` string
                :   ​

                **id**

                Set `type` to `"id"`.

                `id` integer
                :   ​

        **s3paths**

        Set `type` to `"s3paths"`.

        `s3paths` array of string
        :   ​

        **noManifest**

        Set `type` to `"noManifest"`.

        `noManifest` [`NoTimestampManifest`](https://dev.nominal.io/api/rest/video-service.md#notimestampmanifest)
        :   ​

            Fields of `NoTimestampManifest`

            `startingTimestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp) required
            :   Specifies the original starting timestamp of the video.

                Fields of `Timestamp`

                `seconds` integer (int64) required
                :   ​

                `nanos` integer (int64) required
                :   ​

            `scaleParameter` [`ScaleParameter`](https://dev.nominal.io/api/rest/video-service.md#scaleparameter)
            :   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.

                **trueFrameRate**

                Set `type` to `"trueFrameRate"`.

                `trueFrameRate` number
                :   ​

                **endingTimestamp**

                Set `type` to `"endingTimestamp"`.

                `endingTimestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
                :   ​

                **scaleFactor**

                Set `type` to `"scaleFactor"`.

                `scaleFactor` number
                :   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.

`workspace` string (RID)
:   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` array of string (RID)
:   The markings to apply to the created video. If not provided, the video will be visible to all users in the same workspace.

Response

`rid` string (RID)
:   ​

`title` string
:   ​

`description` string
:   ​

`labels` array of string
:   ​

`properties` map of `PropertyName` to string
:   ​

`createdBy` string (RID)
:   ​

`createdAt` string (date-time)
:   ​

`isArchived` boolean
:   ​

`originMetadata` [`VideoOriginMetadata`](https://dev.nominal.io/api/rest/video-service.md#videooriginmetadata) deprecated
:   **Deprecated:** deprecated in favor of per-file VideoFileOriginMetadata. Will be removed after April 15th.

    Fields of `VideoOriginMetadata`

    `videoSources` array of [`Handle`](https://dev.nominal.io/api/rest/video-service.md#handle) deprecated
    :   **Deprecated:** deprecated in favor of per-file VideoFileOriginMetadata. Will be removed after April 15th.

        **s3**

        Set `type` to `"s3"`.

        `s3` string
        :   ​

    `timestampManifest` [`VideoTimestampManifest`](https://dev.nominal.io/api/rest/video-service.md#videotimestampmanifest) deprecated
    :   **Deprecated:** deprecated in favor of per-file VideoFileOriginMetadata. Will be removed after April 15th.

        **mcap**

        Set `type` to `"mcap"`.

        `mcap` [`McapTimestampManifest`](https://dev.nominal.io/api/rest/video-service.md#mcaptimestampmanifest)
        :   ​

            Fields of `McapTimestampManifest`

            `mcapChannelLocator` [`McapChannelLocator`](https://dev.nominal.io/api/rest/video-service.md#mcapchannellocator)
            :   ​

                **topic**

                Set `type` to `"topic"`.

                `topic` string
                :   ​

                **id**

                Set `type` to `"id"`.

                `id` integer
                :   ​

        **s3paths**

        Set `type` to `"s3paths"`.

        `s3paths` array of string
        :   ​

        **noManifest**

        Set `type` to `"noManifest"`.

        `noManifest` [`NoTimestampManifest`](https://dev.nominal.io/api/rest/video-service.md#notimestampmanifest)
        :   ​

            Fields of `NoTimestampManifest`

            `startingTimestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
            :   Specifies the original starting timestamp of the video.

                Fields of `Timestamp`

                `seconds` integer (int64)
                :   ​

                `nanos` integer (int64)
                :   ​

            `scaleParameter` [`ScaleParameter`](https://dev.nominal.io/api/rest/video-service.md#scaleparameter)
            :   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.

                **trueFrameRate**

                Set `type` to `"trueFrameRate"`.

                `trueFrameRate` number
                :   ​

                **endingTimestamp**

                Set `type` to `"endingTimestamp"`.

                `endingTimestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
                :   ​

                **scaleFactor**

                Set `type` to `"scaleFactor"`.

                `scaleFactor` number
                :   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.

`allSegmentsMetadata` [`VideoAllSegmentsMetadata`](https://dev.nominal.io/api/rest/video-service.md#videoallsegmentsmetadata)
:   ​

    Fields of `VideoAllSegmentsMetadata`

    `rid` string (RID)
    :   ​

    `numFrames` integer
    :   ​

    `numSegments` integer
    :   ​

    `scaleFactor` number
    :   deprecated, in favor of per-file VideoFileSegmentsMetadata scaleFactor. Will be removed after April 15th.

    `minAbsoluteTimestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
    :   ​

    `maxAbsoluteTimestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
    :   the timestamp corresponding to absolute starting timestamp plus absolute duration of the video.

    `mediaDurationSeconds` number
    :   ​

    `mediaFrameRate` number
    :   The average media frame rate (FPS) of the video calculated as total frames / duration in seconds.

    `minTimestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
    :   deprecated. Will be removed after April 15th.

    `maxTimestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
    :   deprecated. Will be removed after April 15th.

    `durationSeconds` number
    :   deprecated. Will be removed after April 15th.

    `frameRate` number
    :   deprecated. Will be removed after April 15th.

Request

**curl**

```shell
curl -X POST "https://api.gov.nominal.io/api/video/v1/videos" \
  -H "Authorization: Bearer <api key>" \
  -H "Content-Type: application/json" \
  --data '{
  "title": "<title>"
}'
```

**requests**

```python
import requests

response = requests.post(
    "https://api.gov.nominal.io/api/video/v1/videos",
    headers={"Authorization": "Bearer <api key>"},
    json={"title": "<title>"},
)
response.raise_for_status()
print(response.json())
```

**httpx**

```python
import httpx

response = httpx.post(
    "https://api.gov.nominal.io/api/video/v1/videos",
    headers={"Authorization": "Bearer <api key>"},
    json={"title": "<title>"},
)
response.raise_for_status()
print(response.json())
```

**aiohttp**

```python
import asyncio

import aiohttp

async def main() -> None:
    async with aiohttp.ClientSession() as session:
        async with session.post(
            "https://api.gov.nominal.io/api/video/v1/videos",
            headers={"Authorization": "Bearer <api key>"},
            json={"title": "<title>"},
        ) as response:
            response.raise_for_status()
            print(await response.json())

asyncio.run(main())
```

Response: `200`

```json
{
  "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
  }
}
```

### Get ingest status

GET `/video/v1/videos/{videoRid}/ingest-status`

**Deprecated:** Legacy Video-entity API. Videos are now channels on datasets; ingest status is tracked per file on the Catalog dataset file (CatalogService#getDatasetFile).

Path parameters

`videoRid` string (RID) required
:   ​

Response

A [`DetailedIngestStatus`](https://dev.nominal.io/api/rest/video-service.md#detailedingeststatus) union.

**success**

Set `type` to `"success"`.

`success` [`SuccessIngestStatus`](https://dev.nominal.io/api/rest/video-service.md#successingeststatus)
:   ​

**error**

Set `type` to `"error"`.

`error` [`ErrorIngestStatus`](https://dev.nominal.io/api/rest/video-service.md#erroringeststatus)
:   ​

    Fields of `ErrorIngestStatus`

    `errors` array of [`IngestError`](https://dev.nominal.io/api/rest/video-service.md#ingesterror)
    :   ​

        Fields of `IngestError`

        `errorType` string
        :   ​

        `message` string
        :   ​

        `errorInstanceId` string
        :   ​

**inProgress**

Set `type` to `"inProgress"`.

`inProgress` number
:   A number between 0 and 1 representing percentage progress.

Request

**curl**

```shell
curl "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/ingest-status" \
  -H "Authorization: Bearer <api key>"
```

**requests**

```python
import requests

response = requests.get(
    "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/ingest-status",
    headers={"Authorization": "Bearer <api key>"},
)
response.raise_for_status()
print(response.json())
```

**httpx**

```python
import httpx

response = httpx.get(
    "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/ingest-status",
    headers={"Authorization": "Bearer <api key>"},
)
response.raise_for_status()
print(response.json())
```

**aiohttp**

```python
import asyncio

import aiohttp

async def main() -> None:
    async with aiohttp.ClientSession() as session:
        async with session.get(
            "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/ingest-status",
            headers={"Authorization": "Bearer <api key>"},
        ) as response:
            response.raise_for_status()
            print(await response.json())

asyncio.run(main())
```

Response: `200`

```json
{
  "type": "success",
  "success": {}
}
```

### Batch get ingest status

POST `/video/v1/videos/batch-get-ingest-status`

**Deprecated:** Legacy Video-entity API. Videos are now channels on datasets; ingest status is tracked per file on the Catalog dataset file (CatalogService#batchGetDatasetFiles).

Body

The body is an array of string (RID).

Response

The body is a map of `VideoRid` to [`DetailedIngestStatus`](https://dev.nominal.io/api/rest/video-service.md#detailedingeststatus).

**success**

Set `type` to `"success"`.

`success` [`SuccessIngestStatus`](https://dev.nominal.io/api/rest/video-service.md#successingeststatus)
:   ​

**error**

Set `type` to `"error"`.

`error` [`ErrorIngestStatus`](https://dev.nominal.io/api/rest/video-service.md#erroringeststatus)
:   ​

    Fields of `ErrorIngestStatus`

    `errors` array of [`IngestError`](https://dev.nominal.io/api/rest/video-service.md#ingesterror)
    :   ​

        Fields of `IngestError`

        `errorType` string
        :   ​

        `message` string
        :   ​

        `errorInstanceId` string
        :   ​

**inProgress**

Set `type` to `"inProgress"`.

`inProgress` number
:   A number between 0 and 1 representing percentage progress.

Request

**curl**

```shell
curl -X POST "https://api.gov.nominal.io/api/video/v1/videos/batch-get-ingest-status" \
  -H "Authorization: Bearer <api key>" \
  -H "Content-Type: application/json" \
  --data '[
  "<video rid>"
]'
```

**requests**

```python
import requests

response = requests.post(
    "https://api.gov.nominal.io/api/video/v1/videos/batch-get-ingest-status",
    headers={"Authorization": "Bearer <api key>"},
    json=["<video rid>"],
)
response.raise_for_status()
print(response.json())
```

**httpx**

```python
import httpx

response = httpx.post(
    "https://api.gov.nominal.io/api/video/v1/videos/batch-get-ingest-status",
    headers={"Authorization": "Bearer <api key>"},
    json=["<video rid>"],
)
response.raise_for_status()
print(response.json())
```

**aiohttp**

```python
import asyncio

import aiohttp

async def main() -> None:
    async with aiohttp.ClientSession() as session:
        async with session.post(
            "https://api.gov.nominal.io/api/video/v1/videos/batch-get-ingest-status",
            headers={"Authorization": "Bearer <api key>"},
            json=["<video rid>"],
        ) as response:
            response.raise_for_status()
            print(await response.json())

asyncio.run(main())
```

Response: `200`

```json
{
  "<key>": {
    "type": "success",
    "success": {}
  }
}
```

### Get enriched ingest status

POST `/video/v1/videos/enriched-ingest-status`

**Deprecated:** Legacy Video-entity API. Videos are now channels on datasets; ingest status is tracked per file on the Catalog dataset file (CatalogService#getDatasetFile).

Body

`videoRid` string (RID) required
:   ​

`token` string
:   ​

Response

`status` [`VideoIngestStatus`](https://dev.nominal.io/api/rest/video-service.md#videoingeststatus)
:   ​

    **ready**

    Set `type` to `"ready"`.

    `ready` [`Empty`](https://dev.nominal.io/api/rest/video-service.md#empty)
    :   ​

    **inProgress**

    Set `type` to `"inProgress"`.

    `inProgress` [`Empty`](https://dev.nominal.io/api/rest/video-service.md#empty)
    :   ​

    **error**

    Set `type` to `"error"`.

    `error` [`Empty`](https://dev.nominal.io/api/rest/video-service.md#empty)
    :   ​

`fileIngestStatus` map of `VideoFileRid` to [`VideoFileIngestStatus`](https://dev.nominal.io/api/rest/video-service.md#videofileingeststatus)
:   ​

    **success**

    Set `type` to `"success"`.

    `success` [`SuccessIngestStatus`](https://dev.nominal.io/api/rest/video-service.md#successingeststatus)
    :   ​

    **error**

    Set `type` to `"error"`.

    `error` [`IngestError`](https://dev.nominal.io/api/rest/video-service.md#ingesterror)
    :   ​

        Fields of `IngestError`

        `errorType` string
        :   ​

        `message` string
        :   ​

        `errorInstanceId` string
        :   ​

    **inProgress**

    Set `type` to `"inProgress"`.

    `inProgress` [`Empty`](https://dev.nominal.io/api/rest/video-service.md#empty)
    :   ​

`nextPageToken` string
:   ​

When there is nothing to return, the response is HTTP 204 with no body.

Request

**curl**

```shell
curl -X POST "https://api.gov.nominal.io/api/video/v1/videos/enriched-ingest-status" \
  -H "Authorization: Bearer <api key>" \
  -H "Content-Type: application/json" \
  --data '{
  "videoRid": "<video rid>"
}'
```

**requests**

```python
import requests

response = requests.post(
    "https://api.gov.nominal.io/api/video/v1/videos/enriched-ingest-status",
    headers={"Authorization": "Bearer <api key>"},
    json={"videoRid": "<video rid>"},
)
response.raise_for_status()
print(response.json())
```

**httpx**

```python
import httpx

response = httpx.post(
    "https://api.gov.nominal.io/api/video/v1/videos/enriched-ingest-status",
    headers={"Authorization": "Bearer <api key>"},
    json={"videoRid": "<video rid>"},
)
response.raise_for_status()
print(response.json())
```

**aiohttp**

```python
import asyncio

import aiohttp

async def main() -> None:
    async with aiohttp.ClientSession() as session:
        async with session.post(
            "https://api.gov.nominal.io/api/video/v1/videos/enriched-ingest-status",
            headers={"Authorization": "Bearer <api key>"},
            json={"videoRid": "<video rid>"},
        ) as response:
            response.raise_for_status()
            print(await response.json())

asyncio.run(main())
```

Response: `200`

```json
{
  "status": {
    "type": "ready",
    "ready": {}
  },
  "fileIngestStatus": {
    "<key>": {
      "type": "success",
      "success": {}
    }
  },
  "nextPageToken": "<token>"
}
```

### Archive

PUT `/video/v1/videos/{videoRid}/archive`

**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.

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.

Path parameters

`videoRid` string (RID) required
:   ​

Response

No content (HTTP 204).

Request

**curl**

```shell
curl -X PUT "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/archive" \
  -H "Authorization: Bearer <api key>"
```

**requests**

```python
import requests

response = requests.put(
    "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/archive",
    headers={"Authorization": "Bearer <api key>"},
)
response.raise_for_status()
```

**httpx**

```python
import httpx

response = httpx.put(
    "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/archive",
    headers={"Authorization": "Bearer <api key>"},
)
response.raise_for_status()
```

**aiohttp**

```python
import asyncio

import aiohttp

async def main() -> None:
    async with aiohttp.ClientSession() as session:
        async with session.put(
            "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/archive",
            headers={"Authorization": "Bearer <api key>"},
        ) as response:
            response.raise_for_status()

asyncio.run(main())
```

Response: `204`

No content.

### Unarchive

PUT `/video/v1/videos/{videoRid}/unarchive`

**Deprecated:** Legacy Video-entity API. Videos are now channels on datasets; unarchive the backing dataset with CatalogService#unarchiveDataset.

Unarchives a previously archived video.

Path parameters

`videoRid` string (RID) required
:   ​

Response

No content (HTTP 204).

Request

**curl**

```shell
curl -X PUT "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/unarchive" \
  -H "Authorization: Bearer <api key>"
```

**requests**

```python
import requests

response = requests.put(
    "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/unarchive",
    headers={"Authorization": "Bearer <api key>"},
)
response.raise_for_status()
```

**httpx**

```python
import httpx

response = httpx.put(
    "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/unarchive",
    headers={"Authorization": "Bearer <api key>"},
)
response.raise_for_status()
```

**aiohttp**

```python
import asyncio

import aiohttp

async def main() -> None:
    async with aiohttp.ClientSession() as session:
        async with session.put(
            "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/unarchive",
            headers={"Authorization": "Bearer <api key>"},
        ) as response:
            response.raise_for_status()

asyncio.run(main())
```

Response: `204`

No content.

### Get playlist

GET `/video/v1/videos/{videoRid}/playlist`

**Deprecated:** Replaced by getPlaylistV2, which addresses the video channel series (channel + tags) instead of a Video rid.

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.

Note: The start and end parameters must either both be provided or both be omitted. Providing only one will result in a MissingTimestampBoundPair error.

Path parameters

`videoRid` string (RID) required
:   ​

Query parameters

`start` string
:   Start bound as ISO-8601 timestamp (e.g., “2024-01-01T00:00:00Z”). Must be provided together with end, or neither.

`end` string
:   End bound as ISO-8601 timestamp (e.g., “2024-01-01T01:00:00Z”). Must be provided together with start, or neither.

Response: `application/octet-stream`

The body is the raw bytes.

A successful response.

Request

**curl**

```shell
curl "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/playlist" \
  -H "Authorization: Bearer <api key>" \
  --output "<file>"
```

**requests**

```python
from pathlib import Path

import requests

response = requests.get(
    "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/playlist",
    headers={"Authorization": "Bearer <api key>"},
)
response.raise_for_status()
Path("<file>").write_bytes(response.content)
```

**httpx**

```python
from pathlib import Path

import httpx

response = httpx.get(
    "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/playlist",
    headers={"Authorization": "Bearer <api key>"},
)
response.raise_for_status()
Path("<file>").write_bytes(response.content)
```

**aiohttp**

```python
import asyncio
from pathlib import Path

import aiohttp

async def main() -> None:
    async with aiohttp.ClientSession() as session:
        async with session.get(
            "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/playlist",
            headers={"Authorization": "Bearer <api key>"},
        ) as response:
            response.raise_for_status()
            Path("<file>").write_bytes(await response.read())

asyncio.run(main())
```

Response: `200`

The raw bytes.

### Get segment summaries

GET `/video/v1/videos/{videoRid}/segment-summaries`

**Deprecated:** Replaced by getSegmentSummariesInBounds. Will be removed after April 15th.

Returns the min and max absolute and media timestamps for each segment in a video. To be used during frame-timestamp mapping.

Path parameters

`videoRid` string (RID) required
:   ​

Response

The body is an array of [`SegmentSummary`](https://dev.nominal.io/api/rest/video-service.md#segmentsummary).

Fields of `SegmentSummary`

`minAbsoluteTimestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
:   ​

    Fields of `Timestamp`

    `seconds` integer (int64)
    :   ​

    `nanos` integer (int64)
    :   ​

`maxAbsoluteTimestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
:   ​

`minMediaTimestamp` number
:   ​

`maxMediaTimestamp` number
:   ​

Request

**curl**

```shell
curl "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/segment-summaries" \
  -H "Authorization: Bearer <api key>"
```

**requests**

```python
import requests

response = requests.get(
    "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/segment-summaries",
    headers={"Authorization": "Bearer <api key>"},
)
response.raise_for_status()
print(response.json())
```

**httpx**

```python
import httpx

response = httpx.get(
    "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/segment-summaries",
    headers={"Authorization": "Bearer <api key>"},
)
response.raise_for_status()
print(response.json())
```

**aiohttp**

```python
import asyncio

import aiohttp

async def main() -> None:
    async with aiohttp.ClientSession() as session:
        async with session.get(
            "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/segment-summaries",
            headers={"Authorization": "Bearer <api key>"},
        ) as response:
            response.raise_for_status()
            print(await response.json())

asyncio.run(main())
```

Response: `200`

```json
[
  {
    "minAbsoluteTimestamp": {
      "seconds": 1,
      "nanos": 1
    },
    "maxAbsoluteTimestamp": {
      "seconds": 1,
      "nanos": 1
    },
    "minMediaTimestamp": 1,
    "maxMediaTimestamp": 1
  }
]
```

### Get playlist in bounds

POST `/video/v1/videos/{videoRid}/playlist-in-bounds`

**Deprecated:** Use getPlaylist (GET) for HLS.js compatibility.

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.

Path parameters

`videoRid` string (RID) required
:   ​

Body

`bounds` [`Bounds`](https://dev.nominal.io/api/rest/video-service.md#bounds)
:   ​

    Fields of `Bounds`

    `start` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp) required
    :   ​

        Fields of `Timestamp`

        `seconds` integer (int64) required
        :   ​

        `nanos` integer (int64) required
        :   ​

    `end` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp) required
    :   ​

Response: `application/octet-stream`

The body is the raw bytes.

A successful response.

Request

**curl**

```shell
curl -X POST "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/playlist-in-bounds" \
  -H "Authorization: Bearer <api key>" \
  -H "Content-Type: application/json" \
  --data '{
  "bounds": {
    "start": {
      "seconds": 1,
      "nanos": 1
    },
    "end": {
      "seconds": 1,
      "nanos": 1
    }
  }
}' \
  --output "<file>"
```

**requests**

```python
from pathlib import Path

import requests

response = requests.post(
    "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/playlist-in-bounds",
    headers={"Authorization": "Bearer <api key>"},
    json={
        "bounds": {
            "start": {"seconds": 1, "nanos": 1},
            "end": {"seconds": 1, "nanos": 1},
        },
    },
)
response.raise_for_status()
Path("<file>").write_bytes(response.content)
```

**httpx**

```python
from pathlib import Path

import httpx

response = httpx.post(
    "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/playlist-in-bounds",
    headers={"Authorization": "Bearer <api key>"},
    json={
        "bounds": {
            "start": {"seconds": 1, "nanos": 1},
            "end": {"seconds": 1, "nanos": 1},
        },
    },
)
response.raise_for_status()
Path("<file>").write_bytes(response.content)
```

**aiohttp**

```python
import asyncio
from pathlib import Path

import aiohttp

async def main() -> None:
    async with aiohttp.ClientSession() as session:
        async with session.post(
            "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/playlist-in-bounds",
            headers={"Authorization": "Bearer <api key>"},
            json={
                "bounds": {
                    "start": {"seconds": 1, "nanos": 1},
                    "end": {"seconds": 1, "nanos": 1},
                },
            },
        ) as response:
            response.raise_for_status()
            Path("<file>").write_bytes(await response.read())

asyncio.run(main())
```

Response: `200`

The raw bytes.

### Get playlist in bounds v2

POST `/video/v2/videos/playlist-in-bounds`

**Deprecated:** Use getPlaylistV2 (GET) for HLS.js compatibility.

Generates an HLS playlist for a video series (identified by channel + tags) within bounds.

Body

`channelSeries` [`VideoChannelSeries`](https://dev.nominal.io/api/rest/video-service.md#videochannelseries) required
:   ​

    **dataSource**

    Set `type` to `"dataSource"`.

    `dataSource` [`VideoDataSourceChannel`](https://dev.nominal.io/api/rest/video-service.md#videodatasourcechannel)
    :   ​

        Fields of `VideoDataSourceChannel`

        `dataSourceRid` string required
        :   ​

        `channel` string required
        :   ​

        `tags` map of `TagName` to string
        :   ​

    **asset**

    Set `type` to `"asset"`.

    `asset` [`VideoAssetChannel`](https://dev.nominal.io/api/rest/video-service.md#videoassetchannel)
    :   ​

        Fields of `VideoAssetChannel`

        `assetRid` string required
        :   ​

        `dataScopeName` string required
        :   ​

        `channel` string required
        :   ​

        `tags` map of `TagName` to string
        :   ​

`bounds` [`Bounds`](https://dev.nominal.io/api/rest/video-service.md#bounds) required
:   ​

    Fields of `Bounds`

    `start` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp) required
    :   ​

        Fields of `Timestamp`

        `seconds` integer (int64) required
        :   ​

        `nanos` integer (int64) required
        :   ​

    `end` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp) required
    :   ​

Response: `application/octet-stream`

The body is the raw bytes.

A successful response.

Request

**curl**

```shell
curl -X POST "https://api.gov.nominal.io/api/video/v2/videos/playlist-in-bounds" \
  -H "Authorization: Bearer <api key>" \
  -H "Content-Type: application/json" \
  --data '{
  "channelSeries": {
    "type": "dataSource",
    "dataSource": {
      "dataSourceRid": "<data source rid>",
      "channel": "<channel>"
    }
  },
  "bounds": {
    "start": {
      "seconds": 1,
      "nanos": 1
    },
    "end": {
      "seconds": 1,
      "nanos": 1
    }
  }
}' \
  --output "<file>"
```

**requests**

```python
from pathlib import Path

import requests

response = requests.post(
    "https://api.gov.nominal.io/api/video/v2/videos/playlist-in-bounds",
    headers={"Authorization": "Bearer <api key>"},
    json={
        "channelSeries": {
            "type": "dataSource",
            "dataSource": {"dataSourceRid": "<data source rid>", "channel": "<channel>"},
        },
        "bounds": {
            "start": {"seconds": 1, "nanos": 1},
            "end": {"seconds": 1, "nanos": 1},
        },
    },
)
response.raise_for_status()
Path("<file>").write_bytes(response.content)
```

**httpx**

```python
from pathlib import Path

import httpx

response = httpx.post(
    "https://api.gov.nominal.io/api/video/v2/videos/playlist-in-bounds",
    headers={"Authorization": "Bearer <api key>"},
    json={
        "channelSeries": {
            "type": "dataSource",
            "dataSource": {"dataSourceRid": "<data source rid>", "channel": "<channel>"},
        },
        "bounds": {
            "start": {"seconds": 1, "nanos": 1},
            "end": {"seconds": 1, "nanos": 1},
        },
    },
)
response.raise_for_status()
Path("<file>").write_bytes(response.content)
```

**aiohttp**

```python
import asyncio
from pathlib import Path

import aiohttp

async def main() -> None:
    async with aiohttp.ClientSession() as session:
        async with session.post(
            "https://api.gov.nominal.io/api/video/v2/videos/playlist-in-bounds",
            headers={"Authorization": "Bearer <api key>"},
            json={
                "channelSeries": {
                    "type": "dataSource",
                    "dataSource": {
                        "dataSourceRid": "<data source rid>",
                        "channel": "<channel>",
                    },
                },
                "bounds": {
                    "start": {"seconds": 1, "nanos": 1},
                    "end": {"seconds": 1, "nanos": 1},
                },
            },
        ) as response:
            response.raise_for_status()
            Path("<file>").write_bytes(await response.read())

asyncio.run(main())
```

Response: `200`

The raw bytes.

### Get playlist v2

GET `/video/v2/videos/playlist`

Generates an HLS playlist for a video series within time bounds. Specify either dataSourceRid OR (assetRid + dataScopeName) to identify the series source.

Note: Both start and end parameters are required and must be provided together.

Query parameters

`dataSourceRid` string (RID)
:   Data source RID (mutually exclusive with assetRid)

`assetRid` string (RID)
:   Asset RID (mutually exclusive with dataSourceRid, requires dataScopeName)

`dataScopeName` string
:   Data scope name (required when using assetRid)

`channel` string required
:   Channel name

`tags` string
:   Tags as JSON-encoded map (e.g., {“vehicle”:”car1”})

`start` string required
:   Required start bound as ISO-8601 timestamp (e.g., “2024-01-01T00:00:00Z”). Must be provided with end.

`end` string required
:   Required end bound as ISO-8601 timestamp (e.g., “2024-01-01T01:00:00Z”). Must be provided with start.

Response: `application/octet-stream`

The body is the raw bytes.

A successful response.

Request

**curl**

```shell
curl "https://api.gov.nominal.io/api/video/v2/videos/playlist?channel=<channel>&start=<start>&end=<end>" \
  -H "Authorization: Bearer <api key>" \
  --output "<file>"
```

**requests**

```python
from pathlib import Path

import requests

response = requests.get(
    "https://api.gov.nominal.io/api/video/v2/videos/playlist?channel=<channel>&start=<start>&end=<end>",
    headers={"Authorization": "Bearer <api key>"},
)
response.raise_for_status()
Path("<file>").write_bytes(response.content)
```

**httpx**

```python
from pathlib import Path

import httpx

response = httpx.get(
    "https://api.gov.nominal.io/api/video/v2/videos/playlist?channel=<channel>&start=<start>&end=<end>",
    headers={"Authorization": "Bearer <api key>"},
)
response.raise_for_status()
Path("<file>").write_bytes(response.content)
```

**aiohttp**

```python
import asyncio
from pathlib import Path

import aiohttp

async def main() -> None:
    async with aiohttp.ClientSession() as session:
        async with session.get(
            "https://api.gov.nominal.io/api/video/v2/videos/playlist?channel=<channel>&start=<start>&end=<end>",
            headers={"Authorization": "Bearer <api key>"},
        ) as response:
            response.raise_for_status()
            Path("<file>").write_bytes(await response.read())

asyncio.run(main())
```

Response: `200`

The raw bytes.

### Get segment summaries in bounds

POST `/video/v1/videos/{videoRid}/segment-summaries-in-bounds`

**Deprecated:** Replaced by getSegmentSummariesInBoundsV2, which addresses the video channel series (channel + tags) instead of a Video rid.

Returns the min and max absolute and media timestamps for each segment in a video that overlap with an optional set of bounds.

Path parameters

`videoRid` string (RID) required
:   ​

Body

`bounds` [`Bounds`](https://dev.nominal.io/api/rest/video-service.md#bounds)
:   ​

    Fields of `Bounds`

    `start` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp) required
    :   ​

        Fields of `Timestamp`

        `seconds` integer (int64) required
        :   ​

        `nanos` integer (int64) required
        :   ​

    `end` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp) required
    :   ​

Response

The body is an array of [`SegmentSummary`](https://dev.nominal.io/api/rest/video-service.md#segmentsummary).

Fields of `SegmentSummary`

`minAbsoluteTimestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
:   ​

    Fields of `Timestamp`

    `seconds` integer (int64)
    :   ​

    `nanos` integer (int64)
    :   ​

`maxAbsoluteTimestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
:   ​

`minMediaTimestamp` number
:   ​

`maxMediaTimestamp` number
:   ​

Request

**curl**

```shell
curl -X POST "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/segment-summaries-in-bounds" \
  -H "Authorization: Bearer <api key>" \
  -H "Content-Type: application/json" \
  --data '{
  "bounds": {
    "start": {
      "seconds": 1,
      "nanos": 1
    },
    "end": {
      "seconds": 1,
      "nanos": 1
    }
  }
}'
```

**requests**

```python
import requests

response = requests.post(
    "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/segment-summaries-in-bounds",
    headers={"Authorization": "Bearer <api key>"},
    json={
        "bounds": {
            "start": {"seconds": 1, "nanos": 1},
            "end": {"seconds": 1, "nanos": 1},
        },
    },
)
response.raise_for_status()
print(response.json())
```

**httpx**

```python
import httpx

response = httpx.post(
    "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/segment-summaries-in-bounds",
    headers={"Authorization": "Bearer <api key>"},
    json={
        "bounds": {
            "start": {"seconds": 1, "nanos": 1},
            "end": {"seconds": 1, "nanos": 1},
        },
    },
)
response.raise_for_status()
print(response.json())
```

**aiohttp**

```python
import asyncio

import aiohttp

async def main() -> None:
    async with aiohttp.ClientSession() as session:
        async with session.post(
            "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/segment-summaries-in-bounds",
            headers={"Authorization": "Bearer <api key>"},
            json={
                "bounds": {
                    "start": {"seconds": 1, "nanos": 1},
                    "end": {"seconds": 1, "nanos": 1},
                },
            },
        ) as response:
            response.raise_for_status()
            print(await response.json())

asyncio.run(main())
```

Response: `200`

```json
[
  {
    "minAbsoluteTimestamp": {
      "seconds": 1,
      "nanos": 1
    },
    "maxAbsoluteTimestamp": {
      "seconds": 1,
      "nanos": 1
    },
    "minMediaTimestamp": 1,
    "maxMediaTimestamp": 1
  }
]
```

### Get segment summaries in bounds v2

POST `/video/v2/videos/segment-summaries-in-bounds`

Returns the min and max absolute and media timestamps for each segment matching a video series (identified by channel + tags) within the specified bounds.

Body

`channelSeries` [`VideoChannelSeries`](https://dev.nominal.io/api/rest/video-service.md#videochannelseries) required
:   ​

    **dataSource**

    Set `type` to `"dataSource"`.

    `dataSource` [`VideoDataSourceChannel`](https://dev.nominal.io/api/rest/video-service.md#videodatasourcechannel)
    :   ​

        Fields of `VideoDataSourceChannel`

        `dataSourceRid` string required
        :   ​

        `channel` string required
        :   ​

        `tags` map of `TagName` to string
        :   ​

    **asset**

    Set `type` to `"asset"`.

    `asset` [`VideoAssetChannel`](https://dev.nominal.io/api/rest/video-service.md#videoassetchannel)
    :   ​

        Fields of `VideoAssetChannel`

        `assetRid` string required
        :   ​

        `dataScopeName` string required
        :   ​

        `channel` string required
        :   ​

        `tags` map of `TagName` to string
        :   ​

`bounds` [`Bounds`](https://dev.nominal.io/api/rest/video-service.md#bounds) required
:   ​

    Fields of `Bounds`

    `start` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp) required
    :   ​

        Fields of `Timestamp`

        `seconds` integer (int64) required
        :   ​

        `nanos` integer (int64) required
        :   ​

    `end` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp) required
    :   ​

Response

The body is an array of [`SegmentSummaryV2`](https://dev.nominal.io/api/rest/video-service.md#segmentsummaryv2).

Fields of `SegmentSummaryV2`

`datasetFileId` string (UUID)
:   The dataset file ID that this segment belongs to.

`minAbsoluteTimestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
:   ​

    Fields of `Timestamp`

    `seconds` integer (int64)
    :   ​

    `nanos` integer (int64)
    :   ​

`maxAbsoluteTimestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
:   ​

`minMediaTimestamp` number
:   ​

`maxMediaTimestamp` number
:   ​

Request

**curl**

```shell
curl -X POST "https://api.gov.nominal.io/api/video/v2/videos/segment-summaries-in-bounds" \
  -H "Authorization: Bearer <api key>" \
  -H "Content-Type: application/json" \
  --data '{
  "channelSeries": {
    "type": "dataSource",
    "dataSource": {
      "dataSourceRid": "<data source rid>",
      "channel": "<channel>"
    }
  },
  "bounds": {
    "start": {
      "seconds": 1,
      "nanos": 1
    },
    "end": {
      "seconds": 1,
      "nanos": 1
    }
  }
}'
```

**requests**

```python
import requests

response = requests.post(
    "https://api.gov.nominal.io/api/video/v2/videos/segment-summaries-in-bounds",
    headers={"Authorization": "Bearer <api key>"},
    json={
        "channelSeries": {
            "type": "dataSource",
            "dataSource": {"dataSourceRid": "<data source rid>", "channel": "<channel>"},
        },
        "bounds": {
            "start": {"seconds": 1, "nanos": 1},
            "end": {"seconds": 1, "nanos": 1},
        },
    },
)
response.raise_for_status()
print(response.json())
```

**httpx**

```python
import httpx

response = httpx.post(
    "https://api.gov.nominal.io/api/video/v2/videos/segment-summaries-in-bounds",
    headers={"Authorization": "Bearer <api key>"},
    json={
        "channelSeries": {
            "type": "dataSource",
            "dataSource": {"dataSourceRid": "<data source rid>", "channel": "<channel>"},
        },
        "bounds": {
            "start": {"seconds": 1, "nanos": 1},
            "end": {"seconds": 1, "nanos": 1},
        },
    },
)
response.raise_for_status()
print(response.json())
```

**aiohttp**

```python
import asyncio

import aiohttp

async def main() -> None:
    async with aiohttp.ClientSession() as session:
        async with session.post(
            "https://api.gov.nominal.io/api/video/v2/videos/segment-summaries-in-bounds",
            headers={"Authorization": "Bearer <api key>"},
            json={
                "channelSeries": {
                    "type": "dataSource",
                    "dataSource": {
                        "dataSourceRid": "<data source rid>",
                        "channel": "<channel>",
                    },
                },
                "bounds": {
                    "start": {"seconds": 1, "nanos": 1},
                    "end": {"seconds": 1, "nanos": 1},
                },
            },
        ) as response:
            response.raise_for_status()
            print(await response.json())

asyncio.run(main())
```

Response: `200`

```json
[
  {
    "datasetFileId": "<dataset file id>",
    "minAbsoluteTimestamp": {
      "seconds": 1,
      "nanos": 1
    },
    "maxAbsoluteTimestamp": {
      "seconds": 1,
      "nanos": 1
    },
    "minMediaTimestamp": 1,
    "maxMediaTimestamp": 1
  }
]
```

### Get segment metadata v2

POST `/video/v2/videos/segment-metadata`

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.

Body

`channelSeries` [`VideoChannelSeries`](https://dev.nominal.io/api/rest/video-service.md#videochannelseries) required
:   ​

    **dataSource**

    Set `type` to `"dataSource"`.

    `dataSource` [`VideoDataSourceChannel`](https://dev.nominal.io/api/rest/video-service.md#videodatasourcechannel)
    :   ​

        Fields of `VideoDataSourceChannel`

        `dataSourceRid` string required
        :   ​

        `channel` string required
        :   ​

        `tags` map of `TagName` to string
        :   ​

    **asset**

    Set `type` to `"asset"`.

    `asset` [`VideoAssetChannel`](https://dev.nominal.io/api/rest/video-service.md#videoassetchannel)
    :   ​

        Fields of `VideoAssetChannel`

        `assetRid` string required
        :   ​

        `dataScopeName` string required
        :   ​

        `channel` string required
        :   ​

        `tags` map of `TagName` to string
        :   ​

`bounds` [`Bounds`](https://dev.nominal.io/api/rest/video-service.md#bounds)
:   ​

    Fields of `Bounds`

    `start` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp) required
    :   ​

        Fields of `Timestamp`

        `seconds` integer (int64) required
        :   ​

        `nanos` integer (int64) required
        :   ​

    `end` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp) required
    :   ​

Response

`numFrames` integer
:   ​

`numSegments` integer
:   ​

`minAbsoluteTimestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
:   ​

    Fields of `Timestamp`

    `seconds` integer (int64)
    :   ​

    `nanos` integer (int64)
    :   ​

`maxAbsoluteTimestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
:   ​

`mediaDurationSeconds` number
:   ​

`mediaFrameRate` number
:   The average media frame rate (FPS) calculated as total frames / duration in seconds.

When there is nothing to return, the response is HTTP 204 with no body.

Request

**curl**

```shell
curl -X POST "https://api.gov.nominal.io/api/video/v2/videos/segment-metadata" \
  -H "Authorization: Bearer <api key>" \
  -H "Content-Type: application/json" \
  --data '{
  "channelSeries": {
    "type": "dataSource",
    "dataSource": {
      "dataSourceRid": "<data source rid>",
      "channel": "<channel>"
    }
  }
}'
```

**requests**

```python
import requests

response = requests.post(
    "https://api.gov.nominal.io/api/video/v2/videos/segment-metadata",
    headers={"Authorization": "Bearer <api key>"},
    json={
        "channelSeries": {
            "type": "dataSource",
            "dataSource": {"dataSourceRid": "<data source rid>", "channel": "<channel>"},
        },
    },
)
response.raise_for_status()
print(response.json())
```

**httpx**

```python
import httpx

response = httpx.post(
    "https://api.gov.nominal.io/api/video/v2/videos/segment-metadata",
    headers={"Authorization": "Bearer <api key>"},
    json={
        "channelSeries": {
            "type": "dataSource",
            "dataSource": {"dataSourceRid": "<data source rid>", "channel": "<channel>"},
        },
    },
)
response.raise_for_status()
print(response.json())
```

**aiohttp**

```python
import asyncio

import aiohttp

async def main() -> None:
    async with aiohttp.ClientSession() as session:
        async with session.post(
            "https://api.gov.nominal.io/api/video/v2/videos/segment-metadata",
            headers={"Authorization": "Bearer <api key>"},
            json={
                "channelSeries": {
                    "type": "dataSource",
                    "dataSource": {
                        "dataSourceRid": "<data source rid>",
                        "channel": "<channel>",
                    },
                },
            },
        ) as response:
            response.raise_for_status()
            print(await response.json())

asyncio.run(main())
```

Response: `200`

```json
{
  "numFrames": 1,
  "numSegments": 1,
  "minAbsoluteTimestamp": {
    "seconds": 1,
    "nanos": 1
  },
  "maxAbsoluteTimestamp": {
    "seconds": 1,
    "nanos": 1
  },
  "mediaDurationSeconds": 1,
  "mediaFrameRate": 1
}
```

### Get segment by timestamp v2

POST `/video/v2/videos/get-segment-by-timestamp`

Returns metadata for the segment within a video series containing the requested absolute timestamp.

Body

`channelSeries` [`VideoChannelSeries`](https://dev.nominal.io/api/rest/video-service.md#videochannelseries) required
:   ​

    **dataSource**

    Set `type` to `"dataSource"`.

    `dataSource` [`VideoDataSourceChannel`](https://dev.nominal.io/api/rest/video-service.md#videodatasourcechannel)
    :   ​

        Fields of `VideoDataSourceChannel`

        `dataSourceRid` string required
        :   ​

        `channel` string required
        :   ​

        `tags` map of `TagName` to string
        :   ​

    **asset**

    Set `type` to `"asset"`.

    `asset` [`VideoAssetChannel`](https://dev.nominal.io/api/rest/video-service.md#videoassetchannel)
    :   ​

        Fields of `VideoAssetChannel`

        `assetRid` string required
        :   ​

        `dataScopeName` string required
        :   ​

        `channel` string required
        :   ​

        `tags` map of `TagName` to string
        :   ​

`timestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp) required
:   ​

    Fields of `Timestamp`

    `seconds` integer (int64) required
    :   ​

    `nanos` integer (int64) required
    :   ​

`viewRangeStart` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
:   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.

Response

`rid` string (RID)
:   ​

`datasetFileId` string (UUID)
:   The dataset file ID that this segment belongs to.

`dataHandle` [`Handle`](https://dev.nominal.io/api/rest/video-service.md#handle)
:   ​

    **s3**

    Set `type` to `"s3"`.

    `s3` string
    :   ​

`frameRate` number
:   The average frame rate (FPS) of the segment calculated as total frames / duration in seconds.

`durationSeconds` number
:   The duration of a segment in media time.

`timestamps` [`SegmentTimestamps`](https://dev.nominal.io/api/rest/video-service.md#segmenttimestamps)
:   for videos with frame-level timestamps, we provide mappings, otherwise we just include a single list of timestamps.

    **timestampMappings**

    Set `type` to `"timestampMappings"`.

    `timestampMappings` [`TimestampMappings`](https://dev.nominal.io/api/rest/video-service.md#timestampmappings)
    :   ​

        Fields of `TimestampMappings`

        `mediaTimestamps` array of number
        :   ​

        `absoluteTimestamps` array of [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
        :   ​

            Fields of `Timestamp`

            `seconds` integer (int64)
            :   ​

            `nanos` integer (int64)
            :   ​

When there is nothing to return, the response is HTTP 204 with no body.

Request

**curl**

```shell
curl -X POST "https://api.gov.nominal.io/api/video/v2/videos/get-segment-by-timestamp" \
  -H "Authorization: Bearer <api key>" \
  -H "Content-Type: application/json" \
  --data '{
  "channelSeries": {
    "type": "dataSource",
    "dataSource": {
      "dataSourceRid": "<data source rid>",
      "channel": "<channel>"
    }
  },
  "timestamp": {
    "seconds": 1,
    "nanos": 1
  }
}'
```

**requests**

```python
import requests

response = requests.post(
    "https://api.gov.nominal.io/api/video/v2/videos/get-segment-by-timestamp",
    headers={"Authorization": "Bearer <api key>"},
    json={
        "channelSeries": {
            "type": "dataSource",
            "dataSource": {"dataSourceRid": "<data source rid>", "channel": "<channel>"},
        },
        "timestamp": {"seconds": 1, "nanos": 1},
    },
)
response.raise_for_status()
print(response.json())
```

**httpx**

```python
import httpx

response = httpx.post(
    "https://api.gov.nominal.io/api/video/v2/videos/get-segment-by-timestamp",
    headers={"Authorization": "Bearer <api key>"},
    json={
        "channelSeries": {
            "type": "dataSource",
            "dataSource": {"dataSourceRid": "<data source rid>", "channel": "<channel>"},
        },
        "timestamp": {"seconds": 1, "nanos": 1},
    },
)
response.raise_for_status()
print(response.json())
```

**aiohttp**

```python
import asyncio

import aiohttp

async def main() -> None:
    async with aiohttp.ClientSession() as session:
        async with session.post(
            "https://api.gov.nominal.io/api/video/v2/videos/get-segment-by-timestamp",
            headers={"Authorization": "Bearer <api key>"},
            json={
                "channelSeries": {
                    "type": "dataSource",
                    "dataSource": {
                        "dataSourceRid": "<data source rid>",
                        "channel": "<channel>",
                    },
                },
                "timestamp": {"seconds": 1, "nanos": 1},
            },
        ) as response:
            response.raise_for_status()
            print(await response.json())

asyncio.run(main())
```

Response: `200`

```json
{
  "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
        }
      ]
    }
  }
}
```

### Get segment at or after timestamp

POST `/video/v1/videos/{videoRid}/get-segment-at-or-after-timestamp`

**Deprecated:** Replaced by getSegmentAtOrAfterTimestampV2, which addresses the video channel series (channel + tags) instead of a Video rid.

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.

Path parameters

`videoRid` string (RID) required
:   ​

Body

`timestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp) required
:   ​

    Fields of `Timestamp`

    `seconds` integer (int64) required
    :   ​

    `nanos` integer (int64) required
    :   ​

Response

`rid` string (RID)
:   ​

`videoRid` string (RID)
:   ​

`dataHandle` [`Handle`](https://dev.nominal.io/api/rest/video-service.md#handle)
:   ​

    **s3**

    Set `type` to `"s3"`.

    `s3` string
    :   ​

`frameRate` number
:   The average frame rate (FPS) of the segment calculated as total frames / duration in seconds.

`durationSeconds` number
:   The duration of a segment in media time.

`timestamps` [`SegmentTimestamps`](https://dev.nominal.io/api/rest/video-service.md#segmenttimestamps)
:   for videos with frame-level timestamps, we provide mappings, otherwise we just include a single list of timestamps.

    **timestampMappings**

    Set `type` to `"timestampMappings"`.

    `timestampMappings` [`TimestampMappings`](https://dev.nominal.io/api/rest/video-service.md#timestampmappings)
    :   ​

        Fields of `TimestampMappings`

        `mediaTimestamps` array of number
        :   ​

        `absoluteTimestamps` array of [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
        :   ​

            Fields of `Timestamp`

            `seconds` integer (int64)
            :   ​

            `nanos` integer (int64)
            :   ​

When there is nothing to return, the response is HTTP 204 with no body.

Request

**curl**

```shell
curl -X POST "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/get-segment-at-or-after-timestamp" \
  -H "Authorization: Bearer <api key>" \
  -H "Content-Type: application/json" \
  --data '{
  "timestamp": {
    "seconds": 1,
    "nanos": 1
  }
}'
```

**requests**

```python
import requests

response = requests.post(
    "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/get-segment-at-or-after-timestamp",
    headers={"Authorization": "Bearer <api key>"},
    json={"timestamp": {"seconds": 1, "nanos": 1}},
)
response.raise_for_status()
print(response.json())
```

**httpx**

```python
import httpx

response = httpx.post(
    "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/get-segment-at-or-after-timestamp",
    headers={"Authorization": "Bearer <api key>"},
    json={"timestamp": {"seconds": 1, "nanos": 1}},
)
response.raise_for_status()
print(response.json())
```

**aiohttp**

```python
import asyncio

import aiohttp

async def main() -> None:
    async with aiohttp.ClientSession() as session:
        async with session.post(
            "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/get-segment-at-or-after-timestamp",
            headers={"Authorization": "Bearer <api key>"},
            json={"timestamp": {"seconds": 1, "nanos": 1}},
        ) as response:
            response.raise_for_status()
            print(await response.json())

asyncio.run(main())
```

Response: `200`

```json
{
  "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
        }
      ]
    }
  }
}
```

### Get segment at or after timestamp v2

POST `/video/v2/videos/get-segment-at-or-after-timestamp`

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.

Body

`channelSeries` [`VideoChannelSeries`](https://dev.nominal.io/api/rest/video-service.md#videochannelseries) required
:   ​

    **dataSource**

    Set `type` to `"dataSource"`.

    `dataSource` [`VideoDataSourceChannel`](https://dev.nominal.io/api/rest/video-service.md#videodatasourcechannel)
    :   ​

        Fields of `VideoDataSourceChannel`

        `dataSourceRid` string required
        :   ​

        `channel` string required
        :   ​

        `tags` map of `TagName` to string
        :   ​

    **asset**

    Set `type` to `"asset"`.

    `asset` [`VideoAssetChannel`](https://dev.nominal.io/api/rest/video-service.md#videoassetchannel)
    :   ​

        Fields of `VideoAssetChannel`

        `assetRid` string required
        :   ​

        `dataScopeName` string required
        :   ​

        `channel` string required
        :   ​

        `tags` map of `TagName` to string
        :   ​

`timestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp) required
:   ​

    Fields of `Timestamp`

    `seconds` integer (int64) required
    :   ​

    `nanos` integer (int64) required
    :   ​

Response

`rid` string (RID)
:   ​

`datasetFileId` string (UUID)
:   The dataset file ID that this segment belongs to.

`dataHandle` [`Handle`](https://dev.nominal.io/api/rest/video-service.md#handle)
:   ​

    **s3**

    Set `type` to `"s3"`.

    `s3` string
    :   ​

`frameRate` number
:   The average frame rate (FPS) of the segment calculated as total frames / duration in seconds.

`durationSeconds` number
:   The duration of a segment in media time.

`timestamps` [`SegmentTimestamps`](https://dev.nominal.io/api/rest/video-service.md#segmenttimestamps)
:   for videos with frame-level timestamps, we provide mappings, otherwise we just include a single list of timestamps.

    **timestampMappings**

    Set `type` to `"timestampMappings"`.

    `timestampMappings` [`TimestampMappings`](https://dev.nominal.io/api/rest/video-service.md#timestampmappings)
    :   ​

        Fields of `TimestampMappings`

        `mediaTimestamps` array of number
        :   ​

        `absoluteTimestamps` array of [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
        :   ​

            Fields of `Timestamp`

            `seconds` integer (int64)
            :   ​

            `nanos` integer (int64)
            :   ​

When there is nothing to return, the response is HTTP 204 with no body.

Request

**curl**

```shell
curl -X POST "https://api.gov.nominal.io/api/video/v2/videos/get-segment-at-or-after-timestamp" \
  -H "Authorization: Bearer <api key>" \
  -H "Content-Type: application/json" \
  --data '{
  "channelSeries": {
    "type": "dataSource",
    "dataSource": {
      "dataSourceRid": "<data source rid>",
      "channel": "<channel>"
    }
  },
  "timestamp": {
    "seconds": 1,
    "nanos": 1
  }
}'
```

**requests**

```python
import requests

response = requests.post(
    "https://api.gov.nominal.io/api/video/v2/videos/get-segment-at-or-after-timestamp",
    headers={"Authorization": "Bearer <api key>"},
    json={
        "channelSeries": {
            "type": "dataSource",
            "dataSource": {"dataSourceRid": "<data source rid>", "channel": "<channel>"},
        },
        "timestamp": {"seconds": 1, "nanos": 1},
    },
)
response.raise_for_status()
print(response.json())
```

**httpx**

```python
import httpx

response = httpx.post(
    "https://api.gov.nominal.io/api/video/v2/videos/get-segment-at-or-after-timestamp",
    headers={"Authorization": "Bearer <api key>"},
    json={
        "channelSeries": {
            "type": "dataSource",
            "dataSource": {"dataSourceRid": "<data source rid>", "channel": "<channel>"},
        },
        "timestamp": {"seconds": 1, "nanos": 1},
    },
)
response.raise_for_status()
print(response.json())
```

**aiohttp**

```python
import asyncio

import aiohttp

async def main() -> None:
    async with aiohttp.ClientSession() as session:
        async with session.post(
            "https://api.gov.nominal.io/api/video/v2/videos/get-segment-at-or-after-timestamp",
            headers={"Authorization": "Bearer <api key>"},
            json={
                "channelSeries": {
                    "type": "dataSource",
                    "dataSource": {
                        "dataSourceRid": "<data source rid>",
                        "channel": "<channel>",
                    },
                },
                "timestamp": {"seconds": 1, "nanos": 1},
            },
        ) as response:
            response.raise_for_status()
            print(await response.json())

asyncio.run(main())
```

Response: `200`

```json
{
  "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
        }
      ]
    }
  }
}
```

### Get file summaries

POST `/video/v1/videos/{videoRid}/get-ranges-with-existing-segment-data`

**Deprecated:** Replaced by listVideoChannelDatasetFiles, which returns the dataset files backing a video channel together with the bounds each file contributes.

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.

Path parameters

`videoRid` string (RID) required
:   ​

Body

`bounds` [`Bounds`](https://dev.nominal.io/api/rest/video-service.md#bounds)
:   ​

    Fields of `Bounds`

    `start` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp) required
    :   ​

        Fields of `Timestamp`

        `seconds` integer (int64) required
        :   ​

        `nanos` integer (int64) required
        :   ​

    `end` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp) required
    :   ​

Response

`fileSummaries` array of [`FileSummary`](https://dev.nominal.io/api/rest/video-service.md#filesummary)
:   ​

    Fields of `FileSummary`

    `fileRid` string (RID)
    :   ​

    `bounds` [`Bounds`](https://dev.nominal.io/api/rest/video-service.md#bounds)
    :   ​

        Fields of `Bounds`

        `start` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
        :   ​

            Fields of `Timestamp`

            `seconds` integer (int64)
            :   ​

            `nanos` integer (int64)
            :   ​

        `end` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
        :   ​

Request

**curl**

```shell
curl -X POST "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/get-ranges-with-existing-segment-data" \
  -H "Authorization: Bearer <api key>" \
  -H "Content-Type: application/json" \
  --data '{
  "bounds": {
    "start": {
      "seconds": 1,
      "nanos": 1
    },
    "end": {
      "seconds": 1,
      "nanos": 1
    }
  }
}'
```

**requests**

```python
import requests

response = requests.post(
    "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/get-ranges-with-existing-segment-data",
    headers={"Authorization": "Bearer <api key>"},
    json={
        "bounds": {
            "start": {"seconds": 1, "nanos": 1},
            "end": {"seconds": 1, "nanos": 1},
        },
    },
)
response.raise_for_status()
print(response.json())
```

**httpx**

```python
import httpx

response = httpx.post(
    "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/get-ranges-with-existing-segment-data",
    headers={"Authorization": "Bearer <api key>"},
    json={
        "bounds": {
            "start": {"seconds": 1, "nanos": 1},
            "end": {"seconds": 1, "nanos": 1},
        },
    },
)
response.raise_for_status()
print(response.json())
```

**aiohttp**

```python
import asyncio

import aiohttp

async def main() -> None:
    async with aiohttp.ClientSession() as session:
        async with session.post(
            "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/get-ranges-with-existing-segment-data",
            headers={"Authorization": "Bearer <api key>"},
            json={
                "bounds": {
                    "start": {"seconds": 1, "nanos": 1},
                    "end": {"seconds": 1, "nanos": 1},
                },
            },
        ) as response:
            response.raise_for_status()
            print(await response.json())

asyncio.run(main())
```

Response: `200`

```json
{
  "fileSummaries": [
    {
      "fileRid": "<video file rid>",
      "bounds": {
        "start": {
          "seconds": 1,
          "nanos": 1
        },
        "end": {
          "seconds": 1,
          "nanos": 1
        }
      }
    }
  ]
}
```

### Generate WHIP stream

POST `/video/v1/videos/{videoRid}/streaming/whip`

**Deprecated:** Replaced by generateWhipStreamV2, which addresses a channel-backed live video series instead of a Video rid.

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.

Path parameters

`videoRid` string (RID) required
:   ​

Response

`streamId` string
:   ​

`whipUrl` string
:   ​

`iceServers` array of [`IceServer`](https://dev.nominal.io/api/rest/video-service.md#iceserver)
:   ​

    Fields of `IceServer`

    `urls` array of string
    :   ​

    `username` string
    :   ​

    `credential` string
    :   ​

Request

**curl**

```shell
curl -X POST "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/streaming/whip" \
  -H "Authorization: Bearer <api key>"
```

**requests**

```python
import requests

response = requests.post(
    "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/streaming/whip",
    headers={"Authorization": "Bearer <api key>"},
)
response.raise_for_status()
print(response.json())
```

**httpx**

```python
import httpx

response = httpx.post(
    "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/streaming/whip",
    headers={"Authorization": "Bearer <api key>"},
)
response.raise_for_status()
print(response.json())
```

**aiohttp**

```python
import asyncio

import aiohttp

async def main() -> None:
    async with aiohttp.ClientSession() as session:
        async with session.post(
            "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/streaming/whip",
            headers={"Authorization": "Bearer <api key>"},
        ) as response:
            response.raise_for_status()
            print(await response.json())

asyncio.run(main())
```

Response: `200`

```json
{
  "streamId": "<stream id>",
  "whipUrl": "<whip url>",
  "iceServers": [
    {
      "urls": [
        "<urls>"
      ],
      "username": "<username>",
      "credential": "<credential>"
    }
  ]
}
```

### Generate WHIP stream v2

POST `/video/v2/videos/streaming/whip`

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.

Body

`channelSeries` [`VideoChannelSeries`](https://dev.nominal.io/api/rest/video-service.md#videochannelseries) required
:   ​

    **dataSource**

    Set `type` to `"dataSource"`.

    `dataSource` [`VideoDataSourceChannel`](https://dev.nominal.io/api/rest/video-service.md#videodatasourcechannel)
    :   ​

        Fields of `VideoDataSourceChannel`

        `dataSourceRid` string required
        :   ​

        `channel` string required
        :   ​

        `tags` map of `TagName` to string
        :   ​

    **asset**

    Set `type` to `"asset"`.

    `asset` [`VideoAssetChannel`](https://dev.nominal.io/api/rest/video-service.md#videoassetchannel)
    :   ​

        Fields of `VideoAssetChannel`

        `assetRid` string required
        :   ​

        `dataScopeName` string required
        :   ​

        `channel` string required
        :   ​

        `tags` map of `TagName` to string
        :   ​

Response

`streamId` string
:   ​

`whipUrl` string
:   ​

`iceServers` array of [`IceServer`](https://dev.nominal.io/api/rest/video-service.md#iceserver)
:   ​

    Fields of `IceServer`

    `urls` array of string
    :   ​

    `username` string
    :   ​

    `credential` string
    :   ​

Request

**curl**

```shell
curl -X POST "https://api.gov.nominal.io/api/video/v2/videos/streaming/whip" \
  -H "Authorization: Bearer <api key>" \
  -H "Content-Type: application/json" \
  --data '{
  "channelSeries": {
    "type": "dataSource",
    "dataSource": {
      "dataSourceRid": "<data source rid>",
      "channel": "<channel>"
    }
  }
}'
```

**requests**

```python
import requests

response = requests.post(
    "https://api.gov.nominal.io/api/video/v2/videos/streaming/whip",
    headers={"Authorization": "Bearer <api key>"},
    json={
        "channelSeries": {
            "type": "dataSource",
            "dataSource": {"dataSourceRid": "<data source rid>", "channel": "<channel>"},
        },
    },
)
response.raise_for_status()
print(response.json())
```

**httpx**

```python
import httpx

response = httpx.post(
    "https://api.gov.nominal.io/api/video/v2/videos/streaming/whip",
    headers={"Authorization": "Bearer <api key>"},
    json={
        "channelSeries": {
            "type": "dataSource",
            "dataSource": {"dataSourceRid": "<data source rid>", "channel": "<channel>"},
        },
    },
)
response.raise_for_status()
print(response.json())
```

**aiohttp**

```python
import asyncio

import aiohttp

async def main() -> None:
    async with aiohttp.ClientSession() as session:
        async with session.post(
            "https://api.gov.nominal.io/api/video/v2/videos/streaming/whip",
            headers={"Authorization": "Bearer <api key>"},
            json={
                "channelSeries": {
                    "type": "dataSource",
                    "dataSource": {
                        "dataSourceRid": "<data source rid>",
                        "channel": "<channel>",
                    },
                },
            },
        ) as response:
            response.raise_for_status()
            print(await response.json())

asyncio.run(main())
```

Response: `200`

```json
{
  "streamId": "<stream id>",
  "whipUrl": "<whip url>",
  "iceServers": [
    {
      "urls": [
        "<urls>"
      ],
      "username": "<username>",
      "credential": "<credential>"
    }
  ]
}
```

### Generate WHEP stream

POST `/video/v1/videos/{videoRid}/streaming/whep`

**Deprecated:** Replaced by generateWhepStreamV2, which addresses a channel-backed live video series instead of a Video rid.

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.

Path parameters

`videoRid` string (RID) required
:   ​

Response

`whepUrl` string
:   ​

`iceServers` array of [`IceServer`](https://dev.nominal.io/api/rest/video-service.md#iceserver)
:   ​

    Fields of `IceServer`

    `urls` array of string
    :   ​

    `username` string
    :   ​

    `credential` string
    :   ​

`token` string
:   ​

When there is nothing to return, the response is HTTP 204 with no body.

Request

**curl**

```shell
curl -X POST "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/streaming/whep" \
  -H "Authorization: Bearer <api key>"
```

**requests**

```python
import requests

response = requests.post(
    "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/streaming/whep",
    headers={"Authorization": "Bearer <api key>"},
)
response.raise_for_status()
print(response.json())
```

**httpx**

```python
import httpx

response = httpx.post(
    "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/streaming/whep",
    headers={"Authorization": "Bearer <api key>"},
)
response.raise_for_status()
print(response.json())
```

**aiohttp**

```python
import asyncio

import aiohttp

async def main() -> None:
    async with aiohttp.ClientSession() as session:
        async with session.post(
            "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/streaming/whep",
            headers={"Authorization": "Bearer <api key>"},
        ) as response:
            response.raise_for_status()
            print(await response.json())

asyncio.run(main())
```

Response: `200`

```json
{
  "whepUrl": "<whep url>",
  "iceServers": [
    {
      "urls": [
        "<urls>"
      ],
      "username": "<username>",
      "credential": "<credential>"
    }
  ],
  "token": "<token>"
}
```

### Generate WHEP stream v2

POST `/video/v2/videos/streaming/whep`

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.

Body

`channelSeries` [`VideoChannelSeries`](https://dev.nominal.io/api/rest/video-service.md#videochannelseries) required
:   ​

    **dataSource**

    Set `type` to `"dataSource"`.

    `dataSource` [`VideoDataSourceChannel`](https://dev.nominal.io/api/rest/video-service.md#videodatasourcechannel)
    :   ​

        Fields of `VideoDataSourceChannel`

        `dataSourceRid` string required
        :   ​

        `channel` string required
        :   ​

        `tags` map of `TagName` to string
        :   ​

    **asset**

    Set `type` to `"asset"`.

    `asset` [`VideoAssetChannel`](https://dev.nominal.io/api/rest/video-service.md#videoassetchannel)
    :   ​

        Fields of `VideoAssetChannel`

        `assetRid` string required
        :   ​

        `dataScopeName` string required
        :   ​

        `channel` string required
        :   ​

        `tags` map of `TagName` to string
        :   ​

Response

`whepUrl` string
:   ​

`iceServers` array of [`IceServer`](https://dev.nominal.io/api/rest/video-service.md#iceserver)
:   ​

    Fields of `IceServer`

    `urls` array of string
    :   ​

    `username` string
    :   ​

    `credential` string
    :   ​

`token` string
:   ​

When there is nothing to return, the response is HTTP 204 with no body.

Request

**curl**

```shell
curl -X POST "https://api.gov.nominal.io/api/video/v2/videos/streaming/whep" \
  -H "Authorization: Bearer <api key>" \
  -H "Content-Type: application/json" \
  --data '{
  "channelSeries": {
    "type": "dataSource",
    "dataSource": {
      "dataSourceRid": "<data source rid>",
      "channel": "<channel>"
    }
  }
}'
```

**requests**

```python
import requests

response = requests.post(
    "https://api.gov.nominal.io/api/video/v2/videos/streaming/whep",
    headers={"Authorization": "Bearer <api key>"},
    json={
        "channelSeries": {
            "type": "dataSource",
            "dataSource": {"dataSourceRid": "<data source rid>", "channel": "<channel>"},
        },
    },
)
response.raise_for_status()
print(response.json())
```

**httpx**

```python
import httpx

response = httpx.post(
    "https://api.gov.nominal.io/api/video/v2/videos/streaming/whep",
    headers={"Authorization": "Bearer <api key>"},
    json={
        "channelSeries": {
            "type": "dataSource",
            "dataSource": {"dataSourceRid": "<data source rid>", "channel": "<channel>"},
        },
    },
)
response.raise_for_status()
print(response.json())
```

**aiohttp**

```python
import asyncio

import aiohttp

async def main() -> None:
    async with aiohttp.ClientSession() as session:
        async with session.post(
            "https://api.gov.nominal.io/api/video/v2/videos/streaming/whep",
            headers={"Authorization": "Bearer <api key>"},
            json={
                "channelSeries": {
                    "type": "dataSource",
                    "dataSource": {
                        "dataSourceRid": "<data source rid>",
                        "channel": "<channel>",
                    },
                },
            },
        ) as response:
            response.raise_for_status()
            print(await response.json())

asyncio.run(main())
```

Response: `200`

```json
{
  "whepUrl": "<whep url>",
  "iceServers": [
    {
      "urls": [
        "<urls>"
      ],
      "username": "<username>",
      "credential": "<credential>"
    }
  ],
  "token": "<token>"
}
```

### Get stream

GET `/video/v1/videos/{videoRid}/streaming/streams/{streamId}`

Returns stream session metadata for a given stream ID scoped to the video. Enforces read permission on the video.

Path parameters

`videoRid` string (RID) required
:   ​

`streamId` string required
:   ​

Response

`streamId` string
:   ​

`videoRid` string (RID)
:   ​

`streamStatus` string
:   ​

`start` string (date-time)
:   ​

`end` string (date-time)
:   ​

`createdAt` string (date-time)
:   ​

`updatedAt` string (date-time)
:   ​

When there is nothing to return, the response is HTTP 204 with no body.

Request

**curl**

```shell
curl "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/streaming/streams/<stream id>" \
  -H "Authorization: Bearer <api key>"
```

**requests**

```python
import requests

response = requests.get(
    "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/streaming/streams/<stream id>",
    headers={"Authorization": "Bearer <api key>"},
)
response.raise_for_status()
print(response.json())
```

**httpx**

```python
import httpx

response = httpx.get(
    "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/streaming/streams/<stream id>",
    headers={"Authorization": "Bearer <api key>"},
)
response.raise_for_status()
print(response.json())
```

**aiohttp**

```python
import asyncio

import aiohttp

async def main() -> None:
    async with aiohttp.ClientSession() as session:
        async with session.get(
            "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/streaming/streams/<stream id>",
            headers={"Authorization": "Bearer <api key>"},
        ) as response:
            response.raise_for_status()
            print(await response.json())

asyncio.run(main())
```

Response: `200`

```json
{
  "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"
}
```

### Get streams in bounds

POST `/video/v1/videos/{videoRid}/streaming/streams-in-bounds`

**Deprecated:** Replaced by getStreamsInBoundsV2, which addresses a channel-backed live video series instead of a Video rid.

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.

Path parameters

`videoRid` string (RID) required
:   ​

Body

`bounds` [`Bounds`](https://dev.nominal.io/api/rest/video-service.md#bounds) required
:   ​

    Fields of `Bounds`

    `start` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp) required
    :   ​

        Fields of `Timestamp`

        `seconds` integer (int64) required
        :   ​

        `nanos` integer (int64) required
        :   ​

    `end` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp) required
    :   ​

`pageSize` integer
:   Defaults to 100. Will throw if larger than 1_000.

`token` string
:   ​

Response

`streams` array of [`VideoStream`](https://dev.nominal.io/api/rest/video-service.md#videostream)
:   ​

    Fields of `VideoStream`

    `streamId` string
    :   ​

    `videoRid` string (RID)
    :   ​

    `streamStatus` string
    :   ​

    `start` string (date-time)
    :   ​

    `end` string (date-time)
    :   ​

    `createdAt` string (date-time)
    :   ​

    `updatedAt` string (date-time)
    :   ​

`nextPageToken` string
:   ​

Request

**curl**

```shell
curl -X POST "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/streaming/streams-in-bounds" \
  -H "Authorization: Bearer <api key>" \
  -H "Content-Type: application/json" \
  --data '{
  "bounds": {
    "start": {
      "seconds": 1,
      "nanos": 1
    },
    "end": {
      "seconds": 1,
      "nanos": 1
    }
  }
}'
```

**requests**

```python
import requests

response = requests.post(
    "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/streaming/streams-in-bounds",
    headers={"Authorization": "Bearer <api key>"},
    json={
        "bounds": {
            "start": {"seconds": 1, "nanos": 1},
            "end": {"seconds": 1, "nanos": 1},
        },
    },
)
response.raise_for_status()
print(response.json())
```

**httpx**

```python
import httpx

response = httpx.post(
    "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/streaming/streams-in-bounds",
    headers={"Authorization": "Bearer <api key>"},
    json={
        "bounds": {
            "start": {"seconds": 1, "nanos": 1},
            "end": {"seconds": 1, "nanos": 1},
        },
    },
)
response.raise_for_status()
print(response.json())
```

**aiohttp**

```python
import asyncio

import aiohttp

async def main() -> None:
    async with aiohttp.ClientSession() as session:
        async with session.post(
            "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/streaming/streams-in-bounds",
            headers={"Authorization": "Bearer <api key>"},
            json={
                "bounds": {
                    "start": {"seconds": 1, "nanos": 1},
                    "end": {"seconds": 1, "nanos": 1},
                },
            },
        ) as response:
            response.raise_for_status()
            print(await response.json())

asyncio.run(main())
```

Response: `200`

```json
{
  "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>"
}
```

### Get streams in bounds v2

POST `/video/v2/videos/streaming/streams-in-bounds`

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.

Body

`channelSeries` [`VideoChannelSeries`](https://dev.nominal.io/api/rest/video-service.md#videochannelseries) required
:   ​

    **dataSource**

    Set `type` to `"dataSource"`.

    `dataSource` [`VideoDataSourceChannel`](https://dev.nominal.io/api/rest/video-service.md#videodatasourcechannel)
    :   ​

        Fields of `VideoDataSourceChannel`

        `dataSourceRid` string required
        :   ​

        `channel` string required
        :   ​

        `tags` map of `TagName` to string
        :   ​

    **asset**

    Set `type` to `"asset"`.

    `asset` [`VideoAssetChannel`](https://dev.nominal.io/api/rest/video-service.md#videoassetchannel)
    :   ​

        Fields of `VideoAssetChannel`

        `assetRid` string required
        :   ​

        `dataScopeName` string required
        :   ​

        `channel` string required
        :   ​

        `tags` map of `TagName` to string
        :   ​

`bounds` [`Bounds`](https://dev.nominal.io/api/rest/video-service.md#bounds) required
:   ​

    Fields of `Bounds`

    `start` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp) required
    :   ​

        Fields of `Timestamp`

        `seconds` integer (int64) required
        :   ​

        `nanos` integer (int64) required
        :   ​

    `end` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp) required
    :   ​

`pageSize` integer
:   Defaults to 100. Will throw if larger than 1_000.

`token` string
:   ​

Response

`streams` array of [`VideoStreamV2`](https://dev.nominal.io/api/rest/video-service.md#videostreamv2)
:   ​

    Fields of `VideoStreamV2`

    `streamId` string
    :   ​

    `streamStatus` string
    :   ​

    `createdAt` string (date-time)
    :   ​

    `updatedAt` string (date-time)
    :   ​

    `start` string (date-time)
    :   ​

    `end` string (date-time)
    :   ​

`nextPageToken` string
:   ​

Request

**curl**

```shell
curl -X POST "https://api.gov.nominal.io/api/video/v2/videos/streaming/streams-in-bounds" \
  -H "Authorization: Bearer <api key>" \
  -H "Content-Type: application/json" \
  --data '{
  "channelSeries": {
    "type": "dataSource",
    "dataSource": {
      "dataSourceRid": "<data source rid>",
      "channel": "<channel>"
    }
  },
  "bounds": {
    "start": {
      "seconds": 1,
      "nanos": 1
    },
    "end": {
      "seconds": 1,
      "nanos": 1
    }
  }
}'
```

**requests**

```python
import requests

response = requests.post(
    "https://api.gov.nominal.io/api/video/v2/videos/streaming/streams-in-bounds",
    headers={"Authorization": "Bearer <api key>"},
    json={
        "channelSeries": {
            "type": "dataSource",
            "dataSource": {"dataSourceRid": "<data source rid>", "channel": "<channel>"},
        },
        "bounds": {
            "start": {"seconds": 1, "nanos": 1},
            "end": {"seconds": 1, "nanos": 1},
        },
    },
)
response.raise_for_status()
print(response.json())
```

**httpx**

```python
import httpx

response = httpx.post(
    "https://api.gov.nominal.io/api/video/v2/videos/streaming/streams-in-bounds",
    headers={"Authorization": "Bearer <api key>"},
    json={
        "channelSeries": {
            "type": "dataSource",
            "dataSource": {"dataSourceRid": "<data source rid>", "channel": "<channel>"},
        },
        "bounds": {
            "start": {"seconds": 1, "nanos": 1},
            "end": {"seconds": 1, "nanos": 1},
        },
    },
)
response.raise_for_status()
print(response.json())
```

**aiohttp**

```python
import asyncio

import aiohttp

async def main() -> None:
    async with aiohttp.ClientSession() as session:
        async with session.post(
            "https://api.gov.nominal.io/api/video/v2/videos/streaming/streams-in-bounds",
            headers={"Authorization": "Bearer <api key>"},
            json={
                "channelSeries": {
                    "type": "dataSource",
                    "dataSource": {
                        "dataSourceRid": "<data source rid>",
                        "channel": "<channel>",
                    },
                },
                "bounds": {
                    "start": {"seconds": 1, "nanos": 1},
                    "end": {"seconds": 1, "nanos": 1},
                },
            },
        ) as response:
            response.raise_for_status()
            print(await response.json())

asyncio.run(main())
```

Response: `200`

```json
{
  "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>"
}
```

### List video channel dataset files

POST `/video/v2/videos/channel-dataset-files`

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.

Body

`channelSeries` [`VideoChannelSeries`](https://dev.nominal.io/api/rest/video-service.md#videochannelseries) required
:   ​

    **dataSource**

    Set `type` to `"dataSource"`.

    `dataSource` [`VideoDataSourceChannel`](https://dev.nominal.io/api/rest/video-service.md#videodatasourcechannel)
    :   ​

        Fields of `VideoDataSourceChannel`

        `dataSourceRid` string required
        :   ​

        `channel` string required
        :   ​

        `tags` map of `TagName` to string
        :   ​

    **asset**

    Set `type` to `"asset"`.

    `asset` [`VideoAssetChannel`](https://dev.nominal.io/api/rest/video-service.md#videoassetchannel)
    :   ​

        Fields of `VideoAssetChannel`

        `assetRid` string required
        :   ​

        `dataScopeName` string required
        :   ​

        `channel` string required
        :   ​

        `tags` map of `TagName` to string
        :   ​

`bounds` [`Bounds`](https://dev.nominal.io/api/rest/video-service.md#bounds)
:   ​

    Fields of `Bounds`

    `start` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp) required
    :   ​

        Fields of `Timestamp`

        `seconds` integer (int64) required
        :   ​

        `nanos` integer (int64) required
        :   ​

    `end` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp) required
    :   ​

`pageSize` integer
:   Defaults to 100. Will throw if larger than 1_000.

`token` string
:   ​

Response

`datasetFiles` array of [`VideoChannelDatasetFile`](https://dev.nominal.io/api/rest/video-service.md#videochanneldatasetfile)
:   ​

    Fields of `VideoChannelDatasetFile`

    `datasetFileId` string (UUID)
    :   ​

    `start` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
    :   ​

        Fields of `Timestamp`

        `seconds` integer (int64)
        :   ​

        `nanos` integer (int64)
        :   ​

    `end` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
    :   ​

`nextPageToken` string
:   ​

Request

**curl**

```shell
curl -X POST "https://api.gov.nominal.io/api/video/v2/videos/channel-dataset-files" \
  -H "Authorization: Bearer <api key>" \
  -H "Content-Type: application/json" \
  --data '{
  "channelSeries": {
    "type": "dataSource",
    "dataSource": {
      "dataSourceRid": "<data source rid>",
      "channel": "<channel>"
    }
  }
}'
```

**requests**

```python
import requests

response = requests.post(
    "https://api.gov.nominal.io/api/video/v2/videos/channel-dataset-files",
    headers={"Authorization": "Bearer <api key>"},
    json={
        "channelSeries": {
            "type": "dataSource",
            "dataSource": {"dataSourceRid": "<data source rid>", "channel": "<channel>"},
        },
    },
)
response.raise_for_status()
print(response.json())
```

**httpx**

```python
import httpx

response = httpx.post(
    "https://api.gov.nominal.io/api/video/v2/videos/channel-dataset-files",
    headers={"Authorization": "Bearer <api key>"},
    json={
        "channelSeries": {
            "type": "dataSource",
            "dataSource": {"dataSourceRid": "<data source rid>", "channel": "<channel>"},
        },
    },
)
response.raise_for_status()
print(response.json())
```

**aiohttp**

```python
import asyncio

import aiohttp

async def main() -> None:
    async with aiohttp.ClientSession() as session:
        async with session.post(
            "https://api.gov.nominal.io/api/video/v2/videos/channel-dataset-files",
            headers={"Authorization": "Bearer <api key>"},
            json={
                "channelSeries": {
                    "type": "dataSource",
                    "dataSource": {
                        "dataSourceRid": "<data source rid>",
                        "channel": "<channel>",
                    },
                },
            },
        ) as response:
            response.raise_for_status()
            print(await response.json())

asyncio.run(main())
```

Response: `200`

```json
{
  "datasetFiles": [
    {
      "datasetFileId": "<dataset file id>",
      "start": {
        "seconds": 1,
        "nanos": 1
      },
      "end": {
        "seconds": 1,
        "nanos": 1
      }
    }
  ],
  "nextPageToken": "<token>"
}
```

### Batch update video channel dataset files

POST `/video/v2/videos/channel-dataset-files/batch-update`

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.

Body

`channelSeries` [`VideoChannelSeries`](https://dev.nominal.io/api/rest/video-service.md#videochannelseries)
:   ​

    **dataSource**

    Set `type` to `"dataSource"`.

    `dataSource` [`VideoDataSourceChannel`](https://dev.nominal.io/api/rest/video-service.md#videodatasourcechannel)
    :   ​

        Fields of `VideoDataSourceChannel`

        `dataSourceRid` string required
        :   ​

        `channel` string required
        :   ​

        `tags` map of `TagName` to string
        :   ​

    **asset**

    Set `type` to `"asset"`.

    `asset` [`VideoAssetChannel`](https://dev.nominal.io/api/rest/video-service.md#videoassetchannel)
    :   ​

        Fields of `VideoAssetChannel`

        `assetRid` string required
        :   ​

        `dataScopeName` string required
        :   ​

        `channel` string required
        :   ​

        `tags` map of `TagName` to string
        :   ​

`datasetRid` string (RID)
:   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` array of [`VideoChannelDatasetFileUpdate`](https://dev.nominal.io/api/rest/video-service.md#videochanneldatasetfileupdate)
:   ​

    Fields of `VideoChannelDatasetFileUpdate`

    `datasetFileId` string (UUID) required
    :   ​

    `start` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
    :   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.

        Fields of `Timestamp`

        `seconds` integer (int64) required
        :   ​

        `nanos` integer (int64) required
        :   ​

    `title` string
    :   New name (title) for the dataset file.

    `scaleParameter` [`ScaleParameter`](https://dev.nominal.io/api/rest/video-service.md#scaleparameter)
    :   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.

        **trueFrameRate**

        Set `type` to `"trueFrameRate"`.

        `trueFrameRate` number
        :   ​

        **endingTimestamp**

        Set `type` to `"endingTimestamp"`.

        `endingTimestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
        :   ​

        **scaleFactor**

        Set `type` to `"scaleFactor"`.

        `scaleFactor` number
        :   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.

Response

`datasetFiles` array of [`VideoChannelDatasetFile`](https://dev.nominal.io/api/rest/video-service.md#videochanneldatasetfile)
:   ​

    Fields of `VideoChannelDatasetFile`

    `datasetFileId` string (UUID)
    :   ​

    `start` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
    :   ​

        Fields of `Timestamp`

        `seconds` integer (int64)
        :   ​

        `nanos` integer (int64)
        :   ​

    `end` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
    :   ​

Request

**curl**

```shell
curl -X POST "https://api.gov.nominal.io/api/video/v2/videos/channel-dataset-files/batch-update" \
  -H "Authorization: Bearer <api key>" \
  -H "Content-Type: application/json" \
  --data '{
  "channelSeries": {
    "type": "dataSource",
    "dataSource": {
      "dataSourceRid": "<data source rid>",
      "channel": "<channel>"
    }
  },
  "datasetRid": "<dataset rid>",
  "updates": [
    {
      "datasetFileId": "<dataset file id>"
    }
  ]
}'
```

**requests**

```python
import requests

response = requests.post(
    "https://api.gov.nominal.io/api/video/v2/videos/channel-dataset-files/batch-update",
    headers={"Authorization": "Bearer <api key>"},
    json={
        "channelSeries": {
            "type": "dataSource",
            "dataSource": {"dataSourceRid": "<data source rid>", "channel": "<channel>"},
        },
        "datasetRid": "<dataset rid>",
        "updates": [{"datasetFileId": "<dataset file id>"}],
    },
)
response.raise_for_status()
print(response.json())
```

**httpx**

```python
import httpx

response = httpx.post(
    "https://api.gov.nominal.io/api/video/v2/videos/channel-dataset-files/batch-update",
    headers={"Authorization": "Bearer <api key>"},
    json={
        "channelSeries": {
            "type": "dataSource",
            "dataSource": {"dataSourceRid": "<data source rid>", "channel": "<channel>"},
        },
        "datasetRid": "<dataset rid>",
        "updates": [{"datasetFileId": "<dataset file id>"}],
    },
)
response.raise_for_status()
print(response.json())
```

**aiohttp**

```python
import asyncio

import aiohttp

async def main() -> None:
    async with aiohttp.ClientSession() as session:
        async with session.post(
            "https://api.gov.nominal.io/api/video/v2/videos/channel-dataset-files/batch-update",
            headers={"Authorization": "Bearer <api key>"},
            json={
                "channelSeries": {
                    "type": "dataSource",
                    "dataSource": {
                        "dataSourceRid": "<data source rid>",
                        "channel": "<channel>",
                    },
                },
                "datasetRid": "<dataset rid>",
                "updates": [{"datasetFileId": "<dataset file id>"}],
            },
        ) as response:
            response.raise_for_status()
            print(await response.json())

asyncio.run(main())
```

Response: `200`

```json
{
  "datasetFiles": [
    {
      "datasetFileId": "<dataset file id>",
      "start": {
        "seconds": 1,
        "nanos": 1
      },
      "end": {
        "seconds": 1,
        "nanos": 1
      }
    }
  ]
}
```

### End stream

POST `/video/v1/videos/{videoRid}/streaming/end`

**Deprecated:** Replaced by endStreamV2, which addresses a channel-backed live video series instead of a Video rid.

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.

Path parameters

`videoRid` string (RID) required
:   ​

Response

`streamId` string
:   ​

`endedAt` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
:   ​

    Fields of `Timestamp`

    `seconds` integer (int64)
    :   ​

    `nanos` integer (int64)
    :   ​

Request

**curl**

```shell
curl -X POST "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/streaming/end" \
  -H "Authorization: Bearer <api key>"
```

**requests**

```python
import requests

response = requests.post(
    "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/streaming/end",
    headers={"Authorization": "Bearer <api key>"},
)
response.raise_for_status()
print(response.json())
```

**httpx**

```python
import httpx

response = httpx.post(
    "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/streaming/end",
    headers={"Authorization": "Bearer <api key>"},
)
response.raise_for_status()
print(response.json())
```

**aiohttp**

```python
import asyncio

import aiohttp

async def main() -> None:
    async with aiohttp.ClientSession() as session:
        async with session.post(
            "https://api.gov.nominal.io/api/video/v1/videos/<video rid>/streaming/end",
            headers={"Authorization": "Bearer <api key>"},
        ) as response:
            response.raise_for_status()
            print(await response.json())

asyncio.run(main())
```

Response: `200`

```json
{
  "streamId": "<stream id>",
  "endedAt": {
    "seconds": 1,
    "nanos": 1
  }
}
```

### End stream v2

POST `/video/v2/videos/streaming/end`

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.

Body

`channelSeries` [`VideoChannelSeries`](https://dev.nominal.io/api/rest/video-service.md#videochannelseries) required
:   ​

    **dataSource**

    Set `type` to `"dataSource"`.

    `dataSource` [`VideoDataSourceChannel`](https://dev.nominal.io/api/rest/video-service.md#videodatasourcechannel)
    :   ​

        Fields of `VideoDataSourceChannel`

        `dataSourceRid` string required
        :   ​

        `channel` string required
        :   ​

        `tags` map of `TagName` to string
        :   ​

    **asset**

    Set `type` to `"asset"`.

    `asset` [`VideoAssetChannel`](https://dev.nominal.io/api/rest/video-service.md#videoassetchannel)
    :   ​

        Fields of `VideoAssetChannel`

        `assetRid` string required
        :   ​

        `dataScopeName` string required
        :   ​

        `channel` string required
        :   ​

        `tags` map of `TagName` to string
        :   ​

Response

`streamId` string
:   ​

`endedAt` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
:   ​

    Fields of `Timestamp`

    `seconds` integer (int64)
    :   ​

    `nanos` integer (int64)
    :   ​

When there is nothing to return, the response is HTTP 204 with no body.

Request

**curl**

```shell
curl -X POST "https://api.gov.nominal.io/api/video/v2/videos/streaming/end" \
  -H "Authorization: Bearer <api key>" \
  -H "Content-Type: application/json" \
  --data '{
  "channelSeries": {
    "type": "dataSource",
    "dataSource": {
      "dataSourceRid": "<data source rid>",
      "channel": "<channel>"
    }
  }
}'
```

**requests**

```python
import requests

response = requests.post(
    "https://api.gov.nominal.io/api/video/v2/videos/streaming/end",
    headers={"Authorization": "Bearer <api key>"},
    json={
        "channelSeries": {
            "type": "dataSource",
            "dataSource": {"dataSourceRid": "<data source rid>", "channel": "<channel>"},
        },
    },
)
response.raise_for_status()
print(response.json())
```

**httpx**

```python
import httpx

response = httpx.post(
    "https://api.gov.nominal.io/api/video/v2/videos/streaming/end",
    headers={"Authorization": "Bearer <api key>"},
    json={
        "channelSeries": {
            "type": "dataSource",
            "dataSource": {"dataSourceRid": "<data source rid>", "channel": "<channel>"},
        },
    },
)
response.raise_for_status()
print(response.json())
```

**aiohttp**

```python
import asyncio

import aiohttp

async def main() -> None:
    async with aiohttp.ClientSession() as session:
        async with session.post(
            "https://api.gov.nominal.io/api/video/v2/videos/streaming/end",
            headers={"Authorization": "Bearer <api key>"},
            json={
                "channelSeries": {
                    "type": "dataSource",
                    "dataSource": {
                        "dataSourceRid": "<data source rid>",
                        "channel": "<channel>",
                    },
                },
            },
        ) as response:
            response.raise_for_status()
            print(await response.json())

asyncio.run(main())
```

Response: `200`

```json
{
  "streamId": "<stream id>",
  "endedAt": {
    "seconds": 1,
    "nanos": 1
  }
}
```

### Upload segment from media mtx

POST `/video/v1/segment/upload`

MediaMTX segment upload endpoint. Receives video segments from MediaMTX hooks. Validates JWT and logs session. Future: create video segments from uploaded files.

Query parameters

`streamPath` string required
:   MTX_PATH from MediaMTX indicating the stream path

`filePath` string required
:   File path of the uploaded segment

`duration` string required
:   MTX_SEGMENT_DURATION from MediaMTX in seconds

`minTimestampSeconds` integer (int64) required
:   Minimum timestamp seconds since epoch

`minTimestampNanos` integer (int64) required
:   Nanosecond offset (0-999999999)

Headers

`Content-Length` integer (int64) required
:   Size of the segment in bytes from Content-Length header

Body: `application/octet-stream`

The body is the raw bytes.

Response

No content (HTTP 204).

Request

**curl**

```shell
curl -X POST "https://api.gov.nominal.io/api/video/v1/segment/upload?streamPath=<stream path>&filePath=<file path>&duration=<duration>&minTimestampSeconds=1&minTimestampNanos=1" \
  -H "Authorization: Bearer <api key>" \
  -H "Content-Length: 1" \
  -H "Content-Type: application/octet-stream" \
  --data-binary "@<file>"
```

**requests**

```python
from pathlib import Path

import requests

response = requests.post(
    "https://api.gov.nominal.io/api/video/v1/segment/upload?streamPath=<stream path>&filePath=<file path>&duration=<duration>&minTimestampSeconds=1&minTimestampNanos=1",
    headers={
        "Authorization": "Bearer <api key>",
        "Content-Length": "1",
        "Content-Type": "application/octet-stream",
    },
    data=Path("<file>").read_bytes(),
)
response.raise_for_status()
```

**httpx**

```python
from pathlib import Path

import httpx

response = httpx.post(
    "https://api.gov.nominal.io/api/video/v1/segment/upload?streamPath=<stream path>&filePath=<file path>&duration=<duration>&minTimestampSeconds=1&minTimestampNanos=1",
    headers={
        "Authorization": "Bearer <api key>",
        "Content-Length": "1",
        "Content-Type": "application/octet-stream",
    },
    content=Path("<file>").read_bytes(),
)
response.raise_for_status()
```

**aiohttp**

```python
import asyncio
from pathlib import Path

import aiohttp

async def main() -> None:
    async with aiohttp.ClientSession() as session:
        async with session.post(
            "https://api.gov.nominal.io/api/video/v1/segment/upload?streamPath=<stream path>&filePath=<file path>&duration=<duration>&minTimestampSeconds=1&minTimestampNanos=1",
            headers={
                "Authorization": "Bearer <api key>",
                "Content-Length": "1",
                "Content-Type": "application/octet-stream",
            },
            data=Path("<file>").read_bytes(),
        ) as response:
            response.raise_for_status()

asyncio.run(main())
```

Response: `204`

No content.

## Types

### ArchivedStatus

`NOT_ARCHIVED`
:   ​

`ARCHIVED`
:   ​

### Bounds

`start` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp) required
:   ​

`end` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp) required
:   ​

### DetailedIngestStatus

Set `type` to the name of one of the other fields, and set only that field.

`success` [`SuccessIngestStatus`](https://dev.nominal.io/api/rest/video-service.md#successingeststatus)
:   ​

`error` [`ErrorIngestStatus`](https://dev.nominal.io/api/rest/video-service.md#erroringeststatus)
:   ​

`inProgress` number
:   A number between 0 and 1 representing percentage progress.

### Empty

An empty JSON object, `{}`.

### ErrorIngestStatus

`errors` array of [`IngestError`](https://dev.nominal.io/api/rest/video-service.md#ingesterror)
:   ​

### FileSummary

`fileRid` string (RID) required
:   ​

`bounds` [`Bounds`](https://dev.nominal.io/api/rest/video-service.md#bounds) required
:   ​

### Handle

Set `type` to the name of one of the other fields, and set only that field.

`s3` string
:   ​

### IceServer

WebRTC ICE server configuration

`urls` array of string
:   ​

`username` string
:   ​

`credential` string
:   ​

### IngestError

`errorType` string required
:   ​

`message` string required
:   ​

`errorInstanceId` string
:   ​

### IngestStatus

`SUCCEEDED`
:   ​

`FAILED`
:   ​

`IN_PROGRESS`
:   ​

### McapChannelLocator

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.

Set `type` to the name of one of the other fields, and set only that field.

`topic` string
:   ​

`id` integer
:   ​

### McapTimestampManifest

Timestamps are derived from the mcap file containing the video frames.

`mcapChannelLocator` [`McapChannelLocator`](https://dev.nominal.io/api/rest/video-service.md#mcapchannellocator) required
:   ​

### NoTimestampManifest

these values will not be updated after ingest time, to allow for resetting. The updated values are stored implicitly through the segment timestamps.

`startingTimestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp) required
:   Specifies the original starting timestamp of the video.

`scaleParameter` [`ScaleParameter`](https://dev.nominal.io/api/rest/video-service.md#scaleparameter)
:   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.

### Property

`name` string required
:   ​

`value` string required
:   ​

### ScaleParameter

Set `type` to the name of one of the other fields, and set only that field.

`trueFrameRate` number
:   ​

`endingTimestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
:   ​

`scaleFactor` number
:   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.

### SearchVideosQuery

Set `type` to the name of one of the other fields, and set only that field.

`searchText` string
:   ​

`label` string
:   ​

`property` [`Property`](https://dev.nominal.io/api/rest/video-service.md#property)
:   ​

`and` array of [`SearchVideosQuery`](https://dev.nominal.io/api/rest/video-service.md#searchvideosquery)
:   ​

`or` array of [`SearchVideosQuery`](https://dev.nominal.io/api/rest/video-service.md#searchvideosquery)
:   ​

`ingestStatus` [`IngestStatus`](https://dev.nominal.io/api/rest/video-service.md#ingeststatus)
:   ​

`workspace` string (RID)
:   ​

### SegmentSummary

Bounding timestamps for the frames within a segment. For non-frame-mapped videos, the min and max media timestamps will be empty.

`minAbsoluteTimestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp) required
:   ​

`maxAbsoluteTimestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp) required
:   ​

`minMediaTimestamp` number required
:   ​

`maxMediaTimestamp` number required
:   ​

### SegmentSummaryV2

Bounding timestamps for the frames within a segment. Includes datasetFileId for V2 channel-based API.

`datasetFileId` string (UUID)
:   The dataset file ID that this segment belongs to.

`minAbsoluteTimestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp) required
:   ​

`maxAbsoluteTimestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp) required
:   ​

`minMediaTimestamp` number required
:   ​

`maxMediaTimestamp` number required
:   ​

### SegmentTimestamps

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.

Set `type` to the name of one of the other fields, and set only that field.

`timestampMappings` [`TimestampMappings`](https://dev.nominal.io/api/rest/video-service.md#timestampmappings)
:   ​

### SortField

`CREATED_AT`
:   ​

### SortOptions

`isDescending` boolean required
:   ​

`field` [`SortField`](https://dev.nominal.io/api/rest/video-service.md#sortfield) required
:   ​

### SuccessIngestStatus

An empty JSON object, `{}`.

### Timestamp

Deprecated for new APIs. Use google.protobuf.Timestamp for absolute instants in proto APIs.

This 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.

`seconds` integer (int64) required
:   ​

`nanos` integer (int64) required
:   ​

### TimestampMappings

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.

`mediaTimestamps` array of number
:   ​

`absoluteTimestamps` array of [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
:   ​

### Video

`rid` string (RID) required
:   ​

`title` string required
:   ​

`description` string
:   ​

`labels` array of string
:   ​

`properties` map of `PropertyName` to string
:   ​

`createdBy` string (RID) required
:   ​

`createdAt` string (date-time) required
:   ​

`isArchived` boolean required
:   ​

`originMetadata` [`VideoOriginMetadata`](https://dev.nominal.io/api/rest/video-service.md#videooriginmetadata) deprecated
:   **Deprecated:** deprecated in favor of per-file VideoFileOriginMetadata. Will be removed after April 15th.

`allSegmentsMetadata` [`VideoAllSegmentsMetadata`](https://dev.nominal.io/api/rest/video-service.md#videoallsegmentsmetadata)
:   ​

### VideoAllSegmentsMetadata

`rid` string (RID) required
:   ​

`numFrames` integer required
:   ​

`numSegments` integer required
:   ​

`scaleFactor` number
:   deprecated, in favor of per-file VideoFileSegmentsMetadata scaleFactor. Will be removed after April 15th.

`minAbsoluteTimestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp) required
:   ​

`maxAbsoluteTimestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp) required
:   the timestamp corresponding to absolute starting timestamp plus absolute duration of the video.

`mediaDurationSeconds` number required
:   ​

`mediaFrameRate` number required
:   The average media frame rate (FPS) of the video calculated as total frames / duration in seconds.

`minTimestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
:   deprecated. Will be removed after April 15th.

`maxTimestamp` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
:   deprecated. Will be removed after April 15th.

`durationSeconds` number
:   deprecated. Will be removed after April 15th.

`frameRate` number
:   deprecated. Will be removed after April 15th.

### VideoAssetChannel

Reference a video channel via an Asset’s data scope

`assetRid` string required
:   ​

`dataScopeName` string required
:   ​

`channel` string required
:   ​

`tags` map of `TagName` to string
:   ​

### VideoChannelDatasetFile

A dataset file backing a video channel, with the min and max absolute timestamps of the segments it contributes to the channel.

`datasetFileId` string (UUID) required
:   ​

`start` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp) required
:   ​

`end` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp) required
:   ​

### VideoChannelDatasetFileUpdate

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.

`datasetFileId` string (UUID) required
:   ​

`start` [`Timestamp`](https://dev.nominal.io/api/rest/video-service.md#timestamp)
:   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` string
:   New name (title) for the dataset file.

`scaleParameter` [`ScaleParameter`](https://dev.nominal.io/api/rest/video-service.md#scaleparameter)
:   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.

### VideoChannelSeries

Union type for referencing a video channel. Allows querying video data via datasource/channel, asset data scopes, or run data scopes.

Set `type` to the name of one of the other fields, and set only that field.

`dataSource` [`VideoDataSourceChannel`](https://dev.nominal.io/api/rest/video-service.md#videodatasourcechannel)
:   ​

`asset` [`VideoAssetChannel`](https://dev.nominal.io/api/rest/video-service.md#videoassetchannel)
:   ​

### VideoDataSourceChannel

Reference a video channel directly from a datasource/dataset

`dataSourceRid` string required
:   ​

`channel` string required
:   ​

`tags` map of `TagName` to string
:   ​

### VideoFileIngestStatus

Set `type` to the name of one of the other fields, and set only that field.

`success` [`SuccessIngestStatus`](https://dev.nominal.io/api/rest/video-service.md#successingeststatus)
:   ​

`error` [`IngestError`](https://dev.nominal.io/api/rest/video-service.md#ingesterror)
:   ​

`inProgress` [`Empty`](https://dev.nominal.io/api/rest/video-service.md#empty)
:   ​

### VideoIngestStatus

Set `type` to the name of one of the other fields, and set only that field.

`ready` [`Empty`](https://dev.nominal.io/api/rest/video-service.md#empty)
:   ​

`inProgress` [`Empty`](https://dev.nominal.io/api/rest/video-service.md#empty)
:   ​

`error` [`Empty`](https://dev.nominal.io/api/rest/video-service.md#empty)
:   ​

### VideoOriginMetadata

`videoSources` array of [`Handle`](https://dev.nominal.io/api/rest/video-service.md#handle) deprecated
:   **Deprecated:** deprecated in favor of per-file VideoFileOriginMetadata. Will be removed after April 15th.

`timestampManifest` [`VideoTimestampManifest`](https://dev.nominal.io/api/rest/video-service.md#videotimestampmanifest) required deprecated
:   **Deprecated:** deprecated in favor of per-file VideoFileOriginMetadata. Will be removed after April 15th.

### VideoStream

Metadata for a single video stream session.

`streamId` string required
:   ​

`videoRid` string (RID) required
:   ​

`streamStatus` string required
:   ​

`start` string (date-time)
:   ​

`end` string (date-time)
:   ​

`createdAt` string (date-time) required
:   ​

`updatedAt` string (date-time) required
:   ​

### VideoStreamV2

Metadata for a single channel-backed video stream session.

`streamId` string required
:   ​

`streamStatus` string required
:   ​

`createdAt` string (date-time) required
:   ​

`updatedAt` string (date-time) required
:   ​

`start` string (date-time)
:   ​

`end` string (date-time)
:   ​

### VideoTimestampManifest

Set `type` to the name of one of the other fields, and set only that field.

`mcap` [`McapTimestampManifest`](https://dev.nominal.io/api/rest/video-service.md#mcaptimestampmanifest)
:   ​

`s3paths` array of string
:   ​

`noManifest` [`NoTimestampManifest`](https://dev.nominal.io/api/rest/video-service.md#notimestampmanifest)
:   ​

Page design based on [Scalar](https://scalar.com), MIT License.
