Toolvore

Query String ⇄ JSON

Convert URL query strings to JSON and back.

This tool runs entirely in your browser. Your data is never uploaded, never stored, and never leaves your device.

A querystring parser both ways: it splits a URL's query string into a readable JSON object and reassembles a flat JSON object back into a query string, so parameters can be inspected, edited and rebuilt without counting ampersands.

How to use it

  1. 1Pick a direction with the Query → JSON and JSON → Query buttons.
  2. 2Paste a whole URL, a bare query string, or a flat JSON object into the input box.
  3. 3Press Convert, then Copy — switching direction clears the previous result.

Example

Input
https://example.com?page=1&tag=a&tag=b
Output
{ "page": "1", "tag": ["a", "b"] }

Everything before the ? and anything after a # is discarded. Every value comes back as a string, because a query string carries no types — so 1 becomes "1", not a number. A key that appears twice becomes an array.

What happens to your data

Parsing uses the browser's built-in URLSearchParams, the same implementation your own code would use, so the result here is exactly what your application will see. No request is made and the URL never leaves the tab.

Last updated August 2026

A URL arrives in a bug report or a support ticket with a dozen parameters strung end to end, and the only question you have is a simple one: what is actually in it? Reading it by eye means tracking ampersands across three wrapped lines while percent escapes hide the values that matter. The opposite errand is just as common — the parameters already exist as a tidy object, and what you need is a link you can paste into a browser, a test or a curl command.

Before converting anything, be clear about what the format will hold. A query string is a flat list of name and value pairs, and both halves are text. There is no number, no boolean and no nesting, so the structure you think you can see in something like filter[status]=open is a convention agreed between one client and one particular server rather than anything the standard defines. Where the data has real shape to it, a request body is where it belongs.

The common mistake going from JSON back to a link is expecting a whole URL out. What you get is the parameter list on its own — no scheme, no host, no leading question mark — because the base was never part of what was converted, and you put it back yourself.

The other is trusting the round trip to be lossless. Text survives it exactly. Anything else is flattened into text on the way out and cannot be told apart from text on the way back in, which is worth knowing before you use the output as a fixture in a test.

How it works

Toolvore hands both directions to the browser's own URLSearchParams, which is why what you read here matches what your server or your client code will see rather than an approximation of it. Going from JSON to a link, every value is passed through JavaScript's string conversion before it is appended, so a number, a boolean or a null arrives as its own text — true becomes the four characters true, and nothing downstream can distinguish it from a user who typed the word. Anything nested is refused outright rather than guessed at or flattened: an object or an array sitting inside a value stops the conversion with the message 'Only flat objects and arrays of primitives are supported', while a top-level array, a bare string or null is refused with 'Input must be a JSON object'. Nothing runs until you press Convert, and an empty box clears the result without raising an error. The weak point is the plus sign, because encoding follows the form-encoded convention: a space is written as +, and a plus in your own data comes back as a space unless it was percent-encoded before it got here.

Common use cases

  • Reading the parameters out of a long tracking URL pasted into a bug report
  • Checking which UTM values a marketing link is really carrying
  • Building a test URL from parameters you already hold as an object
  • Spotting a repeated parameter that a server is only reading once
  • Turning a captured request URL into a fixture for a test
  • Comparing two long URLs by converting both and reading the objects side by side

Frequently asked questions

Why does a plus sign in a URL turn into a space?

Because a query string uses the same encoding as an HTML form, application/x-www-form-urlencoded, and in that scheme a plus is shorthand for a space. Anything that reads a query string properly — browsers, server frameworks, the URLSearchParams behind this page — decodes it that way, so a value such as a phone number written +44 or a base64 string ending in a plus arrives mangled. The fix belongs to whoever builds the URL: a literal plus has to be written %2B. Going the other direction, expect your spaces to come out as + rather than %20. Both are correct and interchangeable in a query string, though not in a path.

Can a query string hold nested objects or lists of objects?

Not as part of the format. It is a flat list of name and value pairs, both of them text, and there is no syntax for a structure inside a value. What looks like nesting — filter[status]=open, tags[]=a, or a whole JSON document crammed into one parameter — is an agreement between one client and one server rather than something the standard defines, which is why PHP, Rails, Express and .NET each read those brackets differently or not at all. That is also why nested JSON is rejected here instead of being flattened into a guess. When the data genuinely has structure, put it in a POST body and leave the URL for identifiers.

Is it safe to paste a URL containing an access token or an email address?

On this page nothing goes anywhere: both conversions are plain functions inside the component, there is no fetch, no upload and no storage, and the text stays in the tab until you close it. The larger question is whether that value should be in a URL at all. Query strings are written into server access logs, browser history and proxy caches, and they are handed to whatever you click next in the Referer header. A token that has travelled in a URL should be treated as one that has been shared with strangers, and rotated. The same reasoning applies to email addresses, order numbers and password reset codes.

How long can a query string be before something breaks?

HTTP itself sets no limit, so the ceiling belongs to whatever sits in the path. The 2,000-character rule of thumb people repeat comes from Internet Explorer's 2,083-character cap on a whole URL; current browsers allow considerably more. Servers, proxies and load balancers each impose their own maximum on the request line and answer with a 414 when it is passed, and those limits are usually a few kilobytes rather than unlimited. Content delivery networks may also decline to cache beyond a length, or drop parameters they do not recognise. A link creeping past a couple of thousand characters is a signal that the payload wants to be in a body.

What is the difference between the query string and the part after the hash?

The query string is everything between the question mark and the hash, and it is sent to the server as part of the request. The fragment — everything from the hash onwards — never leaves the browser. It was designed to point at a location within a document, and single-page routers and OAuth implicit flows later borrowed it precisely because a server never sees it, which also keeps it out of access logs. That is why a fragment is dropped rather than parsed when a full URL is converted here: it is not among the parameters a server receives. If your values live after the hash, take that portion on its own and convert what follows the hash.

What happens to true, false and null when JSON becomes a query string?

They become words. Each value is converted to text before it is appended, so true is written as the four characters true, 42 as two digits, and null as the word null — a query string carries no types, so there is nowhere else for them to go. Nothing at the far end can tell that null from a user who typed it, which matters when your server treats an empty parameter, a missing parameter and the string null as three different things. To signal absence, leave the key out of the object entirely rather than setting it to null, or agree an explicit convention with whatever reads the link.

How do servers handle a parameter that appears twice?

There is no rule, which is exactly the trouble. A URL ending tag=a&tag=b is read as an array by most Node code, as b alone by PHP unless the name is written tag[], as the single joined value a,b by ASP.NET, and as whichever comes first by Java's getParameter. None of them is wrong; the specification never said. Seeing a repeat presented as an array tells you what the URL contains, not what your framework will do with it. When the answer matters, test it against the real server rather than assuming, and prefer one unambiguous parameter over a repeat you have to explain to every future reader.

Which characters must be percent-encoded in a query value?

The ones that mean something structurally. An ampersand ends the value, an equals sign separates name from value, a hash begins the fragment, a plus means a space and a percent starts an escape, so any of those appearing inside a value has to be written as %26, %3D, %23, %2B or %25 — otherwise the parameter you get back is cut in half at the wrong point. Letters, digits, hyphen, full stop, underscore and tilde never need escaping. Everything else is safer encoded, and non-ASCII text is encoded as its UTF-8 bytes, which is why an accented character costs two escapes and an emoji four.

Used in these workflows