---
title: "Assets"
canonical: "https://docs.pbs.org/space/CDA/3048577/Assets"
format: markdown
---
> Macro (toc)

## Overview

An asset resource is a video content object in Media Manager. Assets hold metadata, media files (video, caption/s, transcript, thumbnail image), availability windows, platform assignments, and geo-availability settings for different content types.

Assets can be one of three `object_type` values: **full_length**, **clip**, or **preview**. A full_length asset can only be created under an episode or special (max one per parent). Any number of clips and previews can be created under any parent: episodes, specials, seasons, shows, or franchises.

An asset can be uniquely identified by `id` or `slug`. If retrieving a resource by its slug, do not store the slug value as it may change. The `id` never changes.

The following related data is included in asset responses: videos, captions, transcripts, availability windows, platform availability, and geo availability.

## Endpoints

| Method | URL | Description |
| --- | --- | --- |
| GET | `/assets/{id|slug}/` | Get a single published asset |
| GET | `/assets/{id}/edit/` | Get an asset (including unpublished) |
| GET | `/episodes/{episode_id}/assets/` | List assets for an episode |
| GET | `/specials/{special_id}/assets/` | List assets for a special |
| GET | `/seasons/{season_id}/assets/` | List assets for a season (season-level extras only) |
| GET | `/shows/{show_id}/assets/` | List assets for a show (show-level extras only) |
| GET | `/franchises/{franchise_id}/assets/` | List assets for a franchise |
| POST | `/episodes/{episode_id}/assets/` | Create an asset under an episode |
| POST | `/specials/{special_id}/assets/` | Create an asset under a special |
| POST | `/seasons/{season_id}/assets/` | Create an asset under a season |
| POST | `/shows/{show_id}/assets/` | Create an asset under a show |
| POST | `/franchises/{franchise_id}/assets/` | Create an asset under a franchise |
| PATCH | `/assets/{id}/edit/` | Update an asset |
| DELETE | `/assets/{id}/edit/` | Delete an asset |
| GET | `/assets/search/` | Search assets |

> ℹ️ All URLs require the base endpoint prefix and a trailing slash. See [Resources](https://docs.pbs.org/space/CDA/3058039/Resources) for base endpoint and testing environment details.

> 📝 The `/edit/` suffix is required for PATCH, DELETE, and for retrieving unpublished assets via GET. Standard GET endpoints only return published assets.

## API Rate Limits

Rate limits apply to asset create and update operations, with specific enforced limits for video ingestion requests. See [Resources](https://docs.pbs.org/space/CDA/3058039/Resources) for the full rate limit details.

## Asset Fields

Fields returned on GET requests and available for create/update operations.

### Core Metadata

| Field | Type | Description | Create | Update |
| --- | --- | --- | --- | --- |
| `type` | string | Object type | — | — |
| `id` | string (UUID) | Unique PBS content identifier | — | — |
| `slug` | string | URL-friendly identifier. **Set on create only** — cannot be updated. Auto-generated if omitted. | Optional | — |
| `title` | string | Asset title (120 characters max). For `full_length` assets, inherited from parent episode/special. | Required * | Optional |
| `title_sortable` | string | Title without leading articles, used for alphabetical sorting | Optional | Optional |
| `description_short` | string | Short description (100 characters max). For `full_length` assets, inherited from parent episode/special. | Required * | Optional |
| `description_long` | string | Long description (400 characters max). For `full_length` assets, inherited from parent episode/special. | Required * | Optional |
| `object_type` | string | Content type. Values: `full_length`, `clip`, `preview` | Required | Optional |
| `premiered_on` | date (YYYY-MM-DD) | Original on-air or online broadcast date (no time)<br>For `full_length` assets, inherited from parent episode/special. | Required * | Optional |
| `encored_on` | date (YYYY-MM-DD) | The on-air or online rebroadcast date (no time)<br>For `full_length` assets, inherited from parent episode/special. | Required * | Optional |
| `duration` | integer | Length of video in seconds. Auto-populated during video ingestion. | — | — |
| `language` | string | Language code (e.g., `en`, `es`). 2-character ISO code. | Optional | Optional |
| `tags` | list of strings or null | Metadata tags. Not currently used by PBS platforms. Returns `null` when not set. | Optional | Optional |
| `updated_at` | datetime | Timestamp of last update in UTC (read-only) | — | — |
| `funder_message` | string | Funder/sponsor message. May contain HTML. | Optional | Optional |

For `full_length` assets, `title`, `description_short`, `description_long`, `premiered_on`, and `encored_on` are inherited from the parent episode or special and are not required (or accepted) in the create payload. For `clip` and `preview` assets, these fields are required.

### Content Controls

| Field | Type | Description | Create | Update |
| --- | --- | --- | --- | --- |
| `content_rating` | string | Content rating. Values: `TV-Y`, `TV-Y7`, `TV-G`, `TV-PG`, `TV-14`, `TV-MA`, `NR`, `E`. Conditionally required if the parent show requires it. Returns empty string when not set. | Conditional | Optional |
| `content_rating_descriptor` | list of strings or null | Content rating descriptors. Values: `D`, `L`, `S`, `V`, `FV` | Optional | Optional |
| `content_rating_required` | boolean | Whether the parent show requires a content rating. Read-only. | — | — |
| `is_excluded_from_dfp` | boolean | Prevents DFP/Google Ad Manager pre-roll and mid-roll sponsorship from displaying | Optional | Optional |
| `can_embed_player` | boolean | Whether the viral player embed code is available for this asset | Optional | Optional |
| `drm_enabled` | boolean | Whether the asset has DRM protection. Set automatically based on show-level DRM setting and video ingestion timing. Most assets are not DRM-enabled. | — | — |
| `has_captions` | boolean | Whether the asset has at least one caption file uploaded. Read-only. | — | — |
| `auto_publish` | boolean | Auto-publish the asset when all required fields are completed | Optional | Optional |
| `publish_state` | boolean | Whether the asset is currently published. Read-only (returned on `/edit/` endpoint only). | — | — |
| `player_code` | string | PBS partner player iframe embed code. Read-only. | — | — |
| `enhance_html_title_tag` | string | Additional SEO-targeted data for the HTML title tag | Optional | Optional |

### Media Files

| Field | Type | Description | Create | Update |
| --- | --- | --- | --- | --- |
| `video` | dict | Video file for ingestion. Contains `source` (URL). Profile is auto-detected. | Optional | Optional |
| `videos` | dict (keyed by audience) | Output video files, keyed by audience tier (`public`, `all_members`, `station_members`). Each tier contains a list of objects with `url` (URS-protected) and `profile`. Read-only. | — | — |
| `images` | list of objects | Image files. Each object contains `image` (URL), `profile`, and `updated_at`. On create/update, provide `source` (URL) and `profile`. | Optional | Optional |
| `audio` | list of objects | Audio track metadata (auto-detected). Each object contains `language` (2-char code), `descriptive` (boolean), and `channel` (e.g., `2.0`, `1.0`). Read-only. | — | — |
| `captions_language` | list of objects | Caption files for all languages. Each object contains `profile`, `url`, `language` (2-char code), and `primary` (boolean). On create/update, provide `language` and `source` (URL). | Optional | Optional |
| `transcripts` | list of objects | Auto-generated transcript files. Each object contains `profile` (`transcript`), `url` (.txt), `language` (2-char code), and `primary` (boolean). Transcript files do not contain timestamps. Clients using transcript files are responsible for any necessary encoding conversions to accommodate special characters in non-English files. Read-only. | — | — |
| `trick_play_files` | list of objects | Video scrubbing preview thumbnail files. Each object contains `url`, `filename`, `filetype` (`vtt`, `bif-hd`, `bif-fhd`), and `updated_at`. Read-only. | — | — |
| `caption_justification` | string | FCC caption exemption justification. Use a predefined value or a custom string. See the Create and Update sections for predefined options. | Optional | Optional |
| `has_justification` | boolean | Whether the asset has a caption justification assigned. Read-only (returned on `/edit/` endpoint only). | — | — |
| `other_justification` | string | Custom caption justification text. Read-only — populated when `caption_justification` is a custom value (in which case `caption_justification` is set to `Other`). | — | — |

### Availability and Platforms

| Field | Type | Description | Create | Update |
| --- | --- | --- | --- | --- |
| `availabilities` | dict (keyed by audience) | Availability windows and geo settings, keyed by audience tier: `public`, `all_members`, and `station_members` (station_members only present if parent show has local audience). Each tier contains: `start` (datetime), `end` (datetime or null), `countries` (list of country objects with `id`, `code`, `name`), `geo_profile` (object with `id`, `name`), and `updated_at`. On create/update, only `start`, `end`, and optionally `geo_profile` (as ID string) are accepted. Availability windows must nest: public <= all_members <= station_members. | Optional | Optional |
| `platforms` | list of objects | Platforms on which the asset is available. Each object contains `id`, `name`, `slug`, and `updated_at`. On create/update, provide a list of platform IDs. | Optional | Optional |

### Parent and Related Objects

| Field | Type | Description | Create | Update |
| --- | --- | --- | --- | --- |
| `episode` | object or null | Parent episode. Contains `type`, `id`, `attributes` (slug, ordinal, segment, title, title_sortable, updated_at), and `links`. Null if asset is not under an episode. Read-only (auto-populated from create endpoint URL). | — | Special * |
| `season` | object or null | Parent season (if asset is a season-level extra). Null for episode/special/show/franchise assets. | — | Special * |
| `show` | object or null | Parent show (if asset is a show-level extra). Null for episode/special/season assets. | — | Special * |
| `franchise` | object or null | Parent franchise (if asset is a franchise-level extra). Null otherwise. | — | Special * |
| `parent_tree` | dict | Full parent hierarchy. Contains the direct parent (episode/special/season/show/franchise) with nested parents up to the show level, including audience and franchise info. Read-only. | — | — |
| `related_links` | list of objects | Remote assets linked to this asset. Each is a remoteasset object with `title`, `description_short`, `url`, `image`, `updated_at`, and `tags`. | Optional | Optional |
| `related_promos` | list of objects | Promotional assets linked to this asset. Each is an asset object with basic attributes (slug, title, object_type, duration, images, etc.). | Optional | Optional |
| `chapters` | list | Chapter break markers for the asset | Optional | Optional |

Parent fields (`episode`, `season`, `show`, `franchise`) are auto-populated from the create endpoint URL and cannot be set in the create payload. On update, they can be used to **move** an asset to a different parent — see the Update section below.

### Deprecated Fields

> ⚠️ The following fields are deprecated and should not be used in new integrations. They are still returned in responses for backward compatibility.

| Field | Type | Description | Use Instead |  |
| --- | --- | --- | --- | --- |
| `countries` | <span style="color: #97a0af">list of objects</span> | <span style="color: #97a0af">Legacy asset-level country list. Always matches the </span>`public`<span style="color: #97a0af"> window in </span>`availabilities`<span style="color: #97a0af">.</span> | `availabilities.{tier}.countries` |  |
| `geo_profile` | <span style="color: #97a0af">object</span> | <span style="color: #97a0af">Legacy asset-level geo profile. Always matches the </span>`public`<span style="color: #97a0af"> window in </span>`availabilities`<span style="color: #97a0af">.</span> | `availabilities.{tier}.geo_profile` |  |
| `captions` | <span style="color: #97a0af">list of objects</span> | <span style="color: #97a0af">Single primary-language caption outputs only. Each object contains </span>`profile`<span style="color: #97a0af"> and </span>`url`<span style="color: #97a0af">.</span> | `captions_language` |  |
| `caption` | <span style="color: #97a0af">dict</span> | <span style="color: #97a0af">Legacy single caption file field for create/update.</span> | `captions_language` |  |
| `topics` | <span style="color: #97a0af">list of objects</span> | <span style="color: #97a0af">Topics assigned to the asset. Only allowed if the parent show/franchise has topics enabled. On create/update, provide a list of topic IDs.</span> | <span style="color: #97a0af">N/A</span> |  |

## Common Queries

Common query patterns for the `/assets/` endpoint. These examples show how to combine query parameters to retrieve specific sets of assets.

| Use Case | URL | Notes |
| --- | --- | --- |
| All assets for a show (regardless of hierarchy) | `/assets/?show-id={show_id}` | Returns all assets belonging to the show — not just show-level extras. Multiple `show-id` values can be chained. |
| All assets for a season (regardless of hierarchy) | `/assets/?season-id={season_id}` | Returns all assets belonging to the season. Multiple `season-id` values can be chained. |
| All full-length assets for a show | `/assets/?show-id={show_id}&type=full_length` | `show-id` is required when using the `type` filter on the `/assets/` endpoint. |
| Assets by title within a show (all hierarchy levels) | `/shows/{show_id}/assets/?title={keyword}&only_for_show=false` | Uses the **Shows endpoint**, not `/assets/`. The `only_for_show=false` flag is required to include assets from episodes, specials, and seasons — without it, only show-level extras are returned. Supports `type` filter. |
| Get `episode_links` (purchase links) for an asset | `/assets/{asset_id}/?fetch-related` | Returns `episode_links` if the asset has a parent episode with populated links (Amazon, iTunes, etc.). Also enriches `parent_tree` show object with `funder_message`. |
| Published full-length episode assets currently publicly available | `/assets/?show-id={show_id}&type=full_length&parent-type=episode&available=public` | Combines show, type, parent-type, and availability filters. Remember `/assets/` only returns published assets (use `/edit/` for unpublished). |
| Assets for a show filtered by country | `/assets/?show-id={show_id}&available=station_members&country=CA&platform-slug=bento&sort=-encored_on&page=1&page-size=10` | Filters by audience availability, country, and platform. Sorted by most recent encore date. `country` is a secondary filter and does not work standalone. |
| Assets by parent type (specials, episodes, shows, seasons) | `/assets/?show-id={show_id}&parent-type=special` | Returns assets directly associated with the given parent type. Add `type` filter for specific asset types (e.g., `&type=full_length&parent-type=special`). When `parent-type` is `show` or `season`, only `clip` and `preview` types are available. |

> 📝 Filtering by asset title is **not supported** on the `/assets/` endpoint. Use the Shows endpoint (`/shows/{show_id}/assets/?title={keyword}&only_for_show=false`) instead, which does support title filtering.

## Get Asset

`GET /assets/{id|slug}/`

Returns a single published asset by its ID or slug. Non-published assets are not returned. Append `/edit/` for unpublished assets.

### URL Parameters

| Parameter | Type | Description |
| --- | --- | --- |
| `id` | string | PBS content ID of the asset |
| `slug` | string | URL slug of the asset (alternative to ID) |

### Example Request

```
GET https://media.services.pbs.org/api/v1/assets/{id}/
```

### Example Response

```json
{
  "jsonapi": {
    "version": "1.0"
  },
  "data": {
    "type": "asset",
    "id": "05fcbb84-a1ac-43cb-9941-3d54850fdcc3",
    "attributes": {
      "slug": "weta-arts-511-md09hp",
      "title": "WETA Arts 511",
      "title_sortable": "WETA Arts 511",
      "description_short": "Acclaimed artist Ai Weiwei addresses the refugee crisis, and much more!",
      "description_long": "Vermeer and the masters of genre painting at the National Gallery of Art; acclaimed artist Ai Weiwei addresses the refugee crisis; and much more!",
      "object_type": "full_length",
      "premiered_on": "2017-11-10",
      "encored_on": "2017-11-10",
      "is_excluded_from_dfp": false,
      "duration": 1737,
      "content_rating": "",
      "content_rating_descriptor": [],
      "legacy_tp_media_id": 3006494340,
      "can_embed_player": true,
      "tags": [
        "art",
        "weiwei",
        "vermeer",
        "national gallery of art"
      ],
      "language": "en",
      "funder_message": "",
      "images": [
        {
          "image": "https://image.pbs.org/video-assets/image-file.png",
          "profile": "asset-mezzanine-16x9",
          "updated_at": "2017-11-08T15:59:53.937962Z"
        }
      ],
      "updated_at": "2021-02-26T08:28:14.268579Z",
      "countries": [],
      "geo_profile": null,
      "topics": [],
      "platforms": [
        {
          "id": "e5a289b8-01b3-41ce-92c1-3eb5a4e14bc0",
          "name": "All Platforms",
          "slug": "allplatforms",
          "updated_at": "2017-04-03T15:57:09.459445Z"
        }
      ],
      "player_code": "<iframe  id='partnerPlayer' frameborder='0' marginwidth='0' marginheight='0' scrolling='no' width='100%' height='100%' src='//player.pbs.org/partnerplayer/{id}?topbar=false&end=0&endscreen=true&start=0&autoplay=false' allowfullscreen></iframe>",
      "availabilities": {
        "public": {
          "end": null,
          "start": "2017-11-11T02:00:00Z",
          "countries": [],
          "updated_at": "2017-11-08T16:00:45.137014Z",
          "geo_profile": null
        },
        "all_members": {
          "end": null,
          "start": "2017-11-11T02:00:00Z",
          "countries": [],
          "updated_at": "2017-11-08T16:00:45.229575Z",
          "geo_profile": null
        },
        "station_members": {
          "end": null,
          "start": "2017-11-11T02:00:00Z",
          "countries": [],
          "updated_at": "2017-11-08T16:00:45.269075Z",
          "geo_profile": null
        }
      },
      "related_links": [],
      "related_promos": [],
      "parent_tree": {
        "id": "f6a0d0e7-b3bc-4268-879c-ae73e69c3d1e",
        "type": "episode",
        "attributes": {
          "title": "WETA Arts 511",
          "slug": "weta-arts-511-6mgwpe",
          "ordinal": 7,
          "season": {
            "id": "aef694e2-435d-4887-9db0-cb75fd6a0870",
            "type": "season",
            "attributes": {
              "title": "",
              "ordinal": 5,
              "show": {
                "id": "a8e00042-3564-4ecb-b210-f50af646b304",
                "type": "show",
                "attributes": {
                  "slug": "weta-arts",
                  "title": "WETA Arts",
                  "display_episode_number": true,
                  "tracking_ga_page": "UA-2017906-1",
                  "tracking_ga_event": "UA-2017906-7",
                  "seasons_count": 13,
                  "api_countries": [],
                  "audience": [
                    {
                      "scope": "all-stations",
                      "station": null
                    },
                    {
                      "scope": "local",
                      "station": {
                        "id": "92d89794-5ff0-4fe6-a443-cc888104e021",
                        "type": "station",
                        "attributes": {
                          "call_sign": "WETA",
                          "updated_at": "2022-01-11T18:06:50.946342Z",
                          "full_common_name": "WETA",
                          "short_common_name": "WETA"
                        },
                        "links": {
                          "self": "https://media.services.pbs.org/api/v1/stations/92d89794-5ff0-4fe6-a443-cc888104e021/"
                        }
                      }
                    }
                  ],
                  "franchise": null
                },
                "links": {
                  "self": "https://media.services.pbs.org/api/v1/shows/a8e00042-3564-4ecb-b210-f50af646b304/"
                }
              }
            },
            "links": {
              "self": "https://media.services.pbs.org/api/v1/seasons/aef694e2-435d-4887-9db0-cb75fd6a0870/"
            }
          }
        },
        "links": {
          "self": "https://media.services.pbs.org/api/v1/episodes/f6a0d0e7-b3bc-4268-879c-ae73e69c3d1e/"
        }
      },
      "drm_enabled": false,
      "has_captions": true,
      "enhance_html_title_tag": "",
      "episode": {
        "type": "episode",
        "id": "f6a0d0e7-b3bc-4268-879c-ae73e69c3d1e",
        "attributes": {
          "slug": "weta-arts-511-6mgwpe",
          "ordinal": 7,
          "segment": "",
          "title": "WETA Arts 511",
          "title_sortable": "WETA Arts 511",
          "updated_at": "2021-02-26T08:13:40.516149Z"
        },
        "links": {
          "self": "https://media.services.pbs.org/api/v1/episodes/f6a0d0e7-b3bc-4268-879c-ae73e69c3d1e/"
        }
      },
      "season": null,
      "show": null,
      "franchise": null,
      "chapters": [],
      "captions": [
        {
          "profile": "Caption-SAMI",
          "url": "https://ga.video.cdn.pbs.org/captions/weta-arts/05fcbb84-a1ac-43cb-9941-3d54850fdcc3/captions/file-name.sami"
        },
        {
          "profile": "DFXP",
          "url": "https://ga.video.cdn.pbs.org/captions/weta-arts/05fcbb84-a1ac-43cb-9941-3d54850fdcc3/captions/file-name.dfxp"
        },
        {
          "profile": "SRT",
          "url": "https://ga.video.cdn.pbs.org/captions/weta-arts/05fcbb84-a1ac-43cb-9941-3d54850fdcc3/captions/file-name.srt"
        },
        {
          "profile": "WebVTT",
          "url": "https://ga.video.cdn.pbs.org/captions/weta-arts/05fcbb84-a1ac-43cb-9941-3d54850fdcc3/captions/file-name.vtt"
        }
      ],
      "videos": {
        "public": [
          {
            "url": "https://urs.pbs.org/redirect/{id}/p/pbs-cs/",
            "profile": "mp4-16x9-720p"
          },
          {
            "url": "https://urs.pbs.org/redirect/{id}/p/pbs-cs/",
            "profile": "mp4-16x9-baseline"
          },
          {
            "url": "https://urs.pbs.org/redirect/{id}/p/pbs-cs/",
            "profile": "hls-16x9-720p"
          }
        ],
        "all_members": [
          {
            "url": "https://urs.pbs.org/redirect/{id}/p/pbs-cs/",
            "profile": "mp4-16x9-720p"
          },
          {
            "url": "https://urs.pbs.org/redirect/{id}/p/pbs-cs/",
            "profile": "mp4-16x9-baseline"
          },
          {
            "url": "https://urs.pbs.org/redirect/{id}/p/pbs-cs/",
            "profile": "hls-16x9-720p"
          }
        ],
        "station_members": [
          {
            "url": "https://urs.pbs.org/redirect/{id}/p/pbs-cs/",
            "profile": "mp4-16x9-720p"
          },
          {
            "url": "https://urs.pbs.org/redirect/{id}/p/pbs-cs/",
            "profile": "mp4-16x9-baseline"
          },
          {
            "url": "https://urs.pbs.org/redirect/{id}/p/pbs-cs/",
            "profile": "hls-16x9-720p"
          }
        ]
      },
      "trick_play_files": [
        {
          "url": "https://ga.video.cdn.pbs.org/trick_play/weta-arts/05fcbb84-a1ac-43cb-9941-3d54850fdcc3/file-name.bif",
          "filename": "file-name.bif",
          "filetype": "bif-hd",
          "updated_at": "2020-08-02T07:14:48.176306Z"
        },
        {
          "url": "https://ga.video.cdn.pbs.org/trick_play/weta-arts/05fcbb84-a1ac-43cb-9941-3d54850fdcc3/file-name.bif",
          "filename": "file-name.bif",
          "filetype": "bif-fhd",
          "updated_at": "2020-08-02T07:14:48.182447Z"
        },
        {
          "url": "https://ga.video.cdn.pbs.org/trick_play/weta-arts/05fcbb84-a1ac-43cb-9941-3d54850fdcc3/file-name.vtt",
          "filename": "file-name.vtt",
          "filetype": "vtt",
          "updated_at": "2022-04-09T22:05:04.805673Z"
        }
      ],
      "audio": [],
      "captions_language": [
        {
          "profile": "Caption-SAMI",
          "url": "https://ga.video.cdn.pbs.org/captions/weta-arts/05fcbb84-a1ac-43cb-9941-3d54850fdcc3/captions/file-name.sami",
          "language": "en",
          "primary": true
        },
        {
          "profile": "DFXP",
          "url": "https://ga.video.cdn.pbs.org/captions/weta-arts/05fcbb84-a1ac-43cb-9941-3d54850fdcc3/captions/file-name.dfxp",
          "language": "en",
          "primary": true
        },
        {
          "profile": "SRT",
          "url": "https://ga.video.cdn.pbs.org/captions/weta-arts/05fcbb84-a1ac-43cb-9941-3d54850fdcc3/captions/file-name.srt",
          "language": "en",
          "primary": true
        },
        {
          "profile": "WebVTT",
          "url": "https://ga.video.cdn.pbs.org/captions/weta-arts/05fcbb84-a1ac-43cb-9941-3d54850fdcc3/captions/file-name.vtt",
          "language": "en",
          "primary": true
        }
      ],
      "transcripts": [
        {
          "profile": "transcript",
          "url": "https://ga.pbs-video.pbs.org/captions/weta-arts/05fcbb84-a1ac-43cb-9941-3d54850fdcc3/captions/file-name.txt",
          "language": "en",
          "primary": true
        }
      ]
    }
  },
  "meta": {
    "type": "resource"
  },
  "links": {
    "self": "https://media.services.pbs.org/api/v1/assets/05fcbb84-a1ac-43cb-9941-3d54850fdcc3/"
  }
}
```

## Create Asset

`POST /episodes/{episode_id}/assets/` (or `/specials/`, `/seasons/`, `/shows/`, `/franchises/`)

Creates a new asset under a parent resource. A successful request returns **204 No Content**. The `Location` response header contains the URL of the new asset's `/edit/` endpoint.

### URL Parameters

| Parameter | Type | Description |
| --- | --- | --- |
| `{parent_id}` | string | PBS content ID of the parent resource (episode, special, season, show, or franchise) |

### Required Headers

| Header | Value |
| --- | --- |
| `Content-Type` | `application/json` |

### Required Fields by Object Type

| Requirement | Clip / Preview | Full Length |
| --- | --- | --- |
| Always Required | `object_type`, `title`, `description_short`, `description_long`, `premiered_on`, `encored_on` | `object_type` |
| Conditionally Required | `content_rating` (if required on show level) | `content_rating` (if required on show level) |
| Optional | `slug`, `video`, `images`, `captions_language`, `availabilities`, `platforms`, `tags`, `language`, `funder_message`, `auto_publish`, `topics`, `caption_justification`, `chapters`, `related_links`, `related_promos` | `slug`, `video`, `images`, `captions_language`, `availabilities`, `platforms`, `auto_publish`, `caption_justification` |

Full-length assets inherit `title`, `description_short`, `description_long`, `premiered_on`, and `encored_on` from the parent episode or special. These fields are ignored if included in the create payload.

### Minimal Payload (clip/preview)

```json
{
  "data": {
    "type": "asset",
    "attributes": {
      "title": "Sample Video Asset Title",
      "object_type": "preview",
      "description_short": "Short description here",
      "description_long": "Long description here",
      "premiered_on": "2023-01-01",
      "encored_on": "2023-05-01"
    }
  }
}
```

### Minimal Payload (full_length)

```json
{
  "data": {
    "type": "asset",
    "attributes": {
      "object_type": "full_length"
    }
  }
}
```

### Full Payload (with video, captions, availability, and images)

```json
{
  "data": {
    "type": "asset",
    "attributes": {
      "title": "Video Asset Title",
      "object_type": "preview",
      "description_short": "Short description",
      "description_long": "Long description",
      "premiered_on": "2024-01-01",
      "encored_on": "2024-01-01",
      "video": {
        "source": "<video-file-url>"
      },
      "captions_language": [
        { "language": "English", "source": "<english-caption-file-url>" },
        { "language": "Spanish", "source": "<spanish-caption-file-url>" }
      ],
      "images": [
        { "source": "<image-file-url>", "profile": "asset-mezzanine-16x9" }
      ],
      "availabilities": {
        "public": {
          "start": "2024-08-01T00:00:00Z",
          "end": "2024-10-01T03:59:59Z",
          "geo_profile": "<geo-profile-id>"
        },
        "all_members": {
          "start": "2024-07-15T00:00:00Z",
          "end": "2025-07-01T03:59:59Z",
          "geo_profile": "<geo-profile-id>"
        },
        "station_members": {
          "start": "2024-07-15T00:00:00Z",
          "end": null,
          "geo_profile": "<geo-profile-id>"
        }
      },
      "auto_publish": true
    }
  }
}
```

### Response

**204 No Content** on success. Check the `Location` header for the new asset's `/edit/` URL.

## Update Asset

`PATCH /assets/{id}/edit/`

Updates an existing asset. A successful request returns **204 No Content**. Include only the fields you want to change.

### URL Parameters

| Parameter | Type | Description |
| --- | --- | --- |
| `id` | string | PBS content ID of the asset |

### Required Headers

| Header | Value |
| --- | --- |
| `Content-Type` | `application/json` |

### Payload Fields

All fields are optional — include only what you are changing. The `id` must be included in the payload body. The `slug` field cannot be updated.

### Example Payload

```json
{
  "data": {
    "type": "asset",
    "id": "{asset_id}",
    "attributes": {
      "description_short": "Updated short description",
      "description_long": "Updated long description",
      "availabilities": {
        "public": {
          "start": "2024-08-01T00:00:00Z",
          "end": "2024-10-01T03:59:59Z"
        }
      }
    }
  }
}
```

### Replacing Video and Caption Files

To replace existing video or caption files on a published asset without disrupting playback, include `"replace": "true"` in the attributes:

```json
{
  "data": {
    "type": "asset",
    "id": "{asset_id}",
    "attributes": {
      "replace": "true",
      "video": { "source": "<new-video-file-url>" },
      "captions_language": [
        { "language": "English", "source": "<new-caption-file-url>" }
      ]
    }
  }
}
```

### Removing Video or Caption Files

Set `video` to `null` to remove a video file. To remove a caption file, pass the `language` without a `source`:

```
// Remove video
{ "data": { "type": "asset", "id": "{asset_id}", "attributes": { "video": null } } }

// Remove English caption
{ "data": { "type": "asset", "id": "{asset_id}", "attributes": {
    "captions_language": [ { "language": "English" } ]
} } }
```

### Moving an Asset to a Different Parent

To move an asset to a different parent, include only the target parent's ID in the attributes. **No other fields should be included when moving.**

```json
{
  "data": {
    "type": "asset",
    "id": "{asset_id}",
    "attributes": {
      "episode": "{target_episode_id}"
    }
  }
}
```

Valid move targets: `episode`, `special`, `season`, `show`, `franchise`.

### Response

**204 No Content** on success.

## Delete Asset

`DELETE /assets/{id}/edit/`

Permanently deletes the specified asset.

### URL Parameters

| Parameter | Type | Description |
| --- | --- | --- |
| `id` | string | PBS content ID of the asset |

### Required Headers

| Header | Value |
| --- | --- |
| `Content-Type` | `application/json` |

### Response

**204 No Content** on success.

## Search Assets

`GET /assets/search/`

Full-text search across assets. Filters can be chained (except `asset-title`, which is standalone).

### Search Parameters

| Parameter | Type | Description |
| --- | --- | --- |
| `asset-title` | string | Search by asset title. **Cannot be combined** with other search arguments. Returns intersection of multiple words. |
| `show-title` | string | Search by show title. Partial matches included (e.g., "Nature" matches "Nature Cat" too). |
| `show-id` | string | Filter by show ID. Can be repeated for multiple shows. |
| `episode-title` | string | Search by episode title (not asset title) |
| `special-title` | string | Search by special title |
| `description` | string | Keyword search within asset description (short and long) and title. Returns intersection of multiple keywords. |
| `tag` | string | Filter by tag name. Multiple tags = union (any match). Can be repeated. |
| `itag` | string | Filter by tag name. Multiple itags = intersection (all must match). Can be repeated. |
| `topic-id` | string | Filter by topic ID. Can be repeated for multiple topics (union). |
| `available` | string | Filter by viewer type availability: `public`, `all_members`, `station_members` |
| `platform-slug` | string | Required if searched assets are not on All Platforms |
| `drm-enabled` | boolean | Filter by DRM status |
| `country` | string | Filter by country code (e.g., `US`, `CA`). Can be repeated; returns assets available in ALL provided countries. |

### Example Requests

```
// Search by show and description
GET .../assets/search/?show-id={show_id}&description=black%20hole

// Search by asset title
GET .../assets/search/?asset-title=nature

// Search by tag with country filter
GET .../assets/search/?tag=wildlife&country=CA
```

## Query Parameters (List and Get)

These parameters can be used with the List and Get endpoints.

| Parameter | Type | Description |
| --- | --- | --- |
| `fetch-related` | flag | Include additional related data: `episode_links` (the parent episode's external purchase links, e.g., Amazon, iTunes) if the asset has a parent episode with populated links. Also enriches the `parent_tree` show object with `funder_message`. |
| `id` | string | Filter by one or more asset IDs (repeat parameter for multiple) |
| `slug` | string | Filter by one or more asset slugs (repeat parameter for multiple) |
| `show-id` | string | Filter by show ID. Returns all assets for the show regardless of hierarchy. Can be repeated. |
| `show-slug` | string | Filter by show slug |
| `season-id` | string | Filter by season ID. Returns all assets for the season regardless of hierarchy. Can be repeated. |
| `episode-id` | string | Filter by episode ID |
| `episode-slug` | string | Filter by episode slug |
| `special-id` | string | Filter by special ID |
| `type` | string | Filter by asset type: `full_length`, `clip`, `preview`. Can be repeated. Note: `show-id` is required when using this filter on the `/assets/` endpoint. |
| `parent-type` | string | Filter by parent type: `episode`, `special`, `season`, `show`. Returns assets directly associated with the given parent type. Requires `show-id`. |
| `available` | string | Filter by viewer availability: `public`, `all_members`, `station_members` |
| `platform-slug` | string | Filter by platform slug. Can be repeated. If not set, only assets on All Platforms are returned. |
| `platform-id` | string | Filter by platform ID. Can be repeated. |
| `drm-enabled` | boolean | Filter by DRM status |
| `country` | string | Filter by country code (e.g., `US`, `CA`). Can be repeated; returns assets available in ALL countries. Secondary filter — does not work standalone. |
| `membership` | string | CID of the station of which the user is a member. Used for Passport availability logic — see the **Asset Availability Logic** section below. Can be repeated for multiple memberships. |
| `localized_station` | string | CID of the station to which the user is localized. Used with `membership` for Passport availability logic — see the **Asset Availability Logic** section below. |
| `sort` | string | Sort results. Values: `encored_on`, `-encored_on`, `premiered_on`, `-premiered_on`, `title_sortable`, `-title_sortable`. Prefix with `-` for descending. |
| `page` | integer | Page number |
| `page-size` | integer | Results per page (max 50) |

### Filtering by Multiple IDs

```
GET https://media.services.pbs.org/api/v1/assets/?id={id1}&id={id2}&id={id3}
```

Returns 0 or more matching assets.

## Asset Availability Logic

Availability logic is used for Passport filtering. When requesting assets, additional parameters can be passed to determine the availability of an asset for a specific user based on their membership and localized station.

At least one of the following parameters is required to perform availability logic:

| Parameter | Type | Description |
| --- | --- | --- |
| `membership` | string | CID of the station of which the user is a member. This is the "Station ID" found in the Core Data tab in the Station Manager console. Can be repeated for multiple memberships. |
| `localized_station` | string | CID of the station to which the user is localized. This is the "Station ID" found in the Core Data tab in the Station Manager console. |

### Example Requests

```
// Single membership
GET https://media.services.pbs.org/api/v1/assets/?membership={CID}&localized_station={CID}

// Multiple memberships
GET https://media.services.pbs.org/api/v1/assets/?membership={CID}&membership={CID}&localized_station={CID}
```

### Additional Response Properties

When `membership` and/or `localized_station` parameters are passed, the asset response includes two additional properties:

```json
{
  "availability_window": "station_members",
  "playable_window": "public"
}
```

| **Property** | **Description** | **Possible Values** |
| --- | --- | --- |
| `availability_window` | Use this value as a key to access the `availabilities` object to determine the proper availability window for the user (with the given station membership and/or localization criteria). | `station_members`, `all_members`, `public`, `unavailable` |
| `playable_window` | Use this value as a key to access the `videos` object to determine the proper media files for playback by the user (with the given station membership and/or localization criteria). | `station_members`, `all_members`, `public`, `unavailable` |

## Availability Filtering of Assets

When requesting assets, an availability filter can be applied on viewer type. The returned assets are available to the viewer type requested.

| Viewer Type | Description | Value |
| --- | --- | --- |
| Public | Anonymous or non-logged-in users, or those without a localized station. | `public` |
| All Passport Members | Users who made a donation to a station that is different from the show's local audiences. | `all_members` |
| Your Station's Passport Members | Users who made a donation to a station that is the same as one of the show's local audiences. | `station_members` |

### Example Request

```
GET https://media.services.pbs.org/api/v1/assets/?available=public

// Scoped to an episode
GET https://media.services.pbs.org/api/v1/episodes/{episode_id}/assets/?available=public
```

## Geo Profile and Countries

### Overview

We recommend using the `geo_profile` and `countries` fields within the `availabilities` object rather than the deprecated asset-level fields. The asset-level `geo_profile` and `countries` fields always match the corresponding values for the `public` window in `availabilities`.

The `geo_profile` and `countries` fields always populate with the configured values, except when geo profile is set to "All Countries" — in that case, `geo_profile` is `null` and `countries` is empty.

### When a New Asset Is Created

All `geo_profile` and `countries` fields are populated with default values inherited from the parent show, or from values explicitly passed in the create payload.

### When an Asset Is Updated

If the asset-level `geo_profile` or `countries` fields are updated, the new values are also applied to the `public` window in `availabilities`. The reverse is also true — updating the `public` window fields in `availabilities` also updates the asset-level fields.

The `geo_profile` and `countries` fields on the Passport availability tiers (`all_members`, `station_members`) must be updated separately if needed.

> ℹ️ We recommend managing geo settings via the fields in the `availabilities` object, not the asset-level legacy fields. This allows for future deprecation of the legacy fields, for which advance notice would be provided.

### Example Create Payload with Geo-Profile IDs

```json
{
  "data": {
    "type": "asset",
    "attributes": {
      "title": "Asset Title",
      "object_type": "preview",
      "description_long": "Long Description",
      "description_short": "Short Description",
      "premiered_on": "2020-12-15",
      "encored_on": "2021-12-15",
      "availabilities": {
        "public": {
          "end": "2021-10-11T03:59:59Z",
          "start": "2021-08-03T00:30:00Z",
          "geo_profile": "c94e2e6d-0052-493a-a67d-266d51cc6445"
        },
        "all_members": {
          "end": "2022-07-05T03:59:59Z",
          "start": "2021-07-18T23:30:00Z",
          "geo_profile": "b8d29462-dbd3-481b-846c-1a0488299f63"
        },
        "station_members": {
          "end": "2028-07-05T03:59:59Z",
          "start": "2018-07-18T23:30:00Z",
          "geo_profile": "023ec9e6-2b09-461d-9de4-af5b9334367f"
        }
      }
    }
  }
}
```

### Common Geo-Profile IDs

| Name | Production ID | Staging ID |
| --- | --- | --- |
| US | `2ed1fd2f-a711-490b-8cdc-94ef51635bc1` | `47a11b60-55d1-4190-9e6c-a6ad95bccab9` |
| US, US Territories | `495585bd-a963-4245-b602-6ae4f2675c3a` | `639d5119-deed-4205-957c-d341c37e8895` |
| US, US Territories, Canada | `b8d29462-dbd3-481b-846c-1a0488299f63` | `695152a3-dc9e-44ee-8d2c-91a4b32db32d` |
| US, US Territories, Mexico | `be65c864-4589-4e1b-a733-2b2c9a888c4e` | `9a43b350-2c17-4e1d-8892-7297680d3f81` |
| Canada Only | `180842d5-5a63-4876-83a3-461222b7381b` | `362b2f43-dbc5-4be0-8488-b6a038517047` |

## Platform List

> 📝 If no platform filter is applied when requesting assets, only assets assigned to **All Platforms** are returned. If one or more platform filters are applied, assets assigned to the specified platforms *plus* All Platforms are returned.

Use the endpoint below to get a list of all available platforms:

```
GET https://media.services.pbs.org/api/v1/platforms/
```

Or, get info about an individual platform by passing its slug or id. Examples:

```
GET https://media.services.pbs.org/api/v1/platforms/partnerplayer/

```