Submit a URL-encoded form

Send form data as `application/x-www-form-urlencoded` — the classic HTML form encoding, also used by OAuth token endpoints and similar APIs.

Overview

Send form data as `application/x-www-form-urlencoded` — the classic HTML form encoding, also used by OAuth token endpoints and similar APIs.

In code

# --data-urlencode encodes special characters (spaces, &, =) safely:
curl -X POST https://example.com/login \
  --data-urlencode 'user=alice' \
  --data-urlencode 'note=hello world & more'
# Content-Type: application/x-www-form-urlencoded (default for -d)
const body = new URLSearchParams({
  user: 'alice',
  note: 'hello world & more'
});
await fetch('https://example.com/login', {
  method: 'POST',
  headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
  body // URLSearchParams stringifies + encodes for you
});
import requests

# passing a dict as data= sends x-www-form-urlencoded and encodes values
res = requests.post('https://example.com/login',
                    data={'user': 'alice', 'note': 'hello world & more'})

Details

This format joins values as `key=value&key2=value2` and percent-encodes special characters. In curl, `-d` (`--data`) sends the value raw and does not encode it, so spaces, `&`, and `=` break it. Use `--data-urlencode` per field, which encodes the value for you.

In `fetch`, `URLSearchParams` handles encoding and stringification, and passing it as the body lets the browser set the Content-Type. In `requests`, a dict passed to `data=` is auto-encoded to this format (use `json=` for JSON instead).

This encoding is unsuitable for file uploads (use multipart). It also has no standard way to express arrays or nested objects — servers vary between `key[]=a&key[]=b` and other schemes — so JSON POST is clearer for complex structures.

Related headers

Related status codes