Skip to main content
The Machine Markets API is the HTTP/JSON interface for Scale. It handles machine identity proofs, machine records, , the skill registry, the service catalogue, and machine-aware market search.

Base path

All endpoints sit under /api/v1 on the orchestrator host. The canonical peaq-managed endpoint is https://orchestration.peaq.xyz:
export PEAQOS_ORCHESTRATION_URL=https://orchestration.peaq.xyz
# All paths below are relative to ${PEAQOS_ORCHESTRATION_URL}/api/v1
GET /health is an exception: it lives at host root, not under /api/v1, and is exempt from API-key auth. Self-hosters can run their own orchestrator via Docker Compose and point PEAQOS_ORCHESTRATION_URL at it.

Access model

  • The API is public unless the deployment enables API-key auth (PEAQOS_REQUIRE_API_AUTH=true).
  • Machine registration accepts identityRef as either a peaq (did:peaq:0x...) or a peaqOS machine public ID (peaqos:machine:<id>).
  • When PEAQOS_MACHINE_IDENTITY_VERIFICATION=required (production default), every machine registration and machine-bound write verifies identityRef against peaqOS data and requires a signed DID-controller challenge.
  • Machine Agent pairing is challenge-based. The agent signs a server-issued challenge with the wallet key behind agentAddress (). The orchestrator verifies the signature, persists the pairing, and issues a signed session JWT as pairingToken.
  • Market search requires (a) an active, bonded peaqOS machine, (b) a verified identityRef with ownership proof, and (c) an active Machine Agent pairing.
  • When PEAQOS_REQUIRE_AGENT_PAIRING_AUTH=true (production default), market search must include the x-agent-pairing-token header. The token is a signed HS256 JWT with claims for machineId, pairingId, sessionId, agentAddress, agentDid, delegationPolicyHash, and expiry. Rotate it via the pairing sessions endpoint before exp.
  • The pairing token proves delegated permission. It does not prove machine activation.
  • Pass provider credentials per request under providerCredentials. They feed runtime discovery and are redacted before persistence.

Payment model

peaqOS does not collect marketplace payments. The payment-intent and payment-proof endpoints record provider/service payment state only when the selected adapter requires direct provider payment (x402, , wallet rails). Operators or machines pay the selected provider directly through that provider’s supported . pay.sh and Agentic Market services use request-scoped payment proofs: the API returns the provider’s payment challenge from payment-intent, the operator agent signs or pays locally, and the resulting proof or header is sent to payment-proof and execute. Raw payment headers are never stored.

Common envelopes

type ListResponse<T> = {
  items: T[];
  nextCursor?: string;        // omitted when there is no next page
};

type ListQuery = {
  limit?: number;             // 1..500, default 100
  cursor?: string;            // opaque base64url, do not parse
};

type PaymentHeaders = {
  xPayment?: string;
  paymentSignature?: string;
  authorization?: string;
  signInWithX?: string;
};

type ItemResponse<T> = {
  item: T;
};

type ErrorResponse = {
  error: {
    code: string;
    message: string;
    details?: unknown;
  };
};

Error codes

type CommonErrorCode =
  // Auth
  | "AUTH_REQUIRED"
  | "AUTH_INVALID"
  | "AGENT_AUTH_REQUIRED"
  | "AGENT_AUTH_INVALID"
  | "AGENT_AUTH_EXPIRED"
  // Generic
  | "VALIDATION_ERROR"
  | "NOT_FOUND"
  // Machine
  | "MACHINE_NOT_ACTIVE"
  | "MACHINE_NOT_ACTIVATED"
  | "MACHINE_IDENTITY_EXISTS"
  | "MACHINE_IDENTITY_IMMUTABLE"
  | "MACHINE_IDENTITY_PROOF_REQUIRED"
  | "MACHINE_IDENTITY_PROOF_INVALID"
  | "MACHINE_IDENTITY_PROOF_EXPIRED"
  | "PEAQOS_IDENTITY_UNAVAILABLE"
  // Pairing
  | "AGENT_PAIRING_PROOF_REQUIRED"
  | "AGENT_PAIRING_PROOF_INVALID"
  | "AGENT_PAIRING_PROOF_EXPIRED"
  | "AGENT_PAIRING_UNAVAILABLE"
  | "AGENT_PAIRING_REQUIRED"
  | "AGENT_PAIRING_INACTIVE"
  | "AGENT_POLICY_DENIED"
  | "AGENT_SPEND_LIMIT_EXCEEDED"
  | "AGENT_DAILY_LIMIT_EXCEEDED"
  // Market orders
  | "OPEN_MARKET_ORDERS"
  | "QUOTE_EXPIRED"
  | "ROUTE_REQUIRED"
  | "ORDER_CLOSED"
  | "ORDER_NOT_DELIVERED"
  // Payments
  | "PAYMENT_REQUIRED"
  | "PAYMENT_RPC_REQUIRED"
  | "PAYMENT_RPC_ERROR"
  | "PAYMENT_NOT_MINED"
  | "PAYMENT_TX_FAILED"
  | "PAYMENT_TRANSFER_NOT_FOUND";

Common types

type ExecutionMode = "native" | "external-handoff";

type IntegrationStatus =
  | "native"
  | "credentials-required"
  | "partner-required"
  | "local-config-required"
  | "setup-required"
  | "docs-only";

type ServiceType =
  | "oracle.price-feed"
  | "compute.marketplace"
  | "storage.object"
  | "data.location"
  | "network.partner-console"
  | "identity.proof-of-person"
  | "device.control"
  | "machine.commerce";

type ProviderCredentials = {
  // Per-adapter credentials. Shape is provider-specific and
  // documented per-adapter on robotic.sh. Always redacted
  // before request bodies are persisted.
  [providerKey: string]: Record<string, string | undefined>;
};

Pagination

Every list endpoint accepts ListQuery. Cursors are opaque — do not parse them.
// First page
GET /api/v1/market/services?limit=100

// Next page: pass the previous response's nextCursor exactly as returned
GET /api/v1/market/services?limit=100&cursor=eyJ2IjoxLCJvZmZzZXQiOjEwMH0
Rules:
  • First page omits cursor.
  • nextCursor is omitted when there is no next page. It is never null.
  • Pass nextCursor back unchanged on the next request.
  • Invalid limit (out of range or non-integer) or malformed cursor returns 400 VALIDATION_ERROR.

Health

EndpointPathDescription
GET /healthhost root (not /api/v1)Process health. Returns { ok: true }. Exempt from API-key auth.
GET /readiness/api/v1/readinessStore, catalog, auth, runtime, and skill checks. Returns { status, checks[] }.

Endpoint groups

Machines & identity

Identity challenges, machine CRUD, EIP-191 controller proofs.

Machine Agent pairings

Challenge-based pairings, session JWT rotation, delegation policy.

Skills & services

Browse the skill registry, the partner service catalogue, and the adapter setup catalogue; run market search.

Market orders & payments

Order lifecycle, payment intent, escrow, execute, confirm, dispute.

Orchestration

Runtime endpoints, machine-side agents, graph, tasks, routes, outcomes, runs, policies, audit events.

Server configuration

When self-hosting the orchestrator, these toggles change the contract callers see. Defaults match the .env.example ships.
VariableDefaultPurpose
PEAQOS_REQUIRE_API_AUTHfalseGate every /api/v1/* request with a deployment API key (PEAQOS_API_KEY/PEAQOS_API_KEYS).
PEAQOS_REQUIRE_AGENT_PAIRING_AUTHtrueRequire x-agent-pairing-token on market writes.
PEAQOS_MACHINE_IDENTITY_VERIFICATIONrequiredEnforce DID-controller proof on machine writes.
PEAQOS_AGENT_PAIRING_VERIFICATIONrequiredEnforce EIP-191 challenge proof on pairings.
PEAQOS_AGENT_PAIRING_SESSION_SECRETrequired in prodHS256 secret for session JWTs and challenge HMAC.
PEAQOS_AGENT_PAIRING_CHALLENGE_TTL_MS600000Pairing challenge TTL (10 min).
PEAQOS_AGENT_PAIRING_SESSION_TTL_MS3600000Session token TTL (1 hour).
PEAQOS_REQUIRE_MARKET_QUOTESfalseReject POST /market/orders without searchId and quoteId.
PEAQOS_ENFORCE_SERVICE_PAYMENT_RAILSfalseReject payment-intent rails not in the service’s supportedRails.
PEAQOS_REQUIRE_PAYMENT_BEFORE_EXECUTEfalseBlock execute unless payment is held / release_pending / released / not_required.
PEAQOS_REQUIRE_PAYMENT_RPC_VERIFICATIONfalseForce verificationMode=rpc on payment-proof.
PEAQOS_PAYMENT_RPC_URLfalls back to PEAQ_EVM_RPC_URL, PEAQOS_EVM_RPC_URLPrimary RPC for proof verification.
PEAQOS_USDT_CONTRACT / PEAQOS_USDT_DECIMALSnone / 6Default USDT contract and decimals for payment proof.
PEAQOS_MCR_API_URLhttps://mcr.peaq.xyzpeaqOS MCR endpoint for identity resolution.