Opencode httpie
install
source · Clone the upstream repo
git clone https://github.com/jjmartres/opencode
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/jjmartres/opencode "$T" && mkdir -p ~/.claude/skills && cp -r "$T/opencode/skills/httpie" ~/.claude/skills/jjmartres-opencode-httpie && rm -rf "$T"
manifest:
opencode/skills/httpie/SKILL.mdsource content
HTTPie CLI Skill
HTTPie is a modern, human-friendly HTTP client for the command line. The main command is
http (or https for HTTPS-only).
Installation
# pip (recommended) pip install httpie # brew (macOS) brew install httpie # apt (Debian/Ubuntu) sudo apt install httpie
Verify:
http --version
Request Syntax
http [METHOD] URL [REQUEST_ITEMS...]
- METHOD is optional: defaults to
when no data,GET
when data is presentPOST - URL: scheme defaults to
; usehttp://
as shorthand for:3000localhost:3000
Request Items ¿ Key Separators
| Separator | Type | Example |
|---|---|---|
| JSON string field (or form field with ) | |
| Raw JSON value (non-string) | , , |
| URL query parameter | |
| HTTP header | |
| File upload (form/multipart) | |
| File content as string field | |
| File content as raw JSON | |
Common Examples
GET requests
# Simple GET http GET https://api.example.com/users # With query params http GET https://api.example.com/users search==alice limit==10 # Shorthand (method inferred) http https://api.example.com/users # Localhost shorthand http :8080/health
POST with JSON (default)
# String and non-string fields http POST https://api.example.com/users \ name="Jean-Jacques" \ email="jj@example.com" \ active:=true \ roles:='["admin","user"]' # Inline raw JSON body (pipe it in) echo '{"name":"test"}' | http POST https://api.example.com/users
PUT / PATCH / DELETE
http PUT https://api.example.com/users/42 name="Updated" http PATCH https://api.example.com/users/42 email="new@example.com" http DELETE https://api.example.com/users/42
Form data (-f
)
-fhttp -f POST https://api.example.com/login username=admin password=secret
File upload (multipart)
http -f POST https://api.example.com/upload file@./document.pdf title="My Doc"
Authentication
# Basic auth http -a username:password https://api.example.com/secure # Bearer token http -A bearer -a TOKEN https://api.example.com/secure # Prompt for password (don't expose it in shell history) http -a username https://api.example.com/secure
Headers
# Custom headers http GET https://api.example.com/data \ Accept:application/json \ X-Request-Id:abc-123 \ Authorization:"Bearer $(cat token.txt)"
Output Control
# Show full exchange (request + response) http -v GET https://api.example.com/users # Only response headers http -h GET https://api.example.com/users # Only response body http -b GET https://api.example.com/users # Show request headers + response body http --print=Hb GET https://api.example.com/users # Flags: H=request headers, B=request body, h=response headers, b=response body, m=metadata # No color / formatting (useful in scripts) http --pretty=none GET https://api.example.com/users # Check HTTP status (exit non-zero on 4xx/5xx) http --check-status GET https://api.example.com/users
Download Files
# Download and auto-name http --download https://example.com/file.zip # Download to specific path http --download -o /tmp/output.zip https://example.com/file.zip # Resume interrupted download http --download --continue -o /tmp/output.zip https://example.com/file.zip
Sessions (Persist cookies & auth)
# Create/use named session (stored in ~/.config/httpie/sessions/) http --session=myapi POST https://api.example.com/login username=admin password=secret http --session=myapi GET https://api.example.com/profile # Read-only session (don't update it) http --session-read-only=myapi GET https://api.example.com/data
Useful Flags
--offline # Build and print request without sending it (dry-run) --follow # Follow redirects --timeout=10 # Set timeout in seconds (default: 0 = no timeout) --proxy=http:http://proxy:8080 # Use a proxy --verify=no # Skip SSL certificate verification (¿¿ dev only) --cert=./cert.pem # Client TLS certificate --stream # Stream response body (useful for SSE / long-polling) --quiet # Suppress output except errors
Scripting Patterns
Avoid stdin conflicts in scripts
When running HTTPie in a script or CI pipeline where stdin may not be a TTY, add
--ignore-stdin to avoid the "body from stdin and key=value cannot be mixed" error:
http --ignore-stdin POST https://api.example.com/users name=test active:=true
Use in shell pipelines
# Extract a field with jq TOKEN=$(http POST https://api.example.com/auth username=admin password=secret \ --pretty=none -b | jq -r '.token') # Pass token to next call http GET https://api.example.com/profile "Authorization:Bearer $TOKEN"
Exit codes with --check-status
if http --check-status --quiet GET https://api.example.com/health; then echo "API is up" else echo "API returned error" fi
Offline dry-run (inspect before sending)
http --offline POST https://api.example.com/users name=test active:=true
HTTPie vs curl Equivalents
| Goal | HTTPie | curl |
|---|---|---|
| GET request | | |
| POST JSON | | |
| Bearer auth | | |
| Show headers | | |
| Verbose | | |
Configuration
HTTPie config lives at
~/.config/httpie/config.json:
{ "default_options": ["--style=monokai", "--pretty=all", "--check-status"] }
Tips
- Always quote values with spaces:
description='hello world' - Escape colons in field names:
field\:name=value - GCP/cloud APIs: use
http -A bearer -a "$(gcloud auth print-access-token)" ... - Pipe JSON input:
cat payload.json | http POST https://api.example.com/endpoint - Debug CI pipelines: use
to validate request shape without actually calling the API--offline - Combine with
for powerful JSON manipulation in scriptsjq