> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.westiq.ai/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.westiq.ai/_mcp/server.

# Content Package v1

## Purpose

A content package is a versioned title catalog with optional artwork references. It lets a partner
load the same title identities and descriptive metadata that WestIQ uses while continuing to own
playback, media delivery, rights enforcement and its user interface.

The package contains metadata and HTTPS references only. It does not contain video, audio, trailers,
DRM material, licences or commercial terms. WestIQ stores and returns artwork URLs but never fetches,
resolves, caches or proxies the referenced media.

Products are not included in the v1 `items` array. Product ingestion has its own contract, including
optional `imageUrl` and `heroUrl` artwork references.

## Manifest

The manifest is UTF-8 JSON with camel-case property names and omitted nulls:

```json
{
  "packageVersion": "2026.09.22.1",
  "generatedAtUtc": "2026-09-22T00:00:00Z",
  "titleCount": 2,
  "mediaBaseUrl": "https://media.example.com/",
  "items": [
    {
      "externalTitleId": "movie-1001",
      "kind": "Movie",
      "title": "Example Feature",
      "year": 2025,
      "genres": ["Drama"],
      "cast": ["Example Performer"],
      "rating": "PG-13",
      "synopsis": "An example synopsis.",
      "language": "English",
      "runtimeMinutes": 104,
      "keywords": ["journey"],
      "artwork": {
        "posterUrl": "https://media.example.com/posters/movie-1001.webp",
        "heroUrl": "https://media.example.com/heroes/movie-1001.webp"
      }
    },
    {
      "externalTitleId": "tv-2001",
      "kind": "TV",
      "title": "Example Series",
      "genres": ["Documentary"]
    }
  ]
}
```

| Field            | Type               | Rule                                                                        |
| ---------------- | ------------------ | --------------------------------------------------------------------------- |
| `packageVersion` | string             | Required, non-empty identifier for this immutable manifest revision.        |
| `generatedAtUtc` | RFC 3339 timestamp | Required UTC generation time.                                               |
| `titleCount`     | integer            | Required; must equal `items.length`.                                        |
| `mediaBaseUrl`   | absolute HTTPS URL | Required base for package-hosted artwork.                                   |
| `items`          | array              | Required title-catalog records. Kinds are `Movie`, `TV`, `Audio` or `Game`. |

Each item uses the catalog-ingest item schema. `externalTitleId`, `kind` and `title` are required;
the other catalog fields are optional under their documented vocabulary and sentinel rules. A
consumer may wrap at most 500 items at a time in a catalog-ingest job request with its stable
`sourceSystem` value. Use the same `sourceSystem` on catalog-serve requests to receive the package's
`externalTitleId` in responses.

The optional `artwork` object has:

| Field       | Type   | Rule                                                   |
| ----------- | ------ | ------------------------------------------------------ |
| `posterUrl` | string | Optional absolute HTTPS URL, at most 2,048 characters. |
| `heroUrl`   | string | Optional absolute HTTPS URL, at most 2,048 characters. |

Omit unavailable artwork fields and omit `artwork` when neither reference is available. Empty,
relative, non-HTTPS and over-length URLs are rejected. URLs are carried exactly as supplied and are
not checked for reachability.

## Media paths

Package-hosted files use these public read paths:

* `posters/{externalTitleId}.webp` for 2:3 poster artwork, normally 500 by 750 pixels.
* `heroes/{externalTitleId}.webp` for wide hero artwork.
* `manifests/{packageVersion}/catalog.json` for this manifest.

Directory listing is disabled. V1 does not use signed URLs. Clients follow the cache headers returned
with each object; a published manifest version is immutable, and replacing artwork requires publishing
a new package version whose manifest carries the new reference.

## Identity and loading

`externalTitleId` is the package's stable join key. Keep it unchanged when loading the package into a
partner catalog. WestIQ returns it from catalog serve when the request supplies the same
`sourceSystem` used for ingestion, so clients can join search and serve results to their own catalog
without adopting a second identifier.

Unknown optional fields may be added in future package versions. Consumers should ignore fields they
do not understand. Producers must send only fields accepted by the current catalog-ingest contract;
an unknown submitted item field is not a substitute for extending that contract.