This document is the canonical contract for the paybond CLI shipped by both kits:
- TypeScript:
@paybond/kitexposes thepaybondbinary. - Python:
paybond-kitexposes thepaybondbinary.
Both implementations must expose the same command names, global flags, JSON output keys, exit codes, error categories, and redaction behavior. Parity tests compare --help, JSON schemas, and error handling across both kits.
Legacy entry points remain as thin wrappers over this tree:
| Legacy alias | Canonical command |
|---|---|
paybond-kit-login | paybond login |
paybond-init / paybond-kit-init | paybond init guardrail |
paybond-mcp-server | paybond mcp serve |
Design rules
- Tenant scope always comes from authenticated credentials (
PAYBOND_API_KEYor the configured env file). Normal tenant-scoped commands must not accept tenant IDs from unauthenticated CLI arguments. - Human output defaults to safe, masked values suitable for terminals and CI logs.
- Machine output uses
--format jsonand returns stable, documented keys. JSON mode never omits required envelope fields. - Destructive or live-money actions require
--yesand are still subject to server-side RBAC. - Secrets on disk use file mode
0600. Default.env.localtargets are added to.gitignorewhen needed. Custom env-file paths inside a git repo must already be ignored.
Global flags
These flags are accepted on every subcommand unless a command explicitly documents an exception. Global flags may appear before or after the subcommand.
| Flag | Default | Description |
|---|---|---|
--gateway <url> | https://api.paybond.ai | Gateway base URL for authenticated API calls. |
--env-file <path> | .env.local | Local secrets file containing PAYBOND_API_KEY. Login writes here; other commands read from here unless the key is already in the process environment. |
--format table|json | table | Human table output or stable JSON envelope (see below). |
--profile <name> | (unset) | Named credential profile stored in the Paybond CLI config file. When set, overrides --env-file for credential resolution. |
--request-id <id> | (generated) | Correlation ID sent to Gateway on API calls and echoed in JSON output. When omitted, the CLI generates a ULID-style identifier. |
--yes | false | Skip interactive confirmation for destructive or irreversible operations. |
--no-open | false | Do not open a browser for device login or other browser-assisted flows. |
Commands may define additional flags. Command-specific flags must not redefine global flag names with different semantics.
Output formats
Table (default)
- Write human-readable lines to stdout.
- Write errors to stderr.
- Apply redaction rules to every field before printing.
- Do not print raw API keys, capability tokens, signing seeds, or API bearer tokens.
- Success lines should be concise and actionable (for example, masked key identity, resource IDs, and next steps).
JSON (--format json)
Every JSON response uses one envelope regardless of command:
{ "ok": true, "command": "whoami", "data": {}, "warnings": [], "request_id": "01JABY5EXAMPLE", "error": null }
On failure:
{ "ok": false, "command": "keys revoke", "data": null, "warnings": [], "request_id": "01JABY5EXAMPLE", "error": { "category": "forbidden", "code": "cli.rbac.denied", "message": "caller lacks keys:revoke permission", "details": { "gateway_status": 403, "gateway_code": "auth.forbidden" } } }
Envelope fields:
| Field | Type | Description |
|---|---|---|
ok | boolean | true on success, false on failure. |
command | string | Canonical command path (for example, login, whoami, audit exports list). |
data | object | null | Command payload on success; null on failure. |
warnings | string[] | Non-fatal notices (for example, skipped browser open). |
request_id | string | Correlation identifier for support and log correlation. |
error | object | null | Populated on failure; null on success. |
Error object fields:
| Field | Type | Description |
|---|---|---|
category | string | Stable error class (see error categories). |
code | string | Stable machine-readable code (cli.* for local errors; Gateway error.code when proxied). |
message | string | Safe, loggable summary without secrets. |
details | object | Optional structured context (HTTP status, resource IDs, confirmation hints). |
JSON mode writes the envelope to stdout only (including failures). Exit code still reflects success or failure.
Exit codes
| Code | Meaning |
|---|---|
0 | Success. |
1 | General failure: usage error, validation error, business-state conflict, or unclassified CLI error. |
2 | Authentication failure: missing, invalid, or expired credentials. |
3 | Authorization failure: authenticated but RBAC or entitlement denied. |
4 | Confirmation required: destructive command run without --yes. |
5 | Gateway or upstream unavailable (503, network failure, timeout). |
6 | Local environment failure: unreadable env file, git-ignore refusal, filesystem permission error. |
When Gateway returns a structured error, the CLI maps HTTP status to exit code:
| HTTP status | Exit code | Error category |
|---|---|---|
400, 409, 422, 428 | 1 | validation |
401 | 2 | auth |
403 | 3 | forbidden |
404 | 1 | not_found |
410 | 1 | gone |
429 | 5 | rate_limit |
500, 502, 503, 504 | 5 | gateway |
Error categories
| Category | When used |
|---|---|
usage | Unknown command, invalid flag, or missing required argument. |
auth | Credential missing, malformed, expired, or rejected by Gateway principal lookup. |
forbidden | Authenticated caller lacks the required role or entitlement. |
validation | Request rejected because of invalid input or incompatible resource state. |
not_found | Resource absent in the authenticated tenant scope. |
gone | Temporary download or export no longer available. |
confirmation_required | Destructive command attempted without --yes. |
rate_limit | Gateway rate limit exceeded. |
gateway | Upstream Gateway or dependency error. |
network | Transport failure before a structured Gateway response is received. |
environment | Local filesystem, git-ignore, or permission failure. |
internal | Unexpected CLI bug; should be rare. |
Redaction rules
Apply these rules in table output and in any human-readable log lines. JSON data fields follow the per-command schema below; secret fields are omitted or replaced with masked placeholders unless the command explicitly documents a full-value JSON field for automation.
| Material | Table output | JSON data |
|---|---|---|
API key (paybond_sk_*) | Mask to paybond_sk_{env}_{first8}...{last4}; fallback paybond_sk_... | key_masked in list/read responses; include one-time plaintext api_key only for keys create and keys rotate when the Gateway returns a new secret; never include the raw login secret in JSON (login uses key_written instead) |
| Capability token | Never print | capability_token allowed only when the command creates or returns a new token for immediate use (for example, guardrails bootstrap); otherwise omit |
| Gateway bearer token | Never print | Never include |
| Signing seed / private key material | Never print | Never include |
| Device codes during login | Print user_code and verification URL (required for approval); never print device_code | Include user_code and verification_uri; omit device_code |
request_id from Gateway | Print when present | Always echo in envelope and in proxied error details |
Key masking algorithm (both kits must match):
- Split the key on
_. - When the shape is
paybond_sk_{environment}_{key_id}_{secret}, emitpaybond_sk_{environment}_{key_id[0:8]}...{key_id[-4:]}whenlen(key_id) > 12, otherwisepaybond_sk_{environment}_redacted. - Otherwise emit
paybond_sk_....
Command tree
Top-level invocation:
paybond [--global-flags] <command> [<subcommand> ...] [args] [--command-flags] paybond --help paybond <command> --help
paybond login
Sandbox device login. Writes PAYBOND_API_KEY to the env file.
| Flag | Default | Notes |
|---|---|---|
--env sandbox | sandbox | Only sandbox is supported. Live device login is rejected. |
--force | false | Replace an existing PAYBOND_API_KEY in the target env file. |
Inherits global flags --gateway, --env-file, --no-open, --format.
Table output (success): verification URL, user code, env file path, masked key, target tenant, optional expiry notice.
login is the one command that intentionally performs a local secret write; it still never prints the raw key.
JSON data fields:
| Field | Type |
|---|---|
env_file | string |
key_masked | string |
key_written | boolean |
tenant_id | string |
tenant_uuid | string |
environment | string |
expires_at | string (RFC 3339, optional) |
verification_uri | string |
user_code | string |
These next four commands are post-login operator surfaces. They do not replace login, init, doctor, or dev loop for first success — use them after credentials exist to inspect state, script sticky context, or deep-link into Console for rare admin tasks.
paybond status
Summarize sandbox auth, the local policy file, last smoke/trace event, and the local trace dashboard URL. Tenant scope comes from authenticated credentials only — never from CLI tenant flags. Useful offline even when principal lookup fails (auth still reports key presence / next steps).
| Flag | Default | Notes |
|---|---|---|
--policy-file <path> | paybond.policy.yaml | Local policy path to check for presence/mtime. |
Inherits global --format, --gateway, --env-file, --profile.
JSON data fields:
| Field | Type |
|---|---|
auth | object — authenticated, source, env_file, gateway, optional key_masked, profile, tenant_id, tenant_uuid, environment, service_account_role, or principal_error / next when unresolved |
policy | object — path, present, optional mtime, bytes |
last_smoke | object | null — recorded_at, operation, authorized, run_id, intent_id, source (dev-trace | dev-audit) |
trace | object — url, port, file meta, event_count |
audit_log | object — file meta for .paybond/dev-audit.jsonl |
happy_path | string[] — canonical first-success command hints |
next_commands | string[] |
Examples: paybond status, paybond status --format json. Suggested next: paybond control --once --format json.
paybond shell
Interactive REPL with sticky --gateway / --env-file / --profile context (Heroku-style). Nested shell or control inside the REPL is refused. Non-TTY, CI, and --format json must not hang — use --exec for one-shot.
| Flag | Default | Notes |
|---|---|---|
--exec "<command>" | (unset) | Run one sticky-context command line and exit (required in CI / non-TTY / JSON). |
JSON data fields:
| Mode | Fields |
|---|---|
exec | mode, command, exit_code, sticky (gateway, env_file, profile) — or exited when the line was exit/quit |
repl | mode, commands_run, sticky |
Examples: paybond shell, paybond shell --exec "status", paybond shell --exec "whoami --format json".
paybond control
Live read-mostly control-plane TUI over gateway intents, agent receipts, local policy, spend decisions, and denials. TypeScript uses Ink; Python uses a terminal panel loop. Honors NO_COLOR and TTY detection. Tenant scope comes from authenticated credentials only.
| Flag | Default | Notes |
|---|---|---|
--once | false | Print a snapshot and exit (no TUI). Implied when --format json or non-interactive. |
--policy-file <path> | paybond.policy.yaml | Local policy panel source. |
--limit <n> | 10 | Max rows per list panel (positive integer). |
JSON / snapshot data fields: mode (snapshot | tui), active_panel, tenant_id, environment, gateway, trace_url, panels (intents, receipts, policy, spend, denials), generated_at, limitations[], and next_commands[] in snapshot mode.
Examples: paybond control, paybond control --once --format json, paybond control --once --limit 5.
paybond open
Explicit deep-link escape hatch to Console (or local trace / docs) for rare admin tasks. Not the default path for day-to-day Kit work — prefer status, control, and shell.
paybond open <resource> [<id>] [--port <n>] [--no-open]
| Resource | Target |
|---|---|
console | /console |
billing | /console/configuration/billing |
sso | /console/configuration/identity/sso |
scim | /console/configuration/identity/scim |
compliance-exports | /console/investigations/compliance-exports |
intent <intent_id> | Intent dossier in Console |
export <job_id> | Compliance export job in Console |
trace [<run_id>] | Local trace dashboard (http://127.0.0.1:9477, optional run deep link) |
docs | Kit docs |
| Flag | Default | Notes |
|---|---|---|
--port <n> | 9477 | Trace dashboard port (for open trace only). |
--no-open | false | Print the URL without launching a browser (also honors global --no-open). |
Console origin: PAYBOND_CONSOLE_BASE_URL or PAYBOND_PUBLIC_BASE_URL, else http://127.0.0.1:3000. Docs origin: PAYBOND_DOCS_BASE_URL, else https://paybond.ai/docs.
JSON data fields: resource, url, purpose, opened, note.
Examples: paybond open console, paybond open billing --no-open, paybond open intent <uuid>, paybond open export job-123 --no-open, paybond open trace.
paybond init guardrail
Scaffold a sandbox paid-tool guardrail integration file.
| Flag | Default |
|---|---|
--preset paid-tool-guard | paid-tool-guard |
--framework <name> | provider-agnostic |
--out <path> | paybond-paid-tool-guard.ts or paybond_paid_tool_guard.py |
--force | false |
Allowed --framework values: generic, provider-agnostic, openai, claude, anthropic, gemini, google-ai, vercel-ai, langgraph, mcp.
JSON data fields: out, preset, framework, bytes_written.
paybond mcp
| Subcommand | Description |
|---|---|
serve | Start the MCP server over stdio (default) or Streamable HTTP (--transport http; replaces paybond-mcp-server). |
install | Write MCP host configuration for Claude, Codex, OpenAI, or generic stdio clients. |
tools | List tools exposed by the local MCP server. |
mcp install flags:
| Flag | Default |
|---|---|
--host claude|codex|openai|generic | (required) |
--scope local|project|user | project |
--env-file <path> | .env.local |
Generated MCP configs must reference PAYBOND_ENV_FILE by default, not embed raw API keys.
JSON data fields (install): host, scope, config_path, server_command, printed. When printed is true (local scope) and --format json is set, payload contains the generated config text.
paybond doctor
Validate local runtime, package version, env file, key shape, principal lookup, and optional agent/MCP setup.
| Flag | Default |
|---|---|
--agent | false — when set, also validate MCP server startup and tool listing. |
JSON data fields: checks[] with { name, ok, message, details? }, summary (pass | fail).
With --agent, also runs agent middleware sandbox smoke when sandbox credentials are present.
paybond adyen
Read-only BYO Adyen Checkout settlement readiness against GET /v1/admin/settlement/config. Does not upsert API keys, HMAC secrets, or stored payment methods — use Console Settlement or POST /v1/admin/settlement/adyen/destination.
| Subcommand | Description |
|---|---|
ready | Checklist: adyen_manual_capture enabled, destination, API key, HMAC, stored payment method, live URL prefix when live, paid-plan gate, rail readiness. |
doctor | Expands ready with webhook URL checklist (/webhooks/live/adyen and /webhooks/sandbox/adyen), sandbox/live mismatch hints, and Console destination pointer. |
JSON data fields (ready): ready, checks[], summary, checklist_lines.
JSON data fields (doctor): checks[], summary, checklist_lines, next_steps.
Tenant walkthrough: Configure Adyen settlement. Shopify has a larger orchestration surface documented separately in Shopify CLI workflow.
paybond flutterwave
Read-only BYO Flutterwave Virtual Account settlement readiness against GET /v1/admin/settlement/config. Does not upsert secret keys or webhook secrets — use Console Settlement or POST /v1/admin/settlement/flutterwave/destination.
| Subcommand | Description |
|---|---|
ready | Checklist: flutterwave_virtual_account enabled, destination, secret key, webhook secret, paid-plan gate, rail readiness. |
doctor | Expands ready with webhook URL checklist (/webhooks/live/flutterwave and /webhooks/sandbox/flutterwave), per-destination token URL when configured, sandbox/live mismatch hints, and Console destination pointer. |
JSON data fields (ready): ready, checks[], summary, checklist_lines.
JSON data fields (doctor): checks[], summary, checklist_lines, next_steps.
Tenant walkthrough: Configure Flutterwave settlement.
paybond dev
Local sandbox developer workflows: travel smoke with checklist output, trace dashboard, optional WireMock Gateway (dev up), and a guided login → policy → validate → smoke loop.
| Subcommand | Description |
|---|---|
smoke | Wraps agent sandbox smoke with travel preset defaults; records a local trace event. |
trace | Starts a local HTTP trace dashboard (default port 9477) with a vertical timeline of recent smoke runs. Reads .paybond/dev-trace.jsonl from the current working directory. |
loop | Guided loop: login when needed → policy init --preset travel → validate-tools --local-only → dev smoke. |
up | Start or stop a local WireMock Gateway (Docker required). |
paybond dev smoke
| Flag | Default |
|---|---|
--preset <id> | travel |
--offline | false — in-process mock capability and simulated settlement; no PAYBOND_API_KEY required. Also stubs POST /harbor/intents/{id}/fund with an x402 402 → 202 → 200 state machine for local fund contract tests. |
--format table|json | table |
JSON data fields (smoke): bind, execute, trace_url, audit_log, offline (when set). Timeline events are persisted under .paybond/dev-trace.jsonl.
paybond dev trace
| Flag | Default |
|---|---|
--port <n> | 9477 |
Serves a self-contained HTML dashboard at / and /runs/<run-id>. Polls /api/events for timeline data. Run from the same project directory as dev smoke / dev loop so .paybond/dev-trace.jsonl is found.
JSON data fields (trace): trace_url, port, events[] (each event may include trace_events[] with structured middleware records: tool_selected, spend_authorized, tool_executed, evidence_submitted, spend_finalized, plus steps[] for the vertical timeline UI).
paybond dev loop
| Flag | Default |
|---|---|
--policy-file <path> | paybond.policy.yaml |
--offline | false — skip login and use offline mock capability. |
--no-login | false — skip the login step when credentials are already configured. |
--format table|json | table |
JSON data fields (loop): steps[], smoke, trace_url, audit_log, banner_lines[], offline (when set).
paybond dev up
| Flag | Default |
|---|---|
--port <n> | 18089 |
--down | false — stop the WireMock container instead of starting it. |
Starts WireMock with bundled Gateway stubs under kit/dev/wiremock/mappings/ (also packaged in the Python wheel). Includes an x402 fund sequence for intent aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa: mappings 11-x402-fund-challenge.json (402 with payment-required), 12-x402-fund-pending.json (202), and 13-x402-fund-success.json (200 with capability_token). Use with paybond --gateway http://127.0.0.1:18089 intents fund ... or fundWithX402 / fund_with_x402 to rehearse the handshake without a remote sandbox API.
JSON data fields (up): gateway_url, port, wiremock_dir, container_name, status, next_commands[].
Dev smoke and loop append audit events to .paybond/dev-audit.jsonl under the working directory.
paybond config
| Subcommand | Description |
|---|---|
get <key> | Read a config value (sensitive values are redacted using the same rules as list). |
set <key> <value> | Write a config value. |
unset <key> | Remove a config value. |
list | List all config entries (values redacted when sensitive). |
Config is profile-scoped when --profile is set.
paybond whoami
Resolve the authenticated principal and tenant realm.
JSON data fields: tenant_id, tenant_uuid, environment, service_account_role, principal (Gateway principal payload, secrets stripped).
paybond keys
| Subcommand | Description | Destructive |
|---|---|---|
list | List service-account keys for the tenant. | |
create | Create a new key. | |
rotate <key_id> | Rotate an existing key. | yes — requires --yes |
revoke <key_id> | Revoke a key. | yes — requires --yes |
JSON data fields (list): keys[] with key_id, key_masked, role, created_at, expires_at, status.
JSON data fields (create, rotate): key_id, key_masked, plus one-time plaintext api_key when the Gateway returns a newly minted secret.
paybond intents
| Subcommand | Description |
|---|---|
list | List intents (read-only Gateway operator route). |
get <intent_id> | Fetch one intent (read-only Gateway operator route). |
create | Create an intent from pre-signed --body JSON via paybond.harbor.createIntent with a replay-safe recognition proof. |
fund <intent_id> | Fund an intent via paybond.harbor.fundIntent with a replay-safe recognition proof. Returns structured 200 / 202 / 402 results (including x402 paymentRequired challenges). |
evidence <intent_id> | Submit pre-signed evidence --body JSON via paybond.harbor.submitEvidence with a replay-safe recognition proof. Distinct from agent harbor evidence smoke, which Kit-signs payee evidence; this command accepts upstream-signed wire JSON. |
settlement-confirm <intent_id> | Confirm settlement via paybond.intents.confirmSettlement with a replay-safe recognition proof. |
Read vs mutation paths: list and get call Gateway operator routes directly and do not require agent recognition. Intent mutation subcommands open a Paybond session (withPaybondCli / with_paybond_cli), sign a request-bound recognition proof over the wire body (or {} for fund), and delegate to the SDK Harbor surface.
Shared recognition flags (intent mutations):
| Flag | Env fallback |
|---|---|
--agent-recognition-key-id <id> | APP_AGENT_RECOGNITION_KEY_ID |
--agent-recognition-signing-seed-hex <hex> | APP_AGENT_RECOGNITION_SEED_HEX |
--idempotency-key <key> | — |
create, fund, evidence, and settlement-confirm require these credentials when Gateway Harbor recognition enforcement is enabled.
paybond intents create
| Flag | Required |
|---|---|
--body <json-file> or --stdin | yes — caller-supplied signed intent JSON forwarded verbatim to Harbor |
--agent-recognition-key-id, --agent-recognition-signing-seed-hex | yes when recognition is enforced (or APP_AGENT_* env) |
--idempotency-key | no |
paybond intents fund <intent_id>
| Flag | Required |
|---|---|
--payment-signature <sig> | no — x402 retry header after signing paymentRequired |
--body <json-file> or --stdin | no — deprecated shim; reads payment_signature from JSON when --payment-signature is omitted (emits a stderr warning) |
--agent-recognition-key-id, --agent-recognition-signing-seed-hex | yes when recognition is enforced (or APP_AGENT_* env) |
--idempotency-key | no |
Harbor receives an empty POST body; the recognition proof binds to {}. On x402 rails, a 402 response includes payment-session metadata in the structured CLI JSON (statusCode, paymentRequired, etc.). Retry with a fresh recognition proof plus --payment-signature.
paybond intents evidence <intent_id>
| Flag | Required |
|---|---|
--body <json-file> or --stdin | yes — caller-supplied signed evidence JSON forwarded verbatim to Harbor |
--agent-recognition-key-id, --agent-recognition-signing-seed-hex | yes when recognition is enforced (or APP_AGENT_* env) |
--idempotency-key | no |
The recognition proof binds to the exact wire body bytes Harbor verifies (same digest rule as agent harbor evidence smoke, but without Kit-side payee signing).
JSON data fields (evidence): intentId / intent_id, tenant, state, optional predicatePassed / predicate_passed.
paybond intents settlement-confirm <intent_id>
| Flag | Required |
|---|---|
--body <json-file> or --stdin | no — defaults to {} |
--agent-recognition-key-id, --agent-recognition-signing-seed-hex | yes when recognition is enforced (or APP_AGENT_* env) |
--idempotency-key | no |
JSON data fields (fund): statusCode (or status_code in Python CLI output), intentId / intent_id, tenant, state, settlementRail / settlement_rail, currency, amountCents / amount_cents, funded, optional capabilityToken / capability_token, optional paymentRequired / payment_required, optional paymentResponse / payment_response, optional funding.
--request-id is forwarded as a correlation header on all subcommands. Responses redact capability_token / capabilityToken and other sensitive fields using the shared CLI redaction rules.
paybond guardrails
| Subcommand | Description |
|---|---|
bootstrap | Bootstrap a sandbox guardrail intent and capability. Request body must include completion_preset or evidence_schema, not both — see Agent policy. |
evidence | Submit sandbox guardrail evidence. |
JSON data fields (bootstrap): tenant_id, intent_id, capability_token, operation, requested_spend_cents, sandbox_lifecycle_status.
paybond agent
Agent middleware commands wrap PaybondAgentRun and PaybondToolInterceptor. They default to sandbox-only unless --production is passed (live API keys require the explicit flag).
| Subcommand | Description |
|---|---|
run bind | Bind a run via sandbox bootstrap or production attach. Production attach requires --payee-did, --payee-signing-seed-hex, --agent-recognition-key-id, and --agent-recognition-signing-seed-hex (or APP_* env fallbacks). Persists context to .paybond/runs/<run_id>.json (mode 0600), including hex-encoded signing seeds for re-attach on tool execute. |
run status | Read a persisted run binding from .paybond/runs/. |
run trace | Show middleware trace events for a bound run. Reads .paybond/runs/<run_id>.trace.json written during tool execute. Use --format json for trace_events[] / steps[] or --format table for a vertical checklist. |
tool execute | Authorize, execute (via --result-body / --result-file), complete spend, and auto-submit evidence for a registered side-effecting tool. --result-body must match the bind completion_preset canonical evidence fields (CLI does not apply SDK evidenceMapper). |
tool validate | Authorize-only dry run for a tool call (no execution or evidence). |
registry validate | Validate a local agent tool registry YAML/JSON file. |
sandbox smoke | One-shot bind and execute for CI and coding agents. With --policy-file, bootstrap sends completion_preset from tool evidence_preset only — do not pair with a custom evidence_schema (Gateway rejects both). See Agent policy. |
JSON data fields (run bind): run_id, tenant_id, intent_id, capability_token, operation, sandbox_lifecycle_status, allowed_tools[].
JSON data fields (run trace): run_id, intent_id, trace_events[] (tool_selected, spend_authorized, spend_denied, approval_required, tool_executed, evidence_submitted, spend_finalized), steps[], trace_url, trace_file, updated_at. Table mode prints trace_lines[] instead of the default key-value table.
JSON data fields (tool execute): authorization, tool_result, evidence (submitted, intent_state, predicate_passed, sandbox_lifecycle_status).
When evidence.submitted is false and the error category is gateway, check that --result-body matches the preset (for example cost_and_completion requires top-level status and cost_cents). Harbor predicate rejections are often surfaced as HTTP 502 harbor_evidence_failed through the Gateway.
JSON data fields (sandbox smoke): bind, execute (same shapes as above).
Use --format json for automation. --write-env on run bind appends PAYBOND_INTENT_ID, PAYBOND_CAPABILITY_TOKEN, and PAYBOND_RUN_ID to an env file.
paybond spend authorize
Authorize delegated spend for a tool call.
JSON data fields: authorized, intent_id, operation, requested_spend_cents, deny_reason (when not authorized).
paybond signal
| Subcommand | Description |
|---|---|
reputation | Read reputation summaries. |
portfolio | Read portfolio summaries. |
fraud | Read fraud signals. |
Each subcommand accepts resource selectors documented in the SDK references.
paybond receipts
| Subcommand | Description |
|---|---|
get <receipt_id> | Fetch a receipt. |
verify <receipt_id> | Verify receipt signatures and binding. |
paybond mandates
| Subcommand | Description |
|---|---|
verify | Verify a mandate artifact. |
import | Import a mandate into the tenant. |
paybond a2a
| Subcommand | Description |
|---|---|
card | Agent card discovery and validation. |
contracts | Contract listing and inspection. |
paybond audit exports
Delegates to paybond.audit.exports on the Kit SDK (POST /v1/compliance/audit-exports and related routes). Tenant scope comes from authenticated credentials only — never pass a tenant id. Progress lines for create --wait go to stderr; use --format json for the envelope. Operator Console remains available for investigation UI (paybond open compliance-exports).
| Subcommand | Description | Destructive |
|---|---|---|
create | Create a tenant-scoped compliance audit export pack. | |
list | List compliance audit export jobs. | |
get <job_id> | Fetch export job status; optional --issue-download / --output for bundle bytes. | |
verify <path> | Verify a downloaded export bundle locally (Ed25519 manifest). | |
delete <job_id> | Delete an export job. | yes — requires --yes |
paybond audit exports create flags: --time-start, --time-end (RFC 3339), --intent-id, --case-id, --operator-did, --includes a,b, --disclosure-tier standard\|extended, --retention-hours <n>, --wait, --output <path>, --timeout-seconds <n>.
JSON data fields (create): job, waited, output, bytes_written, next_commands[].
JSON data fields (list): exports[] with job_id, status, created_at, expires_at. Optional next_cursor when the Gateway paginates results.
SDK: paybond.audit.exports.create|list|get|delete|verify (TypeScript and Python) — same surface as the CLI. MCP readonly: paybond_list_audit_exports, paybond_get_audit_export when --tool-policy readonly (no create via MCP). Bundle verify stays SDK/CLI only.
Security invariants
Both kits must enforce:
- No live device login — reject
--env liveand hidden live flags. - Git-ignore gate — refuse to write secret files that are not ignored inside a git repository (except when adding the default
.env.localto.gitignore). - 0600 secret files — env files containing API keys are written with owner-read/write only.
- No tenant override — reject
--tenant-idand similar unauthenticated tenant selectors on normal commands. - Confirmation gate — refuse destructive subcommands without
--yes. - Operator key expectation for login — reject device-login tokens whose role is not
operator.
Parity and testing
Both kits must maintain:
- Snapshot parity for
paybond --helpand each subcommand--help. - JSON shape parity for
whoami,doctor,keys list,guardrails bootstrap, and representative error cases. - Identical exit codes and error categories for the same failure inputs.
- Identical key masking output for the same raw key material.
Run kit tests from the repository root:
cd kit/ts && npm run test cd kit/python && uv run pytest
Related
- Authentication & tenant binding
- Error handling
- MCP server
- Coding-agent setup
- Shopify CLI workflow —
paybond shopifyorchestration surface - Configure Adyen settlement —
paybond adyen ready/doctor - Configure Flutterwave settlement —
paybond flutterwave ready/doctor - API error envelope