capctl is built to be driven by scripts, cron, and CI. This page collects the machine-facing contract in one place.
Provide credentials via environment variables (never via flags — flags leak into
ps and shell history):
export CAP_API_KEY=... # required
export CAP_IDENTIFIER=you@example.com
export CAP_API_PASSWORD=... # the API-key custom password
export CAP_ENV=demo # stay on demo until provenOr point at a file with --env-file /path/to/.env.
- capctl never prompts. Mutating commands require
--yes; without it they fail closed (exit code 4) rather than hang — safe for CI. - Use
--jsonfor machine-readable output and--plainfor tab-delimited rows. - Disable color with
--no-colororNO_COLOR=1. - The global flags
--json,--plain, and--no-colorwork in any position —capctl session status --jsonis equivalent tocapctl --json session status.
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | Unexpected internal error |
| 2 | Invalid input |
| 3 | Configuration error (missing/invalid credentials) |
| 4 | Safety policy block (trading disabled, dry-run, confirm required, epic not allowed, risk limit) |
| 5 | Authentication/session failure |
| 6 | Local rate limit exceeded |
| 7 | Broker / upstream API error |
| 8 | Preview not found, expired, or failed checks |
| 130 | Interrupted (Ctrl-C) |
Branch on them directly:
capctl --json trade execute-position "$PREVIEW" --yes
case $? in
0) echo filled ;;
4) echo "blocked by safety policy" ;;
5) echo "auth problem" ;;
7) echo "broker/upstream error" ;;
esacA confirmation result of {"status": "TIMEOUT"} (from execute-position,
execute-order, close, cancel, or amend-* with --wait) is ambiguous:
the request may have reached the broker and the order may have landed — capctl
simply stopped waiting for the confirmation. There is no broker idempotency
key, so blindly re-running execute-* can place a duplicate order.
On TIMEOUT, an automation or agent MUST reconcile before retrying:
capctl --json trade execute-position "$PREVIEW" --yes
# If the confirmation status is TIMEOUT, do NOT resend. Reconcile first:
capctl --json trade positions # did the position appear?
capctl --json trade orders # or did a working order land?
# Only retry execute-* if neither shows the intended order.The same applies to close/cancel/amend-*: re-check trade positions /
trade orders to see whether the mutation already took effect.
Extract the GOLD bid:
capctl --json market search --epics GOLD | jq -r '.markets[0].bid'Export daily candles to CSV:
capctl --json market prices GOLD --resolution DAY --max 200 \
| jq -r '.prices[] | [.snapshotTime, .openPrice.bid, .highPrice.bid, .lowPrice.bid, .closePrice.bid] | @csv'Total unrealised P&L across open positions:
capctl --json trade positions | jq '[.positions[].position.upl] | add'capctl --plain market search --epics GOLD,SILVER | cut -f1,3