Skip to main content

URL Parser and Resolver API

REAL DATA

Parse absolute URLs or resolve relative references with the WHATWG URL algorithm — canonical hosts, ordered query pairs and no credential leakage.

Authoritative reference data or standards computation

Base URL
/api/urls
Capabilities
2 routes
Last updated
July 30, 2026
Data source

GET /api/urls/parse

Live requestRuns against the public API
No key required
GET/api/urls/parse?url=https%3A%2F%2Fexample.com%3A443%2Fdocs%3Fq%3Done%26q%3Dtwo%23api

Request parameters

Absolute URL to parse, up to 2048 characters. Credentials are detected but removed from all echoed URL values.

Advanced response options4 options

Return only these fields (comma-separated). Mutually exclusive with 'exclude'.

Return all fields except these (comma-separated).

Pretty-print the JSON response.

Drop the envelope: return the raw array/object without data/meta wrapper.

Response

Example parameters are ready. Send the request to inspect the live response.

Route reference

Code samples Ready-to-copy requests in 4 languages
Choose a code sample language
curl "https://randomapi.dev/api/urls/parse?url=https%3A%2F%2Fexample.com%3A443%2Fdocs%3Fq%3Done%26q%3Dtwo%23api"
const res = await fetch("https://randomapi.dev/api/urls/parse?url=https%3A%2F%2Fexample.com%3A443%2Fdocs%3Fq%3Done%26q%3Dtwo%23api");
const { data, meta } = await res.json();
import requests

data = requests.get("https://randomapi.dev/api/urls/parse?url=https%3A%2F%2Fexample.com%3A443%2Fdocs%3Fq%3Done%26q%3Dtwo%23api").json()["data"]
$json = json_decode(file_get_contents(
  "https://randomapi.dev/api/urls/parse?url=https%3A%2F%2Fexample.com%3A443%2Fdocs%3Fq%3Done%26q%3Dtwo%23api"
), true);
$data = $json["data"];
Parameters Route-specific request inputs 1
url string required

Absolute URL to parse, up to 2048 characters. Credentials are detected but removed from all echoed URL values.

allowed: 1 – 2048
example: url=https://example.com:443/docs?q=one&q=two#api
Universal parameters Shared response and formatting options 4
fields list

Return only these fields (comma-separated). Mutually exclusive with 'exclude'.

example: fields=href,origin
exclude list

Return all fields except these (comma-separated).

example: exclude=hasCredentials
pretty boolean

Pretty-print the JSON response.

default: false
example: pretty=true
unwrap boolean

Drop the envelope: return the raw array/object without data/meta wrapper.

default: false
example: unwrap=true
Response schema Fields returned in each record 9
href string (URL)

Canonical absolute URL with username and password removed.

example: https://example.com/docs?q=one&q=two#api

origin string

Serialized URL origin; 'null' for schemes without an origin.

example: https://example.com

protocol string

Lowercase scheme including its trailing colon.

example: https:

hostname string

Canonical hostname; Unicode domains use ASCII/punycode and IPv6 retains brackets.

example: example.com

port string

Explicit non-default port, or an empty string when absent/default.

example:

pathname string

Serialized URL path.

example: /docs

query object[]

Decoded `{name,value}` pairs in source order, preserving duplicate names.

example: [{"name":"q","value":"one"},{"name":"q","value":"two"}]

hash string

Serialized fragment including '#', or an empty string.

example: #api

hasCredentials boolean

Whether the input contained a username or password before safe removal.

example: false

Documented examples

Build-generated requests and complete responses
3
Canonicalize a URL and preserve duplicate query names
GET /api/urls/parse?url=https%3A%2F%2Fexample.com%3A443%2Fdocs%3Fq%3Done%26q%3Dtwo%23api
{
  "data": {
    "href": "https://example.com/docs?q=one&q=two#api",
    "origin": "https://example.com",
    "protocol": "https:",
    "hostname": "example.com",
    "port": "",
    "pathname": "/docs",
    "query": [
      {
        "name": "q",
        "value": "one"
      },
      {
        "name": "q",
        "value": "two"
      }
    ],
    "hash": "#api",
    "hasCredentials": false
  },
  "meta": {
    "endpoint": "urls",
    "route": "/parse",
    "params": {
      "url": "https://example.com/docs?q=one&q=two#api"
    },
    "generatedAt": "2026-07-30T15:14:08.000Z"
  }
}
Parse a Unicode hostname
GET /api/urls/parse?url=https%3A%2F%2Fm%C3%BCnich.example%2Fcaf%C3%A9
{
  "data": {
    "href": "https://xn--mnich-kva.example/caf%C3%A9",
    "origin": "https://xn--mnich-kva.example",
    "protocol": "https:",
    "hostname": "xn--mnich-kva.example",
    "port": "",
    "pathname": "/caf%C3%A9",
    "query": [],
    "hash": "",
    "hasCredentials": false
  },
  "meta": {
    "endpoint": "urls",
    "route": "/parse",
    "params": {
      "url": "https://xn--mnich-kva.example/caf%C3%A9"
    },
    "generatedAt": "2026-07-30T15:14:08.000Z"
  }
}
Inspect an IPv6 URL
GET /api/urls/parse?url=http%3A%2F%2F%5B2001%3Adb8%3A%3A1%5D%3A8080%2Fhealth
{
  "data": {
    "href": "http://[2001:db8::1]:8080/health",
    "origin": "http://[2001:db8::1]:8080",
    "protocol": "http:",
    "hostname": "[2001:db8::1]",
    "port": "8080",
    "pathname": "/health",
    "query": [],
    "hash": "",
    "hasCredentials": false
  },
  "meta": {
    "endpoint": "urls",
    "route": "/parse",
    "params": {
      "url": "http://[2001:db8::1]:8080/health"
    },
    "generatedAt": "2026-07-30T15:14:08.000Z"
  }
}

GET /api/urls/resolve

Live requestRuns against the public API
No key required
GET/api/urls/resolve?base=https%3A%2F%2Fexample.com%2Fdocs%2Fguides%2Fstart&relative=..%2Fapi%3Fformat%3Djson

Request parameters

Absolute base URL, up to 2048 characters. Credential-bearing bases are rejected.

Relative or absolute URL reference, up to 2048 characters. Credential-bearing results are rejected.

Advanced response options4 options

Return only these fields (comma-separated). Mutually exclusive with 'exclude'.

Return all fields except these (comma-separated).

Pretty-print the JSON response.

Drop the envelope: return the raw array/object without data/meta wrapper.

Response

Example parameters are ready. Send the request to inspect the live response.

Route reference

Code samples Ready-to-copy requests in 4 languages
Choose a code sample language
curl "https://randomapi.dev/api/urls/resolve?base=https%3A%2F%2Fexample.com%2Fdocs%2Fguides%2Fstart&relative=..%2Fapi%3Fformat%3Djson"
const res = await fetch("https://randomapi.dev/api/urls/resolve?base=https%3A%2F%2Fexample.com%2Fdocs%2Fguides%2Fstart&relative=..%2Fapi%3Fformat%3Djson");
const { data, meta } = await res.json();
import requests

data = requests.get("https://randomapi.dev/api/urls/resolve?base=https%3A%2F%2Fexample.com%2Fdocs%2Fguides%2Fstart&relative=..%2Fapi%3Fformat%3Djson").json()["data"]
$json = json_decode(file_get_contents(
  "https://randomapi.dev/api/urls/resolve?base=https%3A%2F%2Fexample.com%2Fdocs%2Fguides%2Fstart&relative=..%2Fapi%3Fformat%3Djson"
), true);
$data = $json["data"];
Parameters Route-specific request inputs 2
base string required

Absolute base URL, up to 2048 characters. Credential-bearing bases are rejected.

allowed: 1 – 2048
example: base=https://example.com/docs/guides/start
relative string required

Relative or absolute URL reference, up to 2048 characters. Credential-bearing results are rejected.

allowed: 1 – 2048
example: relative=../api?format=json
Universal parameters Shared response and formatting options 4
fields list

Return only these fields (comma-separated). Mutually exclusive with 'exclude'.

example: fields=base,relative
exclude list

Return all fields except these (comma-separated).

example: exclude=origin
pretty boolean

Pretty-print the JSON response.

default: false
example: pretty=true
unwrap boolean

Drop the envelope: return the raw array/object without data/meta wrapper.

default: false
example: unwrap=true
Response schema Fields returned in each record 4
base string (URL)

Canonical absolute base URL.

example: https://example.com/docs/guides/start

relative string

Relative reference exactly as interpreted after surrounding whitespace is trimmed.

example: ../api?format=json

resolved string (URL)

Canonical absolute result of WHATWG URL resolution.

example: https://example.com/docs/api?format=json

origin string

Origin of the resolved URL.

example: https://example.com

Documented examples

Build-generated requests and complete responses
3
Resolve a parent-directory link
GET /api/urls/resolve?base=https%3A%2F%2Fexample.com%2Fdocs%2Fguides%2Fstart&relative=..%2Fapi%3Fformat%3Djson
{
  "data": {
    "base": "https://example.com/docs/guides/start",
    "relative": "../api?format=json",
    "resolved": "https://example.com/docs/api?format=json",
    "origin": "https://example.com"
  },
  "meta": {
    "endpoint": "urls",
    "route": "/resolve",
    "params": {
      "base": "https://example.com/docs/guides/start",
      "relative": "../api?format=json"
    },
    "generatedAt": "2026-07-30T15:14:08.000Z"
  }
}
Resolve a root-relative link
GET /api/urls/resolve?base=https%3A%2F%2Fexample.com%2Fdocs%2F&relative=%2Fpricing%23teams
{
  "data": {
    "base": "https://example.com/docs/",
    "relative": "/pricing#teams",
    "resolved": "https://example.com/pricing#teams",
    "origin": "https://example.com"
  },
  "meta": {
    "endpoint": "urls",
    "route": "/resolve",
    "params": {
      "base": "https://example.com/docs/",
      "relative": "/pricing#teams"
    },
    "generatedAt": "2026-07-30T15:14:08.000Z"
  }
}
An absolute reference replaces the base
GET /api/urls/resolve?base=https%3A%2F%2Fexample.com%2Fdocs%2F&relative=https%3A%2F%2Fcdn.example.net%2Fasset.js
{
  "data": {
    "base": "https://example.com/docs/",
    "relative": "https://cdn.example.net/asset.js",
    "resolved": "https://cdn.example.net/asset.js",
    "origin": "https://cdn.example.net"
  },
  "meta": {
    "endpoint": "urls",
    "route": "/resolve",
    "params": {
      "base": "https://example.com/docs/",
      "relative": "https://cdn.example.net/asset.js"
    },
    "generatedAt": "2026-07-30T15:14:08.000Z"
  }
}

About this API

Coverage & behavior

Uses the same WHATWG URL model implemented by browsers and Cloudflare Workers. /parse canonicalizes an absolute URL into its origin, protocol, hostname, port, path, ordered query pairs and fragment. Duplicate query names are preserved in their original order.

Unicode hostnames are returned in their canonical ASCII/punycode representation, IPv6 hosts retain their brackets, and default ports are removed by the standard algorithm. Each input is capped at 2048 characters.

URLs containing user information are detectable through hasCredentials, but usernames and passwords are stripped from href and meta.params and are never returned. /resolve rejects credentials in either input, then resolves relative against the canonical absolute base.

Use it for

  • Normalize and inspect URLs before storing them in a crawler or CMS
  • Preserve duplicate query parameters while presenting them as structured JSON
  • Resolve links found in HTML against a document's absolute base URL

Frequently asked questions

Are duplicate query parameters preserved?

Yes. ?tag=one&tag=two returns two ordered { name, value } entries rather than collapsing them into one object property.

How are Unicode domains returned?

The WHATWG parser canonicalizes internationalized hostnames to their ASCII/punycode form, matching browser URL behavior.

Does the URL parser expose passwords?

No. /parse reports hasCredentials: true when user information was present, but strips the username and password from both the returned URL and meta.params; /resolve rejects credential-bearing inputs.

Can the resolve route work without an absolute base URL?

No. base is required and must itself be absolute; malformed or relative bases return a 400 naming the parameter.

Standards & references