fetch provides multiple options for sending request bodies with different content types.
Request body options are mutually exclusive - you can only use one per request:
| Option | Content-Type | Use Case |
|---|---|---|
-d, --data |
Auto-detected | Raw data, binary files |
-j, --json |
application/json |
JSON APIs |
-x, --xml |
application/xml |
XML/SOAP APIs |
-f, --form |
application/x-www-form-urlencoded |
Simple forms |
-F, --multipart |
multipart/form-data |
File uploads |
The -d or --data flag sends raw request body data. Content-Type is auto-detected when reading from files.
fetch -d 'Hello, world!' -m PUT example.com/resourcefetch -d @data.txt -m PUT example.com/resource
fetch -d @payload.bin -m POST example.com/uploadecho 'Request body' | fetch -d @- -m PUT example.com/resource
cat data.json | fetch -d @- -m POST example.com/apiWhen using @filename, the Content-Type is detected from the file extension.
Some examples are:
| Extension | Content-Type |
|---|---|
.json |
application/json |
.xml |
application/xml |
.html |
text/html |
.txt |
text/plain |
.csv |
text/csv |
| Unknown | application/octet-stream |
Override with a header:
fetch -d @data.bin -H "Content-Type: application/custom" -m POST example.comThe -j or --json flag sends JSON data and sets Content-Type: application/json.
fetch -j '{"name": "test", "value": 42}' -m POST example.com/apifetch -j @payload.json -m POST example.com/apiecho '{"key": "value"}' | fetch -j @- -m POST example.com/api
# Build JSON dynamically
jq -n '{name: "test", time: now}' | fetch -j @- -m POST example.com/apifetch -j '{
"user": {
"name": "John",
"email": "john@example.com"
},
"settings": {
"theme": "dark",
"notifications": true
}
}' -m POST example.com/api/usersThe -x or --xml flag sends XML data and sets Content-Type: application/xml.
fetch -x '<user><name>John</name></user>' -m POST example.com/apifetch -x @request.xml -m POST example.com/soap/endpointfetch -x '<?xml version="1.0"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Body>
<GetUser>
<UserId>123</UserId>
</GetUser>
</soap:Body>
</soap:Envelope>' -m POST example.com/soapThe -f or --form flag sends URL-encoded form data. Use multiple times for multiple fields.
fetch -f username=john -f password=secret -m POST example.com/loginValues are automatically URL-encoded:
fetch -f "message=Hello World!" -f "email=user@example.com" -m POST example.com/contactContent-Type: application/x-www-form-urlencoded
Request body:
username=john&password=secret
The -F or --multipart flag sends multipart form data, typically used for file uploads.
fetch -F name=John -F email=john@example.com -m POST example.com/usersUse @ prefix to upload files:
fetch -F file=@document.pdf -m POST example.com/upload
fetch -F avatar=@photo.jpg -F name=John -m POST example.com/profileWhen uploading a file by path, only the file's base name is sent in the multipart filename parameter.
fetch -F "files=@doc1.pdf" -F "files=@doc2.pdf" -m POST example.com/uploadfetch \
-F "title=My Document" \
-F "description=A sample upload" \
-F "file=@document.pdf" \
-F "thumbnail=@preview.png" \
-m POST example.com/documentsThe ~ is expanded to your home directory:
fetch -F config=@~/config.json -m POST example.com/settingsThe -e or --edit flag opens an editor to compose or modify the request body before sending.
fetch --edit -m PUT example.com/resourceCombine with other body options to edit before sending:
fetch -j '{"name": "template"}' --edit -m POST example.com/apiThe editor is selected in this order:
VISUALenvironment variableEDITORenvironment variable- Well-known editors (
vim,nano, etc.)
EDITOR=code fetch --edit -m POST example.com/apiBody options that accept [@]VALUE support these formats:
| Format | Description |
|---|---|
value |
Use the literal value |
@filename |
Read content from file |
@- |
Read content from stdin |
@~/path |
Read from home directory |
# Literal value
fetch -j '{"inline": true}' -m POST example.com
# From file
fetch -j @data.json -m POST example.com
# From stdin
cat data.json | fetch -j @- -m POST example.com
# Home directory
fetch -d @~/Documents/data.txt -m PUT example.comWhen a request body is provided without specifying a method, the default is still GET. Always specify the method explicitly for clarity:
# Explicit POST
fetch -j '{"data": true}' -m POST example.com
# Don't rely on implicit behavior
fetch -j '{"data": true}' example.com # Still uses GET!For large file uploads, consider:
- Streaming:
fetchstreams file content rather than loading it all into memory - Timeout: Set appropriate timeouts with
--timeout - Progress: Use
-vto see request/response headers
fetch -F "large=@bigfile.zip" --timeout 300 -v -m POST example.com/uploadfetch -j '{
"title": "New Post",
"content": "Hello, World!",
"published": true
}' -m POST example.com/api/postsfetch -f username=admin -f password=secret -m POST example.com/loginfetch \
-F "file=@report.pdf" \
-F "title=Monthly Report" \
-F "tags=finance,monthly" \
-m POST example.com/documentsfetch -j '{
"query": "{ user(id: 1) { name email } }"
}' -m POST example.com/graphqlfetch -j @webhook-payload.json \
-H "X-Webhook-Secret: $WEBHOOK_SECRET" \
-m POST example.com/webhooks/receive- CLI Reference - All request body options
- gRPC - Sending Protocol Buffer messages
- Output Formatting - Response formatting