Posting request bodies from the terminal is useful for API tests, form replay, and small automation jobs that need more than a simple GET. In wget, POST support keeps that workflow inside one familiar transfer tool, which is often enough for health checks, webhook tests, and service endpoints that expect straightforward request bodies.
The important switches are --post-data for short inline bodies and --post-file for larger or reusable payloads. Pair either option with the right Content-Type header so the remote service can interpret the body correctly, then save or inspect the response to confirm that the endpoint received the exact fields or JSON structure that was intended.
Wget does not support multipart/form-data uploads, so browser-style file form posts still need another client. For ordinary POST bodies, the main risks are bad shell quoting, stale test payloads left on disk, and secrets exposed through shell history when sensitive JSON or form fields are typed directly into the command line.
Related: How to upload files with wget
Related: How to send custom headers with wget
$ wget -S -O post-form.json \ --header='Content-Type: application/x-www-form-urlencoded' \ --post-data='name=user&role=admin' \ https://httpbin.org/post 2>&1 | sed -n '1,16p' --2026-03-27 06:57:06-- https://httpbin.org/post Resolving httpbin.org (httpbin.org)... 44.221.213.41, 54.146.128.0, 44.196.185.120, ... Connecting to httpbin.org (httpbin.org)|44.221.213.41|:443... connected. HTTP request sent, awaiting response... HTTP/1.1 200 OK Date: Thu, 26 Mar 2026 22:57:07 GMT Content-Type: application/json Content-Length: 486 Length: 486 [application/json] Saving to: 'post-form.json'
--post-data is the quickest path for short form bodies that already fit cleanly on one shell line.
$ jq '.form' post-form.json { "name": "user", "role": "admin" }
A correct form echo proves both the body string and the application/x-www-form-urlencoded content type were accepted.
$ wget -qO- \ --header='Content-Type: application/json' \ --post-data='{"username":"api-user","password":"pass"}' \ https://httpbin.org/post | jq '{json, data, headers: .headers | {"Content-Type": ."Content-Type", "Content-Length": ."Content-Length"}}' { "json": { "password": "pass", "username": "api-user" }, "data": "{\"username\":\"api-user\",\"password\":\"pass\"}", "headers": { "Content-Type": "application/json", "Content-Length": "41" } }
Inline JSON is convenient for quick checks, but sensitive fields typed directly into --post-data remain in shell history unless the history is disabled or cleaned.
$ cat > post-body.json <<'JSON' { "name": "user", "role": "admin", "tags": ["cli", "wget", "post"] } JSON $ wget -qO- \ --header='Content-Type: application/json' \ --post-file=post-body.json \ https://httpbin.org/post | jq '{json, headers: .headers | {"Content-Type": ."Content-Type", "Content-Length": ."Content-Length"}}' { "json": { "name": "user", "role": "admin", "tags": [ "cli", "wget", "post" ] }, "headers": { "Content-Type": "application/json", "Content-Length": "75" } }
--post-file avoids complex shell escaping and is the safer choice for longer payloads or bodies reused across multiple requests.
$ rm -f post-form.json post-body.json
Cleanup prevents sample payloads, secrets, and echoed responses from lingering in the working directory after the POST test is finished.