JSON Output Contract¶
Bullpen commands that support --output json are intended for scripts, agents, and dashboards. This page defines the shared JSON contract used by command-reference pages.
Successful Output¶
Non-streaming commands emit a single JSON document to stdout and then exit. The top-level value is normally an object envelope with command-specific fields. Some older commands may emit an array or a narrower object; command pages document the representative top-level keys for automation.
Streaming commands, such as websocket watches, emit one JSON document per event line. Consumers should parse each line independently.
Upstream API Shape¶
--output json is the Bullpen command contract. It is not automatically the raw upstream API response.
Command docs use these terms when the distinction matters:
| label | meaning |
|---|---|
exact |
The command or documented adapter matches the upstream endpoint's method, parameters, and response shape. |
normalized |
Bullpen calls an upstream API or SDK path, then returns a stable Bullpen envelope or field names for CLI and agent use. |
proxied |
Bullpen intentionally routes through Bullpen services for auth, safety, or trade execution instead of calling the upstream endpoint directly. |
Polymarket trade placement commands such as bullpen polymarket buy, sell, limit-buy, and limit-sell are proxied through Bullpen's trade path. They should not be treated as raw CLOB POST /order calls. Read-only market data commands may also normalize rows for stable CLI output.
Error Envelope¶
When JSON mode can handle an error before process exit, the CLI emits a single JSON object. Consumers should accept this shape:
| key | type | nullable | notes |
|---|---|---|---|
ok |
boolean | yes | false when the central typed error envelope is present |
code |
string | yes | Stable dotted error family, for example auth.login_required, auth.device_login_stalled, wallet.selection_disagreement, or redeem.discovery_rate_limited; prefer this over prose when present |
recoverability |
string | yes | Machine-readable recovery class such as login_required, state_inspection_required, retryable_without_action, user_action_required, or support_required |
requires_login |
boolean | yes | Whether the next safe action requires bullpen login |
safe_to_retry |
boolean | yes | Whether the same operation can be retried without additional state inspection |
next_command |
string | yes | Single support-safe bullpen ... command to run next, if one exists |
support_safe_evidence |
object | yes | Redacted support context such as typed code, legacy error code, service, operation, auth state, or bounded device-login stall counters |
error |
string | no | Short human-readable failure summary |
error_code |
string | yes | Legacy or command-specific support code. Prefer code when both are present. |
support_safe_cause |
string | yes | Support-safe machine label for the diagnosed cause. It is a string enum, not a boolean. |
retryable_without_action |
boolean | yes | Whether the exact same command can be retried before running diagnostics or inspecting state. |
recovery_action |
string | yes | Ownership class for the next action, such as retry_later, contact_support, or support_backend_if_repeated. |
next_action |
string | yes | Human-readable next step when an older or command-specific envelope does not emit next_command. |
chain |
array |
yes | Sanitized cause chain when emitted by the central CLI error renderer; omits the top-level error frame |
caused_by |
array |
yes | Legacy error chain field when available |
hint |
string | yes | Recovery guidance when available |
recovery_command |
string | yes | Suggested bullpen ... command without internal sentinel wrappers |
recovery |
object | yes | Canonical money-path recovery projection for Polymarket trade, relayer, wallet-routing, redeem, and provider failures. Use this before scraping command-specific prose. |
recovery_plan |
object | yes | Shared account-level recovery plan emitted by bullpen fix, bullpen recover polymarket, bullpen support, and Polymarket wallet diagnostics. |
Legacy commands may emit only {"error": "..."}. Treat missing optional keys as
null. Agents should branch on code, requires_login, safe_to_retry, and
next_command when those fields are present, and should not start login,
forced logout, or money-moving retries from prose alone.
Wallet-routing diagnostics may include deposit_wallet_derivation. Valid values
include beacon_proxy, legacy_uups, and
legacy_uups_fallback_rpc_unavailable. Treat fallback provenance as evidence
quality, not as proof that the legacy address is the current trading wallet.
When retryable_without_action is false, do not keep retrying the same
command automatically. A command-specific next_action may still allow one
bounded retry before escalating, such as a repeated relayer 5xx support path.
Recovery Objects¶
Polymarket money-path errors may include a nested recovery object. It
normalizes older top-level fields into one machine-readable shape:
| key | type | notes |
|---|---|---|
schema_version |
integer | Recovery object schema version. Current value: 1. |
status |
string | Usually mirrors the top-level command status, such as error. Recovery previews may also use values such as diagnostic_required, diagnostic_incomplete, or support_required. |
error_code |
string | Stable support code for the failure. |
recovery_status |
string | Optional normalized recovery class, such as login_required, user_action_required, provider_transient, diagnostic_required, diagnostic_incomplete, support_required, or retryable. |
resolution_owner |
string | Who owns the next step: user, provider, Bullpen support, backend support, or unknown support inspection. |
next_action |
string | One human-safe next action. Prefer this over legacy prose fields when present. |
terminal |
boolean | Whether the current operation should stop until the next action completes. |
safe_to_retry |
boolean | Whether the same command may be retried without more state inspection. |
support_artifact |
string | Support-safe command to gather evidence when support owns the next step. |
evidence |
object | Redacted machine details copied from the command-specific envelope. |
Account-recovery commands emit recovery_plan instead of recovery.
recovery_plan has the same intent but describes account readiness rather than
one failed command. It includes status, title, reason, next_action,
terminal, safe_to_retry, resolution_owner, optional support_artifact,
and redacted evidence.
bullpen recover funds --dry-run --output json emits a consolidation plan. If
that preview cannot prove order-credit state, it includes a plan-shaped
recovery object with the same status, resolution_owner, terminal,
safe_to_retry, next_action, and optional support_artifact fields.
For bullpen support --output json, next_action is the account recovery next
step. support_next_action is the artifact-handling instruction.
Numeric Fields¶
Decimal values that represent token amounts, prices, rates, and balances may be serialized as strings to preserve precision. Examples include CLOB prices such as midpoint, Hyperliquid fields such as mark_px, and Solana token amounts. Consumers should parse numeric-as-string fields with decimal-safe libraries instead of binary floating point.
Integers used for counts, timestamps, and small indexes may be JSON numbers. When precision matters, prefer the type documented on the command page.
Some compatibility fields are raw token base units even when their names are
older and less explicit. For bullpen polymarket preflight --output json,
usdc_e_balance is the legacy raw micro-USDC.e value,
usdc_e_balance_base_units is the explicit raw micro-USDC.e value, and
usdc_e_balance_usd is the human-readable formatted value.
For bullpen polymarket positions --output json, redeemable is the
Bullpen-normalized actionable flag. It is true only when the row is expected to
pay non-zero value. upstream_redeemable preserves the raw Polymarket Data API
flag when available; a lost resolved row can have upstream_redeemable: true
and redeemable: false.
Schema Version¶
Commands may include schema_version at the top level. When present, it is an integer version for that command's JSON shape.
Commands that do not emit schema_version inherit contract version 1. Consumers should default absent schema_version to 1 and tolerate additional fields.
Simple Command Aliases¶
Simple user-journey commands such as bullpen trade buy,
bullpen trade sell, bullpen recover funds, and
bullpen recover redeem call the same underlying Polymarket handlers as the
detailed commands. In JSON mode, those simple commands may add a top-level
command_alias object:
| key | type | notes |
|---|---|---|
command_alias.command |
string | Simple command the user or agent ran, for example bullpen trade buy |
command_alias.underlying_command |
string | Detailed command family that produced the payload, for example bullpen polymarket buy |
command_alias.journey |
string | High-level journey, such as trade or recover |
Treat this object as additive metadata. It does not replace command-specific
fields and is not emitted by the detailed bullpen polymarket ... command when
run directly.
Most command pages document JSON output with worked examples. A smaller stable
subset also has machine-validated JSON Schemas under
reference/schemas/. Absence of a formal schema does not
mean JSON is unsupported; use the command page examples and this shared
contract for commands that do not yet have a dedicated schema file.
SIGPIPE Safety¶
JSON output is safe to pipe into tools such as head, jq, and shell pipelines. If the downstream reader closes the pipe early, Bullpen treats SIGPIPE or broken-pipe writes as a normal pipe termination and exits without printing a Rust panic or backtrace.
Stability¶
Patch releases may add optional or nullable fields and may add values to existing string enums. They should not remove documented fields, rename documented fields, or change documented field types.
Minor releases may add required fields, increment schema_version, or introduce a new envelope for a command when the old shape remains documented during migration.
Major releases may remove fields, rename fields, or change field types. Command pages and this contract should be updated in the same release.
Consumer Guidance¶
Treat unknown fields as non-breaking. Treat absent optional fields as null. For strict automation, validate the exact command path in the target Bullpen version and pin the CLI version used by production jobs.