URL encoder/decoder · Guide

URL Encoded Content Type: application/x-www-form-urlencoded

`application/x-www-form-urlencoded` is the default encoding for HTML form submissions and still the required format for OAuth token requests and many webhooks. It looks like a query string because it is one — placed in the body instead of the URL.

What the body looks like

Key-value pairs joined by &, keys and values separated by =, everything percent-encoded — with one difference from a URL query string: a space is +, not %20:

Text
POST /login HTTP/1.1
Content-Type: application/x-www-form-urlencoded

username=alice&password=s3cr%26t&remember=on

Because + means space, a literal plus must be %2B. This is the single most common bug with form encoding: a phone number +380501234567 arrives as a leading space unless encoded.

Versus the alternatives

A query string carries the same format in the URL, where it is visible in logs, browser history and referrer headers. Form-encoded bodies keep values out of those places, which is why credentials go in the body.

multipart/form-data is for file uploads — form-urlencoded cannot carry binary efficiently, since every byte would need escaping.

JSON handles nested structures and types; form encoding is flat strings only. Nesting requires conventions such as filter[status]=active, which every framework parses slightly differently.

Sending one

Let the client library build the body so encoding is handled per value:

Shell
# curl sets the content type automatically
curl -X POST https://example.com/token \
  --data-urlencode "grant_type=client_credentials" \
  --data-urlencode "scope=read write"
JavaScript
// fetch — URLSearchParams sets the header for you
await fetch('/token', {
  method: 'POST',
  body: new URLSearchParams({ grant_type: 'client_credentials', scope: 'read write' }),
});

Passing a URLSearchParams object as the body makes the browser set Content-Type automatically — setting it by hand while sending a JSON string is a frequent mismatch that produces empty parameters server-side.

Frequently asked questions

Why did my plus sign become a space?

Form encoding treats + as a space. Encode a literal plus as %2B.

Form-encoded or JSON?

JSON for structured data and APIs you control. Form encoding where a spec requires it, such as OAuth token endpoints.

Can I send a file this way?

Not practically. Use multipart/form-data for binary uploads.

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