So which is it? URI or URL?
I wrote this page because I kept forgetting the answers to questions like "What's the difference between a URI and a URL? What's a URN again? Was that part called the 'base url' or was it called the 'root url'?" and so on.
If you're determined to find the correct words to break down the components of a URI, it ends up being way harder than you'd think, because it's so hard to be sure the answer you find was correct is still correct. The right answer keeps changing! RFC 1630 defines the syntax for Uniform Resource Identifiers (URIs)s and RFC 1738 defines the syntax for Uniform Resource Locators (URLs), but it didn't stay that way, here, because RFC 1808 is adds a syntax for Relative URLs and RFC 2396 updates the syntax for the URIs defined in RFC 1808 and RFC 1738. This wasn't the only update either. RFC 2732 updates the syntax for URIs once again. At this point, it's such a mess, so RFC 3986 is written to restore order and declare a definitive syntax.
Don't dive down the rabbit hole yet (or ever, honestly.) Because if you open up RFC 3986 you'll find that at the top of page one, RFC 3986 itself ends up being updated by publications later on like RFC 6874, RFC 7320, and RFC 8820. It turns out, these updates don't really update the syntax much (if at all), they're moreso clarifications made about some of the more ambiguous parts of RFC 3986 and general guidelines for the people reading it. As far as I know, RFC 3986 is still the ultimate "source of truth" for this topic.
But at the end of the day, anybody reading this got here from a Google search isn't here to read through an entire RFC publication. I wrote this page so that I'd never have to read through it (again), but I will be quoting it extensively.
Uniform Resources

There are three types of uniform resources
- Uniform Resource Identifiers (URIs)
- Uniform Resource Locators (URLs)
- Uniform Resources Names (URNs)
The syntax of a URI
Every URI consists of a hierarchical sequence of five components
schemeauthoritypathqueryfragment
These components can be seen in the diagram below
scheme authority path query fragment
┌┴──┐ ┌───┴───┐┌───────┴────────┐ ┌───────────┴─────────┐ ┌───┴────┐
https://127.0.0.1/dir/path/file.txt?key1=value1&key2=value2#anchor-tag
└─────────────────────────────────┬────────────────────────────────────┘
URI
| Component | Value |
|---|---|
| Scheme | https |
| Authority | 127.0.0.1 |
| Path | /dir/path/file.txt |
| Query | key1=value1&key2=value2 |
| Fragment | anchor-tag |
Scheme
The scheme component declares which protocol is to be used. For instance, on the web, the scheme https in the URI https://helpful.wiki specifies HTTPS as the application transfer protocol. To learn more, I recommend taking a look at Wikipedia's List of URI schemes.
Authority
The
authoritycomponent has three subcomponentsuserinfohostport
userinfo host port
┌─────┴─────┐ ┌──────┴─────┐ ┌──┐
ssh://user:password@sub.domain.tld:1337
└────────────────┬──────────────┘
authority
userinfo
The
userinfocomponent, part of theauthoritycomponent, itself has two subcomponentsusernamepassword
username password
┌┴─┐┌──┴────┐
ssh://user:password@127.0.0.1:1337
└──────┬────┘ └───┬───┘ └┬─┘
userinfo host port
host
The
hostcomponent, part of theauthoritycomponent, takes three forms- Registered Name
- IPv4 Address, denoted in dotted-decimal form (the formal name for the familiar
#.#.#.#convention) - IPv6 Address, surrounded by square brackets (e.g.:
[::1])
Example of a host identified by its registered name
sub.domain.com:registered name ┌──────┴─────┐ https://sub.domain.com └─────┬──────┘ hostExample of a host identified by its IPv4 address:
IPv4 address ┌───┴───┐ https://127.0.0.1/index.html └───┬───┘ hostExample of a host identified by its IPv6 address, surrounded in
[square brackets]:IPv6 address ┌─────────────────┴───────────────────┐ http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html └─────────────────┬─────────────────────┘ hostAccording to RFC 3986, the port is not part of the host
For HTTP requests...
Services in the name of one host can be provided by many servers, which have different IP addresses.
One server, with one IP address, can provide services in the name of many hosts. This is known as virtual hosting
Host names are mapped to IP addresses by a server known as a DNS server, or domain name server. DNS stands for Domain Name Service. In a large network, many DNS servers may collaborate to provide the mapping between host names and IP addresses.
This is the general format:
https://app.website.com/path/?key1=val1&key2=val2
Network devices
Nodes
A node refers to any device that participates in a network. Valid examples of nodes include modems, switches, and hosts.
Hosts
A host is a computer connected to a network, including the Internet. A host that is connected to the Internet has one or more IP addresses assigned to it. A host is a type of node, one that participates in user applications. either as a server, client, or both.
Servers
A server is a type of host that offers resources to the other hosts.
Domain names
The domain name consists of one or more parts. Each of these parts is called a label, and they are concatenated together, delimited with the dot . character.
For instance, the domain name api.website.com is made of three labels:
apiexamplecom
Subdomains
A subdomain is a subtree within a domain. The name of a subdomain will include the name of the domain it belongs to. For example, www.example.com is a subdomain of the example.com domain. What many don't realize is that example.com is also a subdomain! It's a subdomain of the of com top level domain. All domains are a subdomain of root. The domain name api.website.com is the subdomain of the website.com.
Fully qualified domain names
Although in practice it is often omitted, this domain name is still a partially qualified domain name, even though it includes the .com top level domain. The reason is, it's missing the root level domain, specified by the zero-length root label. The the trailing . in example.com. tells the DNS server that the domain name provided is an fully qualified domain name, all the way up to the root domain. In practice, though it can be explicit, as shown in example.com., more often than not, a DNS will not get tripped up by an implicit fully qualified domain name, such as sub.domain.tld.
The second-level domain (SLD) would be
examplefor the URLexample.comThe subdomain would be
appfor the URLapp.product.net
root domain name
┌────┴───┐
https://sub.domain.net/dir/path/doc.html
└┬┘ └─┬──┘ └┬┘
subdomain SLD TLD
username password fully qualified domain name
┌┴─┐┌──┴────┐ ┌─────┴──────┐
sftp://user:password@sub.domain.tld:1337
└──────┬────┘ └─────┬──────┘ └─┬─┘
userinfo host port
URI prefix authority
┌──┴──┐┌──────────────┴────────────────┐
sftp://user:password@sub.domain.tld:1337/dir/path/doc.html
└─────────────────┬────────────────────┘
host
Some additional examples of URIs are included below:
userinfo host port
┌──┴───┐ ┌──────┴──────┐ ┌┴┐
https://ttrojan@www.example.com:123/forum/questions/?tag=networking&order=newest#top
└─┬─┘ └───────────┬──────────────┘└───────┬───────┘ └───────────┬─────────────┘ └┬┘
scheme authority path query fragment
mailto:ttrojan@example.com
└─┬──┘ └────┬─────────────┘
scheme path
tel:+1-816-555-1212
└┬┘ └──────┬──────┘
scheme path
telnet://192.0.2.16:80/
└─┬──┘ └─────┬─────┘└┘
scheme authority path
Public suffixes
RFC 8499 defines a public suffix as follows:
A domain that is controlled by a public registry.
An alternative definition: a domain under which subdomains can be registered by third parties.
The public suffix is sometimes called the effective top-level domain, or eTLD.
A registered domain is one layer below an eTLD — which is where the term eTLD+1 gets its name.
Sockets
A network socket is externally identified to other hosts by its socket address, which is the triad of transport protocol, IP address, and port number.
A socket address is a tuple consisting of three elements
- transport protocol (e.g.
TCP) - IP address (e.g.
127.0.0.1) - port number (e.g.
80)
- transport protocol (e.g.
Socket pairs
Communicating local and remote sockets are called socket pairs. Each socket pair is described by a unique tuple consisting of 4 elements 1. source IP 1. source port number 1. destination IP 1. destination port number
In other words, a socket pair consists of two socket addresses, one local, and one remote.
REST APIs
Base URLs
Every endpoint within an API contains a path relative to a particular base URL, such as https://api.getpostman.com.
https://api.example.com/v1/users
└──────────┬──────────┘
base URL
Loopback Addresses
Sometimes localhost will not be aliased to your computer, and you'll have to manually specify a loopback address when directing your requests to an API.
A client could reach a server running locally on IPv4 address 127.0.0.1, listening on port 443 by making an HTTPS request for the file index.html using the following URL:
https://127.0.0.1:443/index.html
A client could reach a server running locally on IPv6 address ::1 listening on port 443, making an HTTPS request for the file index.html using the following URL:
URI Schemes
The facetime: URI scheme
The facetime:// URL scheme can be used to initiate a FaceTime call to a specified user. You can use the phone number or email address of a user to initiate the call. When a user taps a FaceTime link in a webpage, iOS confirms that the user really wants to initiate a FaceTime call before proceeding. When an app opens a URL with the facetime scheme, iOS opens the FaceTime app and initiates the call without prompting the user. When opening FaceTime URLs on macOS, the system always prompts the user before initiating a call.
You can specify FaceTime links explicitly in both web and native iOS apps using the facetime:// URL scheme. The following examples show the strings formatted for Safari and for a native app:
Making a FaceTime video call directed to a particular phone number:
Making a FaceTime video call directed to a particular Apple ID:
The facetime-audio: URI scheme
Similarly, you can use the facetime-audio:// URL scheme to initiate a FaceTime audio call.
Making a FaceTime Audio call directed to a particular phone number:
Making a FaceTime Audio call directed to a particular phone number:
The file: URI scheme
- Example of a URI specifying a resource on the local host
file:/Users/ttrojan/Downloads/file.txt
└┬─┘ └───────┬───────────────────────┘
scheme path
The podcast:// URL scheme
You can create a link that directs the user to the Podcasts app, whether they are on iOS, iPadOS, or macOS. You can subscribe to a podcast's RSS feed using the podcast://RSS_FEED URL scheme. For example:
podcast://feeds.99percentinvisible.org/99percentinvisible
The messages: URI scheme
A link that begins drafting an iMessage to recipient +1-555-123-4567 can be created by clicking on the following link:
The sms: URI scheme
The sms: URI scheme can be used in exactly the same way as messages: and tel:, as long as you specify the recipient's phone number, not an email address.
A link that begins drafting a text message to recipient +1-555-123-4567 can be created by clicking on the following link:
The mailto: URI scheme
You can create a link to a user where, when they click on it, the subject and body are pre-populated
mailto:RECIPIENT?subject=SUBJECT&body=BODY
Replace the following, being sure to percent encoded values as necessary
- RECIPIENT:
ttrojan@usc.edu - SUBJECT:
Breaking%20news - BODY:
You%20are%20a%20hacker
The message: URL scheme
Linking to existing emails
In the macOS Mail app, go to Preferences -> Viewing -> Show message headers -> Custom... and add a new entry: Message-ID. Now, whenever you view an email, you'll see the message ID below the typical To:, From:, etc. displayed below the message subject.
To create a link to a message, right click the message ID, select Copy, open up Terminal, and run the following command:
email="message:%3c$(pbpaste)%3e"
print ${email}
pbcopy < =(<<<${email})
The commands above URL encode the angle brackets that must surround a message ID. This is an arbitrary specification of the message: URL scheme. To add the angle brackets that surround the < message ID >, you'll have to add the URL encoded strings %3c and %3e to the beginning and ending of the path respectively. In your terminal, you could do so using the following command:
The tel: URI scheme
The tel: URI scheme is as simple as they come. Clicking on a link will call the number supplied by the URI.
For instance, one can make a call to +1-555-123-4567 using the following URI:
The sms: URI scheme
The sms: URI scheme is as simple as they come. Look at the following example to better understand the syntax. Clicking on the hyperlink will prompt the user to compose a new text message to +1-555-123-4567:
The maps: URI scheme
Apple doesn't actually provide a dedicated URL scheme to create links that open in the Maps app. However, the functionality can be replicated with HTTPS hyperlinks to maps.apple.com.
Consider, for example, the following address:
120 Beach St
Santa Cruz, CA
You can create a URI that points to this address within Maps by providing the address=ADDRESS query parameter, as shown below:
https://maps.apple.com/?address=120%20Beach%20St,%20Santa%20Cruz,%20CA
The shortcuts: URI scheme
Opening and creating shortcuts
The Shortcuts URL scheme allows you to open the app, create, run, or edit a shortcut, and interact with the Gallery in the Shortcuts app, from anywhere.
You can even open the Shortcuts app itself using a URL scheme. The hyperlink shortcuts://, by itself, will open the Shortcuts app, displaying the state when it was last used beforehand.
There's even a shortcut to create shortcuts: shortcuts://create-shortcut creates a new shortcut, and jumps directly to the shortcut editor.
You can launch the app to a particular shortcut in your collection. A hyperlink such as shortcuts://open-shortcut?name=NAME will open up Shortcuts directly to the shortcut with a title of NAME.
To learn more, see Open and create a shortcut using a URL scheme on iPhone or iPad
Running shortcuts
You can run a shortcut using a URL scheme as well, like this:
shortcuts://run-shortcut?name=NAME&input=INPUT&text=TEXT
Use the following parameters in the URL:
name: The name of the shortcut to run.input(optional): The initial input into the shortcut. There are two input options: the keywordtextor the keywordclipboard. When the input value is atext, the value of the query parametertextis used. When the input value isclipboard, the contents of the Clipboard are used.text: If input is set totext, then value of thetextparameter is passed as input to the shortcut. If input is set toclipboard, then this parameter is ignored.
By using a text string, you can provide your own URL-encoded text as input to the shortcut. For example, a URL that uses the text Hello World as input to a shortcut named Create PDF would resemble the following:
shortcuts://run-shortcut?name=Create%20PDF&input=text&text=Hello%20World
Similarly, a URL to transfer the most recently copied text into a shortcut called Add to Notes would look like this:
shortcuts://run-shortcut?name=Add20%to20%Notes&input=clipboard
To learn more, see Run a shortcut using a URL scheme on iPhone or iPad
Searching the Shortcuts Gallery
You can open or search the Shortcuts Gallery using a URL scheme.
You can reach the Shortcuts Gallery by visiting shortcuts://gallery, which will take you there directly.
To search the Shortcuts Gallery from a URL, use the following structure:
shortcuts://gallery/search?query=QUERY
Where QUERY is the URL-encoded keywords to be searched in the Gallery.
For example, if you want to send someone a link to explore shortcuts for photos available in the Gallery, you would instruct them to open shortcuts://gallery/search?query=photos
To learn more, see Open or search the Shortcuts Gallery using a URL scheme on iPhone or iPad
The slack:// URL scheme
Reference: Deep Linking in Slack
slack://open
Here's the process to find the "Workspace ID" for a Slack workspace:
- Grab the domain name for a particular workspace
- Visit that URL in your web browser: (e.g.:
example-team.slack.com) - Copy the Workspace ID that the URL converts it to (e.g.:
T2G8RTHAM)
Now, you can create a link to your user profile within that workspace:
Go back to Slack, go to your DMs with yourself, copy the channel ID
Craft the following URL:
slack://user?team={{WORKSPACE_ID}}&id=CHANNEL_IDFor example:
slack://user?team=T28RTGHAM&id=DHU2E6LGK
Using HTTPS to link to a Slack channel
Using a CHANNEL_NAME
https://slack.com/app_redirect?channel=CHANNEL_NAMEThe channel can be either the name of a channel, such as
threat-huntersor the ID of the channel,
https://slack.com/app_redirect?channel=C0VD1QBZB
Discord
Discord links can use either the https:// URL scheme to open links within a web browser, but additionally, you can use the discord:// URL scheme to open links within the Discord app. Interestingly, this feature does not seem to be documented by Discord...
This is the general structure:
https://discord.com/channels/SERVER_ID/CHANNEL_ID
Here is a concrete example:
Linking to a channel within a Discord server: (
#welcomein this example))discord://discord.com/channels/407970595418931200/721077130456203335- SERVER_ID:
407970595418931200 - CHANNEL_ID:
721077130456203335
- SERVER_ID: