Safe Browsing with Google Cloud Web Risk
How Google Safe Browsing and the Web Risk API differ, what each costs, and how to check URLs with the Web Risk Lookup API in Python.
Google Safe Browsing is one of the most widely used free security services on the web: Google says it protects more than five billion devices today. Its commercial counterpart, Google Cloud Web Risk, gives businesses the same threat data with an SLA. This post covers how the two differ, what Web Risk costs, and how to check URLs from your own code, with a small Streamlit app as the example.
What is Google Safe Browsing?
Google Safe Browsing is a free service from Google that warns users when they try to visit a dangerous website or download a malicious file. If using Google's webmaster tools, Safe Browsing notifies website owners when their sites are compromised, and helps them diagnose and clean up the problem. Safe Browsing launched in 2005 and has since become an integral part of the web browsing experience for millions of users worldwide. It works by constantly analyzing billions of URLs and web pages to identify any suspicious activity or content. When a user attempts to access a potentially harmful website, Safe Browsing immediately issues a warning, giving the user the option to proceed at their own risk or return to safety.

Chrome, Firefox and Safari all use Safe Browsing; Microsoft Edge uses its own SmartScreen service instead. Developers can query it through the Safe Browsing API, now on version 5. The API lets clients check URLs in real time, or check hashed URL prefixes so the actual URL never leaves the client, and keep a local copy of the threat lists. An optional companion API, the Oblivious HTTP Gateway, hides end users' IP addresses from Google as well. Anyone can report a phishing page with this form.

Malware, social engineering, and unwanted software are the major threat types supported today. Users who need or want more advanced capabilities while browsing the web can enable Enhanced Safe Browsing; when enabled, this option shares additional information with Google servers in return for deeper file scans and protection against previously unknown attacks. The Safe Browsing API is meant for non-commercial use only; for revenue-generating use cases, users are encouraged to use the Web Risk API.
What is Google Cloud Web Risk?
Google Cloud Web Risk is effectively the "Enterprise" edition of Safe Browsing. It extends Safe Browsing capabilities to use the APIs at higher volumes, offers access to enterprise features like risk scoring, confidence levels, file/attachment reputation coverage, and integrates with Google Cloud security and analytics tools. More importantly, it offers an SLA, which is critical for Enterprise adoption.
Web Risk offers four APIs, but only two are open to everyone. Prices are from Google's Web Risk pricing page (November 2026):
- Lookup API: send a URL, get back a verdict and the threat types it matches. The first 100,000 calls a month are free, then $0.50 per 1,000.
- Update API: download hashed threat lists to a local database and check URLs against it yourself. Downloading the lists is free. When a local hash matches, you confirm it with a hash search, which costs $50 per 1,000 calls.
- Submission API: report suspicious URLs for Safe Browsing to analyse. Google no longer accepts new customers for it and will retire it by the end of 2027.
- Evaluate API: returns a confidence score per threat type instead of a yes/no verdict, using blocklists, machine learning and generative AI models. It's a private preview, and you have to request access through Google's sales team.
The threat information Web Risk returns can't be redistributed. The rest of this post uses the Lookup API.
Build a Streamlit App for Web Risk Lookup API
You need a Google Cloud project (new Google Cloud accounts get $300 in free credit for 90 days) with billing enabled and the Web Risk API turned on. Then create an API key, rather than a service account key:
- In the Cloud console, open
APIs & Services→Credentials→Create credentials→API key. - Edit the key and, under
API restrictions, restrict it to theWeb Risk API. A leaked key then can't be used for anything else.
Install the two packages, and set the key as an environment variable:
pip install google-cloud-webrisk==1.23.0 streamlit==1.67.0
export WEBRISK_API_KEY="your-api-key"Save this as streamlit_app.py. The first tab sends the full URL to the Lookup API. The second shows the privacy-preserving approach: it hashes the URL locally, sends only the first 4 bytes of the hash, and compares the full hashes that come back on your side.
import hashlib
import os
import streamlit as st
from google.cloud import webrisk_v1
THREAT_TYPES = [
webrisk_v1.ThreatType.MALWARE,
webrisk_v1.ThreatType.SOCIAL_ENGINEERING,
webrisk_v1.ThreatType.UNWANTED_SOFTWARE,
]
@st.cache_resource
def get_client():
api_key = os.environ.get("WEBRISK_API_KEY")
if not api_key:
st.error("Set the WEBRISK_API_KEY environment variable first.")
st.stop()
return webrisk_v1.WebRiskServiceClient(client_options={"api_key": api_key})
st.subheader("Google Cloud Web Risk API")
client = get_client()
url_tab, hash_tab = st.tabs(["Look up a URL", "Look up by hash prefix"])
with url_tab:
url = st.text_input("URL", placeholder="http://testsafebrowsing.appspot.com/s/malware.html")
if st.button("Check URL") and url.strip():
try:
response = client.search_uris(uri=url.strip(), threat_types=THREAT_TYPES)
except Exception as e:
st.error(f"Lookup failed: {e}")
else:
if response.threat.threat_types:
names = ", ".join(t.name for t in response.threat.threat_types)
st.error(f"Unsafe: {names}")
else:
st.success("No match in Web Risk's threat lists.")
with hash_tab:
expression = st.text_input(
"URL expression (host and path, no scheme)",
placeholder="testsafebrowsing.appspot.com/s/malware.html",
)
if st.button("Check hash prefix") and expression.strip():
full_hash = hashlib.sha256(expression.strip().encode()).digest()
try:
response = client.search_hashes(hash_prefix=full_hash[:4], threat_types=THREAT_TYPES)
except Exception as e:
st.error(f"Lookup failed: {e}")
else:
matches = [t for t in response.threats if t.hash == full_hash]
if matches:
names = ", ".join(tt.name for t in matches for tt in t.threat_types)
st.error(f"Unsafe: {names}")
else:
st.success("No match for this hash.")Run it with streamlit run streamlit_app.py. Google provides test pages that always return a positive result for each threat type.

Before using this in a real application, note that hash searches are expensive: at $50 per 1,000 calls, they’re meant for confirming matches from a local Update API database, not for checking every URL. The hash tab is also simplified. It hashes exactly what you type, while real clients canonicalise the URL first and check several host and path combinations, as described in Google’s URLs and hashing guide. And because a 4-byte prefix can match unrelated URLs, the app compares the full hashes the API returns rather than trusting the prefix match.
In a real application, you'd call the Lookup API from your backend, after receiving a URL and before acting on it: before rendering a link preview, following a redirect, or storing a user-submitted link.
Deploy the Streamlit App on Railway
To share the app, push streamlit_app.py and a requirements.txt (with the two pinned packages) to a GitHub repository and deploy it on Railway. Set WEBRISK_API_KEY as a service variable, and use this as the start command:
streamlit run streamlit_app.py --server.port $PORT --server.address 0.0.0.0Anyone who can reach the app can spend your Web Risk quota. Keep the URL private, or drop the hash tab before sharing it, because hash searches are the expensive call.
Frequently Asked Questions
Is the Google Safe Browsing API free? Yes, for non-commercial use. For commercial use, meaning anything that generates revenue, Google requires the Web Risk API instead.
How much does the Web Risk API cost? The first 100,000 Lookup API calls a month are free, then $0.50 per 1,000. Downloading threat lists with the Update API is free, but each hash search to confirm a match costs $50 per 1,000 calls.
What's the difference between Safe Browsing and Web Risk? They use the same threat data. Web Risk is the commercial version: it allows revenue-generating use, comes with an SLA, and is billed through Google Cloud.
Can I submit phishing URLs to Google? Anyone can report a page with the Safe Browsing report form. The Web Risk Submission API no longer accepts new customers and will be retired by the end of 2027.