/v1/phishing/safe-browsingSafe Browsing Check
Check URLs against Google Safe Browsing to identify pages flagged for malware, social engineering, unwanted software, or potentially harmful applications.
Credits
2
Per request
Max URLs
500
Per request
Plans
All Plans
Free, Starter, Professional, Enterprise
Threat Types Checked
| Threat Type | Description |
|---|---|
| MALWARE | Pages that host or distribute malicious software |
| SOCIAL_ENGINEERING | Phishing pages that trick users into revealing sensitive information |
| UNWANTED_SOFTWARE | Pages that distribute deceptive or unwanted software |
| POTENTIALLY_HARMFUL_APPLICATION | Pages hosting applications that may be harmful to the user or device |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| urls | string[] | Yes | Array of URLs to check (max 500) |
Code Examples
cURL
curl -X POST https://api.dfir-lab.ch/v1/phishing/safe-browsing \
-H "Authorization: Bearer sk-dfir-your-key-here" \
-H "Content-Type: application/json" \
-d '{
"urls": [
"https://example.com",
"http://malware-test.example.org/payload",
"https://legitimate-site.com"
]
}'Python
import requests
response = requests.post(
"https://api.dfir-lab.ch/v1/phishing/safe-browsing",
headers={
"Authorization": "Bearer sk-dfir-your-key-here",
"Content-Type": "application/json",
},
json={
"urls": [
"https://example.com",
"http://malware-test.example.org/payload",
"https://legitimate-site.com",
]
},
)
response.raise_for_status()
payload = response.json()
data = payload.get("data", payload)
for url_result in data["results"]:
threats = url_result.get("threats")
if isinstance(threats, list) and threats:
print(f"{url_result['url']}: potential threat — inspect evidence")
elif url_result.get("state") == "complete" and url_result.get("assessment") == "no_known_threats" and url_result.get("safe") is True and threats == [] and not url_result.get("error"):
print(f"{url_result['url']}: no known threat-list match; safety unverified")
else:
print(f"{url_result.get('url', '(missing URL)')}: unknown or incomplete")Example Response
{
"data": {
"results": [
{
"url": "https://example.com/page",
"safe": true,
"assessment": "no_known_threats",
"state": "complete",
"threats": [],
"checked_at": "2026-09-15T07:00:00Z",
"expires_at": "2026-09-15T07:05:00Z",
"coverage": {
"reputation": "complete",
"redirects": "not_requested",
"content": "not_requested"
},
"limitations": [
"reputation_only",
"no_match_does_not_establish_safety",
"destination_content_not_inspected"
]
}
],
"summary": {
"total": 1,
"safe": 1,
"flagged": 0,
"no_known_threats": 1
},
"provider": "google_safe_browsing",
"threat_types": [
"MALWARE",
"SOCIAL_ENGINEERING",
"UNWANTED_SOFTWARE",
"POTENTIALLY_HARMFUL_APPLICATION"
]
},
"meta": {
"request_id": "example-request",
"credits_used": 2,
"credits_remaining": 98,
"processing_time_ms": 100
}
}Results are powered by the Google Safe Browsing Lookup API v4. Coverage depends on the threat lists available at query time. New, targeted, or changed pages may not be listed.
A URL being marked as safe means it was not found in Google's threat lists at the time of the query. It is not a guarantee of safety. This endpoint does not fetch the destination, follow redirects, or inspect page content.
Treat missing fields, provider errors, and incomplete results as unknown. Match every response URL to a requested URL and require complete coverage before describing the lookup as complete. Never label an empty threat list as safe or legitimate. Prefer the explicit assessment and state fields; safe is a deprecated compatibility alias. Provider outages return 503 and malformed provider responses return 502. Threat entries use threatType and platformType. Do not reuse expired results.
A threat match's returned expiry retains at least Google's cacheDuration. Do not shorten that retention to the default no-match lifetime. In aggregate assessments, positive evidence keeps this expiry even when another requested check is incomplete. Expiry calls for a fresh assessment; it is not a safety verdict.