One more idea, NP:
Your JS code at first page-load asks a third-party service if it's OK to use the API. For example, you host one public file for each user/site under some randomized URL unique to every site. The file contains the domain-name and API key (I guess, the API key is quite public anyway). If those do match, the JS code will know that it can send requests to your API. Again, cache the result, so every client will ask only once per visit.
If you want to exclude all clients of that site, you delete the site's file on GCS. The JS code receives a 404 and doesn't even touch your API and instance hours. You can have your app handle the files operations automatically per site / API key.
Downside is, additional time after page-load and that it adds another point of failure (e.g. outage of GCS). But for the latter case, your JS code could handle 500 errors gracefully and just send requests to the API, especially if you care more about availability of your API service than "unauthorized" usage.
Of course, you would need to compare the potential costs of both ideas.