URL encoder/decoder · Guide
URL Encode Brackets: Square and Curly Braces in URLs
Square brackets have a reserved role in URLs and curly braces have none at all — yet both appear unencoded in real query strings every day. The rules and the practice differ here more than for any other character.
Square brackets are reserved for IPv6
[ and ] were added to the reserved set to wrap IPv6 literals in the host: http://[2001:db8::1]:8080/path. That is their only legitimate structural use.
Everywhere else — path, query, fragment — RFC 3986 says they must be encoded as %5B and %5D.
Why array parameters break the rule
PHP, Rails and many frameworks accept ?filter[status]=active&filter[type]=user with literal brackets, and browsers send them unencoded. It is technically non-conformant and universally supported.
The safe course is to encode and let the server decode — filter%5Bstatus%5D=active parses identically in every framework that supports the bracket syntax:
// URLSearchParams encodes brackets for you
const p = new URLSearchParams();
p.append('filter[status]', 'active');
p.toString(); // 'filter%5Bstatus%5D=active'Where it genuinely matters is signatures: if you sign the encoded form and the server verifies the literal form, the signature fails. Match whatever the API documents.
Curly braces are not URL characters at all
{ and } are not in any URL character set — not reserved, not unreserved. They must be encoded as %7B and %7D.
They appear unencoded mostly by accident: an unfilled template placeholder such as /users/{id}/posts that reached a real request. If you see literal braces in a log, that is usually a bug in string interpolation rather than an encoding question.
JSON in a query parameter is the legitimate case, and there the whole JSON string should be percent-encoded as a value.
Frequently asked questions
Are square brackets allowed in a query string?
Not per RFC 3986, but they are widely accepted for array-style parameters. Encoding them as %5B and %5D is always safe.
How do I put JSON in a URL?
Percent-encode the entire JSON string as a single value with encodeURIComponent.
Why do curly braces appear in my logs?
Usually an unreplaced URL template placeholder, not an encoding issue.
Ready to try it?
Open the free browser-based URL encoder/decoder and apply what you just read — no sign-up, runs locally.
Open the URL encoder/decoder tool