The APIVex Streaming Availability API answers a specific question: where can someone watch a movie or show in a given country? Search by title, select the correct release, then retrieve its streaming, rental, and purchase offers as JSON.
This is a third-party catalog-data API. It does not play videos or complete a provider checkout. A useful integration is a “where to watch” panel that links users to the returned provider offers.
Search by title, then check the release year
Get an APIVex key from the dashboard. Keep it on your server and use the x-apivex-key header. The base URL is https://api.apivex.com/streaming.
curl --get 'https://api.apivex.com/streaming/api/search' \
--header "x-apivex-key: $APIVEX_API_KEY" \
--data-urlencode 'query=dune' \
--data-urlencode 'country=US' \
--data-urlencode 'language=en' \
--data-urlencode 'limit=2'Read data.titles. The request returned two movies named “Dune,” with different release years and identifiers:
| Title | Release year | title_id |
|---|---|---|
| Dune | 2021 | tm305113 |
| Dune | 1984 | tm166964 |
Use the year and type to disambiguate a title before requesting offers. These are identifiers returned by this API; do not substitute a TMDB or IMDb ID into the same path.
Get country-specific offers with Node.js
Pass the selected title_id in /api/titles/{title_id} and keep country explicit. Save this example as where-to-watch.mjs, set APIVEX_API_KEY, and run it using Node.js 20 or newer.
const key = process.env.APIVEX_API_KEY;
if (!key) throw new Error('Set APIVEX_API_KEY first');
const base = 'https://api.apivex.com/streaming';
// Demonstration pacing; use the request rate allowed by your plan.
const pause = () => new Promise(resolve => setTimeout(resolve, 2500));
async function get(path, params) {
const url = new URL(base + path);
url.search = new URLSearchParams(params).toString();
const response = await fetch(url, {
headers: {'x-apivex-key': key},
signal: AbortSignal.timeout(30000)
});
if (!response.ok) throw new Error('HTTP ' + response.status);
const body = await response.json();
if (body.status !== true) throw new Error(body.message || 'API request failed');
return body.data;
}
const search = await get('/api/search', {query: 'dune', country: 'US', language: 'en', limit: 2});
const title = search.titles.find(t => t.release_year === 2021 && t.type === 'movie');
if (!title) throw new Error('Requested release was not in this result page');
await pause();
const detail = await get('/api/titles/' + encodeURIComponent(title.title_id), {country: 'US', language: 'en'});
console.table(detail.offers.map(o => ({
provider: o.provider?.name, access: o.monetization_type,
format: o.presentation_type, price: o.price, currency: o.currency, url: o.url
})));The title response contains data.offers. Each offer includes provider information, monetization_type, presentation_type, price, currency, and a destination url when available.
The sample search uses the United States. Changing the interface language does not select another country’s catalog; use country for that. If your application supports several regions, retrieve the region the user selected and include it in the cache key.
Display subscription, rental, and purchase offers accurately
The captured response contained flatrate offers with a null price, alongside other offer types. A null price is not a zero-dollar offer. Show an appropriate subscription label for flatrate and leave an unknown price unspecified.
Several rows can refer to one provider because presentation formats differ. Decide whether your UI lists every format or groups offers by provider and monetization type. Do not discard a rental offer simply because the same provider also has a purchase option.
Keep currency with every amount. If you group rows, retain their destination URLs and quality information so your interface does not accidentally link a displayed price to a different offer.
Design the cache around location and availability
A practical cache key includes the title ID, country, and language. Store the fetch time and refresh according to your product needs and APIVex plan. Availability can change; avoid describing a saved response as a permanent catalog promise.
An empty offers array means the response did not contain an offer for that request. Your interface can say “No offers returned for this country” rather than claiming the title is unavailable everywhere.
For shows, title details can include a season list, and /api/seasons/{season_id}/episodes retrieves episodes using a season ID. A show title ID and a season ID are different identifiers. Preserve the IDs returned by the relevant parent record.
Does this API supply a video stream?
No. It supplies title metadata and where-to-watch information. Provider links are destinations for the user, not downloadable media files or playback stream URLs.
Try your title and country in the Streaming Availability documentation. Start with one title and one country before adding provider filters or country-specific popular lists.



