{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/arcmira/json-schema/arcmira-channel-videos-response-schema.json",
  "title": "ChannelVideosResponse",
  "x-generated": "2026-11-10",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/arcmira-channels-api-openapi.yml#/components/schemas/ChannelVideosResponse",
  "type": "object",
  "properties": {
    "channel": {
      "type": "object",
      "properties": {
        "id": {
          "type": [
            "string",
            "null"
          ],
          "description": "Public entity id (\"ent_{n}\") of the channel. Null when no channel entity is known."
        },
        "youtube_channel_id": {
          "type": "string",
          "description": "The channel id as supplied."
        },
        "name": {
          "type": [
            "string",
            "null"
          ]
        },
        "page": {
          "type": [
            "string",
            "null"
          ],
          "description": "The channel's page on arcmira.com, absolute. Null when no channel is known."
        }
      },
      "required": [
        "id",
        "youtube_channel_id",
        "name",
        "page"
      ]
    },
    "episodes": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "video_id": {
            "type": "string",
            "description": "11-character YouTube video id. Pass it to GET /v1/mentions/counts video_ids or GET /v1/transcripts/{video_id}."
          },
          "title": {
            "type": [
              "string",
              "null"
            ]
          },
          "published_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "ISO publish date on YouTube."
          },
          "duration_seconds": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Video length in seconds. Null when YouTube reported none."
          },
          "view_count": {
            "type": [
              "integer",
              "null"
            ]
          },
          "channel_id": {
            "type": "string",
            "description": "The channel id as supplied."
          },
          "channel_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "channel_page": {
            "type": [
              "string",
              "null"
            ],
            "description": "The channel's page on arcmira.com, absolute. Null when no channel is known."
          },
          "watch_url": {
            "type": "string",
            "description": "The episode on arcmira.com, absolute."
          }
        },
        "required": [
          "video_id",
          "title",
          "published_at",
          "duration_seconds",
          "view_count",
          "channel_id",
          "channel_name",
          "channel_page",
          "watch_url"
        ]
      },
      "description": "Indexed videos of the channel, newest first."
    },
    "returned": {
      "type": "integer"
    },
    "has_more": {
      "type": "boolean",
      "description": "True when more indexed videos exist past limit in the window."
    },
    "next_cursor": {
      "type": [
        "string",
        "null"
      ],
      "description": "Signed continuation for the next page. Null on the last page."
    },
    "window": {
      "$ref": "#/$defs/PublicationWindow"
    },
    "indexed_through": {
      "type": [
        "string",
        "null"
      ],
      "description": "Newest publish date among every indexed video of the channel, whatever window was asked for. Null when nothing is indexed."
    },
    "index_age_days": {
      "type": [
        "integer",
        "null"
      ],
      "description": "Whole days between indexed_through and now. Past 30 the note says the index may be behind the channel. Null when nothing is indexed."
    },
    "as_of": {
      "type": [
        "string",
        "null"
      ],
      "description": "Same as indexed_through."
    },
    "freshness": {
      "allOf": [
        {
          "$ref": "#/$defs/Freshness"
        },
        {
          "description": "Present when your plan's freshness gate cut the window: where results on this plan stop. unlock names the plan that reads past it."
        }
      ]
    },
    "unlock": {
      "type": "object",
      "properties": {
        "tier": {
          "type": "string",
          "description": "The plan that lifts the freshness gate."
        },
        "url": {
          "type": "string",
          "description": "Where to start that plan."
        }
      },
      "required": [
        "tier",
        "url"
      ],
      "description": "Present with freshness when your plan's freshness gate cut the window; note says so."
    },
    "note": {
      "type": "string",
      "description": "One steering sentence for the agent reading this."
    }
  },
  "required": [
    "channel",
    "episodes",
    "returned",
    "has_more",
    "next_cursor",
    "window",
    "indexed_through",
    "index_age_days",
    "as_of",
    "note"
  ],
  "$defs": {
    "Freshness": {
      "type": "object",
      "properties": {
        "delay_days": {
          "type": "integer",
          "description": "Days after publication before this plan reads a video."
        },
        "served_through": {
          "type": "string",
          "description": "YYYY-MM-DD (UTC). Results on this plan stop at this publish date; media published after it is not read."
        }
      },
      "required": [
        "delay_days",
        "served_through"
      ],
      "description": "Where results stop on a plan that reads media after a delay."
    },
    "PublicationWindow": {
      "type": "object",
      "properties": {
        "after": {
          "type": [
            "string",
            "null"
          ],
          "description": "Inclusive start as an ISO instant. Null when the window has no start."
        },
        "before": {
          "type": [
            "string",
            "null"
          ],
          "description": "Exclusive end as an ISO instant. Null when the window has no end. Earlier than the before you sent when your plan's freshness gate cut the window."
        }
      },
      "required": [
        "after",
        "before"
      ],
      "description": "The publication window the answer covers, [after, before) in UTC, normalized from after and before."
    }
  }
}