POST
/api/v1/url
Check a link
One address on its own: is it shaped like something pretending to be somewhere else.
One address, judged as an address. A different question from moderating a message that contains a link: not "is this an advert" but "is this trying to look like somewhere it is not".
curl https://toxicfilter.com/api/v1/url \
-H "Authorization: Bearer tf_live_..." \
-H "Content-Type: application/json" \
-d '{ "url": "https://paypal.com@login-secure.example/verify", "reference": "link_88" }'
{
"decision": "block",
"flagged": ["scam"],
"signals": [
{ "category": "scam", "score": 0.9, "detector": "url",
"reason": "The address has a username in front of the host, so it opens somewhere other than the name a reader sees." }
]
}
What it looks at
| Shape | |
|---|---|
| Credentials before the host | https://paypal.com@evil.example/ goes to evil.example. The part people read and the part that decides are different, which is the oldest trick there is and still the best. |
| A brand that is not the brand | paypal.com.secure-login.example. Configured, not guessed; see below. |
| Punycode | xn--pypal-4ve.com renders as something else entirely. |
| Bare IP addresses | Legitimate services have names. |
| Deep subdomains | Five labels is how the real domain gets pushed off the end of a phone's address bar. |
| Shorteners | Not bad in themselves, since half the internet posts them, but a shortened link is an unanswered question. |
| Throwaway endings | .zip and .mov especially: they are file extensions, so invoice.zip is both a filename and a domain. |
It never fetches anything. No request to the address, no redirect chain followed, no reputation service asked. So it can tell you an address is shaped like a trick, and it can never tell you a domain is malicious. A clean answer means "this looks like what it says it is", not "this is safe". Treat it as one signal among yours, not as a verdict on the destination.
Whose brands
The impersonation check is configuration and starts empty, because who gets impersonated depends entirely on who you are. A Spanish marketplace cares about Correos, BBVA and Wallapop; a bank cares about itself; nobody cares about a list of American brands their users have never heard of. Each entry is a word to look for in the host and the domains allowed to contain it.
It also works as a batch item:
{"kind": "url", "url": "..."}. Priced as the cheap call, and it never
reaches a model: there is nothing in an address for one to read.
ai is accepted here only as false, for callers who send the
same body shape everywhere. "ai": true is refused with
422 ai_unavailable rather than accepted and quietly ignored, which would be
a model call priced by the quota check and never made. Same on
an address and
a name.
reference, policy, actor and
rules work here as
they do on every other endpoint.