Skip to content

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.