First decision: where should the machine live?
A machine has a home chain: the chain that holds its identity, DID document and NFT. Today that is either peaq or Solana. The machine ID and the peaqID look the same either way, and both homes can use Stream to sell data.
Choose peaq unless the machine’s owner, its buyers or its payments already live on Solana. If you are not sure, start on peaq; it is the shorter path.
What it costs
Activation costs the tier bond plus gas. The bond is priced in US dollars per tier and paid in PEAQ at the oracle’s most recently committed price. The preview (--dry-run) prints the exact PEAQ amount before anything is submitted. To size a wallet before you run anything, divide the tier’s dollar price by the current PEAQ price.
The bond buys one 365-day subscription period, so budget it per machine per year. For a peaq-homed machine, renew with
peaqos machine subscription renew <machine_id> before the period ends; the CLI and SDKs do not renew a Solana-homed machine. A renewal keeps the machine’s tier: --tier is refused with RENEWAL_TIER_UNSUPPORTED before anything is sent, so pick the tier at activation. After the period ends you get a 14-day grace period, then a 14-day runoff in which the bond decays to zero, and then the machine is terminated: on peaq its Machine NFT is burned; on Solana the machine’s accounts stay, with the subscription status mirrored to its terminal record. Renewing late does not refund lost time: the new period runs from the old period end, not from the day you renew, and it costs a full bond. Suspending a machine does not pause any of this. The subscription lifecycle describes the whole sequence.
On top of the bond you pay peaq gas (a few transactions, about 0.3 PEAQ in the measured run). A Solana home works differently: the owner wallet pays the bond on Solana, in PEAQ (bridged to Solana) or in USDC, and peaq books it. On 2026-10-06 a Basic bond was 4.744535245 PEAQ, or 0.200807 USDC through the swap; the price moves with the oracle, and the preview prints yours. The owner also pays about 0.0081 SOL of rent and fees per machine with the DID document below (8,122,140 lamports paying in PEAQ, 8,125,140 paying in USDC; a larger document costs a little more), and the operator wallet pays about 0.01 PEAQ of gas once, for the owner wallet’s registration. There is no messaging fee: peaq’s Trust Validator node delivers the link push.
On peaq, USDT settlement of the bond (--payment usdt) is not configured on peaq mainnet; pay the bond in PEAQ. Gas on peaq is always PEAQ. Bonds are not withdrawable. Prices and the formula are on Economics 2.0.
Part 1: Set up once per fleet
Everything in this part you do once, and every machine you onboard afterwards reuses it.1
Install the CLI
You need Python 3.10 or newer. Installing into a virtual environment keeps it separate from anything else on your machine.You should see the CLI version and the SDK version it runs on. For a Solana home it must be CLI 0.0.19 or newer on SDK 0.11.2 or newer (0.0.17 and 0.0.18 onboard, but cannot send the machine’s events (0.0.17) or manage it (0.0.18) afterwards). Older releases implement a Solana flow that the current programs no longer accept. The
ows extra adds the encrypted wallet vault used below; solana is only needed for a Solana home. Everything here is mainnet.2
Make a folder for the fleet and run the setup wizard
The CLI keeps three things in the folder you run it from: a The wizard asks a handful of questions. Choose mainnet and keep the deployment
.env file with your settings, your DID documents, and peaqos.log, a journal of every transaction it sends. The journal is what lets the CLI pick up safely after an interruption, so keep this folder and back it up. Your wallets are not in it: they live in the vault at ~/.ows/, which needs its own backup.peaq-mainnet. For a Solana home, enter your own provider’s peaq RPC endpoint when it asks for the RPC URL; the public endpoint rate-limits a Solana run. When offered, choose wallet as the key source; it creates an encrypted wallet rather than a raw key. Name the wallet fleet-owner for a peaq home or fleet-operator for a Solana home. It also asks for a passphrase; you need it for every command that signs with that wallet. Accept the defaults for the rest, including the Event Registry address (the wizard fills in the Economics 2.0 contract, 0xA1e7F1d7B24dAb55Dc92491e6d9B89F6E925Ad1e). It fills in the contract addresses from its network defaults and finishes by running peaqos whoami to show what it wrote.3
Create and fund the wallet(s)
Wallets live in the vault at
~/.ows/, each protected by its own passphrase. For each wallet, run peaqos wallet export <name> once and store the seed phrase somewhere safe; nothing else can recover the key. The command prints the phrase to the terminal, so do not run it anywhere the output is logged. Creating a wallet does not put any funds in it: send PEAQ (and SOL, for a Solana home) to the addresses it prints.- Home on peaq
- Home on Solana
The wizard already created Copy the
fleet-owner and named it in .env as the signer. One wallet does everything: it pays the bond and gas and owns the machine.0x… address and send PEAQ to it: the bond plus at least 0.5 PEAQ. Below 0.5 PEAQ a real peaqos activate run stops to fund the wallet for you through the Gas Station, which the first time means enrolling an authenticator app from a QR code. Staying above 0.5 PEAQ avoids it, and --skip-funding turns it off.If you would rather each machine own its own NFT while you keep control as operator, give each machine its own raw key file and activate with --for and --machine-key; the fleet guide explains that pattern and how to make the key files.4
Write the DID document
The DID document is a small JSON file that describes the machine: which key speaks for it and where to find its data and documentation. Save it as Keep the three keys above and nothing else at the top level:
did.json in the fleet folder. You can reuse one template for the whole fleet and change only the URLs if they differ per machine. Replace the example URLs below with your own before you activate: they are written on chain and shown on the machine’s public MCR profile.For a first fleet, point the verification method at the wallet that will own the machines. publicKeyMultibase carries the verifying key in multibase form (z6Mk… for an Ed25519 key). No peaqos command prints it.- Home on peaq
- Home on Solana
Set It prints the
controller to the 0x… address of fleet-owner (from peaqos wallet show fleet-owner --json). The CLI accepts only a 0x address with 40 hex characters here.publicKeyMultibase takes an Ed25519 public key, and the 0x… address cannot give you one: it is a hash of the wallet’s key, not the key itself. If the machine already has an Ed25519 key, use its public key. Otherwise generate one. Run pip install base58 first (the CLI does not install it):z6Mk… value for publicKeyMultibase and writes the private key to machine-ed25519.key, readable only by your user. It refuses to overwrite an existing file. Keep that file safe: it is the key the verification method names.The value is stored exactly as you write it and nothing checks it. One key per machine is the clean setup. The chain does not reject a repeated key, so a first fleet can share one key through the template and give each machine its own later with peaqos machine did set-verification-methods.did.json
id and controller are rejected there, because the machine’s ID is computed on chain and the CLI sets the controller itself. authentication lists which verification methods may authenticate, by position (0 is the first one).Part 2: Activate each machine
Two inputs define a machine forever: a machine type, one word or phrase you use for the whole fleet (Sensor, Robot, Vehicle, Charger…), and a credential subject, some bytes that identify this particular unit. The serial number is the usual choice. Together they produce the machine ID, and that pair cannot be activated a second time while the machine exists, so pick them deliberately.
echo prints more than 0x before you go on. An unset SERIAL produces an empty credential subject, which is accepted and cannot be changed afterwards. Use the serial exactly as printed on the unit and decide the format once for the fleet (case, leading zeros, no spaces): a one-character difference is a different machine for good.
Now follow the tab for your home chain. Every activate and machine write first shows you what it is about to do and asks for confirmation, and most take --dry-run, which shows the same preview and stops.
- Home on peaq
- Home on Solana
1
Preview
Nothing is sent. The output shows the bond for your tier, any voucher credit, and the net PEAQ the wallet needs.
--manufacturer is any EVM address you choose to record as the maker; the network stores it but does not check it. --tier is entry, basic or pro. If the preview says the wallet is short, top it up and preview again.2
Activate
The same command without Activation is one atomic call: it mints the NFT, stores the DID document, bonds the tier and records peaq as the home. When your wallet’s allowance does not already cover the bond, the CLI sends a separate token approval before it, so you may see two transactions go out. The output includes the
--dry-run. Read the terms it prints and confirm. In a script, add --yes to confirm and --json for machine-readable output, and set OWS_PASSPHRASE (no PEAQOS_ prefix on this one) to the signing wallet’s passphrase or it still stops to ask.machine_id, a long decimal number. Keep it; every later command identifies the machine by it.3
Check
owner, your tier under subscription, and is_homed_locally: true. The machine’s peaqID is did:peaq:<machine_id>..env are reused either way; a peaq machine can run from the same fleet folder, a Solana machine gets its own folder. Keep a list of serial number to machine_id as you go: the machine ID is how every later command, and peaq support, identifies the machine.
For a fleet on Solana, run the machines one after another, each in its own folder. The owner wallet’s registration is sent once, by the first machine; every later machine reconciles it and sends nothing on peaq. At about 10 minutes per machine, 28 machines take about 5 hours; script Part 2 per serial with --yes --json and OWS_PASSPHRASE exported, write each run’s JSON to a file in the machine’s folder, and read machine_id and spent from there.
Part 3: After activation
- Home on peaq
- Home on Solana
Record what the machine does. Events are how a machine builds its credit history. An activity event says “I did work”; a revenue event says “I earned this much” (in the currency’s smallest unit, so cents for USD). On peaq, The second command reads the machine’s credit rating.Manage it.
qualify event submits straight away, with no preview and no confirmation prompt, so check the values before you run it (--dry-run previews native Solana submissions only).peaqos machine covers the lifecycle: status, suspend, resume, subscription renew, transfer, and the did set-… commands to update the DID document. The two subscription writes prompt for confirmation but have no --dry-run. Details on CLI: machine.peaqos stream publish encrypts and signs a data file, stream distribute delivers it to a buyer once their payment is confirmed, and stream grant hands a buyer access directly when you have checked payment yourself. Buyers pay with the native token or an ERC-20 on peaq or Base, or with SOL or an SPL token on Solana.
If something goes wrong
The CLI is designed so that a failed or interrupted step is safe to run again: it reads its journal first and reconciles a pending transaction instead of sending it twice. Don’t deletepeaqos.log, don’t change the arguments, and rerun the step. For peaqos machine writes this covers pending writes only: once a write is recorded as confirmed, running the same command again is a new write (a second subscription renew pays again), so check machine status before repeating one that already went through. A Solana onboarding run is different: every confirmed phase is reconciled from the journal and never sent again, so rerunning it with the same inputs never pays twice.
On peaq
On Solana
Exit codes:
1 means something in your input or a declined confirmation, 2 a chain or network failure, 3 a configuration problem such as a missing setting or extra. With --json, the error_code field says exactly which. Full tables live on CLI: exit codes and Solana onboarding: resume and troubleshoot.
Where to go next
- Activate: what activation creates and why it is one transaction
- Self-managed onboarding: the peaq flow from the SDKs instead of the CLI
- Fleet onboarding with an operator: machines that own themselves while you operate them
- Onboard a machine on Solana: every Solana flag, state and recovery path
- Wallets (OWS), Install, Economics 2.0

