Every API call on my downloader costs me something. I am on the free tier of a few RapidAPI services, and each of those services gives me a fixed number of calls a month. The visitor does not see any of that. They paste a link, tap Download, and expect a video. So one of the first things I learned building ramrom.io was this: never spend an API call on a link you already know is useless.
The fix is boring, and that is the point. Before anything touches the network, the pasted link gets validated in the browser. The first check is the shape of it. A valid URL has to parse, it has to use http or https, and it has to actually have a host. That alone catches the typos, the half-pasted links, and the text that is not a link at all. A visitor who pastes "watch this one" by accident gets a plain message straight away instead of a spinner that ends in a confusing error.
The second check is the one that saves the quota. My downloader supports TikTok, Instagram, Facebook and YouTube, so the host has to belong to one of those platforms or to one of their known short domains. I keep a small allowlist: tiktok.com, vt.tiktok.com, instagram.com, facebook.com, fb.watch, youtube.com, youtu.be, and a handful more. If the host is not on the list, the page says so immediately and no request is ever made.
This matters more than it sounds, because the failure mode without it is expensive in two directions. The visitor waits through a slow API round trip only to be told the link cannot be resolved, and I have burned a call from a quota that does not refill until next month. Multiply that by a few hundred curious pastes a day and the free tier starts looking very small.
The allowlist is deliberately narrow. I check the host, not a substring, because matching on a substring is how you get fooled. A host like tiktok.com.evil.example is not TikTok, and a check that looks for "tiktok" anywhere in the string would let it through. So I compare the end of the hostname against the allowed domains, and I only accept an exact match or a proper subdomain.
There is a server-side check as well, because anything in the browser can be skipped. The same allowlist runs again in resolve.php before the provider is called, so a request that arrives by curl or by a modified page gets the same answer. The browser check gives the visitor a fast, friendly response. The server check is there because the browser check is not a security boundary.
A few small details make the validation feel decent instead of fussy. Short links get expanded before the host is checked, so vt.tiktok.com and youtu.be resolve to the platform they belong to rather than being rejected as unknown. Tracking parameters are stripped, so a ?si= suffix pasted from a share sheet does not break the match. Leading and trailing whitespace and line breaks are trimmed, because people paste from messages where a link often arrives with a stray space attached.
What I would not do is try to be clever about it. I do not fetch the link to see if it exists before validating, because that would cost a request to do the job of avoiding a request. I do not try to guess the platform from the shape of the path, because paths change and hosts are the stable part. And I do not show a different error for every failure. The visitor gets one plain line: this link is not from a supported platform. If the link is supported but the video is private or deleted, that is a different message, from a different stage.
The result is unglamorous but it works. Most bad pastes are caught before a single byte leaves the visitor's browser, the quota goes to real downloads, and the error messages describe the actual problem instead of blaming the provider. On a small tool running on shared hosting with a free-tier budget, that is not a nice extra. It is the whole business model.
