POST
/api/v1/phishing/url-expandURL Expand
Follow a URL through its entire redirect chain to reveal the final destination. Useful for unshortening links and detecting suspicious multi-hop redirects often used in phishing campaigns.
Credits
1
Per request
Max Hops
10
5s timeout per hop
Plans
All
Free, Starter, Professional, Enterprise
Behavior & Security
| Feature | Detail |
|---|---|
| Max redirects | 10 hops — returns an error if exceeded |
| Timeout per hop | 5 seconds — slow servers are treated as dead ends |
| SSRF protection | Redirects to private/internal IPs (RFC 1918, loopback, link-local) are blocked |
| Suspicious flag | Chains with more than 3 hops or SSRF-blocked hops are automatically marked suspicious |
| Hop details | Each hop reports the status code, server header, and location header |
SSRF protection ensures the API cannot be abused to scan internal networks. If any hop in the chain resolves to a private IP address, the chain is terminated and an error is returned for that hop.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| url | string | Yes | The URL to expand (follow redirects). Max 2048 characters, must use http:// or https://, must not contain embedded credentials. |
Code Examples
cURL
curl -X POST https://api.dfir-lab.ch/v1/phishing/url-expand \
-H "Authorization: Bearer sk-dfir-your-key-here" \
-H "Content-Type: application/json" \
-d '{
"url": "https://bit.ly/3xYzAbC"
}'Python
import requests
response = requests.post(
"https://api.dfir-lab.ch/v1/phishing/url-expand",
headers={
"Authorization": "Bearer sk-dfir-your-key-here",
"Content-Type": "application/json",
},
json={
"url": "https://bit.ly/3xYzAbC"
},
)
result = response.json()
data = result["data"]
meta = result["meta"]
print(f"Final URL: {data['finalUrl']}")
print(f"Hops: {data['hopCount']}")
print(f"Suspicious: {data['suspicious']}")
print(f"Credits remaining: {meta['credits_remaining']}")
for i, hop in enumerate(data["hops"], 1):
print(f" {i}. [{hop['statusCode']}] {hop['url']}")Example Response
Standard redirect chain (not suspicious)
{
"data": {
"originalUrl": "https://bit.ly/3xYzAbC",
"finalUrl": "https://www.example.com/landing-page?ref=campaign",
"hopCount": 2,
"suspicious": false,
"redirectLoop": false,
"hops": [
{
"url": "https://bit.ly/3xYzAbC",
"statusCode": 301,
"server": "bit.ly",
"location": "https://www.example.com/landing-page?ref=campaign"
},
{
"url": "https://www.example.com/landing-page?ref=campaign",
"statusCode": 200,
"server": "nginx",
"location": null
}
]
},
"meta": {
"request_id": "req_a1b2c3d4-...",
"credits_used": 1,
"credits_remaining": 486,
"processing_time_ms": 823
}
}Suspicious redirect chain (>3 hops)
{
"data": {
"originalUrl": "https://t.co/aB1cD2eF3g",
"finalUrl": "https://phishing-site.example.com/login",
"hopCount": 5,
"suspicious": true,
"redirectLoop": false,
"hops": [
{
"url": "https://t.co/aB1cD2eF3g",
"statusCode": 301,
"server": "tsa_b",
"location": "https://shortener2.example.com/r/abc123"
},
{
"url": "https://shortener2.example.com/r/abc123",
"statusCode": 302,
"server": "cloudflare",
"location": "https://redirect3.example.net/go?u=xyz"
},
{
"url": "https://redirect3.example.net/go?u=xyz",
"statusCode": 302,
"server": "Apache/2.4",
"location": "https://tracker.example.org/click?id=9876"
},
{
"url": "https://tracker.example.org/click?id=9876",
"statusCode": 301,
"server": "openresty",
"location": "https://phishing-site.example.com/login"
},
{
"url": "https://phishing-site.example.com/login",
"statusCode": 200,
"server": "nginx",
"location": null
}
]
},
"meta": {
"request_id": "req_e5f6g7h8-...",
"credits_used": 1,
"credits_remaining": 485,
"processing_time_ms": 2147
}
}