JSON to Query String
Build a URL query string from a JSON object — arrays expand into repeated keys
JSON
Query String
What does JSON to Query String do?
You built a JSON config in your code — filter parameters, an analytics payload, OAuth state — and now you need it appended to a URL. This page does the boring last mile. Paste the JSON on the left, get back ?customer=Ava+Chen&status=active&total%5Bgte%5D=49.99&page=2&tag=premium&tag=verified on the right, ready to drop into a link, a fetch call, or a webhook URL. Arrays expand into repeated keys (the convention every modern server understands), values are properly percent-encoded, and the leading ? is included so you can paste straight into a URL.
The conversion uses the browser's built-in URLSearchParams — the same primitive your server framework uses to parse the request that comes back. URLSearchParams produces application/x-www-form-urlencoded output per the WHATWG URL Standard, and your JSON is parsed by JSON.parse following RFC 8259. Numbers and booleans are coerced to strings (since query strings have no type system), null and undefined values are skipped, and nested objects throw a friendly error so you can flatten them.
Everything runs locally in your browser — no upload, no server round-trip, no logging. If you have the opposite problem (a query string and you want JSON), use Query String to JSON. If you want the whole URL deconstructed into protocol, host, path, and search parts, the URL to JSON page or the URL Parser are better fits. The percent-encoding rules at play here are defined by RFC 3986 §2.1, and the broader URL parsing model lives in the MDN URL API reference.
How to Convert JSON to a Query String
Three steps. Each one matches a button on this page.
Paste the JSON Object
Drop the JSON into the left panel. The top-level value has to be an object — arrays and primitives don't map cleanly to query parameters. Click Sample for a realistic e-commerce filter payload with a string, a number, a bracketed key, and an array. Sample:
{
"customer": "Ava Chen",
"status": "active",
"total[gte]": "49.99",
"page": 2,
"tag": ["premium", "verified"]
}Numbers and booleans are coerced to strings (query strings carry no types). <code>null</code> and <code>undefined</code> values are skipped — they'd just clutter the URL otherwise.
Read the Query String
The right panel updates as you type. The sample above produces ?customer=Ava+Chen&status=active&total%5Bgte%5D=49.99&page=2&tag=premium&tag=verified. Spaces become + (form-encoded style — see the FAQ), brackets become %5B/%5D, and the tag array expands into two separate tag= parameters.
Copy or Download
Click Copy to send the query string to your clipboard, or Download to save it as querystring.txt. Clear resets the input panel.
When You'd Actually Use This
Building shareable filter URLs
Your dashboard lets a user filter orders by customer, status, and date range. The state lives as a JSON object in your component ({customer: "Marco Rivera", status: "active", date_from: "2026-04-01"}). To make the view shareable, you append it to the URL — paste the JSON here, copy the query string, you're done. Same applies to e-commerce category pages, search results, anything with stateful filters.
Wiring up webhook callback URLs
Stripe, GitHub, and most webhook senders let you put metadata in the callback URL's query string. You've got a JSON object describing the user ({userId: "USR-1001", source: "checkout", flow: "onboarding"}), and you need it appended to https://api.example.com/webhook?.... Paste, copy, paste — beats manually URL-encoding each value and worrying about which characters need escaping.
Generating OAuth and OpenID URLs
OAuth authorization URLs are 8–12 query parameters: client_id, redirect_uri, scope, state, response_type, etc. Building one in JSON first (so you can see it cleanly) and converting here is faster than concatenating strings and praying you got the encoding right. The state parameter often carries a nonce and a return-path that need their own escaping.
Constructing API requests in HTTP clients
When you're testing an API endpoint in cURL, Postman, or a quick fetch(), you usually have the parameters as a JSON snippet from documentation. Convert here, append to the URL, fire the request. Order ORD-1001's product filter {"sku": "SKU-101", "include": "variants"} turns into ?sku=SKU-101&include=variants in one paste.
Common Questions
Why are spaces encoded as + instead of %20?
Because the output is form-encoded (application/x-www-form-urlencoded), which is what every browser sends and every server expects in a query string. RFC 3986 technically prefers %20 in URI components, but the form-encoded convention with + for spaces predates RFC 3986 and is what query strings have used since the 90s. Every modern server framework decodes both — Express, FastAPI, ASP.NET, Spring, Rails, Django, you name it. If you specifically need %20, run a quick .replace(/\+/g, "%20") on the output.
How do arrays get encoded?
They expand into repeated keys. {"tag": ["premium", "verified"]} becomes tag=premium&tag=verified. This is the convention URLSearchParams produces, and it round-trips cleanly through URLSearchParams.getAll() on the receiving side. If your server expects bracket notation (tag[]=premium&tag[]=verified) — common in PHP and Rails — name your JSON key tag[] instead of tag.
Can I have nested objects in the JSON?
No — query strings are flat by design. The page returns a friendly error if it sees a nested object so you can flatten it. The most common workaround is bracket-notation keys: instead of {"filter": {"status": "active"}}, write {"filter[status]": "active"}. Frameworks like Rails, PHP, and qs.js parse those back into nested objects on the server side. Or just flatten conceptually: {"status": "active"} if there's no real ambiguity.
What happens to null and undefined values?
They're skipped. {"customer": "Ava Chen", "status": null} produces ?customer=Ava+Chen, not ?customer=Ava+Chen&status=. The reasoning: status= in the URL means "the empty string", which is a real value and different from "no status". Sending null as empty would be lossy and confusing. If you actually want status=, send {"status": ""}.
Are numbers and booleans preserved as types?
No — query strings only carry strings. {"page": 2} becomes page=2, and {"debug": true} becomes debug=true. Your server-side code has to know the schema and coerce them back. This is fundamental to query strings (and form data) — the wire format doesn't know the difference between the number 2 and the string "2". If you need typed parameters, send them in the request body as JSON instead.
How does it handle Unicode and emoji in keys or values?
Cleanly. URLSearchParams encodes the bytes as UTF-8 and percent-escapes anything outside the safe set. So {"name": "中文"} becomes name=%E4%B8%AD%E6%96%87, and {"reaction": "🔥"} becomes reaction=%F0%9F%94%A5. On the receiving side, URLSearchParams (or any framework's query parser) decodes them right back. There's no encoding setting to fiddle with — UTF-8 is what the URL Standard mandates.
What's the leading question mark for?
So you can paste the output directly onto a URL — https://shop.example.com/orders + ?customer=Ava+Chen&page=2 = a working URL. If you're appending to a URL that already has a query string, drop the ? and use &. If your input is empty or {}, the output is empty too (no bare ?).
Other URL & JSON Tools
Building a query string is one operation. Here's what else pairs with it: