Free Movie Embed API — Developer Guide for Vidsrc
The Vidsrc embed API is a small, predictable HTTP surface that turns any movie or TV show identifier into a ready-to-paste player URL. There is no SDK to install, no manifest to configure, and no monthly bill. If you can make a fetch request from a browser or a server, you can use the API. This guide walks you from your first call to a fully integrated player in a React or Vue app, and it captures the small gotchas that cost the most time when you are moving fast.
By the end of this quickstart you will know how to authenticate, which endpoints are public, what the request and response shapes look like, how to embed the result in a single iframe, and how to debug the three or four errors that show up most often in production. We will keep the prose short and the examples copy-paste ready.
What the Vidsrc embed API actually is
Under the hood, the API is a thin layer over the same player URLs the homepage already exposes. The public routes accept either an IMDb ID or a TMDB ID and return a stable embed URL, plus a small amount of metadata that is convenient for previews and search engine snippets. Because the response is plain JSON, you can consume it from anywhere that speaks HTTP — Node, PHP, Python, Go, or a static site generator.
You will see two flavors of endpoint in the documentation. The build endpoints generate a player URL on demand from an identifier, and the catalog endpoints return lists of the latest movies, TV shows, or episodes. The build endpoints are the ones most site owners need; the catalog endpoints are useful when you want to power a browse page without maintaining your own database of titles.
The API is intentionally small. There are no GraphQL schemas, no SDK matrix, no pagination cursor dialects to learn. A single GET request with two or three query parameters is enough for almost every integration.
Authentication and access
The public embed endpoints do not require an API key, which means you can hit them directly from a browser without exposing a secret. For higher-volume catalog endpoints, a free token is recommended so the request volume can be accounted for and any rate limit can be tuned per integration. Tokens are passed as a token query parameter or, for server-to-server calls, as an Authorization: Bearer header.
CORS and browser-side calls
The API sends permissive CORS headers, so a fetch from any frontend origin works without a proxy. If you are running into a CORS error, the cause is almost always a stale preflight cache, a corporate proxy stripping the headers, or a typo in the URL that redirected to an unrelated domain. Open the network panel and inspect the response headers on the preflight OPTIONS request — the answer is almost always there.
Rate limits
Unauthenticated traffic is throttled to a generous per-IP ceiling that is more than enough for a personal site or a small product. Authenticated traffic gets a higher ceiling tied to the token. If you hit a 429, back off for a few seconds and retry with a simple exponential delay. There is no quota to purchase — the limits exist to keep the public surface healthy for everyone.
Endpoint reference and ID formats
The two ID formats you will encounter most are the IMDb identifier, which always starts with tt and is followed by seven or eight digits, and the TMDB identifier, which is a plain integer. The build endpoints accept either one and return a url field that you can drop straight into an iframe.
Build endpoints
Pass ?imdb=tt0111161 for a movie, or ?tmdb=550 for the same movie identified by TMDB. For TV shows, append &season=1&episode=1 to land directly on a specific episode. The response is a JSON object with the player URL, the resolved title, the poster path, and a stable canonical URL you can use for OpenGraph tags.
Catalog endpoints
The catalog routes return paginated lists. /api/latest/movies, /api/latest/tv, and /api/latest/episodes each accept a page parameter. The default page size is generous; if you want fewer results per call, pass limit. The shape of each item mirrors the build response so you can hand the url straight to an iframe without a translation step.
Drop-in iframe example
Once you have a player URL, embedding the result is the easy part. Wrap the iframe in a 16:9 container so the player scales cleanly across breakpoints, set the width to 100 percent, and leave the height to the wrapper. The snippet below is the entire integration.
If you prefer to render the player on a button click rather than at page load — useful when you want to keep initial page weight low — store the URL in a data attribute and set the iframe src only when the user opts in. That pattern keeps crawlers from accidentally loading the player during a preview scan and keeps Lighthouse scores happy on long browse pages.
Integrating into React or Vue
In a React component, a typical integration calls the build endpoint inside useEffect, stores the resulting URL in state, and renders the iframe once the URL resolves. Show a skeleton placeholder during the fetch so the layout does not jump when the player mounts. In Vue the same flow uses onMounted and a ref for the URL.
For server-rendered sites, hit the API at build time instead of in the browser. Pre-compute the URLs for every title you link to, store them in a JSON manifest, and embed them as plain iframes. That gives you instant renders with no client-side JavaScript at all, which is the fastest path to a great Core Web Vitals score.
Common errors and fixes
404 on a title you know exists
The ID was probably mistyped, or you confused the IMDb identifier with the TMDB identifier and passed one where the other was expected. Cross-check the identifier against the source page and retry.
Empty url field in the response
You hit a catalog endpoint without a token at a moment of high load. Wait a moment and retry, or request a free token to lift you onto the authenticated tier.
Player loads but the iframe is blank
A content security policy on your site is blocking the third-party origin. Add the player host to your frame-src directive and reload. The same fix applies if your X-Frame-Options is set to DENY — switch it to SAMEORIGIN or remove it for that route.
CORS preflight fails
Inspect the OPTIONS response in your network panel. If the headers are missing, a proxy in front of your origin is stripping them — bypass the proxy for API calls or have it forward CORS headers untouched.