Skip to main content
Agents consume JSON, not terminal tables. This page is the contract every other page in this section relies on: how to turn JSON on, the envelope shape, where output goes, and the stable codes the CLI guarantees. Read it once and branch on it. (Per-command flags live in the command reference.)

Get machine-readable output

Pass --json explicitly in scripts. The CLI also switches to JSON automatically when stdout is not a terminal, but an explicit flag keeps logs auditable.
TriggerResult
--jsonJSON on stdout.
--output json / --output tableForces JSON on, or human tables on.
Non-TTY stdout (piped or redirected)JSON automatically.
Precedence: --output wins, then --json, then the TTY check (non-terminal → JSON, terminal → human tables).
Data goes to stdout. Diagnostics, progress, and errors go to stderr. Parse stdout; never scrape stderr for results.

Read the success envelope

Almost every command returns the same two-field envelope. (The few that don’t are listed under envelope exceptions.)
schema
string
required
Stable identifier for the output shape, for example repost.events.search/v1. Branch on this — it is versioned and never changes meaning within a major version.
data
object
required
The command result. Its shape is determined by schema.
repost events search 'method:POST' --bucket stripe-prod --since 15m --limit 2 --json
Guard on schema, then read data. The same result, parsed two ways — this is your consuming code, not Repost internals:
result=$(repost events search 'method:POST' --bucket stripe-prod --since 15m --json)

# Fail loudly if the shape isn't the one you built against
echo "$result" | jq -e '.schema == "repost.events.search/v1"' >/dev/null

# Read fields; take the next page only when there is one
echo "$result" | jq -r '.data.items[] | select(.response_status >= 500) | .id'
next=$(echo "$result" | jq -r 'if .data.has_more then .data.next_cursor else empty end')
Event payloads in data are redacted by default — credential and signature headers and secret-like JSON keys are masked, but PII is not. See Transcript safety for exactly what is and isn’t removed.

Know the envelope exceptions

A few commands do not use the {schema, data} envelope. An agent that assumes a schema field everywhere will break on these.
CommandOutput
expectA single bare JSON object (no envelope, no schema). Always JSON, even without --json.
tailNDJSON — one bare JSON object per matching event, one per line. Always JSON.
capabilitiesTop-level { schema, version, commands }. Always JSON.
events get --body-onlyThe raw request body, no envelope.
docs schema{ schema, command, output_schema, output_mode, envelope, data_shape? }.
docs agent / docs searchMarkdown text, not JSON.
Wait commands (expect, tail) are covered in Wait for events. Discovery commands (capabilities, docs schema) are covered in Discovery.

Handle errors

When JSON is enabled, failures are structured: the error object goes to stderr and the process exits non-zero.
error.code
string
required
Stable machine code. Branch on this, never on the message.
error.message
string
required
Human-readable explanation. For people, not programs.
error.exit_code
integer
required
Mirrors the process exit status (see the table below).
error.hint
string
Suggested next step, when one applies.
error.docs
string
Always present; defaults to repost docs agent.
error.missing_scope
string
The exact scope to request. Present only on forbidden_scope.
error.token_creation_url
string
Where to mint a token with the missing scope. Present only on forbidden_scope.
repost replay evt_01JZ8V1 --bucket stripe-prod --forwarder prod-api --yes --json
Decide from error.code and exit_code, never from the human message:
# Capture stdout (data) and stderr (the error envelope) separately
if out=$(repost replay evt_01JZ8V1 --bucket stripe-prod --forwarder prod-api --yes --json 2>err.json); then
  echo "$out" | jq '.data'
else
  case "$(jq -r '.error.code' err.json)" in
    rate_limited|upstream_unavailable) action=retry ;;   # the only codes worth retrying
    forbidden_scope)                   action=request_scope ;;
    partial_failure)                   action=inspect ;;
    *)                                 action=fail ;;
  esac
  exit "$(jq -r '.error.exit_code' err.json)"
fi
error.codeexitWhenAgent response
validation_failed2Bad input — a client-side flag/argument check or HTTP 400/422Fix the command. Do not retry unchanged.
active_org_required2A user token can see zero or multiple licensed organizations, so a mutation has no unambiguous orgUse an organization token or select a user context with exactly one licensed org.
unauthorized3Invalid or missing token (401)Refresh or replace REPOST_TOKEN.
forbidden_scope3Token lacks a scope (403)Request missing_scope or take a read-only path.
not_found4Unknown id/bucket/forwarder (404)Verify the id and active organization.
quota_exceeded5Plan limit reached (402)Not transient. Stop or reduce scope.
rate_limited6Server limit (429)Back off, then retry.
timeout7expect / tail / replay wait deadline, or promote setup browser pairing deadlineReport the unmet wait. Inspect state before retrying.
partial_failure8health --fail-on breach; replay wait with failuresInspect details before declaring success.
conflict1State changed under you (409/412)Refresh state, then retry.
upstream_unavailable1Service error / unknown (5xx)Retry with backoff, then report instability.
validation_failed, active_org_required, forbidden_scope, and quota_exceeded are terminal — retrying the same command will fail the same way. Only rate_limited and upstream_unavailable are worth retrying.

Pin to a contract version

v1
Current contract
Every command schema is repost.<area>/v1. The success envelope is {schema, data}; the failure envelope is {error}. Exit codes 0–8 are stable. When a payload changes incompatibly, the schema suffix bumps (/v2) and both are served during migration — so an agent can pin to the version it was built against.

Continue

Authentication & scopes

Recover from unauthorized and forbidden_scope, and the read / write / secrets model.

Transcript safety

What events get / events diff mask in data — and what they leave in the clear.

Discovery

Pull each command’s exact data shape from the binary with docs schema.