{"openapi":"3.0.3","info":{"title":"URL Normalizer & Tracking Parameter Stripper API","version":"1.0.0","description":"Canonicalizes URLs, removes 50+ UTM and ad click-ID tracking parameters, detects URL shorteners, and optionally unrolls redirects via the SSRF-isolated fetcher."},"servers":[{"url":"https://api.tinplate.dev","description":"Production Edge Gateway"}],"components":{"schemas":{"UrlNormalizeResponseData":{"type":"object","properties":{"valid":{"type":"boolean","example":true},"original_url":{"type":"string"},"normalized_url":{"type":"string","nullable":true,"example":"https://www.example.com/blog/post?a=1&b=2"},"components":{"type":"object","nullable":true,"properties":{"scheme":{"type":"string"},"hostname":{"type":"string"},"port":{"type":"string","nullable":true},"pathname":{"type":"string"},"query":{"type":"object","additionalProperties":{"type":"string"}},"fragment":{"type":"string","nullable":true}},"required":["scheme","hostname","port","pathname","query","fragment"]},"is_shortener":{"type":"boolean","example":false},"unrolled":{"type":"boolean","example":false},"redirect_hops":{"type":"integer","minimum":0,"example":0},"stripped_params":{"type":"array","items":{"type":"string"},"example":["utm_source","fbclid"]},"ssrf_safe":{"type":"boolean","example":true},"error":{"type":"string","nullable":true,"example":null}},"required":["valid","original_url","normalized_url","components","is_shortener","unrolled","redirect_hops","stripped_params","ssrf_safe","error"]},"UrlNormalizeRequest":{"type":"object","properties":{"url":{"type":"string","minLength":1,"maxLength":8192,"example":"HTTPS://WWW.Example.com:443/blog/post/?utm_source=newsletter&b=2&fbclid=IwAR123&a=1#section-2","description":"URL to canonicalize and strip tracking parameters from."},"strip_tracking":{"type":"boolean","default":true,"example":true,"description":"Strip UTM, click-ID (fbclid, gclid, msclkid, etc.), and email tracking parameters."},"custom_strip_params":{"type":"array","items":{"type":"string","minLength":1,"maxLength":128},"maxItems":100,"description":"Additional query parameter names to remove (case-insensitive)."},"sort_query":{"type":"boolean","default":true,"example":true,"description":"Sort remaining query parameters alphabetically by key."},"strip_fragment":{"type":"boolean","default":true,"example":true,"description":"Remove URL hash fragment (#...)."},"strip_www":{"type":"boolean","default":false,"example":false,"description":"Remove leading 'www.' subdomain."},"strip_trailing_slash":{"type":"boolean","default":true,"example":true,"description":"Remove trailing slash from non-root paths (/blog/post/ -> /blog/post)."},"force_https":{"type":"boolean","default":false,"example":false,"description":"Upgrade http:// scheme to https://."},"resolve_shorteners":{"type":"boolean","default":false,"example":false,"description":"If true, resolves redirects via the SSRF-isolated fetcher Worker before normalizing."}},"required":["url"]},"ResponseMeta":{"type":"object","required":["request_id"],"properties":{"request_id":{"type":"string","format":"uuid"},"ms":{"type":"integer","minimum":0},"version":{"type":"string","example":"1.0.0"}}},"ErrorEnvelope":{"type":"object","required":["ok","error","meta"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","example":"invalid_input"},"message":{"type":"string","example":"Request body failed validation"}}},"meta":{"$ref":"#/components/schemas/ResponseMeta"}}}},"parameters":{}},"paths":{"/v1/url-normalizer":{"post":{"tags":["21_URL_NORMALIZER"],"summary":"Canonicalize a URL, strip tracking parameters, and optionally unroll shortlinks","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UrlNormalizeRequest"}}}},"responses":{"200":{"description":"Canonicalized URL, parsed components, stripped tracking params, and SSRF status","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[true]},"data":{"$ref":"#/components/schemas/UrlNormalizeResponseData"},"meta":{"$ref":"#/components/schemas/ResponseMeta"}},"required":["ok","data","meta"]}}}},"400":{"description":"Invalid input or malformed JSON request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid authentication credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"413":{"description":"Request payload exceeds subscribed plan byte cap","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}}}}