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
incident_code string yes Stable incident label for support-owned terminal cases, for example PM_LEGACY_DEPOSIT_WALLET_PENDING_RECOVERY
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
terminal boolean yes Whether the command should stop until the next action completes
write_mutations_allowed boolean yes Whether CLI write commands are allowed for the diagnosed state
backend_action_required boolean yes Whether support-side action is required before local writes are safe
status_source string | null yes Authoritative recovery-status source when available; null means unavailable
status_updated_at string | null yes Authoritative recovery-status timestamp when available; null means unavailable
eta string | null yes Recovery ETA when authoritative service data exists; null means unavailable
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. Follow the command-specific next_action. Relayer submit failures with an unknown outcome require state reconciliation before any retry.

Native-USDC pre-swap failures identify operation, route_owner, the downstream execution route, resolution_owner, submission_state, safe_to_retry, next_action, next_command, and an optional transfer trace and balance proof. Human and JSON output use the same recovery policy. These fields describe the pre-swap only. They do not imply that the separate Polymarket wrap relayer batch was submitted. Compatibility output derived from an older text-only failure includes classification_source: "legacy_string_fallback"; typed failures do not claim that legacy provenance. When submission is not_submitted, the emitted read-only diagnostic is:

bullpen funds diagnose-deposit --chain polygon --token usdc --output json

Live native-USDC wraps may return less USDC.e than the original request. The CLI proceeds only when the proven output is at least 99% of the approved native USDC input. In that bounded case, requested_amount and requested_amount_raw preserve the original request while amount and amount_raw identify the amount actually submitted to approve and wrap.

Live native-POL sweep output includes operation, route_owner, submission_state, safe_to_retry, receipt_status, verification, and balance_proof. Treat route_owner as routing metadata, not as user action. A confirmed receipt without the expected source and recipient balance movement is a hard failure and exits nonzero.

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.
incident_code string Stable incident label when the recovery object describes a support-owned incident.
code string Alias for the stable incident or error code when emitted by the command.
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, or unknown support inspection.
next_action string One human-safe next action. Prefer this over legacy prose fields when present.
next_command string One support-safe command to run next when a command is required.
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.
funds_onchain_recoverable boolean Whether the diagnosed funds are recoverable on-chain.
cli_can_recover boolean Whether the CLI can perform the recovery without support-side action.
write_mutations_allowed boolean Whether CLI write commands are allowed for the diagnosed state.
backend_action_required boolean Whether support-side action is required before local writes are safe.
blocked_actions array Local action classes that should not be retried for the diagnosed state.
status_source string | null Authoritative recovery-status source when available; null means unavailable.
status_updated_at string | null Authoritative recovery-status timestamp when available; null means unavailable.
eta string | null Recovery ETA when authoritative service data exists; null means unavailable.
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.

For PM_LEGACY_DEPOSIT_WALLET_PENDING_RECOVERY, the canonical contract is: funds are safe and recoverable on-chain, cli_can_recover: false, safe_to_retry: false, write_mutations_allowed: false, backend_action_required: true, and next_command: "bullpen support bundle --output json". Do not retry approve, activate, reregister, wrap, trade, wallet selection, redeposit, or login for that wallet. status_source, status_updated_at, and eta remain null until authoritative service data exists.

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. Support artifacts also include delivery.state: "local_file_not_uploaded", delivery.uploaded: false, and delivery.artifact_path; the file is on this machine and has not been uploaded. Attach the JSON file to your support ticket. When originating_context is present, it contains only the recent command family and typed error code, not raw arguments or error text.

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.