Documentation Index
Fetch the complete documentation index at: https://docs.peaq.xyz/llms.txt
Use this file to discover all available pages before exploring further.
A Machine Agent buys a service through an order. The orchestrator owns the full lifecycle: order create, payment intent, proof or escrow lock, execute, confirm, dispute, release, refund. Server-side enforcement covers identity proofs, agent pairing, delegation policy, per-transaction and daily spend limits, quote freshness, and rail compatibility.
See the Machine Markets overview for base path, auth model, and common envelopes.
Order state machine
created -> payment_pending -> ready -> executing -> delivered -> confirmed
\-> handoff
\-> disputed
\-> failed
\-> cancelled
Payment state machine
intent_created -> held -> release_pending -> released
not_required \-> refunded
\-> frozen (on dispute)
Types
type MarketOrderStatus =
| "created" | "payment_pending" | "ready" | "executing"
| "delivered" | "confirmed" | "disputed" | "cancelled"
| "failed" | "handoff";
type MarketPaymentStatus =
| "not_required" | "intent_created" | "held" | "release_pending"
| "released" | "frozen" | "refunded";
type MarketPaymentRailType =
| "not-required" | "wallet" | "x402" | "xvv42"
| "vault-stripe" | "wdk-usdt-transfer" | "escrow"
| "offchain-record" | "external" | "onchain-escrow";
type MarketOrderRecord = {
id: string;
machineId: string;
agentPairingId: string;
searchId: string | null;
quoteId: string | null;
serviceId: string;
skillKey: string;
providerKey: string;
serviceType: ServiceType;
operation: string;
executionMode: ExecutionMode;
integrationStatus: IntegrationStatus;
status: MarketOrderStatus;
input: Record<string, unknown>;
budget?: { amount?: number | null; currency?: string | null } | null;
payment: MarketPaymentRailRecommendation;
serviceSnapshot: Record<string, unknown>;
taskId: string | null;
routeId: string | null;
runId: string | null;
outcomeId: string | null;
handoff: ExternalHandoff | null;
errorMessage: string | null;
createdAt: string;
updatedAt: string;
};
type MarketPaymentRailRecommendation = {
defaultRail: MarketPaymentRailType;
supportedRails: MarketPaymentRailType[];
required: boolean;
provider?: string | null;
chain?: string | null;
token?: string | null;
walletAddress?: string | null;
externalUrl?: string | null;
notes: string[];
};
type MarketPaymentRecord = {
id: string;
orderId: string;
machineId: string;
status: MarketPaymentStatus;
rail: {
type: MarketPaymentRailType;
chain?: string | null;
token?: string | null;
escrowAddress?: string | null;
externalUrl?: string | null;
provider?: string | null;
accountId?: string | null;
walletAddress?: string | null;
payerAddress?: string | null;
payeeAddress?: string | null;
tokenAddress?: string | null;
transactionHash?: string | null;
paymentIntentId?: string | null;
metadata?: Record<string, unknown>;
};
amount?: number | null;
currency?: string | null;
proof?: {
transactionHash: string;
verificationMode: "recorded" | "rpc";
status: "recorded" | "verified";
chain?: string | null;
token?: string | null;
tokenAddress?: string | null;
payerAddress?: string | null;
payeeAddress?: string | null;
amount?: string | null;
rawAmount?: string | null;
blockNumber?: number | null;
verifiedAt: string;
metadata?: Record<string, unknown>;
} | null;
notes: string[];
createdAt: string;
updatedAt: string;
};
type ExternalHandoff = {
label: string;
url: string;
notes: string[];
};
type MarketDisputeRecord = {
id: string;
orderId: string;
machineId: string;
status: "open" | "resolved";
reason: string;
evidence: Record<string, unknown>;
createdAt: string;
updatedAt: string;
};
Orders
GET /market/orders?machineId={id}
Lists orders for a machine.
type ListMarketOrdersQuery = { machineId: string };
type ListMarketOrdersResponse = ListResponse<MarketOrderRecord>;
Errors: VALIDATION_ERROR, NOT_FOUND, MACHINE_NOT_ACTIVE, MACHINE_NOT_ACTIVATED.
POST /market/orders
Locks a service from the catalogue into an order. Status starts at created. The recommended payment rail is copied from the service into order.payment.
type CreateOrderRequest = {
machineId: string;
agentPairingId: string;
serviceId: string;
searchId?: string; // required when PEAQOS_REQUIRE_MARKET_QUOTES=true
quoteId?: string; // required when PEAQOS_REQUIRE_MARKET_QUOTES=true
operation?: string;
input?: Record<string, unknown>;
budget?: { amount?: number; max?: number; currency?: string };
operatorCredentials?: {
providers?: Record<string, { env?: Record<string, string> } & Record<string, string>>;
};
};
type CreateOrderResponse = ItemResponse<MarketOrderRecord>;
Errors: VALIDATION_ERROR, QUOTE_EXPIRED, AGENT_PAIRING_REQUIRED, AGENT_PAIRING_INACTIVE, AGENT_POLICY_DENIED, AGENT_SPEND_LIMIT_EXCEEDED, AGENT_DAILY_LIMIT_EXCEEDED, MACHINE_NOT_ACTIVE, MACHINE_NOT_ACTIVATED, NOT_FOUND.
GET /market/orders/:orderId
type GetMarketOrderResponse = ItemResponse<MarketOrderRecord>;
Payment
POST /market/orders/:orderId/payment-intent
Creates or returns the payment record. Idempotent: returns the existing payment if one already exists. For not-required rails the order moves straight to ready.
type CreatePaymentIntentRequest = {
amount?: number;
currency?: string;
rail?: {
type?: MarketPaymentRailType;
chain?: string;
token?: string;
tokenAddress?: string;
tokenMint?: string; // alias for tokenAddress on Solana
escrowAddress?: string;
externalUrl?: string;
provider?: string;
accountId?: string;
walletAddress?: string;
payerAddress?: string;
payeeAddress?: string;
transactionHash?: string;
paymentIntentId?: string;
metadata?: Record<string, unknown>;
};
payerAddress?: string;
payeeAddress?: string;
tokenAddress?: string;
tokenMint?: string;
transactionHash?: string;
txHash?: string;
};
type CreatePaymentIntentResponse = ItemResponse<MarketPaymentRecord>;
Errors: NOT_FOUND, VALIDATION_ERROR (unsupported rail, invalid address, rail not in service supportedRails when PEAQOS_ENFORCE_SERVICE_PAYMENT_RAILS=true).
POST /market/orders/:orderId/payment-proof
Records a payment proof. recorded mode stores operator attestation. rpc mode queries an EVM RPC for the transaction receipt and validates the ERC-20 Transfer log against expected token, sender, recipient, and raw amount. Solana proofs are always recorded.
type RecordPaymentProofRequest = {
transactionHash: string; // EVM 0x… 64 hex, or Solana base58 64–100. Aliases: txHash, transactionSignature, signature.
chain?: string; // default "peaq"
token?: string; // default "USDT"
payerAddress?: string;
payeeAddress?: string;
tokenAddress?: string; // aliases: tokenMint, usdtContract; falls back to PEAQOS_USDT_CONTRACT
amount?: string;
rawAmount?: string; // integer in token base units
tokenDecimals?: number; // 0..36, default 6
verificationMode?: "recorded" | "rpc"; // default rpc when RPC URL set
rpcUrl?: string;
metadata?: Record<string, unknown>;
};
type RecordPaymentProofResponse = ItemResponse<MarketPaymentRecord>;
Errors: NOT_FOUND, ORDER_CLOSED, VALIDATION_ERROR, PAYMENT_RPC_REQUIRED (rpc mode with no RPC URL), PAYMENT_RPC_ERROR (502), PAYMENT_NOT_MINED (409, receipt null), PAYMENT_TX_FAILED (402, receipt status not 0x1), PAYMENT_TRANSFER_NOT_FOUND (400, no matching Transfer log).
On successful verification the rail type upgrades from wallet to wdk-usdt-transfer. Payment status moves to held; order moves created/payment_pending → ready.
GET /market/orders/:orderId/payment
type GetMarketPaymentResponse = ItemResponse<MarketPaymentRecord>;
POST /market/orders/:orderId/payment/escrow-lock
Records an on-chain escrow lock. Payment → held. Order → ready. Idempotent for held.
type EscrowLockRequest = {
transactionHash: string;
chain: string;
escrowAddress: string;
};
type EscrowLockResponse = ItemResponse<MarketPaymentRecord>;
Errors: NOT_FOUND, ORDER_CLOSED, VALIDATION_ERROR.
POST /market/orders/:orderId/payment/release
Releases held funds after confirm. Payment must be release_pending, order must be confirmed. Status → released.
type ReleasePaymentRequest = {
transactionHash?: string;
notes?: string;
};
type ReleasePaymentResponse = ItemResponse<MarketPaymentRecord>;
Errors: NOT_FOUND, ORDER_CLOSED, ORDER_NOT_DELIVERED. Idempotent for released and not_required.
POST /market/orders/:orderId/payment/refund
Refunds payment. Status → refunded. Open orders move to cancelled.
type RefundPaymentRequest = {
transactionHash?: string;
reason?: string;
};
type RefundPaymentResponse = ItemResponse<MarketPaymentRecord>;
Errors: NOT_FOUND, ORDER_CLOSED. Idempotent for refunded and not_required.
Execute, confirm, dispute
POST /market/orders/:orderId/execute
Materialises the order as a task plus route, runs the skill runtime, writes a Run and an Outcome. Order status moves executing → delivered (outcome completed) / handoff (outcome external) / failed. The HTTP status code is propagated from the inner execution result.
type ExecuteOrderRequest = Record<string, unknown> & {
operatorCredentials?: {
providers?: Record<string, { env?: Record<string, string> } & Record<string, string>>;
};
};
type ExecuteOrderResponse = {
order: MarketOrderRecord;
execution: {
statusCode: number;
outcome: OutcomeRecord;
run: RunRecord;
resolution: TaskResolution;
};
};
Errors: ORDER_CLOSED (order in confirmed / disputed / cancelled), PAYMENT_REQUIRED (when PEAQOS_REQUIRE_PAYMENT_BEFORE_EXECUTE=true, the production default, and payment is not in not_required / held / release_pending / released — except intent_created is allowed for external / vault-stripe rails). All downstream skill-runtime errors are surfaced as well.
x402-rail services (Agentic Market, most pay.sh) execute through the paidHttp adapter. The execute call replays the original 402-challenged request with the operator-supplied payment headers (x-payment, payment-signature, authorization, sign-in-with-x). The payment intent response now preserves the full x402 accepts[] entries including extra (EIP-712 signing metadata: { name: "USD Coin", version: "2" }-style) and outputSchema. Operators that build their own paid-HTTP adapters should pass headers under operatorCredentials.providers[providerKey]; raw headers are stripped from request bodies before forwarding and never persisted.
POST /market/orders/:orderId/confirm
Buyer confirms delivery. Order delivered / handoff → confirmed. Payment held → release_pending.
type ConfirmOrderResponse = {
order: MarketOrderRecord;
payment: MarketPaymentRecord | null;
};
Errors: ORDER_NOT_DELIVERED.
POST /market/orders/:orderId/dispute
Opens a dispute record. Order → disputed. Payment → frozen. Returns 201.
type DisputeOrderRequest = {
reason: string;
evidence?: Record<string, unknown>;
};
type DisputeOrderResponse = {
order: MarketOrderRecord;
payment: MarketPaymentRecord | null;
dispute: MarketDisputeRecord;
};
Errors: VALIDATION_ERROR (missing reason).