Don't like ads? Go Ad-Free Today

URL Encoding What Gets Escaped and Why Your API Breaks Without It

Published on
URL Encoding: What Gets Escaped and Why Your API Breaks Without It 1
ADVERTISEMENT · REMOVE?

Your API call looked correct. The endpoint matched, the headers were right, and the response came back 400 Bad Request. After twenty minutes of staring at it, you spot the problem: an email address in the query string that contained a + sign — which the server decoded as a space. That is URL encoding in action, and it breaks things in ways that are genuinely hard to debug.

This guide covers what percent-encoding actually does, which characters need encoding in which contexts, the JavaScript trap everyone hits, and how to use a tool like the URL Encoder/Decoder to check your work.

What URL Encoding Actually Does

A URL can only contain a subset of ASCII characters. Everything else — spaces, international characters, symbols with special meaning in URLs — must be converted into a safe format before transmission.

Percent-encoding does this by replacing each unsafe byte with a percent sign followed by two hex digits. A space becomes %20, a hash becomes %23, a forward slash becomes %2F. The name comes from that leading percent sign.

The spec (RFC 3986) defines “unreserved characters” that never need encoding: letters (A–Z, a–z), digits (0–9), and four symbols: - _ . ~. Everything else is either a reserved character (used to delimit URL structure) or must be encoded.

The Characters That Break APIs

Here are the ones that cause the most damage in practice:

Character Encoded Contexts requiring encoding Notes
Space %20 All contexts Also encoded as + in form data — see below
& %26 Query string values Separates query params; must be encoded inside a value
= %3D Query string values Separates key from value; encode it in the value itself
+ %2B Query string values Decoded as space in form encoding — use %2B for a literal plus
# %23 Path, query string Marks the fragment; anything after it is never sent to the server
? %3F Path segments, query values Starts the query string; encode it in path or values
/ %2F Path segments (when literal) Separates path segments; encode it inside a segment value
@ %40 Query string values Email addresses in query params must have this encoded

Three Contexts, Different Rules

The part of the URL you are encoding changes what needs to be escaped.

Full URL — When you have a complete URL to pass around, you want to preserve its structure. Slashes, question marks, and hash signs stay as-is. Only characters outside the allowed set get encoded.

Query string value — This is where most API bugs live. Each value in a query string must be encoded so that the characters used to structure the query (&, =, #, +) cannot appear literally in the value. If the user’s name is “John & Jane”, the query string must read name=John%20%26%20Jane, not name=John & Jane (which the server parses as two separate parameters).

Path segment — A path segment is the part between slashes. If a segment contains a slash itself (a filename with a slash, for example), it must be encoded as %2F. Some servers treat %2F in a path as a security concern; know your backend before using this.

encodeURI vs encodeURIComponent — The JavaScript Trap

JavaScript gives you two built-in encoding functions, and using the wrong one is a very common bug.

// encodeURI — encodes a full URL
// Preserves: : / ? # [ ] @ ! $ & ' ( ) * + , ; =
encodeURI("https://example.com/search?q=hello world&lang=en")
// → "https://example.com/search?q=hello%20world&lang=en"
// Note: & and = are NOT encoded — the query structure is preserved

// encodeURIComponent — encodes a single value
// Encodes everything except: A-Z a-z 0-9 - _ . ! ~ * ' ( )
encodeURIComponent("hello world&lang=en")
// → "hello%20world%26lang%3Den"
// Note: & and = ARE encoded — safe to use as a query value

// The bug: using encodeURI on a value
encodeURI("hello world&lang=en")
// → "hello%20world&lang=en"  ← & survives! Server sees two parameters.

// The correct approach for building query strings
const name = "John & Jane"
const email = "john+jane@example.com"
const url = `https://api.example.com/users?name=${encodeURIComponent(name)}&email=${encodeURIComponent(email)}`
// → "https://api.example.com/users?name=John%20%26%20Jane&email=john%2Bjane%40example.com"

Rule of thumb: use encodeURIComponent on individual values before putting them in a URL. Use encodeURI only when you have a complete URL and want to clean it up without destroying its structure.

The + Sign: Form Encoding vs Percent Encoding

When an HTML form submits with method="GET", browsers encode the data using application/x-www-form-urlencoded. In this format, spaces become + instead of %20. Many server frameworks (PHP, Django, Rails) automatically decode + as a space in query strings.

This creates a problem when your value legitimately contains a plus sign — a phone number like +44 7700 900000. If you pass it as +44..., the server decodes the leading plus as a space and gets 44.... The fix is to encode a literal plus as %2B, which survives both decoding schemes intact.

For modern API work, stick to %20 for spaces (what encodeURIComponent produces) rather than relying on +.

Double-Encoding: When Encoding Goes Wrong

Double-encoding happens when you encode something that is already encoded. The percent sign in %20 itself gets encoded to %2520 — the server decodes %25 to a literal percent, giving you the string %20 instead of a space.

This typically surfaces when:

  • You store a URL in a database and encode it again before using it
  • A framework or library encodes values you have already encoded manually
  • You’re building a URL that contains another URL as a parameter

To avoid it: encode exactly once, at the point where you compose the URL. If you’re unsure whether a value is already encoded, decode it first (with decodeURIComponent), then re-encode it cleanly.

Debugging URL Encoding in DevTools

When an API request behaves unexpectedly, open DevTools (F12), go to the Network tab, and click the failing request. Under Headers, find the Request URL — the browser shows it in its raw form after encoding. Under Payload, you can see query parameters decoded back to their original values, which makes it easy to spot whether an ampersand was interpreted as a separator or passed through as a literal.

For manual testing, a url encode decode online tool lets you paste a string and see exactly what the encoded form looks like — useful for sanity-checking values before embedding them in a request. The IO Tools URL Encoder/Decoder handles both directions and shows you the output immediately.

Want To enjoy an ad-free experience? Go Ad-Free Today

Install Our Extensions

Add IO tools to your favorite browser for instant access and faster searching

Add to Chrome Extension Add to Edge Extension Add to Firefox Extension Add to Opera Extension

Scoreboard Has Arrived!

Scoreboard is a fun way to keep track of your games, all data is stored in your browser. More features are coming soon!

ADVERTISEMENT · REMOVE?
ADVERTISEMENT · REMOVE?
ADVERTISEMENT · REMOVE?

News Corner w/ Tech Highlights

Get Involved

Help us continue providing valuable free tools

Buy me a coffee
ADVERTISEMENT · REMOVE?