Welcome to the API Reference Docs page for the Press Association TV API (v2).
Bring your own key. This API needs your own TV API key - get one from the provider, add it once below, and the proxy injects it on every call. Your OmniStream plan covers the unified SDK, key storage, and proxy - the provider's own rate limits still apply to your key.
This is a community listing. If you own this API, you can request ownership.
npm install omnistream-sdkimport { OmniClient } from "omnistream-sdk";
const omni = new OmniClient({ token: process.env.OMNI_KEY! });
// One key reaches every API on the marketplace.
const data = await omni.call("pressassociation/listAssets");One install, one key - the same client calls every API on the marketplace.
Updated After
Limit the the number of items to be returned per page. For example: 5.
Flag to display Legacy and Provider Ids.
Asset Collection
Asset Detail
Asset Contributors
Catalogue Collection
Catalogue Detail
Catalogue Asset Collection
/**
* TVAPI - generated by OmniStream from TV API's OpenAPI spec.
* One typed method per endpoint. A single Omni key reaches the API.
*/
const DEFAULT_BASE = "https://grid.skinvaults.online/v1/proxy/pressassociation";
export class TVAPIError extends Error {
status: number;
code?: string;
constructor(status: number, code: string | undefined, message?: string) {
super(message || `TVAPI error ${status}`);
this.name = "TVAPIError";
this.status = status;
this.code = code;
}
}
export interface TVAPIOptions {
baseUrl?: string;
fetch?: typeof fetch;
timeoutMs?: number;
}
export class TVAPI {
/** @param token Your OmniStream key (one key for every API). */
constructor(private token: string, private opts: TVAPIOptions = {}) {
if (!token) throw new Error("TVAPI: token is required");
}
rateLimit: { remainingMinute?: number; remainingDay?: number } | null = null;
private async _request(method: string, path: string, { params, body }: { params?: Record<string, unknown>; body?: unknown } = {}): Promise<any> {
const f = this.opts.fetch ?? globalThis.fetch;
const url = new URL((this.opts.baseUrl ?? DEFAULT_BASE).replace(/\/+$/, "") + path);
if (params) for (const [k, v] of Object.entries(params)) if (v != null) url.searchParams.set(k, String(v));
const headers: Record<string, string> = { "x-omni-key": this.token };
if (body !== undefined) headers["content-type"] = "application/json";
const res = await f(url, { method, headers, body: body !== undefined ? JSON.stringify(body) : undefined });
this.rateLimit = {
remainingMinute: Number(res.headers.get("x-ratelimit-remaining-minute")) || undefined,
remainingDay: Number(res.headers.get("x-ratelimit-remaining-day")) || undefined,
};
const data = await res.json().catch(() => ({}));
if (!res.ok) throw new TVAPIError(res.status, data?.error?.code, data?.error?.message);
return data.data ?? data;
}
/** Asset Collection */
listAssets(params: { "updatedAfter"?: string; "limit"?: number; "aliases"?: boolean }): Promise<any> {
return this._request("GET", "/asset", { params });
}
/** Asset Detail */
getAsset(params: { "assetId": string; "aliases"?: boolean }): Promise<any> {
return this._request("GET", "/asset/{assetId}", { params });
}
/** Asset Contributors */
getAssetContributors(params: { "assetId": string; "aliases"?: boolean }): Promise<any> {
return this._request("GET", "/asset/{assetId}/contributor", { params });
}
/** Catalogue Collection */
listCatalogues(): Promise<any> {
return this._request("GET", "/catalogue", {});
}
/** Catalogue Detail */
getCatalogue(params: { "catalogueId": string }): Promise<any> {
return this._request("GET", "/catalogue/{catalogueId}", { params });
}
/** Catalogue Asset Collection */
getCatalogueAsset(params: { "catalogueId": string; "title"?: string; "start"?: string; "end"?: string; "updatedAfter"?: string; "limit"?: number; "aliases"?: boolean }): Promise<any> {
return this._request("GET", "/catalogue/{catalogueId}/asset", { params });
}
/** Catalogue Asset Detail */
getCatalogueAssetDetail(params: { "catalogueId": string; "assetId": string }): Promise<any> {
return this._request("GET", "/catalogue/{catalogueId}/asset/{assetId}", { params });
}
/** Channel Collection */
listChannels(params: { "platformId"?: string; "regionId"?: string; "aliases"?: boolean; "date"?: string; "scheduleStart"?: string; "scheduleEnd"?: string; "scheduleUpdatedSince"?: string }): Promise<any> {
return this._request("GET", "/channel", { params });
}
/** Channel Detail */
getChannel(params: { "channelId": string; "aliases"?: boolean }): Promise<any> {
return this._request("GET", "/channel/{channelId}", { params });
}
/** Contributor Collection */
listContributor(params: { "updatedAfter"?: string; "limit"?: number; "aliases"?: boolean }): Promise<any> {
return this._request("GET", "/contributor", { params });
}
/** Contributor Detail */
getContributor(params: { "contributorId": string; "aliases"?: boolean }): Promise<any> {
return this._request("GET", "/contributor/{contributorId}", { params });
}
/** Feature Collection */
listFeatures(params: { "type"?: string; "date"?: string; "start"?: string; "end"?: string }): Promise<any> {
return this._request("GET", "/feature", { params });
}
/** Feature Type Collection */
listFeatureTypes(): Promise<any> {
return this._request("GET", "/feature-type", {});
}
/** Feature Detail */
getFeature(params: { "featureId": string }): Promise<any> {
return this._request("GET", "/feature/{featureId}", { params });
}
/** Platform Collection */
listPlatforms(params: { "aliases"?: boolean }): Promise<any> {
return this._request("GET", "/platform", { params });
}
/** Platform Detail */
getPlatform(params: { "platformId": string }): Promise<any> {
return this._request("GET", "/platform/{platformId}", { params });
}
/** Platform Region Collection */
listPlatformRegions(params: { "platformId": string; "aliases"?: boolean }): Promise<any> {
return this._request("GET", "/platform/{platformId}/region", { params });
}
/** Schedule Collection */
listSchedule(params: { "channelId": string; "start": string; "end"?: string; "aliases"?: boolean }): Promise<any> {
return this._request("GET", "/schedule", { params });
}
}
export default TVAPI;
No reviews yet. Be the first to rate this API.
Yes. TV API uses apiKey authentication, so you bring your own key from the provider. You store it once on OmniStream and the proxy injects it into every call, so your code only ever sends your Omni key.
Welcome to the API Reference Docs page for the Press Association TV API (v2). It exposes 18 endpoints over GET, including GET /asset, GET /asset/{assetId}, GET /asset/{assetId}/contributor.
Install the OmniStream SDK for your language and call TV API through it. The client is generated from this API's OpenAPI spec, so parameters and responses are fully typed, and the same client also calls every other API in the marketplace.
You can start on the free plan. OmniStream charges for the unified SDK, key storage and proxy rather than for TV API itself, and TV API's own rate limits still apply to your provider key.
TVmaze: A free, keyless TV database - search shows, episodes, cast, and schedules. No sign-up required.
Catalogue Asset Detail
Channel Collection
Channel Detail
Contributor Collection
Contributor Detail
Feature Collection
Feature Type Collection
Feature Detail
Platform Collection
Platform Detail
Platform Region Collection
Schedule Collection