A flexible command-line tool for automating REST API interactions.
api-tool is designed to streamline interactions with REST APIs through a powerful command-line interface and configuration files. It supports both simple, single API requests and complex, multi-step chain workflows, making it ideal for various automation tasks.
Whether you need to fetch data, upload files, authenticate using different methods, handle pagination, or orchestrate a sequence of API calls while passing data between them, api-tool provides the necessary flexibility and features.
It is built with containerization in mind (e.g., Docker) and can serve as a core component in broader automation pipelines, potentially alongside data processing tools like etl-tool.
- Single Request Mode: Execute individual API calls directly from the command line with configuration overrides.
- Chain Workflow Mode: Define complex, multi-step workflows involving multiple API calls, local data filtering, and variable extraction/passing.
- Flexible Authentication: Supports various authentication methods:
noneapi_key(via config credentials)basic(via config credentials)bearer(viaAPI_TOKENenvironment variable or config credentials)digest(MD5/SHA-256, with FIPS mode support)ntlmoauth2(Client Credentials Flow)
- Robust Pagination: Handles common pagination strategies automatically:
offset/page(query or body parameters)cursor(from response body/header, used in next query/body/URL)link_header(RFC 5988 rel="next")
- Data Extraction: Extract data from API response bodies using JQ filters or from response headers using regular expressions.
- File Handling: Upload raw file content or build multipart/form-data requests. Download response bodies directly to files.
- Templating: Utilize Go's
text/templatesyntax ({{.VarName}}) in configuration values (URLs, headers, data payloads, file paths, JQ filters). - Environment Variable Expansion: Seamlessly expand both Unix-style (
$VAR,${VAR}) and Windows-style (%VAR%) environment variables in configuration values. - Retry Logic: Configure automatic retries for requests based on status codes, with exponential backoff and exclusion options.
- Configurable Logging: Control log verbosity (
none,error,warn,info,debug). - TLS Verification Control: Option to skip TLS certificate verification for specific APIs.
- Cookie Jar Support: Maintain cookies across multiple requests within an API or across steps in a chain.
- FIPS Mode: Enforce the use of FIPS-compliant cryptographic algorithms (currently affects Digest authentication, disallowing MD5).
Download the latest pre-compiled binary for your operating system from the Releases Page. (Add link to your releases here)
Extract the archive and place the api-tool executable in a directory included in your system's PATH.
Ensure you have Go (version 1.22 or later recommended) installed and configured.
# Clone the repository
git clone https://github.com/brian-c-moore/api-tool.git
cd api-tool
# Tidy dependencies
go mod tidy
# Build the binary
go build -o api-tool ./cmd/api-tool/
# (Optional) Install to your Go bin directory
go install ./cmd/api-tool/
# Make sure $GOPATH/bin (or $HOME/go/bin) is in your PATHapi-tool operates in two primary modes: single request or chain workflow.
Usage:
api-tool [options]
Options:
-config string YAML configuration file (default "config.yaml")
-chain Run in chain workflow mode (requires a 'chain' section in config)
-api string API name for single request mode (required if not using -chain)
-endpoint string Endpoint name for single request mode (required if not using -chain)
-method string Override HTTP method for single request mode
-headers string Additional headers for single request mode (Key:Value,...)
-data string JSON payload for POST/PUT requests in single request mode
-loglevel string Logging level (none, error, warn, info, debug) (default "info")
-help Show help
# Simple GET request using defaults from config.yaml
api-tool -api myapi -endpoint get_users
# GET request with debug logging, specifying config file
api-tool -config=prod.yaml -api user_service -endpoint get_user_by_id -loglevel=debug
# POST request overriding method and providing data payload
api-tool -api data_service -endpoint create_record -method POST -data '{"name": "New Item", "value": 100}'
# GET request with custom headers
api-tool -api report_api -endpoint download_report -headers "Accept:application/pdf,X-Custom-ID:request123"# Run the chain defined in chain_config.yaml with info logging
api-tool -config=chain_config.yaml -chain -loglevel=infoConfiguration is provided in YAML format (e.g., config.yaml) and includes:
- Global retry and logging settings
- Global authentication definitions
- API-specific configurations
- Endpoint definitions
- Pagination strategies
- Chain workflows
A full configuration example is provided in the original documentation (see full README).
- none: No authentication
- basic: Requires
usernameandpasswordinauth.credentials - api_key: Requires
api_keyinauth.credentials. SendsAuthorization: Bearer <api_key> - bearer: Uses
API_TOKENenv var orbearer_tokenfrom config - digest: Uses
usernameandpassword. Supports MD5/SHA-256 (MD5 disabled in FIPS mode) - ntlm: Uses
usernameandpassword - oauth2: Client Credentials Flow. Requires
client_id,client_secret,token_url
Use environment variables to keep credentials secure (e.g., %DB_PASSWORD% or $DB_PASSWORD).
Pagination is configured per endpoint using the pagination block.
Types:
offset,pagecursorlink_header
For offset and page, use:
limit,offset_param,page_param,size_param,strategy,start_page, etc.
For cursor, use:
next_fieldornext_headercursor_usage_mode:query,body,urlcursor_param
For link_header, the Link header is parsed according to RFC 5988.
Chains are defined under the chain: key in the config file.
Each chain contains:
variables: Initial state (env vars merged automatically)steps: Sequence of operations including API calls, filters, and file operationsoutput: Optional final output written to a file
Steps may include:
- API request definitions
- Filters using
jq - Extract operations (e.g., headers, body values)
- File uploads and downloads
- Header injections with Go templates
Templating uses Go’s text/template syntax: {{.VariableName}}
Environment variables are expanded before rendering templates:
- Unix-style:
$VARor${VAR} - Windows-style:
%VAR%
You can mix environment and chain variables in paths, headers, data, filters, and more.
Enable FIPS mode via:
fips_mode: trueIn FIPS mode:
- Digest auth will not allow MD5
- Other cryptographic functions depend on Go and OS crypto library
Run tests with:
# Ensure dependencies are tidy
go mod tidy
# Run all tests
go test ./...
# Run tests with verbose output
go test ./... -vExample test output:
? api-tool/cmd/api-tool [no test files]
ok api-tool/internal/app 0.195s
ok api-tool/internal/auth 0.330s
ok api-tool/internal/chain 0.606s
ok api-tool/internal/config 0.422s
ok api-tool/internal/executor 0.743s
ok api-tool/internal/httpclient 0.882s
ok api-tool/internal/jq 1.011s
ok api-tool/internal/logging 1.123s
ok api-tool/internal/template 1.143s
ok api-tool/internal/util 0.992s
Tests use mocks for external dependencies (HTTP, file I/O, jq) for fast and reliable execution.
Contributions are welcome! Follow these steps:
- Fork the repository
- Create a feature branch:
git checkout -b feature/my-feature
- Make changes. Format and lint code:
go fmt ./...
- Add or update tests
- Run all tests and ensure they pass:
go test ./... - Commit and push:
git commit -am "Add my feature" git push origin feature/my-feature - Open a Pull Request
This project is licensed under the MIT License. See the LICENSE file for details.
This tool was designed to address a gap I saw in existing automation tools. Golang seemed like the best choice to accomplish my goals, but my experience has been with other programming languages. I’ve leveraged AI for assistance with coding and as a way to teach myself a new language while building something useful. The overall design, architecture, and direction are entirely my own.