Skip to main content

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 pairing binds a third-party AI agent (Claude, OpenAI, Virtuals, Teneo, or your own) to an activated, bonded peaqOS machine and attaches a delegation policy that bounds what the agent can do on the machine’s behalf. Pairing is challenge-based: peaqOS issues a machine-bound challenge, the agent signs it with the wallet key behind agentAddress (EIP-191 personal_sign), and the orchestrator verifies the signature before persisting the pairing and issuing a signed session token. See the Machine Markets overview for base path, auth model, and common envelopes.

AgentPairing type

type AgentPairing = {
  id: string;
  machineId: string;
  status: "active" | "paused" | "revoked";
  agentAddress: string;
  agentDid: string | null;       // did:pkh:eip155:1:<addr> when present
  agentProvider: string;         // "anthropic" | "openai" | "virtuals" | ...
  agentRole: string;             // free-form, e.g. "ops" | "trader" | "buyer"
  description?: string | null;
  verification: {
    method: "eip191";
    signerAddress: string;       // recovered signer; must match agentAddress
    verifiedAt: string;
    challengeExpiresAt: string;
  } | null;
  delegationPolicy: {
    allowedSkillKeys: string[];
    deniedSkillKeys: string[];
    allowedServiceIds: string[];
    deniedServiceIds: string[];
    perTransactionLimit?: number | null;
    dailySpendLimit?: number | null;
    currency?: string | null;
  };
  hasAuthToken: boolean;
  tokenLastFour: string | null;
  sessionId: string | null;
  sessionTokenId: string | null;
  sessionIssuedAt: string | null;
  sessionExpiresAt: string | null;
  pairingToken?: string;         // signed HS256 session JWT, returned once at create/rotate
  createdAt: string;
  updatedAt: string;
};

AgentPairingChallenge and AgentPairingProof

type AgentPairingChallenge = {
  challengeId: string;
  machineId: string;
  machineIdentityRef: string | null;
  agentAddress: string;
  agentDid: string;
  agentProvider: string;
  agentRole: string;
  message: string;            // sign this with the key behind agentAddress
  expiresAt: string;
  verificationMethod: "eip191";
};

type AgentPairingProof = {
  challengeId: string;
  signature: string;
};

Endpoints

GET /machines/:machineId/agent-pairings

type ListAgentPairingsResponse = ListResponse<AgentPairing>;

POST /machines/:machineId/agent-pairings/challenges

Returns a fresh challenge for an agent. The Machine Agent signs item.message (EIP-191) with the wallet key behind agentAddress, then submits the signature to the create-pairing endpoint or the session-rotation endpoint.
type CreateAgentPairingChallengeRequest = {
  agentAddress: string;
  agentDid?: string;
  agentProvider: string;
  agentRole: string;
};

type CreateAgentPairingChallengeResponse = ItemResponse<AgentPairingChallenge>;
If agentDid is omitted, the orchestrator derives did:pkh:eip155:1:<agentAddress> from the normalised agentAddress. If supplied, agentDid must be of the form did:pkh:eip155:<chainId>:<agentAddress> whose address matches agentAddress (checksummed) — anything else returns VALIDATION_ERROR.

POST /machines/:machineId/agent-pairings

Creates a pairing. Requires agentProof when pairing verification is enabled (production default). Returns the pairing with a signed session JWT in pairingToken. The token is returned once at create; rotate via the sessions endpoint.
type CreateAgentPairingRequest = {
  agentAddress: string;
  agentDid?: string;
  agentProvider: string;
  agentRole: string;
  description?: string;
  agentProof: AgentPairingProof;
  delegationPolicy?: Partial<AgentPairing["delegationPolicy"]>;
};

type CreateAgentPairingResponse = ItemResponse<AgentPairing>;
Errors: AGENT_PAIRING_PROOF_REQUIRED, AGENT_PAIRING_PROOF_INVALID, AGENT_PAIRING_PROOF_EXPIRED, AGENT_PAIRING_UNAVAILABLE, MACHINE_NOT_ACTIVE, MACHINE_IDENTITY_PROOF_REQUIRED, VALIDATION_ERROR.

POST /machines/:machineId/agent-pairings/:pairingId/sessions

Rotates the session JWT for an active pairing. The agent gets a fresh challenge, signs it, and submits the new proof here. Returns the pairing with a new pairingToken.
type CreateAgentPairingSessionRequest = {
  agentProof: AgentPairingProof;
};

type CreateAgentPairingSessionResponse = ItemResponse<AgentPairing>;
Default session TTL is 1 hour (PEAQOS_AGENT_PAIRING_SESSION_TTL_MS). Market writes reject expired tokens with AGENT_AUTH_EXPIRED and reject tokens whose delegationPolicyHash no longer matches the persisted policy.

PATCH /machines/:machineId/agent-pairings/:pairingId

Repolicy or pause/resume. Policy changes invalidate the current session token’s delegationPolicyHash. Rotate the session via POST .../sessions after a policy change.
type UpdateAgentPairingRequest = {
  status?: "active" | "paused" | "revoked";
  description?: string | null;
  delegationPolicy?: Partial<AgentPairing["delegationPolicy"]>;
};

type UpdateAgentPairingResponse = ItemResponse<AgentPairing>;

DELETE /machines/:machineId/agent-pairings/:pairingId

Revokes the pairing. The current session token is invalidated. Subsequent market-search calls with that token return AGENT_AUTH_INVALID or AGENT_PAIRING_INACTIVE. If no active pairing exists for a machine, market writes return AGENT_PAIRING_REQUIRED (409). If the pairing has open market orders (status not in confirmed, cancelled, or failed), the call returns OPEN_MARKET_ORDERS (409) with orderIds — cancel or settle those orders first, then retry.
type DeleteAgentPairingResponse = void;

Session JWT claims

The pairingToken is an HS256 JWT signed by the orchestrator. Claims:
type AgentPairingSessionClaims = {
  iss: "peaqos-machine-market";
  aud: "machine-agent";
  typ: "agent-pairing-session";
  ver: 1;
  jti: string;
  sid: string;                   // sessionId
  pairingId: string;
  machineId: string;
  machineIdentityRef?: string | null;
  agentAddress: string;
  agentDid: string;
  agentProvider: string;
  agentRole: string;
  delegationPolicyHash: string;
  delegationPolicy: { /* snapshot of policy at issuance */ };
  iat: number;
  nbf: number;
  exp: number;
};
The orchestrator re-verifies the signature, expiry, pairing status, and delegationPolicyHash against the persisted policy on every market write.

Delegation policy

type DelegationPolicy = {
  allowedSkillKeys: string[];   // empty = allow all skills
  deniedSkillKeys: string[];    // wins over allowed
  allowedServiceIds: string[];  // empty = allow all listed services
  deniedServiceIds: string[];   // wins over allowed
  perTransactionLimit?: number | null;
  dailySpendLimit?: number | null;
  currency?: string | null;     // ISO 4217 or token symbol
};
Enforcement is server-side. Spend-limit violations return AGENT_SPEND_LIMIT_EXCEEDED or AGENT_DAILY_LIMIT_EXCEEDED. Allow/denylist violations return AGENT_POLICY_DENIED.