Skip to content

two-inc/twoctl-cli

Repository files navigation

twoctl

ci Go Report Card License: MIT

Command-line interface for the Two merchant APIs. Generated from the public OpenAPI specs, so every endpoint is exposed as a subcommand.

Install

Homebrew

brew install two-inc/tap/twoctl

Binary releases

Download from releases and place on $PATH.

From source

go install github.com/two-inc/twoctl-cli/cmd/twoctl@latest

Shell completion

twoctl ships completions for bash, zsh, fish, and PowerShell. The binary generates them on demand via twoctl completion <shell>.

bash

Linux:

twoctl completion bash | sudo tee /etc/bash_completion.d/twoctl > /dev/null

macOS (with bash-completion@2 from Homebrew):

twoctl completion bash > "$(brew --prefix)/etc/bash_completion.d/twoctl"

If you don't have write access to a system path, source the completion in your ~/.bashrc:

echo 'source <(twoctl completion bash)' >> ~/.bashrc

zsh

# one-shot (re-run on shell start):
echo 'source <(twoctl completion zsh)' >> ~/.zshrc

# or persist to fpath:
twoctl completion zsh > "${fpath[1]}/_twoctl"

If compinit hasn't been initialised in your ~/.zshrc, add:

autoload -Uz compinit && compinit

before the completion source line.

fish

twoctl completion fish | source                                # current shell
twoctl completion fish > ~/.config/fish/completions/twoctl.fish # persistent

PowerShell

twoctl completion powershell | Out-String | Invoke-Expression                          # current session
twoctl completion powershell >> $PROFILE                                                # persistent

After installing, open a new shell. Tab-completion works on subcommands, flags, and any flag value that has a known enum in the OpenAPI spec (country codes, currencies, statuses).

Contexts

twoctl uses named contexts (kubectl-style). Each context bundles a base URL and an OS-keychain entry holding the API key, so you can switch between sandbox, prod, staging, cyber, perf, release, or any custom environment without copy-pasting keys.

twoctl ctx set sandbox --url https://api.sandbox.two.inc --key secret_test_...
twoctl ctx set prod    --url https://api.two.inc        --key secret_prod_...
twoctl ctx list                  # show all contexts, * marks current
twoctl ctx use prod              # switch the default
twoctl ctx current               # print the current name
twoctl ctx delete temp           # remove + clear keychain entry

Per-invocation overrides (no switching):

twoctl --env prod company company-search --country NO --q two
twoctl --context cyber checkout get-order --order-id abc   # kubectl-style alias
twoctl --url http://localhost:8080 --api-key secret_test_x ...

For built-in env names (prod, sandbox, staging, cyber, perf, release) twoctl knows the URL. For any other name it falls back to https://api.<name>.two.inc; override with --url.

API key resolution order (highest precedence first):

  1. --api-key flag
  2. TWO_API_KEY env var
  3. OS keychain entry for the active context

Keys are obtained from the Two merchant portal.

Usage

The command tree is resource-first: twoctl <resource> <action> [flags]. Every operation across every Two API is classified into a (resource, action) pair derived from the URL path + operationId, then registered under the resource. Non-CRUD actions like cancel, refund, fulfill, search, notify surface as first-class verbs alongside get/create/ edit/delete.

twoctl order get --order-id abc-123          # GET /v1/order/{order_id}
twoctl order create --file order.json        # POST /v1/order
twoctl order cancel --order-id abc-123       # POST /v1/order/{id}/cancel
twoctl order fulfill --order-id abc-123 --file f.json
twoctl order refund --order-id abc-123 --file r.json
twoctl order edit --order-id abc-123 --file patch.json
twoctl company search --q "two" --country NO
twoctl billing-account get --billing-account-id ba_xxx
twoctl explain order create                  # JSON schema for the operation
twoctl api-resources --resource order        # catalog filtered by resource
twoctl api-resources --action cancel         # everything that's a "cancel"

Run twoctl <resource> on its own to see every action available. Each leaf command's --help lists flags derived from the OpenAPI operation; request bodies go via --file path.json or --data '{...}'.

Top-level non-resource commands:

twoctl Purpose
config set-context / use-context / get-contexts / current-context / delete-context Manage contexts (kubectl naming)
auth login / logout / whoami Store the API key in the OS keychain
explain <resource> <action> JSON schema for an operation, no network call
api-resources JSON catalog of every operation, for agent discovery
version Print version and build info
upgrade Self-upgrade from the latest GitHub release
--context / --env (alias) Per-invocation context override

Agent-friendly features

twoctl is designed to be driven by both humans and LLM agents.

  • twoctl catalog [-a <api>] — emits a JSON catalogue of every operation (command, method, path, flags with kind/type/required, body status). Pipe this to an agent's planner so it can pick the right command without parsing --help text.
  • twoctl <api> <op> --describe — JSON view of one operation's full spec (parameters, request body schema, response schemas) without a network call.
  • twoctl <api> <op> --dry-run — render the HTTP request that would be sent (URL, redacted headers, body presence) and exit. No credentials needed.
  • Output defaults to pretty JSON on stdout, -o yaml for YAML.
  • Errors are emitted as JSON on stderr with shape {error, message, status, response}. Stdout stays clean for piping.

Exit codes

Code Meaning
0 success
1 generic error
2 usage / missing required input
3 authentication or authorisation (401/403)
4 not found (404)
5 rate limited (429)
6 server error (5xx)
7 network / transport failure

Self-upgrade

twoctl checks for new releases at most once every 24 hours and prompts when one is available. The prompt offers:

  • y install now
  • n not now (default)
  • s skip this version (won't ask again until the next release)

Direct controls:

twoctl upgrade                      # check + install
twoctl upgrade --check              # only report, don't install
twoctl upgrade --reset-skips        # forget every skipped version
twoctl upgrade --disable-autocheck  # silence the prompt entirely
twoctl upgrade --enable-autocheck   # turn it back on

--no-upgrade-check is a per-run override for scripts. State lives in ~/.config/twoctl/state.json.

APIs covered

Every operation across all six merchant-facing specs surfaces as a twoctl <verb> <resource> command. The verbs are auto-derived from operationId prefixes (get_/retrieve_/list_/search_, create_/make_/fulfill_/refund_/cancel_/... etc.), with HTTP-method fall-back when no prefix matches. Run twoctl api-resources for the full machine-readable catalog.

Spec Source
Checkout (Order) checkout-api.yaml
Billing Account billing-account-api.yaml
Repay repay-api.yaml
Recourse recourse-api.yaml
Company company-api.yaml
Limits limits-api.yaml

Regeneration

The openapi/ specs are vendored from two-inc/docs. When that source changes, a repository_dispatch event fires the regenerate.yml workflow, which pulls fresh specs, runs codegen, and opens a PR.

To regenerate locally:

./scripts/codegen.sh
go build ./...

Contributing

This repository is generated from the OpenAPI specs in two-inc/docs. Bug reports and PRs for the CLI itself (flags, output formatting, ergonomics) are welcome here. For API behaviour or schema changes, please open an issue against two-inc/docs.

Licence

MIT - see LICENSE.

About

Command-line interface for the Two merchant APIs

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors