Basic Usage¶
Command-Line Interface¶
The httptap command-line interface provides various options to customize your HTTP requests and output.
Syntax¶
Options¶
Curl compatibility: Common curl flags are accepted as aliases. Swap
curlforhttptapand keep using familiar options like-X/--request,-L/--location,-m/--max-time,-k/--insecure,-x, and--http1.1;-f/--fail,-4/--ipv4,-6/--ipv6, and--resolveuse the same names as in curl. This is not a full curl clone—stick to the overlapping flags listed here.
Request Options¶
-X, --request, --method METHOD¶
Specify the HTTP method to use. Supported methods: GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS.
Method values are case-insensitive.
Curl-compatible aliases: -X, --request.
Default behavior: - Without --data: defaults to GET - With --data but no --method: auto-switches to POST (similar to curl) - With explicit --method: respects the specified method
-d, --data DATA¶
Send request body data. Can be inline string or file reference using @filename syntax.
Inline JSON data:
Load from file:
Inline data is sent as the exact bytes of the argument, like curl; on POSIX systems this includes arguments that are not valid UTF-8.
Auto-detection: - Content-Type is automatically detected (JSON, XML, plain text) - File extension is checked first (.json, .xml, .txt) - Falls back to JSON validation
Examples with different methods:
# POST (auto-detected when --data is present)
httptap --data '{"key": "value"}' https://httpbin.io/post
# PUT
httptap --method PUT --data '{"status": "updated"}' https://httpbin.io/put
# PATCH
httptap --method PATCH --data '{"field": "modified"}' https://httpbin.io/patch
# Explicit GET with body (uncommon, triggers warning)
httptap --method GET --data 'query-data' https://httpbin.io/get
-H, --header¶
Add custom HTTP headers to the request. Can be used multiple times.
httptap \
-H "User-Agent: MyApp/1.0" \
-H "Authorization: Bearer token123" \
https://httpbin.io/bearer
Header names must be HTTP tokens (letters, digits and !#$%&'*+-.^_`|~), and values may contain only printable ASCII characters, spaces and tabs. A header that breaks these rules, such as a name with a space, a value with CR, LF or another control character, or a non-ASCII value (httpx sends header values as ASCII), is rejected with exit code 64 before any request is made. The error names the header but never prints its value.
-L, --location, --follow¶
Follow HTTP redirects and show timing for each step in the chain (max 10 redirects).
Curl-compatible aliases: -L, --location.
By default, httptap does not follow redirects and will stop at the first redirect response (3xx status code).
If the response is still a redirect after 10 followed redirects, httptap stops, prints a warning, marks that step with redirect_limit_reached: true in the JSON export, and exits with code 47.
When following redirects, httptap applies the same rules as curl and browsers:
Authorization,CookieandProxy-Authorizationheaders are sent only to the original origin (scheme, host and port). Once a redirect points to a different origin, they are dropped for the rest of the chain; anhttp→httpsupgrade on the same host with default ports (80 → 443) keeps them.303 See Other, and301/302after aPOST, switch the next request toGETwithout a body.307and308keep the method and body.
If the Location of a redirect cannot be requested (an invalid or out-of-range port, a missing host, a scheme other than http/https, a malformed IPv6 literal), the 3xx step is kept and the chain ends with a failed step for that target with the error Invalid redirect target: …, and httptap exits with code 75. Without --follow, the 3xx response is reported as received, whatever its Location.
Credentials in a Location URL (https://user:password@host/) are masked in the output and JSON export (https://user:****@host/), but the real URL is followed.
-m, --max-time, --timeout SECONDS¶
Abort the request chain if total elapsed time exceeds the specified number of seconds.
The limit is a hard deadline for the whole chain, redirects included: DNS, connecting, waiting for the response and reading the body all share it, and a server that stalls or keeps trickling bytes is cut off when it passes. The step then fails with Request timeout: total deadline exceeded and httptap exits with code 75.
Curl-compatible aliases: -m, --max-time.
Default timeout is 20 seconds.
--no-http2 / --http1.1¶
Disable HTTP/2 negotiation and force HTTP/1.1 connections.
By default, HTTP/2 is enabled if the server supports it.
Curl-compatible alias: --http1.1.
-4, --ipv4 and -6, --ipv6¶
Restrict DNS resolution and the connection to IPv4 or IPv6. The options are mutually exclusive.
They cannot be used with HTTP, HTTPS, or SOCKS5H proxies, because those proxies resolve the target hostname themselves.
--resolve HOST:PORT:ADDR¶
Connect a hostname and port to a specific IPv4 or IPv6 address while retaining the original Host header and TLS SNI. This is useful when testing one backend before a DNS switch or bypassing a round-robin DNS record. The option can be repeated for different host and port pairs.
httptap --resolve api.example.com:443:203.0.113.10 https://api.example.com/health
httptap --resolve api.example.com:443:[2001:db8::10] https://api.example.com/health
Internationalized hostnames match in either form: an entry for bücher.example also applies to https://xn--bcher-kva.example/, and the other way round. httptap resolves such names in their IDNA 2008 form (xn--…), the same name it sends in the Host header and TLS SNI.
--resolve applies to direct connections and local-DNS SOCKS5 proxies. HTTP, HTTPS, and SOCKS5H proxies resolve the target remotely, so combining them with --resolve is rejected, the same as for -4/-6.
-k, --insecure, --ignore-ssl¶
Disable TLS certificate verification. Useful for debugging self-signed hosts or expired certificates.
Warning
Use this option only on trusted networks. It disables certificate validation and relaxes handshake constraints.
Curl-compatible aliases: -k, --insecure.
-x, --proxy URL¶
Route requests through the specified proxy. Supports HTTP, HTTPS, SOCKS5, and SOCKS5H protocols.
Curl-compatible alias: -x.
# HTTP proxy
httptap --proxy http://proxy.local:8080 https://httpbin.io/get
# SOCKS5 proxy (DNS resolved by proxy)
httptap --proxy socks5h://proxy.local:1080 https://httpbin.io/get
# SOCKS5 proxy (DNS resolved locally)
httptap --proxy socks5://proxy.local:1080 https://httpbin.io/get
# Ignore proxy environment variables and connect directly
httptap --proxy "" https://httpbin.io/get
The --proxy flag takes precedence over environment variables (HTTP_PROXY, HTTPS_PROXY, NO_PROXY). Use --proxy "" to ignore all proxy environment variables and connect directly. See Advanced Features for details on proxy protocols, DNS resolution, and environment variable configuration.
Credentials in the proxy URL (http://user:password@proxy:3128), including ones taken from environment variables, are used for the connection but masked in the output and JSON export (http://user:****@proxy:3128).
A proxy given without a scheme (proxy.local:3128) is treated as http://, as in curl. A malformed proxy URL (an unsupported scheme, a missing host, an invalid or out-of-range port, an unterminated IPv6 literal) is rejected with exit code 64 before any request is made; the error shows the URL with its password masked.
--cacert, --ca-bundle PATH¶
Use a custom CA certificate bundle (PEM format) for TLS verification. Useful for internal endpoints signed by a private CA.
Mutually exclusive with --ignore-ssl.
Output Options¶
--compact¶
Display results in a compact single-line format, suitable for logging.
Output:
Step 1: 200 GET https://httpbin.io/get | dns=8.9ms connect=97.0ms tls=194.6ms ttfb=446.0ms total=447.3ms | 389 B
--compact prints one human-readable line per step (suitable for logs and redirect-chain tracing) while still rendering the analysis header and Redirect Chain Summary table. Response size is shown with the appropriate unit (B, KB, MB). For machine-parseable output, see --metrics-only.
--metrics-only¶
Output raw metrics without formatting, ideal for scripting and automation.
Output:
Step 1: dns=30.1 connect=97.3 tls=199.0 ttfb=472.2 total=476.0 status=200 bytes=389 ip=44.211.11.205 family=IPv4 tls_version=TLSv1.2 proxy=direct
--json PATH¶
Export full request data to a JSON file. Use - to write the JSON to stdout instead; the regular report is then suppressed so the output can be piped.
If the file cannot be written, httptap exits with code 73.
The JSON file contains:
- Timing breakdown for all phases
- Network information (IP address, TLS details, certificate info)
- Response metadata (status, headers, body size)
- Complete redirect chain (when using
--follow) - SLO evaluation (when
--slois supplied)
--har PATH¶
Export the request chain as an HTTP Archive (HAR 1.2) file that browser DevTools and HAR viewers can open. Use - to write it to stdout; the regular report is then suppressed. --har can be combined with --json, but only one of them can use -.
httptap --follow --har run.har https://httpbin.io/redirect/2
httptap --har - https://httpbin.io/get | jq '.log.entries[].timings'
If the file cannot be written, httptap exits with code 73. See HAR Export for the timings mapping and the fields httptap adds.
--prometheus PATH¶
Write per-phase timings in Prometheus textfile collector format. Durations are exported as httptap_request_duration_seconds gauges with host, step and phase labels, next to httptap_request_success and httptap_last_run_timestamp_seconds; paths and query strings are never labels.
--otlp ENDPOINT¶
Export the run as one OpenTelemetry trace: a root span, one span per request step and child spans for DNS, connection, TLS, server wait, and transfer phases. Install the optional dependency first:
--slo KEY=MS[,KEY=MS...], --slo-file PATH¶
Check the final successful step against per-phase latency budgets. On violation httptap still renders the full report but exits with code 4 so the result can gate CI jobs, cron probes, or Kubernetes readiness checks.
httptap --slo total=500,ttfb=200 https://httpbin.io/get
# One threshold per line; inline values override file values.
httptap --slo-file slo.txt --slo total=1000 https://httpbin.io/get
Supported keys: dns, connect, tls, ttfb, wait, xfer, total. See the dedicated SLO Threshold Checking page for the full specification, exit-code precedence, and CI/cron recipes.
-f, --fail¶
Exit with code 22 when any completed request returns HTTP 4xx or 5xx, while still rendering the full timing report and writing --json output. Network and TLS failures keep their existing higher-priority exit codes.
--version¶
Display the httptap version and exit.
HTTP Methods¶
httptap supports all standard HTTP methods:
- GET - Retrieve resource (default when no
--datais provided) - POST - Create/submit resource (auto-selected when
--datais provided) - PUT - Replace resource
- PATCH - Partially update resource
- DELETE - Remove resource
- HEAD - Get headers only
- OPTIONS - Query allowed methods
Method Selection Logic¶
- Explicit method:
--methodalways takes precedence - Auto-POST: When
--datais present without--method, defaults to POST - Default GET: Without
--dataor--method, uses GET
Examples by Use Case¶
API Testing:
# Create resource
httptap --data '{"title": "New Post"}' https://httpbin.io/post
# Update resource
httptap --method PUT --data '{"title": "Updated"}' https://httpbin.io/put
# Partial update
httptap --method PATCH --data '{"status": "published"}' https://httpbin.io/patch
# Delete resource
httptap --method DELETE https://httpbin.io/delete
Health Checks:
# Quick check (headers only)
httptap --method HEAD https://httpbin.io/status/200
# Full response
httptap https://httpbin.io/status/200
Request Flow¶
Every httptap request follows these phases:
- DNS Resolution - Domain name lookup
- TCP Connect - Establish TCP connection (through an HTTP CONNECT proxy: connect to the proxy and open the tunnel)
- TLS Handshake - Negotiate secure connection (HTTPS only)
- Server Wait - Time between request sent and first response byte
- Body Transfer - Download response body
Understanding Output¶
Rich Mode (Default)¶
The default rich output displays a waterfall table with:
- Phase name and duration
- Visual progress bar
- Network details (IP, TLS version, certificate info)
- Response metadata (status, size,
Serverheader, redirect target)
Timing Breakdown¶
- DNS (ms) - Time to resolve domain to IP address
- Connect (ms) - Time to establish TCP connection; through an HTTP CONNECT proxy it also covers the CONNECT round-trip, so the tunnel setup is not counted as server wait. When the host has several addresses and the first ones fail, the time spent on them is also counted here and in Total (like curl's
time_connect) - TLS (ms) - Time for TLS handshake (HTTPS only)
- TTFB (ms) - Time to first byte (includes server processing)
- Transfer (ms) - Time to download response body
- Total (ms) - End-to-end request duration
Network Information¶
- IP Address - Resolved IP address and family (IPv4/IPv6)
- TLS Version - Protocol version (TLS 1.2, TLS 1.3)
- Cipher Suite - Negotiated cipher suite
- Certificate CN - Common Name from server certificate
- Certificate Expiry - Days until certificate expires
Examples¶
Basic Health Check¶
API Request with Authentication¶
httptap \
-H "Authorization: Bearer ${API_TOKEN}" \
-H "Accept: application/json" \
https://httpbin.io/bearer
Follow Redirect Chain¶
Export for Analysis¶
Log to File¶
What's Next?¶
-
Rich, compact, JSON, and metrics modes
-
Custom components and programmatic usage
-
Extend httptap with protocols