URL Lookup
Break a URL down, check its host against what mlab knows, and get a 0 to 100 risk score with every weighted reason behind it.
The URL lookup takes a link apart and weighs everything it knows into one score, from 0 to 100, with the arithmetic shown. It never opens the page: the analysis is a parse of the link plus what mlab already knows about its host. Following the link to its destination is a separate, opt-in step.
1. How to look up a URL
From the search bar. Paste a URL. mlab detects it and opens the URL lookup.
By URL. Open https://mlab.sh/url?q={url}, with the link URL-encoded.
From the API or MCP. GET /api/v1/scan/url?url=..., or the scan_url tool from any
connected AI assistant.
2. What you get
| Field | Meaning |
|---|---|
| Anatomy | Scheme, host (and its Unicode form for an internationalized domain), port, path, query parameters and fragment |
| Decoded form | The URL with percent-encoded characters decoded, when it had any |
| Embedded URL | Another link carried in a redirect parameter, such as ?url= or ?next= |
| Credentials | Whether the URL has a user@ part before the host. Its value is never echoed back. |
| Host context | What mlab knows about the host: registration date, registrar, and the blocklist status a previous domain scan recorded |
| Findings | Each signal, with a severity |
| Score | 0 to 100, with a band and every reason |
Registration date
The age of the host's domain weighs heavily in the score, so it is looked up live from the
domain's registry (RDAP) when mlab has never scanned the domain. host_context.age_source
says where it came from: scan, rdap, or empty when neither answered.
Blocklist status still needs a domain scan. Without one, host_context.scanned is
false and the response says the status is unknown, rather than calling the host clean.
3. Risk score
Every signal adds its weight, and the total is capped at 100. The bands are the same as for the email and crypto lookups.
| Band | Score |
|---|---|
clean | 0–19 |
suspect | 20–49 |
high | 50–79 |
critical | 80–100 |
Facts about the host weigh the most. The shape of the link weighs less, because every one of those tricks also has a legitimate use.
| Reason code | Weight | When |
|---|---|---|
url.domain_blocklisted | 60 | A domain scan found the host's domain on a blocklist |
url.domain_newborn | 45 | Domain registered in the last 7 days |
url.userinfo | 40 | Credentials before the @ disguise the real host |
url.domain_new | 35 | Domain registered in the last 30 days |
url.executable | 35 | Links straight to an executable (.exe, .ps1, .hta, .msi, .lnk, .iso…) |
url.punycode_host | 30 | Internationalized host, possible homograph |
url.ip_blocklisted | 25 | A domain scan found the host's addresses on a blocklist |
url.raw_ip_host | 25 | The host is a raw IP address |
url.embedded_redirect | 15 | Carries another URL in a redirect parameter |
url.domain_recent | 12 | Domain registered in the last 6 months |
url.shortener | 10 | A link shortener hides the real destination |
url.plain_http | 10 | Plaintext HTTP |
url.deep_subdomains | 10 | Deeply nested subdomains |
url.nonstandard_port | 5 | Non-standard port |
url.percent_encoded | 5 | Percent-encoded characters |
"score": {
"value": 85,
"band": "critical",
"conclusive": true,
"reasons": [
{ "code": "url.domain_newborn", "weight": 45, "label": "Host domain registered in the last 7 days" },
{ "code": "url.punycode_host", "weight": 30, "label": "IDN-encoded host, possible homograph" },
{ "code": "url.plain_http", "weight": 10, "label": "Plaintext HTTP" }
]
}Reason codes are stable and safe to alert on; labels are for display and may change.
Read conclusive before reading the score. It is false when the host's registration
date is unknown (a raw IP, or a registry that did not answer). The score then rests on
the link alone, and the page says so: a low number means little is known, not that
the link is safe.
The same score is returned on the page, by the API, by the MCP integration and in exports.
4. Following the link
Add resolve=true to follow the link to where it lands. This is the only part of the
lookup that touches the network, and it is off by default. It turns "this is a shortener"
into "this shortener lands here".
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://mlab.sh/api/v1/scan/url?url=https%3A%2F%2Fbit.ly%2Fexample&resolve=true"The resolution block gives the final URL, its HTTP status, every redirect hop, and
whether the link left the site it started on.
5. API
GET /api/v1/scan/url?url={url}[&resolve=true]The lookup launches no scan job. See the API reference for the full response and the API Guide for authentication and quotas.