README
¶
dot-http
A CLI tool for executing .http files — the same format used by the dot-http VSCode extension.
This project includes two components:
- CLI tool (
dot-http) — run.httpfiles from the terminal - VSCode extension — run
.httpfiles directly inside VS Code (see vsc-extension/)
Install
go install github.com/oktalz/dot-http@latest
Usage
dot-http [flags] <file.http> [request-name]
Flags
| Flag | Description |
|---|---|
-v |
Print version and exit |
-V |
Verbose: print request details before sending |
-H |
Print response headers only (no body) |
-B |
Print response body only (no headers) |
-o <file> |
Save response body to a file |
--env <name> |
Load <name>.env instead of .env |
--timeout <dur> |
Request timeout, e.g. 30s, 1m (default: none) |
--no-follow |
Do not follow redirects |
--session <file> |
Load/save cookies from/to a JSON session file |
--junit <file> |
Write JUnit XML test report to file |
Features
HTTP methods
All standard methods: GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS, CONNECT, TRACE.
.http file format
Requests are separated by ###. Each block can have headers (key: value lines after the method line) and a body (everything after the first blank line).
GET https://api.example.com/users
###
POST https://api.example.com/users
Content-Type: application/json
{
"name": "John"
}
Variables
File variables — defined at the top of the .http file:
@baseUrl = https://api.example.com
###
GET {{baseUrl}}/users
Environment variables — from system environment and a .env file in the current working directory (system env takes precedence):
API_URL=https://api.example.com
TOKEN="secret"
GET {{API_URL}}/users
Authorization: Bearer {{TOKEN}}
Precedence (highest to lowest):
- System environment variables
.envfile (or<name>.envwhen using--env <name>)- File variables (
@var = value)
Use {{$env VAR}} or {{VAR}} — both resolve through the same lookup.
Multiple environments
Use --env to load a named environment file:
dot-http --env prod api.http # loads prod.env
dot-http --env staging api.http # loads staging.env
Per-request directives
Per-request directives use bare @ syntax: @name, @requires, @expect, @assert, @no-follow, @oauth2-*. Lines starting with # are treated as comments — useful for disabling a directive without deleting it:
@expect 201
# @expect 500 ← commented out, ignored
Request chaining
Name a request with @name and reference its response in subsequent requests using dot notation:
@name = login
POST https://api.example.com/auth
Content-Type: application/json
{"username": "user", "password": "pass"}
###
@requires = login
GET https://api.example.com/profile
Authorization: Bearer {{login.body.token}}
Available response fields:
{{name.body.field}}— JSON response body (dot notation for nested fields){{name.headers.Content-Type}}— response headers
Parameterized dependencies
Pass arguments to dependencies to reuse the same request with different parameters:
@name = getUser
GET https://api.example.com/users/{{id}}
###
@requires = getUser(id=1)
@requires = getUser(id=2)
GET https://api.example.com/compare
To use the responses from individual calls, give each one an alias with as <name>:
@name = getUser
GET https://api.example.com/users/{{id}}
###
@requires = getUser(id=1) as user1
@requires = getUser(id=2) as user2
GET https://api.example.com/compare?a={{user1.body.name}}&b={{user2.body.name}}
Without an alias, repeated calls to the same dependency overwrite each other in the response context, so only the last call's response is reachable as {{getUser.body...}}.
Assertions & testing
Use @expect to assert the response status code, and @assert for header/body checks. Exit code is non-zero on failure — suitable for CI.
@name = createUser
@expect 201
@assert body.name == John
@assert header.Content-Type contains application/json
POST https://api.example.com/users
Content-Type: application/json
{"name": "John"}
Supported operators: ==, !=, contains, !contains
Assertion targets:
status— HTTP status codebody.<path>— JSON body field (dot notation)header.<Name>— response header value
Disabling redirects per request
Use @no-follow to disable redirect following for a single request — useful for inspecting Location headers or asserting on the redirect itself:
@expect 302
@assert header.Location == https://example.com/new
@no-follow
GET https://example.com/old
This works in both the CLI and the VS Code extension. The CLI's --no-follow flag still applies globally to every request.
JUnit XML reports
Generate a JUnit-compatible XML report for CI/CD systems (GitHub Actions, Jenkins, etc.):
dot-http --junit report.xml api.http
GraphQL
Set Content-Type: application/graphql and write the query as the body — it will be automatically wrapped as {"query": "..."} JSON:
POST https://api.example.com/graphql
Content-Type: application/graphql
{
users {
id
name
}
}
Cookie sessions
Persist cookies between runs using a session file:
dot-http --session session.json api.http login
dot-http --session session.json api.http profile # reuses cookies from login
Importing other files
Split requests across files using @import. Imported files make their named requests and variables available to the current file.
@import = auth.http
@import = helpers/users.http
###
@requires = login
GET https://api.example.com/profile
Authorization: Bearer {{login.body.token}}
- Paths are relative to the importing file's directory
- Multiple
@importdirectives are supported - Imports are recursive (imported files can import other files)
- Cyclic imports are detected and safely skipped
Circular dependency detection
The tool detects and reports circular dependencies with an error message.
OAuth2
Declare OAuth2 directives as per-request directives. The token is acquired automatically and injected as Authorization: Bearer <token>. Tokens are cached with expiry so re-runs don't re-authenticate.
Client Credentials (machine-to-machine)
@oauth2-grant = client_credentials
@oauth2-token-url = https://auth.example.com/oauth/token
@oauth2-client-id = {{CLIENT_ID}}
@oauth2-client-secret = {{CLIENT_SECRET}}
@oauth2-scope = read write
GET https://api.example.com/resource
Authorization Code + PKCE (browser flow)
Spins up a local server, opens the browser, captures the code, exchanges it for a token.
@oauth2-grant = authorization_code
@oauth2-token-url = https://auth.example.com/oauth/token
@oauth2-auth-url = https://auth.example.com/oauth/authorize
@oauth2-client-id = {{CLIENT_ID}}
@oauth2-scope = openid profile
@oauth2-redirect-port = 9876
GET https://api.example.com/resource
Device Code Flow
Prints the verification URL and user code, then polls until approved.
@oauth2-grant = device_code
@oauth2-token-url = https://auth.example.com/oauth/token
@oauth2-device-url = https://auth.example.com/oauth/device/code
@oauth2-client-id = {{CLIENT_ID}}
@oauth2-scope = read
GET https://api.example.com/resource
Token caching
Add @oauth2-cache at the file level to persist tokens across runs:
@oauth2-cache = .tokens.json
Examples
# Run the last request in the file
dot-http api.http
# Run a specific named request (and its dependencies)
dot-http api.http login
# Print version
dot-http -v
# Verbose: show request details before sending
dot-http -V api.http login
# Headers only
dot-http -H api.http login
# Body only (useful for piping to jq, etc.)
dot-http -B api.http login | jq .
# Save response body to file
dot-http -o response.json api.http
# Use a named environment
dot-http --env prod api.http deploy
# Set a request timeout
dot-http --timeout 10s api.http slow_request
# Do not follow redirects
dot-http --no-follow api.http check_redirect
# Persist cookies across requests
dot-http --session cookies.json api.http login
# Run assertions and output JUnit report
dot-http --junit results.xml api.http create_user
Output includes the full HTTP response (status, headers, body) with JSON pretty-printing.
Documentation
¶
There is no documentation for this package.