Skip to main content
The peaqOS CLI wraps the into a terminal surface for the most common machine flows: activating a machine under Economics 2.0, managing its lifecycle and subscription, submitting events, querying , running fleets, reading a machine’s Verify record and preparing its chip evidence, and the full Scale loop: an , searching the catalogue, placing and confirming orders. It’s the same and orchestration path as the JS and Python SDKs, scripted.

Install

Python 3.10 or newer. Ships to PyPI as peaq-os-cli and exposes the peaqos command. Wraps the Python SDK: same on-chain path, scripted. Install the current release with pip install -U peaq-os-cli. Solana flows need the extras and CLI 0.0.19 or newer: pip install -U 'peaq-os-cli[solana,ows]'. 0.0.17 onboards, but its qualify event and machine … --chain solana cannot reach a Solana-homed machine; 0.0.18 sends events, but its --chain solana management writes fail at submit. Since 0.0.17 the CLI needs click 8.4 or newer; the CLI pins it, and pip install -U installs it. The CLI declares the minimum peaq-os-sdk it needs. There is no Tokenomics 1.0 onboarding path in the CLI. To drive 1.0 machines from the terminal, pin both packages: pip install "peaq-os-cli<0.0.8" "peaq-os-sdk<0.6.0" (Python 3.11 or newer). Pinning the CLI alone resolves an SDK that peaqos monetize cannot use. peaqos --version prints both the CLI and the underlying peaq_os_sdk versions on a single line. Global flags -v / --verbose and -q / --quiet toggle DEBUG and ERROR-only logging respectively (mutually exclusive; logs go to stderr). --orchestration-url <url> and --orch-api-key <key> are global overrides for the corresponding env vars on any peaqos scale ... invocation.

Configure

The CLI reads the same environment variables as the SDKs. Full table on Install.
The root flags --svm-rpc-url and --svm-network (before the command name) override the two Solana variables, which override .env. Other are available. See Public RPC endpoints. Or scaffold a .env interactively with peaqos init.

Commands

peaqos init

Interactive wizard that scaffolds a .env with the required peaqOS variables. Prompts, in this order, for network, source (paste, generate, or wallet), RPC URL, the Economics 2.0 deployment ID (TOKENOMICS_DEPLOYMENT_ID, default peaq-mainnet on mainnet and agung-2026-08-28 on testnet; it selects the MCR and Event Registry defaults that follow), MCR API URL, URL, the Event Registry address, and last PEAQOS_ORCHESTRATION_URL and PEAQOS_ORCH_API_KEY for Machine Markets (leave both empty if you do not use them). The other five Tokenomics 1.0 addresses, labelled legacy and still required by the SDK constructor, are filled without a prompt: the two precompiles from built-in values, and on mainnet IdentityRegistry, IdentityStaking and MachineNFT from peaqos.json, which the wizard downloads from GitHub. If that download fails, the wizard writes those three empty and later commands exit 3 with Missing required env var; copy them from the mainnet section of the install page. The orchestration key is masked in any echoed or logged output. The wallet path creates a new and writes PEAQOS_OWS_WALLET=<name> instead of PEAQOS_PRIVATE_KEY. Writes .env with 0o600 permissions and auto-runs whoami to verify. On peaq mainnet the MCR API URL prompt defaults to https://mcr.peaq.xyz and the wizard writes it to .env as PEAQOS_MCR_API_URL. With TOKENOMICS_DEPLOYMENT_ID set, qualify, show and monetize take the MCR host from the deployment record and do not read this value; peaqos whoami still prints it.
On peaq mainnet the wizard (CLI 0.0.13 or newer) defaults EVENT_REGISTRY_ADDRESS to the Economics 2.0 registry 0xA1e7F1d7B24dAb55Dc92491e6d9B89F6E925Ad1e. CLI 0.0.12 and older default to the Tokenomics 1.0 registry 0x43c6AF2E14dc1327dc3cc6c7117D1CD72fffEcbA instead: upgrade with pip install -U peaq-os-cli, or export EVENT_REGISTRY_ADDRESS=0xA1e7F1d7B24dAb55Dc92491e6d9B89F6E925Ad1e before peaqos init (an exported value takes precedence over the default) or edit .env afterwards. Both contracts share the submitEvent selector, so a 2.0 machine’s event sent to the 1.0 registry reverts with MachineNotFound and is not recorded.
On agung the wizard prefills only the deployment ID and the two precompile addresses. The Event Registry prompt has no default and --non-interactive exits 3 unless EVENT_REGISTRY_ADDRESS is set. Fill PEAQOS_RPC_URL and the IdentityRegistry, IdentityStaking and MachineNFT addresses in .env yourself, from the agung section of the install page.

peaqos whoami

Read-only command that prints the , network, , RPC URL, the PEAQOS_MCR_API_URL value (or http://127.0.0.1:8000 when unset; with TOKENOMICS_DEPLOYMENT_ID set the MCR commands do not use it), the legacy from .env, and a Tokenomics 2.0: block with the deployment ID, chain ID, and the five addresses the SDK record resolved (these come from the SDK, not from .env). Useful as a sanity check after init. When PEAQOS_SVM_NETWORK or PEAQOS_SVM_RPC_URL is set, it also prints the requested Solana cluster, the RPC origin with credentials, path and query stripped, and the SDK’s Solana deployment and packaged-IDL metadata. Those lines are local checks; whoami makes no Solana RPC call.

peaqos activate

Onboard a machine in one atomic transaction. MachineStateAndSync.activateMachine mints the ERC-721, stores the DID document, bonds the subscription tier, and registers the home chain in a single call. Mirrors the Activate flow. Requires TOKENOMICS_DEPLOYMENT_ID. The transaction sender becomes the machine’s owner and bond payer. The bond is quoted in PEAQ per tier at the oracle rate; --payment chooses what settles it.

Flags

--machine-type and --credential-subject-hex alone determine the machine ID (uint256(keccak256(abi.encode(machineType, credentialSubject)))). Neither can change after activation, and the same pair can never be activated twice. Private keys must come from a file. Inline key flags are intentionally unsupported: a file keeps the key out of shell history and ps output. --doc-url, --data-api, and --visibility are not supported: 2.0 records the DID document atomically during activation. Passing any of them exits 1 with a plain error message (no error_code). Put documentation and API URLs into the serviceEndpoints array of --did-document.

DID document schema

Exactly three root fields, all required. Unknown fields, duplicate keys, and a root id or controller are rejected: id is computed on-chain and controller is set by the CLI from the mode.
Each authentication entry is an index into verificationMethods. The CLI bounds-checks them because the contract stores them unchecked at mint.

Ownership modes

In machine-key mode the CLI prints the changed rights before asking: the machine wallet can transfer the NFT and rotate or clear the controller; the operator can run lifecycle, subscription, and DID actions but cannot transfer the NFT or change the controller. There is no operator-sponsored activation; registerFor has no 2.0 equivalent.

Paying in USDT

Not available on peaq mainnet: SubscriptionTokenProvisionPool has no USDT token configured, so USDT settlement fails. Pay in PEAQ. The rest of this section describes the flow on a deployment where the token is set. The bond, the voucher credit, and the net amount stay in PEAQ; only settlement differs. The CLI shows the USDT token, the quote, the accepted slippage, and the resulting maximum USDT, then submits that exact maximum. The allowance goes to SubscriptionTokenProvisionPool, not to MachineSubscription. A bond covered entirely by voucher credit converts and transfers nothing.

Output, exit codes, and error_code

Progress, the preview, and prompts go to stderr; stdout carries only the final summary (or one JSON object with --json). Machine IDs and every unbounded chain integer are decimal strings in JSON, never numbers.
The four CLI-wide exit codes apply. Once input validation has passed, every activate outcome is a JSON report (with --json) whose failures carry a stable error_code, bracketed in human output; success and preview reports have no error_code key and report a status instead: preview, activated, already_active, or pending. Before that point there is no report: the CLI’s own input validation exits 1 with a plain message, a value Click itself rejects (an unknown option, a --tier outside the choices) exits 2 with a usage message, and a missing or wrong Economics 2.0 configuration exits 3 with a plain message. The codes to know: The Solana path adds its own codes; they are listed under Solana home.

Pending transactions and peaqos.log

A submitted transaction whose receipt does not arrive is reported as PENDING at exit 2 with its hash, not as a failure. It may still mine. Every submitted hash is appended to ./peaqos.log (mode 0600) before the receipt wait. Re-running the same command reconciles the recorded hash instead of resubmitting; a hash with no receipt blocks resubmission regardless of age. Never submit a second activation for the same machine, and never delete peaqos.log while a transaction is outstanding.

Solana home

--chain solana homes the machine on Solana instead of peaq. The identity, DID document and Machine NFT then live in Solana accounts that name a Solana key as owner. That key, the owner wallet, pays the bond on Solana, in PEAQ or USDC, through the subscription terminal; peaq then books the bond. Activation is seven stages on two chains instead of one transaction: --phase cancel_request (owner wallet) ends an open request that will not settle and returns the escrow. It prints Cancel request on Solana: confirmed <signature> and landed after N sends, like the stages (since 0.0.17). With no request open, the CLI decides before it asks for consent or a passphrase: a cancel this journal recorded is already done; nothing was signed; a cancel the journal did not record (the node’s) is REQUEST_CLOSED; a request closed after the mint is REQUEST_NOT_CANCELLABLE. One command runs every stage and waits out the three waits; --phase runs one stage at a time. --dry-run without --phase previews the whole onboarding on one screen and needs no wallet. Step by step with costs and recovery: Onboard a machine on Solana.
ARGS is the argument set from the guide. Production’s link push goes to the Trust Validator node with no messaging fee, so neither command takes a fee cap; --phase linkage --dry-run names the route. --manufacturer and the verification-method controllers in --did-document are base58 Solana keys here. --for and --machine-key are rejected. The removed reservation flow’s options are refused by name with OPTION_NOT_FOR_CHAIN (exit 1), naming the replacement: --payment (--pay-in), --max-net-peaq-amount and --max-usdt-amount (--max-in). --from-block is accepted and ignored. Every ceiling is validated before signing and 0 means zero, not unlimited. The CLI warns when an exported PEAQOS_* or TOKENOMICS_* variable differs from .env, and when a write goes to the public api.mainnet-beta.solana.com. Human output starts with a plan block (both wallets, the expected bond and escrow, the rents, what the owner must hold before [2/7]), then each stage’s terms and its numbered outcome on stderr. After every confirmed write the CLI prints an indented landed after N sends line, and for the mint also · <used> of <limit> CU (since 0.0.17). A wait prints a “still waiting” line every two minutes and “landed in …” when it ends. [7/7] reads “Link push queued for the Trust Validator node (seq N, TV nonce M)” before its wait. Once the SDK reports complete, stdout carries the summary with every reference (the push as Link push (Trust Validator)), link seq N applied, the Spent (from receipts) block and the audit trail. With --json, stderr is JSON lines only (plan, consent, stage and wait events) and stdout one JSON result with phases: [{phase, status, reference, exit_code}]; each confirmed phase’s confirmation carries sends, resend_errors and, for the mint, the compute figures. Every write result also carries:
  • resume_command: the command that continues; for the one-command run the run itself. --yes, --dry-run, --svm-rpc-url and --orch-api-key are never carried over; --svm-network is, and other options only when you gave them.
  • spent: read from receipts, never from quotes: the escrow out and back, the rents out and back, the fees, the registration’s gas.
  • audit_trail: every transaction with its slot or block and finality, and the link push’s delivery: the node’s relay with its outbox nonce, or on a LayerZero route the message with a LayerZero Scan link (a convenience, not evidence).
  • record_file: onboarding-<machine-id>.json, written beside peaqos.log after every write: each invocation, the references, spent, the trail, and once complete the chain-read history.
  • a provenance label on each evidence block: journal_claim is what the CLI recorded at submit time in peaqos.log, chain_verified what the SDK read back from the chains. --json adds provenance_legend.
Onboarding is done when next_step.phase is complete. The SDK derives that from peaq’s MachineBridgeAdapter.lastAppliedMirrorPushSeq for the machine reaching the link push’s sequence (reason link_applied, or later_push_pending when a later Solana push is still in flight). Exit 0 on --phase native_onboarding or --phase linkage means that stage’s Solana transaction confirmed, not that onboarding is complete. The Solana receipt of the push proves the send, not the delivery. The watermark is the only evidence of delivery. Keep peaqos.log, the working directory and the exact inputs across runs. A rerun of a confirmed stage reconciles it and never resubmits it. The one write a rerun signs again is a mint the SDK has proven dead (since 0.0.16; the dead row stays in the journal, printed as expired). peaqos machine history <id> --chain solana lists every transaction of an onboarding from the chains alone, and peaqos machine status <id> --json --chain solana reads the machine afterwards without wallet or journal, including the top-level link block with peaq’s watermark (status not_pushed, pending_application, linked or unavailable).

peaqos machine

Everything after onboarding: lifecycle, subscription payments, ERC-721 ownership, DID updates, and relocation status. Requires TOKENOMICS_DEPLOYMENT_ID.
Every write accepts --yes, --json and, except subscription activate and subscription renew, --dry-run (preview and reconcile, sign nothing); every read accepts --json. Machine IDs are full-width uint256: pass them as canonical unsigned decimal (no 0x, no leading zeros) and read them back as decimal strings. Every write runs the same sequence: validate locally, reconcile the journal (a pending transaction for the same action and machine blocks rather than repeats), ask the SDK for a preview (chain, contract, method, current state, intended effect), show it and ask, then submit once and record the hash before waiting for the receipt. A rerun reconciles an unresolved (pending) hash instead of resubmitting; once that outcome is recorded as confirmed, the next rerun is a new write and asks for consent again, so check state with machine status rather than rerunning a write with --yes. Details that matter:
  • Who may sign. Suspend, resume, renew, and DID updates: owner or controller. set-controller and clear-controller: owner only. Transfers: standard ERC-721 authority. Points and credits from a renewal land on the owner even when the controller pays.
  • suspend does not pause billing. It sets a flag on the machine, for example to mark it as under maintenance. The subscription period, grace, runoff and renewal date are unchanged. See Subscription lifecycle.
  • approve-all is not scoped to one machine. It grants the operator every MachineRegistry machine the signer owns, including ones activated later.
  • transfer is safe by default (safeTransferFrom). --unsafe selects transferFrom, which can strand the NFT in an incompatible contract. Transfer does not rotate the DID controller.
  • DID setters replace whole arrays. The file or index list you pass is the complete new state. Authentication indices point into the verification-method array by position. --index and --clear are mutually exclusive and one is required.
  • Renewal extends from the stored period end, not from now, and keeps the stored tier. The contracts allow a tier change once the period has ended (Grace or Runoff), but no published deployment record enables tier selection on renewal (peaq-mainnet and agung-2026-08-28 both set it off), so passing --tier, even the stored tier, reports RENEWAL_TIER_UNSUPPORTED (exit 3, before any RPC). Omit --tier; pick the tier at activation. --payment usdt requires --slippage-bps and is not configured on peaq mainnet.
  • history reads an onboarding from the chains. machine history MACHINE_ID --chain solana needs no wallet, journal or original inputs: one line per transaction of the machine’s onboarding on both chains (step, who sent it, slot or block, cost to its payer), then totals per payer. The link push’s delivery by the Trust Validator node reads actor node, and -v links the push to the node’s outbox (tv_outbox). A Solana transaction the owner did not pay but that moved its balances, such as the node’s cancel of an expired request, adds the owner’s part to its row (owner +3,657,600 lamports, and the escrow back); the owner’s total is its net change. -v adds full references and explorer links; --json carries every amount as a decimal string, with owner_lamports_delta and owner_token_deltas on every Solana row. The owner wallet’s registration and binding are marked reused on a later machine of the same owner and kept out of its totals. A source that could not be read is named and the command exits 2; the rows shown are still exact, and a rerun reads it.
  • Relocation is read-only. relocation status reports pending, arrived, completed, cancelled, or conflicting. Initiation and cancellation are not available, and relocation is disabled on chain.
  • Solana-homed machines. Add --chain solana to route a management command through the native SDK path: machine status, transfer, suspend, resume, did set-controller and the other DID setters, plus machine set-evm-operator MACHINE_ID 0xOperator --chain solana, which maintains the peaq subscription link and exists only for Solana. The flag is a routing choice; the SDK still resolves the machine’s home from its ID and refuses the wrong chain. Needs pip install 'peaq-os-cli[solana,ows]' and PEAQOS_SVM_RPC_URL; without the endpoint a write stops with exit 3 before reading anything (CLI 0.0.18; earlier versions ended STATE_MISMATCH even with it set). The writes submit from CLI 0.0.19: 0.0.18 previews them, then fails after consent with TypeError: … unexpected keyword argument 'solana', before anything is signed. A live Solana write takes its cost ceilings explicitly, as activate --chain solana does: --max-native-fee-lamports (network plus priority fee) and --max-native-rent-lamports (rent top-up; 0 refuses any). --dry-run without them previews the write and prints the values a live run needs; a live write without both stops before consent and before the wallet is unlocked. --compute-unit-price-micro-lamports sets the priority price (default 10000, about 2,000 lamports per write). Four things differ from peaq and are refused rather than approximated: transfer needs --unsafe (there is no safe transfer, --data-hex is refused), approve and approve-all are refused, addresses are base58 and never converted, and operator synchronization is reported unavailable on a keyless read. Without --chain solana, machine status falls back to the Solana read when the peaq record is missing or homed elsewhere: status: "observed" plus a native_current_state with separate peaq and Solana observations (absent, reserved, pending_external, present, conflict, in_flight, unavailable). Status output also names the subscription account the deployed programs read (subscription_source, terminal on peaq mainnet) and shows the mirror and terminal evidence side by side, with unread values null. See Onboard a machine on Solana.
Exit codes and error_code values are the ones documented under peaqos activate: one taxonomy for both. qualify mcr, show machine and show operator machines read from mcr.peaq.xyz. The CLI selects that host only with TOKENOMICS_DEPLOYMENT_ID set; without it the MCR commands do not read Economics 2.0 machines. A machine DID is did:peaq:<decimal machine id>; a did:peaq:0x<address> machine DID exits 1 with INVALID_INPUT (Machine DID requires a canonical decimal ID in 0..2^256-1.). show operator machines takes did:peaq:0x<address>, because an operator DID names an account, not a machine. All three are HTTP-only reads and need no signer. On agung-2026-08-28, which has no paired 2.0 MCR, all three exit 3 with CONFIG_ERROR (The SDK rejected the selected MCR deployment). A failed query exits 2 with the MCR error code (for example SERVICE_UNAVAILABLE while the 2.0 operator index is syncing) instead of a traceback.

peaqos qualify event

Submit a revenue or activity event to the EventRegistry. Wraps submit_event. See the Submit events guide for and patterns.
--value is an ISO 4217 minor-unit integer: cents for USD/HKD, whole units for JPY/KRW/VND. HK$1.23 → --value 123, ¥100 → --value 100. The CLI defaults --currency to USD for revenue events and to "" for activity events; pass --currency explicitly to override. The MCR API converts the value to USD using FX at the event timestamp. Human output on success:

Solana-homed machines

From CLI 0.0.18, qualify event sends an event for a machine homed on Solana to the Solana EventRegistry program. Versions 0.0.16 and 0.0.17 never pass the Solana endpoint to the SDK and refuse with MACHINE_HOMED_ELSEWHERE (”… is unavailable, not resolved”), even with PEAQOS_SVM_RPC_URL set. What it needs:
  • pip install 'peaq-os-cli[solana,ows]' and PEAQOS_SVM_RPC_URL: the same .env the machine was onboarded with.
  • PEAQOS_OWS_WALLET naming the OWS wallet that holds the machine’s Solana owner or controller key. That wallet signs and pays.
  • SOL in that wallet. The first event for a machine pays rent for its event-log account (2,946,400 lamports measured) plus the 5,000-lamport network fee, about 0.003 SOL. Every later event pays the fee only.
Before anything is signed, the preview checks that the signer is the machine’s current owner or controller, that its subscription is eligible, and that the event registry is not paused and the machine not relocating.
The preview, then the result (an activity event on mainnet; this machine’s event log already existed, so no rent):
Log State is initializable for a machine’s first event, which is the one that pays rent. Event Index counts the machine’s events from 0. The signature can be looked up on any Solana explorer. With --json, every integer is a decimal string:
  • --dry-run --json prints status: "preview" with execution_chain, submission_id, machine_id, data_hash, log_state, rent_lamports, network_fee_lamports, compute_units, transaction_size_bytes and last_valid_block_height.
  • A submission prints status: "confirmed" with execution_chain, submission_id, signature, slot, confirmation, machine_id, data_hash, event_index, event_log and compute_units. --json never confirms a write, so a live --json run needs --yes.
If the wait ends without a confirmation (exit 2, PENDING_TRANSACTION), the event may still land. Every submission is written to ./peaqos.log when it is broadcast, before the wait. From the same directory, run:
It only reads the chain and reports one of three outcomes:
  • confirmed: the event landed.
  • expired_unlanded: nothing landed, and sending the event again is safe.
  • unresolved: run it again later.
While an attempt is unresolved, sending the same payload for that machine again is refused, and the error names the --resume command. Events without --raw-data all have the same (zero) payload hash, so this applies to any two of a machine’s events. Checking the event. peaqos qualify mcr did:peaq:<machine-id> counts it within minutes (Events: Total, Activity). At the time of writing, peaqos show machine and machines.peaq.xyz do not list Solana events yet: the profile reads event_count: 0 with rating_unavailable: event_history_not_indexed.

peaqos qualify mcr

Fetch a machine’s credit rating from the MCR API. Wraps query_mcr.
The is did:peaq:<canonical decimal machine ID>; an address DID exits 1. --json emits the raw SDK response on stdout with no banner or prose: useful for jq and scripting. Human output:
revenue_trend is one of up, stable, down, insufficient (not enough revenue history to compute a trend), or null (no trend could be measured, for example while the machine’s history is not indexed); the CLI prints null as unavailable. FX Degraded: reflects the top-level mcr_degraded field: yes when one or more scored events used a stale or unavailable FX snapshot, no otherwise. average_revenue_per_event is always present and can be null; Avg Revenue: then prints unavailable. --json output (raw SDK MCRResponse):

peaqos show machine

Fetch a full machine profile: Machine ID, operator, MCR rating and score, bond status, event count and service endpoints. Wraps query_machine. The profile’s MCR snapshot can name a different rating_unavailable reason than qualify mcr for the same machine (a new Solana machine reads event_history_not_indexed here and no_events_yet there); qualify mcr is the rating.

peaqos show operator machines

List the machines registered under a proxy operator, with MCR per machine. Wraps query_operator_machines.

peaqos wallet

Manage OWS-format wallets in the local encrypted vault at ~/.ows/wallets/. Requires the [ows] extra: pip install 'peaq-os-cli[ows]' (quote the bracketed extra so zsh does not glob it). The vault is read from OWS_PASSPHRASE when set, otherwise prompted interactively. Subcommands wrap the SDK static helpers documented on Wallets (OWS). When PEAQOS_OWS_WALLET is set, load_client() resolves the wallet from the vault using OWS_PASSPHRASE and skips PEAQOS_PRIVATE_KEY entirely. If both are set, the wallet wins.

peaqos stream

The data-stream command group. The crypto core is offline: publish turns a source file into signed, encrypted chunks on disk; grant re-wraps the chunk keys for a buyer; consume decrypts and reassembles the original data on the buyer’s side. Around it sits the paid flow: distribute waits for a buyer’s payment confirmation and delivers access files to S3, pay transfers tokens to the seller on peaq, Base, or Solana, and payproof submits proof for a transfer completed elsewhere. Purchases and delivery are the SDK-level distribution flow; the P2P delivery channel is not exposed as a CLI flag.

peaqos stream publish

Chunk, encrypt, and sign a data file into a local output directory. Each chunk gets a fresh key wrapped (X25519) for three recipients (owner, operator, machine), and the chain is signed Ed25519. Writes chunk-{i}.json (envelope) + chunk-{i}.bin (ciphertext) per chunk, plus a manifest.json (peaq.stream.chunks.v1).
Required: --input (file path or http(s) URL), --output-dir (created if missing), --owner-public-key / --operator-public-key / --machine-public-key (X25519, 64 hex), --signing-key-file (Ed25519 private key file), --machine-did, --machine-key-id. Optional: --chunk-size (bytes, default 262144), --json (emit the manifest to stdout), and S3 upload: --s3 s3://bucket/prefix/, --s3-region, --s3-endpoint (for MinIO / R2 / S3-compatible stores). S3 needs the extra (pip install "peaq-os-cli[s3]") and credentials via PEAQOS_S3_ACCESS_KEY_ID + PEAQOS_S3_SECRET_ACCESS_KEY (or the standard boto3 chain); each chunk’s storageRef is rewritten to its s3:// URI. The human summary goes to stderr; the manifest path prints to stdout for piping. Exit codes: 0 success, 1 validation (bad key hex, wrong length, missing input file, StreamValidationError/StreamSigningError), 2 URL download or S3 upload failure.

peaqos stream grant

Grant a buyer decryption access to a published chunk chain, fully offline. Reads the chunk envelopes, unwraps each chunk key with the owner’s X25519 private key, re-wraps for the buyer, and writes peaq.stream.buyer-access.v1 files (sharded by size). This is a local re-key, not an on-chain access grant.
Required: --chunk-dir (published envelopes), --buyer-public-key (X25519), --buyer-id, --owner-private-key-file, --output-dir. Optional: --max-file-size (bytes per access file, default 512000), --json (summary with per-file listing). Exit codes: 0 success, 1 validation (invalid keys, no chunk files, malformed chunk, --max-file-size <= 0), 2 key-commitment mismatch, meaning the wrong owner key.

peaqos stream consume

Buyer-side: decrypt a purchased chunk chain and reassemble the original data. Reads the chunk envelopes, the encrypted .bin blobs, and the buyer access files (filtered to --buyer-id), verifies the chain (unless --skip-verify), decrypts each chunk with the buyer’s X25519 private key, and writes the result to --output. Two input modes:
  • Local (offline): --chunk-dir, --access-dir, and --data-dir point at directories already on disk.
  • Remote: --download-url points at an HTTP/HTTPS self-contained release package bundling the envelopes, .bin blobs, and access files, exposed as a manifest.json file listing or a ZIP archive. The package is downloaded into a work directory (--work-dir, or a temp dir cleaned up after success unless --keep-files; preserved on any error for debugging), then the same verify → decrypt → reassemble pipeline runs. --download-url is mutually exclusive with the three directory flags.
--download-url does not consume the pre-signed URL from peaqos stream distribute: that URL delivers only the first buyer-access file, while the chunk envelopes and ciphertext stay behind each chunk’s storageRef. A full distribute to consume roundtrip needs a self-hosted bundle as described above.
Required: --buyer-private-key-file (buyer X25519 private key), --buyer-id (must match the recipientId in the access files), --output (reassembled plaintext path), and, in local mode, --chunk-dir (envelopes), --access-dir (buyer access files), --data-dir (encrypted .bin blobs). Optional: --download-url (remote release package; a query token on the URL is preserved when fetching each file), --work-dir / --keep-files (remote mode only), --skip-verify (skip chain verification; debugging only), --json (summary to stdout: output, totalBytes, chunkCount, sourceHash, buyerId, verified). Exit codes: 0 success, 1 validation (empty --buyer-id, unreadable key, missing input files or dirs, --download-url combined with a directory flag or with a non-http(s) scheme), 2 decryption, integrity, or download failure (HTTP error, timeout, invalid ZIP). The buyer-side messages are specific: a wrong or ungranted key gives Decryption failed for chunk <index> with “access not granted for this buyer private key”; a mismatched --buyer-id gives No buyer access for chunk <index> (<chunk-id>); a tampered chunk gives Data integrity check failed for chunk <index> with “plaintext hash mismatch”.

peaqos stream distribute

Seller-side. Listen for a buyer’s payment confirmation, then automatically generate buyer access files (same re-key as stream grant) and deliver them to S3 under {prefix}{buyer_id}/, returning a pre-signed download URL. Polls --confirmation-url every --poll-interval seconds (default 30) until the endpoint reports a confirmed payment or --timeout seconds (default 3600) elapse. The confirmation endpoint must return JSON with status: "confirmed", an order_id matching --order-id, and non-empty strings for buyer_id, buyer_public_key_hex, and tx_hash; confirmed_at is optional.
Required: --chunk-dir (published envelopes from stream publish), --owner-private-key-file (the X25519 key used at publish time, one line of 64 hex with an optional 0x prefix), --confirmation-url, --order-id, --delivery (currently only s3), and --s3 (bucket path). Optional: --poll-interval, --timeout, --s3-region, --s3-endpoint (MinIO / R2 / S3-compatible), --presign-expiry (seconds, default 3600), --max-file-size (bytes per access file, default 512000), --json. S3 needs the extra (pip install "peaq-os-cli[s3]") and credentials via PEAQOS_S3_ACCESS_KEY_ID + PEAQOS_S3_SECRET_ACCESS_KEY or the standard boto3 chain. Exit codes: 0 success, 1 validation (no chunk files, unreadable key, non-positive interval/timeout, --delivery s3 without --s3), 2 confirmation timeout or S3 upload failure, 3 boto3 missing. In the SDK, the same loop is PollingConfirmationProvider + distributeData, where a P2P delivery channel can replace S3.

peaqos stream pay

Buyer-side. Transfer tokens on-chain to a seller, native or ERC-20/SPL on peaq, base, or solana, and optionally submit the transaction hash as payment proof in the same run. With --confirmation-url, proof is submitted right after the transfer; without it, only the transfer executes and the CLI prints the matching peaqos stream payproof command. In human output the tx hash is written to stdout before the proof step, so it survives a failed proof submission. With --json the one JSON object prints after the proof step; when proof submission fails it still carries the tx hash, with proof set to null.
Required: --seller-address (EVM 0x... or Solana base58), --amount (human-readable, e.g. "10.5"), --chain, --order-id. Optional: --confirmation-url, --token-address (ERC-20 contract or SPL mint; omit for the native token), --token-decimals (override for tokens outside the well-known registry), --rpc-url (required for base and solana), --private-key-file (falls back to PEAQOS_PRIVATE_KEY; EVM chains only), --json (proof is null when no confirmation URL was given). --chain solana signs with the OWS wallet’s Solana account instead: it needs PEAQOS_OWS_WALLET (and OWS_PASSPHRASE when non-interactive), the raw key is ignored for the Solana transfer (the OWS wallet’s Solana account signs). Exit codes: 0 success, 1 validation or signing failure (messages never contain key material; Solana support needs pip install "peaq-os-sdk[solana]"), 2 insufficient balance, revert, or proof HTTP failure, 3 missing config.

peaqos stream payproof

Buyer-side. Submit payment proof for a transfer completed outside peaqos stream pay, or retry a proof step that failed.
Required: --tx-hash (EVM hash or Solana signature), --order-id, --confirmation-url, --chain, --payer-address, --payee-address, --amount (must match the original transfer). Optional: --token, --token-address, --json. Exit codes: 0 success, 1 validation, 2 proof HTTP failure, 3 missing config.

Solana payments

There is no peaqos solana command group. Solana is selected per command: peaqos activate --chain solana homes a machine there (Solana home), and peaqos stream pay --chain solana sends native or SPL transfers itself (requires --rpc-url and, for SPL, the mint via --token-address; install with pip install "peaq-os-sdk[solana]"). Solana-quoted Machine Market orders are paid externally: complete the SPL transfer with your own Solana wallet, then pass --payment-tx-hash to peaqos scale order so the orchestrator records it as the payment proof. Solana proofs are recorded, not verified on chain.

peaqos monetize

Manage a machine’s Economics 2.0 monetization decision in the MCR: status is a public read; opt-in and opt-out are signed, off-chain decisions. Thin wrappers over the SDK’s opt-in client: the SDK runs the compatibility check, EIP-191 signing, retries, HTTP, and response validation; the CLI adds parsing, prompts, and output. The MCR at https://mcr.peaq.xyz serves the mirrored 2.0 machines and publishes the /.well-known/peaq-monetization signal. peaqos monetize status <decimal id> returns PENDING for a machine that has never opted in. agung-2026-08-28 has no paired MCR and exits 3 with CONFIG_ERROR.
KEY is a canonical decimal machine ID or did:peaq:<decimal machine id>. Address DIDs (did:peaq:0x…), leading zeros, signs, hex, and exponents are rejected locally: there is no translation from a 1.0 address DID to a 2.0 machine ID. Every command requires TOKENOMICS_DEPLOYMENT_ID. The SDK resolves the MCR URL, chain ID, MachineRegistry, and API version from that deployment and the server’s live compatibility signal (GET /.well-known/peaq-monetization). PEAQOS_MCR_API_URL, IDENTITY_REGISTRY_ADDRESS, and PEAQOS_RPC_URL are not read, and the retired --api-url flag is accepted only to be rejected: it exits 3 with migration guidance. status needs no signer; writes sign with the selected OWS wallet or, without one, PEAQOS_PRIVATE_KEY, and the signing address must be the machine’s current owner or DID controller (a machine-wallet-only key or a 1.0 operator key is not authorized). Before a write the CLI reads the current state; an already-satisfied state returns without a prompt, signature, or PUT. Only 503 MACHINE_UNAVAILABLE is retried. A timeout during a PUT is ambiguous (the MCR may have applied it): rerun the same command, which reads first and sends no second PUT if the state is already there.
2.0 state starts at PENDING; Tokenomics 1.0 decisions and signatures are not imported.

peaqos monetize provision

Provision an opted-in machine as a compute provider node from a schema-driven manifest, entirely from the terminal. Thin wrappers over the SDK’s manifest runner: every command, secret redaction, and verification probe runs inside the SDK; the CLI adds prompts, terminal rendering, and the resume state file.
  • <provider> is the manifest provider key (for example akash). Requires PEAQOS_MANIFEST_REPO_URL or --manifest-repo; --manifest-version pins a manifest version (default: latest).
  • run walks the full flow: monetization pre-check (anything but OPTED_IN stops before the manifest is even fetched), manifest fetch pinned by sha256, input collection (--inputs file plus hidden prompts for secrets), blocking pre-flight, provisioning with a state checkpoint after each step, and verification probes that alone decide success.
  • --mode manual (default) confirms each command; --mode auto runs unattended and requires --grant-sudo, scoped to the manifest’s allowedCommands. Owner-action handoffs (funding, DNS, signing) always pause, even with --yes.
  • --machine takes a decimal machine ID or did:peaq:<decimal id> (address DIDs are rejected), so the machine wallet address for the manifest’s commission context must come from PEAQOS_MACHINE_WALLET_ADDRESS. Unset it before provisioning a different machine. The monetization pre-check goes through the 2.0 SDK read against the deployment’s MCR (mcr.peaq.xyz).
  • --resume continues an interrupted run from the state file (default ./peaqos-provision-state.json, written atomically with 0600). Non-secret inputs are restored; secrets are re-prompted, never persisted.

peaqos verify

Read a machine’s Verify record and build local chip preflight artifacts. Experimental: the command names are stable for v1 beta, the output may still change. Reads need only a Verify API origin: no wallet, private key, RPC or TOKENOMICS_DEPLOYMENT_ID. Available from peaq-os-cli 0.0.14 (pip install --upgrade peaq-os-cli).
The root option --verify-api-url <origin> (before the command name) takes precedence over PEAQOS_VERIFY_API_URL, which the CLI also reads from .env. The value must be an HTTPS origin; there is no default and no fallback to the MCR host, so a missing value exits 3 with Set PEAQOS_VERIFY_API_URL to a valid HTTPS origin.

peaqos verify status

One GET /v1/verify/machines/{machineId} through the SDK read client (API reference): one attempt, five-second deadline, no retry, no redirect, no cache. MACHINE_ID is the decimal machine ID (1 to 2^256-1, no leading zeros); a DID or an address exits 1. Human output prints the machine DID, the home chain (peaq (EVM), Agung testnet (EVM), Solana, or EVM chain <id> for an unnamed chain), the DID controller, the operator, the KYB and chip statuses, and Source: Verify API. --json prints the API record unchanged: machineId, machineDid, homeChain, didController, operator, verification.kyb.status, verification.chip.status. The root option --quiet (peaqos --quiet verify status ...) keeps the data output. Each status is unverified, verified, expired or revoked. An existing machine with both unverified is a successful read. An unknown machine prints Machine not found in the Verify service. and a rate limit prints Verify API rate limit reached; retry later. A 503 prints Verify state is temporarily unavailable; retry later. A Solana-homed machine always gets this message, and retrying does not help. A canceled read prints Verify status request was canceled; retry when ready. An invalid response says do not treat it as verification state.

peaqos verify chip

Three stages that turn a challenge, the chip’s leaf certificate and two signatures into the canonical peaq.verify.chip-evidence/1 document peaq’s onboarding service submits. Every option is a file path, so no nonce, signature or certificate lands in argv or shell history. The commands never talk to the chip, a wallet or the Verify API, and hold no key: the chip signature comes from the secure element, the controller signature from the DID controller’s wallet. Each stage rebuilds the earlier ones from the same files, so nothing is cached or resumed. Chip preflight is EVM-only in v1. The full flow, including the challenge and the submission the onboarding service runs, is in Verify a chip, end to end.
Every stage prints Authority: local preflight only; finalize also prints the fixed identifiers:
  • Protocol: peaq.verify.chip-proof/1
  • Profile: infineon-optiga-trust-m-express-ca306/1
  • Evidence Schema: peaq.verify.chip-evidence/1
  • Trust Bundle: infineon-optiga-trust-m-express-ca306-roots/1
  • Revocation Status: not_evaluated
--json on any stage prints one metadata object (stage, artifact, byteLength, authority, plus the five identifiers on finalize) and never the artifact bytes, a path, a DID or an address.
Hand evidence.json unchanged to the onboarding service that issued the challenge; it submits the file with POST /v1/verify/chip/evidence. Delete the artifacts afterwards. A successful finalize is not a verified machine. Read the state with peaqos verify status.
The challenge is valid for at most five minutes and every stage rechecks it against the local clock. Failures print one line naming the input and the constraint, for example Chip prepare failed because the challenge is outside its freshness window. Request a new challenge and retry.

peaqos scale

Machine Market orchestration commands. Pair an AI agent to an activated machine, search the curated catalogue, and drive the full purchase loop. The peaqos scale surface: agent pair, machine onboard (plus machine status [MACHINE_ID] and machine list, both with --json; list exits 0/2/3, status 0/1/2/3), search, and the scale order family: place (dispatched from a service UUID), status, list with cursor pagination, received, dispute. Order placement also supports the payment rail.

Setup

Two env vars, both optional in load_client(). Override at any point with the root-level flags --orchestration-url / --orch-api-key.
Scale is paused. Registering a machine with the Machine Markets API fails for Tokenomics 1.0 and Economics 2.0 machines (see Scale). With TOKENOMICS_DEPLOYMENT_ID set, the SDK refuses every orchestration call that binds a machine identity (scale machine onboard | list | status, scale agent pair, scale search) with TokenomicsIntegrationUnavailableError (see the SDK gate table). Without it, the orchestrator cannot resolve a Tokenomics 1.0 machine’s identity and machine-bound calls return PEAQOS_IDENTITY_UNAVAILABLE.
peaqos init prompts for both during the wizard and writes them as active .env lines (not commented placeholders). The API key is entered at a hidden prompt (not echoed to the terminal), then written to .env in plaintext, so treat the file as a secret:
peaqos init --non-interactive reads both from existing env vars. The pairing token returned by agent pair is the credential for agent-side commands. Save it once to a single-line file with chmod 600 and reference it via --pairing-token-file.

peaqos scale machine onboard

Operator-facing. Walks a machine through the four-step orchestration onboard: request an identity , with the DID controller key, register the machine with proof attached, then activate (unless --skip-activate). Hits POST /api/v1/machine-identity/challenges and POST /api/v1/machines.
Required: --identity-ref, --display-name, --owner-id, --machine-type, --runtime-profile. Optional: --capabilities (CSV), --skill-keys (CSV), --labels (KEY=VALUE,...), --identity-signature-file, --identity-key-file, --skip-activate, --yes, --json. Signing inputs: --identity-signature-file (a one-line hex signature you produced externally) or --identity-key-file (the CLI signs in-process with the DID controller’s private key); supplying both is rejected. With neither, the CLI signs with the selected OWS wallet, or prompts for a signature interactively. Exit codes: 0 happy path, 1 input error, 2 server / proof error (MACHINE_IDENTITY_EXISTS, MACHINE_IDENTITY_PROOF_INVALID, PEAQOS_IDENTITY_UNAVAILABLE), 3 missing PEAQOS_ORCHESTRATION_URL.

peaqos scale agent pair

Operator-facing. Pairs an AI agent to a machine via a three-step challenge-sign flow. Returns a one-time signed-JWT pairingToken. Internally the command:
  1. Calls client.orchestration.create_agent_pairing_challenge(machine_id, params) for a server-issued challenge keyed to agentAddress, agentProvider, agentRole, and optional agentDid.
  2. The Machine Agent signs the returned challenge message () with the wallet key behind agentAddress. Supply the signature via --agent-signature-file <path>.
  3. Calls client.orchestration.create_agent_pairing(machine_id, params_with_proof) to persist the pairing and issue the session JWT.
Required: --machine-id, --agent-address, --agent-provider, --agent-role. Optional: --agent-did, --agent-signature-file (path to pre-signed EIP-191 challenge signature; required with --json, otherwise the CLI prompts interactively), --description, --per-tx-limit, --daily-limit, --currency, --allowed-skills (CSV), --denied-skills (CSV), --allowed-service-ids (CSV), --denied-service-ids (CSV), -y/--yes to skip the confirmation prompt, --json for raw JSON (implies --yes). Preconditions: PEAQOS_ORCH_API_KEY set. Machine already active in peaqOS or the server returns MACHINE_NOT_ACTIVATED and the CLI exits 2. The pairing summary includes Agent DID, Session ID, Session Expires, and Verification lines. The token prints exactly once on stdout, never written to peaqos.log or --verbose output. Pipe to a file:
Session tokens expire (default 1 hour). Rotate directly via client.orchestration.create_agent_pairing_session(...) (Python) or createAgentPairingSession(...) (JS) from your own tooling, signing a fresh challenge. Agent-facing. Posts a market search and returns ranked service quotes. Hits POST /api/v1/market/search and renders the search record that request returns.
Required: --machine-id, --service-type, --pairing-token-file. Optional: --agent-pairing-id, --operation, --capabilities (CSV), --region, --max-results, --budget-amount, --budget-max, --budget-currency, --native-only, --allow-handoff, --provider-credentials (path to JSON), --json. Preconditions: machine active with verified identityRef, active agent pairing, pairing token in the token file. Provider credential file contents never appear on stdout, stderr, or in log output. Output:
  • Human mode: ranked quote table with columns Service ID, Quote ID, Operation, Provider, Score, Execution, Integration. Footer prints Search ID: msearch_... plus a concrete next-step hint: peaqos scale order <service-id> --search-id <search-id> --quote-id <quote-id>.
  • Empty results print No matching services found. with the same aligned Search ID: line and broaden-your-search guidance.
  • --json emits the full MarketSearch envelope. The raw MarketSearchRequest is constructed from typed SDK data classes, not raw dicts.
The order group is dynamic-dispatch. Any first token that is not status, list, received, or dispute is interpreted as a service UUID and routed to the placement flow. peaqos scale order foo-bar reads as “place an order for service foo-bar.”

peaqos scale order <service-uuid>

Agent-facing. End-to-end purchase. Hits the POST /market/orders + payment intent + execute flow. Four payment paths chosen from the MarketPayment returned at order create:
  • No payment: create → execute (2 steps).
  • Wallet payment: create → intent → transfer → proof → execute (5 steps). If PEAQOS_OWS_WALLET is set the CLI auto-signs the ERC-20 transfer via OWS; otherwise it prompts for a pasted tx hash (or use --payment-tx-hash).
  • Escrow / handoff: same five steps with the .
  • x402: create → intent → sign → proof → execute → confirm (6 steps), for paid-HTTP Agentic Market providers (e.g. Wolfram Alpha over USDC on Base). The CLI signs the provider’s payment challenge locally with the active wallet (client.account, the OWS wallet when PEAQOS_OWS_WALLET is set, otherwise the local key) and hands the signed PAYMENT-SIGNATURE header to peaqOS, which pays the provider during execute. No separate on-chain transfer, no tx-hash prompt; delivery is confirmed automatically in step 6. If execution fails after proof is recorded, the error reports the current payment status so you can check whether the authorization is held.
Set PEAQOS_ORDER_STEP_DELAY_SEC to a non-negative number of seconds to pause between placement steps (demos, eventually-consistent order state); unset means no delay. Required: --machine-id, --agent-pairing-id, --pairing-token-file. Optional: --search-id, --quote-id, --operation, --budget-amount, --budget-currency, --input <path> (JSON object file; there is no @file shorthand), --provider-credentials <path> (JSON file with provider creds; never logged), --payment-tx-hash, --payment-chain (CAIP-2 alias: base, peaq, agung, ethereum/eth, polygon, arbitrum, optimism, bsc, solana), --payment-token (both required with --payment-tx-hash), --skip-payment (requires --payment-tx-hash), -y/--yes, --json. PEAQOS_RPC_URL supplies the payment RPC for peaq; the other chains have built-in endpoints. Without it a peaq payment exits with a configuration error pointing at --payment-tx-hash. Error codes: QUOTE_EXPIRED, EXECUTION_UNSUPPORTED, PAYMENT_REQUIRED, PAYMENT_RPC_ERROR, PAYMENT_TX_FAILED, PAYMENT_TRANSFER_NOT_FOUND, ORDER_CLOSED, ORDER_NOT_DELIVERED, NOT_FOUND. --json suppresses placement progress and prints the JSON envelope to stdout. Global --quiet suppresses progress in human mode and sets logging to ERROR; errors still print to stderr.

peaqos scale order status <order-id>

Returns current state of the purchase. Read-only platform auth. Hits GET /market/orders/:orderId plus the payment lookup. Optional: --json for the { order, payment } envelope. Missing payment record (NOT_FOUND) is not an error: payment is null in the JSON envelope. Missing order ID exits 1.

peaqos scale order list --machine-id <id>

Lists orders for a machine. Hits GET /market/orders?machineId=.... Required: --machine-id. Optional: --limit <int> (1-500, server default 100; outside range exits 1), --cursor <opaque> (from a prior next_cursor; never logged), --json. Output behaviour:
  • Human mode: one page, N order(s) shown. footer. When next_cursor is set, the CLI prints a copy-paste hint: Next page: peaqos scale order list --machine-id <id> [--limit N] --cursor <verbatim>.
  • --json without --limit: auto-paginates all pages and emits a flat root-level JSON array.
  • --json with --limit: emits a single-page envelope { "items": [...], "next_cursor": ... }.
The CLI surfaces next_cursor (snake_case) on stdout; the wire field is nextCursor.

peaqos scale order received <order-id>

Confirms delivery and marks the payment for release. It does not move funds. Requires --pairing-token-file. Hits POST /market/orders/:orderId/confirm. Optional: --json. Status moves to confirmed, payment to release_pending. Error codes: ORDER_NOT_DELIVERED, ORDER_CLOSED, AGENT_AUTH_INVALID. Missing order ID or token file exits 1.

peaqos scale order dispute <order-id>

Raises a dispute. Requires --reason and --pairing-token-file. Hits POST /market/orders/:orderId/dispute. Optional: --evidence <path> (JSON object file), -y/--yes to skip the Raise dispute? [y/N] prompt, --json (also skips the prompt). Status moves to disputed, payment to frozen. Error codes: ORDER_CLOSED, AGENT_AUTH_INVALID. Missing order ID, reason, or token file exits 1.

Exit codes

Every subcommand funnels SDK and network exceptions through a single error handler that raises with a stable exit code. peaqos verify uses 1, 2 and 3 with the meanings in its own tables (verify status, verify chip): verify status exits 2 for an unknown machine, and verify chip exits 1 for a rejected signature or an expired challenge and 2 only for an unexpected failure or a cancellation. A missing PEAQOS_VERIFY_API_URL is a configuration error (3). peaqos activate adds a stable error_code to every failure after input validation (see peaqos activate). peaqos machine status --json and peaqos monetize status --json print exactly one JSON object on failure, with status: "error", error_code (for example CONFIG_ERROR), message, guidance, plus sdk_code on machine reads and context on the MCR and monetize commands; the exit code is unchanged. Every peaqos machine write prints the same structured object for a failure inside its runner (plus the retained transaction context); input validation and configuration errors before the runner starts print a plain message. The other peaqos monetize subcommands print the message only under --json.

See also

peaqOS AI

The peaqOS agent skill that drives these CLI flows from any AI agent.

SDK reference

The TypeScript / Python API the CLI wraps.

API reference

The MCR API that qualify mcr, show machine, and show operator machines hit.