invoke-restmethod — HTTP cmdlet that auto-parses JSON — curl plus jq combined across all 5 shells
Equivalents in every shell
curl -s https://api.example.com/users/1 | jq`curl -s` (silent) drops the progress meter so the JSON pipes cleanly into `jq`. Use `jq -r .field` for raw string output (no surrounding quotes) when feeding the value into another shell command.
curl -s https://api.example.com/users/1 | jqSame external `curl` and `jq`. Both ship on macOS via Homebrew (`brew install jq`) — base macOS has curl but not jq. Linux distros usually ship both via `apt`/`dnf`/`pacman`.
curl -s https://api.example.com/users/1 | jqSame external pipeline. Fish's cleaner quoting helps with URLs that contain shell-special characters — `curl -s 'https://api.example.com/search?q=foo&type=bar'` works without backslash-escaping the `&`.
Invoke-RestMethod https://api.example.com/users/1Auto-detects `Content-Type: application/json` and returns the parsed object graph as `[PSCustomObject]` — `.id`, `.name` etc. all work as property accessors without an explicit `ConvertFrom-Json` step. Aliased as `irm`. For form-encoded or XML responses, use `Invoke-WebRequest` instead.
curl -s https://api.example.com/users/1Windows 10 1803+ ships `curl.exe` natively in `C:\Windows\System32`. cmd.exe itself has no JSON parser — pipe to `powershell -c "$input | ConvertFrom-Json"` or install `jq` via `winget install jqlang.jq`.
Worked examples
POST a JSON body with a bearer token
curl -s -X POST -H 'Authorization: Bearer $TOKEN' -H 'Content-Type: application/json' -d '{"name":"alice"}' https://api.example.com/usersInvoke-RestMethod -Method POST -Uri https://api.example.com/users -Headers @{Authorization="Bearer $env:TOKEN"} -Body (@{name='alice'} | ConvertTo-Json) -ContentType 'application/json'curl -s -X POST -H "Authorization: Bearer %TOKEN%" -H "Content-Type: application/json" -d "{\"name\":\"alice\"}" https://api.example.com/usersDownload a paginated list and extract one field per page
for p in 1 2 3; do curl -s "https://api.example.com/items?page=$p" | jq -r '.data[].id'; done1..3 | ForEach-Object { (Invoke-RestMethod "https://api.example.com/items?page=$_").data.id }Capture response headers alongside the parsed body
curl -s -D /tmp/headers.txt https://api.example.com/users/1 | jq && cat /tmp/headers.txtInvoke-RestMethod https://api.example.com/users/1 -ResponseHeadersVariable hdrs; $hdrsGotchas
- `Invoke-RestMethod` only auto-parses responses whose `Content-Type` header starts with `application/json` (or `text/xml`/`application/xml` → XmlDocument). Some APIs send `Content-Type: application/octet-stream` or `text/plain` for JSON — in that case the cmdlet returns the raw string, and you must call `ConvertFrom-Json` yourself. Inspect with `(Invoke-WebRequest …).Headers.'Content-Type'` if the auto-deserialise mysteriously yields a string.
- `-SkipCertificateCheck` is PowerShell 7+ only. On Windows PowerShell 5.1, to disable TLS validation (testing only) you must hack the PROCESS-WIDE `ServicePointManager` callback: `[System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true }`. Never ship this in a production script — every HTTPS call in the session becomes unvalidated.
- On 5.1, `Invoke-RestMethod` uses the legacy `mshtml.dll` (Internet Explorer) HTML parser for non-JSON responses — slow, and outright fails if IE is uninstalled. Pass `-UseBasicParsing` on 5.1; on pwsh 7+ the flag is a no-op (the modern parser is the only path) but is still accepted.
- Default `-MaximumRedirection 5` differs from curl's default of NOT following redirects (curl needs `-L` to follow). Scripts ported from curl that assume no-follow can produce wrong-URL results when the API starts returning 301s. To match curl's default, set `-MaximumRedirection 0`.
- The entire response body buffers in memory before the cmdlet returns — for multi-GB downloads use `Invoke-WebRequest -OutFile` (streams to disk) or shell out to `curl.exe`. There is no built-in chunked-streaming API; `-ResponseHeadersVariable` exposes headers early but the body is still fully buffered.
WSL & PowerShell Core notes
Common tasks using invoke-restmethod
- Get your public IP
Discover the IPv4 (or IPv6) address that the rest of the internet sees you originating from — for opening a firewall rule, debugging "why does this geo-blocked service reject me", checking whether a VPN / proxy is actually engaged, or seeding a DDNS update.
- Parse JSON from a shell
Extract specific fields from a JSON blob (a curl response, kubectl output, log line) and pipe them into other shell tools — the everyday "grab the .token / .items[].name / .data.url" workflow that differs sharply from just pretty-printing.
- Send an HTTP POST request
POST a JSON body (or form fields, or a file) to a URL and capture the response.