URL canonicalizer and lookalike-host check
Canonicalizes up to 50 absolute http(s) URLs for an agent about to fetch, dedupe or click them: WHATWG-parsed lowercase host, default port and fragment and userinfo removed, dot segments and unreserved percent-escapes normalized, tracking parameters (utm_*, gclid, fbclid and the Mozilla strip list plus yours) removed, and flags userinfo@host tricks, backslash and multiple-@ authorities, obfuscated IPv4 hosts, xn-- labels (decoded to Unicode, invalid or ASCII-only punycode, mixed-script hosts via the Unicode safety rules) and open-redirect-shaped parameters (next=, redirect=, url= pointing off-site or at //host or javascript:). Does NOT resolve DNS, fetch anything, follow redirects, or decide that a site is safe; registrable domains use a public-suffix SUBSET plus any suffixes you supply.
What you get
Catches the URL that reads as one site and loads another, and gives stable keys for dedupe, 50 URLs per $0.005 call.
Call it
Send the JSON body below to https://agents.writerslogic.com/api/v1/url-canonicalize. An unpaid request answers 402 with the price and how to pay; a request that fails with a 5xx status is not charged.
curl -i -X POST https://agents.writerslogic.com/api/v1/url-canonicalize \
-H 'content-type: application/json' \
-d '{"urls":["HTTPS://Example.COM:443/a/./b/%7Efoo?utm_source=x&id=7&gclid=abc#top","https://paypal.com@evil.example/login","https://xn--pple-43d.com/","https://shop.example/login?next=https://evil.example/steal"]}'
Input
| Field | Type | Required | Description |
|---|---|---|---|
urls | array<string; length 0..2048>; max 50 items | yes | Absolute URLs including the scheme. |
extraTrackingParams | array<string; length 0..64>; max 50 items | no | Extra query parameter names to strip (case-insensitive). |
sortQuery | boolean | no | Sort remaining query segments for a dedupe key. Off by default: order can matter to servers. |
publicSuffixes | array<string; length 0..100>; max 200 items | no | Extra public suffixes (e.g. "co.xx") used for registrable-domain decisions. |
Example request body
{
"urls": [
"HTTPS://Example.COM:443/a/./b/%7Efoo?utm_source=x&id=7&gclid=abc#top",
"https://paypal.com@evil.example/login",
"https://xn--pple-43d.com/",
"https://shop.example/login?next=https://evil.example/steal"
]
}
Result
The response is { "data": ..., "_provenance": ... }. data carries these fields; _provenance is a signed W3C Verifiable Credential with a C2PA-style manifest, checked free at POST /api/v1/verify-provenance.
| Field | Type | Required | Description |
|---|---|---|---|
status | string; one of "pass", "fail", "unknown", "unsupported" | no | pass: every rule held. fail: a rule was violated (see witnesses). unknown: the input lacks the evidence to decide. unsupported: outside what this engine covers. Missing evidence is never a pass. |
items | array<object> | no | |
riskCount | integer | no | Number of items with at least one risk finding. |
witnesses | array<object> | no | |
versions | object | no | Every semantic dependency of this answer (engine, tables and their as-of dates, tokenizer, calendar, rounding profile). |
limits | array<string> | no | |
deterministic | boolean | no | Always true: pure code, no model. |
Pay and connect
Available through: x402 (USDC on Base), MCP. MCP clients reach it through the infra-preflight-kit package.
Machine-readable
- This agent as JSON (schemas, example, OpenAPI operation)
- Free signed sample response
- OpenAPI 3.1 · Catalog · Index of every agent