AEA/P API Reference
The complete wire contract for the two server surfaces that implement AEA/P. An Operator exposes the control plane, verification, and interaction endpoints that record identity, settlement, and performance; a Platform exposes the principal-facing onboarding and runtime surface that sits in front of it. Both are documented here so a single implementer — for example, one offering Platform and Operator services together — can build either side against one reference.
Overview
Every endpoint below belongs to one of two roles. Endpoints are versioned under /v1 and exchange JSON. Identity is a did:aeap: identifier; agent-scoped paths take the agent's DID as {did}. Every path is relative to an Operator's base URL, and the contracts are identical across conformant Operators.
The two surfaces
The boundary that keeps the system non-custodial and portable is simple: the Platform mediates the control plane (onboarding, discovery, routing, its own policies) but never touches funds or the service payload; the Operator verifies and records but never submits a settlement transaction; funds move directly through the on-chain Settlement Contract.
| Group | Called by | Purpose |
|---|---|---|
| Principals | Platform | Create the principal account and issue its API key |
| Agents | Platform | Register, activate, and market-config agents; resolve AID and live status |
| Verification | Agents | Challenge nonces, certificate and bound-proof verification, CA key discovery |
| Interaction | Agents | Payment address, settlement facilitation, task confirmation and rating, refunds |
| Group | Called by | Purpose |
|---|---|---|
| Onboarding | Builder | Email + KYC/KYB verification on the Platform, ahead of Operator registration |
| Discovery | Buyer agent | Match tasks to sellers; route requests and apply the Platform's own policies at egress |
| Management | Principal | Spend-policy profile, per-agent overview and event history |
Conventions
/v1. Breaking changes ship under a new prefix.application/json for request and response bodies.sandbox and production. A credential is bound to one environment; the status endpoint surfaces it, and cross-environment interaction is rejected with environment_mismatch.Idempotency-Key header; activation and facilitation are idempotent on it.Cache-Control (status max-age 30 s; payment-address 3600 s; CA JWKS 86400 s).Authentication
Credentials scoped to the caller. The AEAP- namespace (no X- prefix, RFC 6648) carries the agent credentials used at runtime — agent-to-agent and agent-to-Operator alike. A separate management key authenticates a platform's configuration calls.
AEAP-Api-Keyverify-email (value prefix aeap_). Held server-side by the Platform; authenticates management and configuration calls only — register, activate, scope/markets, status, AID. Never used for a runtime economic action.AEAP-Certificate + AEAP-Proof (runtime)AEAP-CertificateAEAP-Challenge-Response / AEAP-Proofnonce|agent_id|timestamp, and a callee-bound proof (Phase 2) over timestamp|caller_id|callee_id, accompanied by AEAP-Timestamp and the relayed AEAP-Challenge nonce.Onboarding entry points — POST /v1/principals and POST /v1/principals/verify-email — take no credential; verify-email is what mints the key used everywhere after.
Errors & status
Failures return a JSON envelope with an error and, where applicable, a reason drawn from the fixed rejection-code set (see Rejection codes). HTTP status follows REST conventions:
400validation_failed_multi with each validator payload in errors[].401 / 403402404 / 409500{
"error": "aeap_verification_failed",
"reason": "environment_mismatch",
"agent_id": "did:aeap:c8f12d34-..."
}Principals
Create the principal account and mint its platform API key. No credential is required to start; verify-email is what mints the key used everywhere after.
/v1/principalsCreates the principal in PENDING_VERIFICATION. principal_type is individual or company; display_name is derived. This is the onboarding entry point and takes no credential.
{
"principal_type": "company",
"company_name": "Acme Labs Inc",
"country": "US",
"first_name": "Jane",
"last_name": "Smith",
"email": "jane@acme.ai",
"password": "a-strong-passphrase"
}{
"pid": "did:aeap:principal:550e8400-e29b-41d4-a716-446655440000",
"principal_type": "company",
"company_name": "Acme Labs Inc",
"display_name": "Acme Labs Inc",
"email": "jane@acme.ai",
"email_verified": false,
"status": "PENDING_VERIFICATION"
}Email verification and KYC/KYB are Platform functions — the Operator is not involved in email verification. The platform API key minted at verify-email is what authorizes the agent-onboarding calls that follow.
/v1/principals/verify-emailVerifies the principal's email and issues the platform API key. The raw_key is shown once and never retrievable — the Platform stores it server-side and authenticates every subsequent agent call with it as AEAP-Api-Key.
{
"email": "jane@acme.ai",
"code": "123456"
}{
"key_prefix": "aeap_a3f2c1d4e",
"raw_key": "aeap_a3f2c1d4e5b6f7...",
"warning": "Store this key securely. It will not be shown again."
}Agents
Register, activate, and (for sellers) market-config agents, and resolve the AID and live status.
/v1/agentsValidates the Platform's Verification Attestation (Tier 2 KYB for a business agent, Tier 1 KYC for a personal agent) and the two type gates — cert_tier and authorized_actions — then creates the AID and returns it wrapped with a next_step pointer. Lifecycle state is DRAFT; public_key and signature populate at activation. The optional status: "ACTIVE" field combines registration and activation atomically.
agent_typePERSONAL or BUSINESS — whom the agent acts for. PERSONAL → BUSINESS is an in-place upgrade once the principal holds a Tier 2 attestation; BUSINESS → PERSONAL requires a new agent.display_nameauthorized_actionspurchase, sell, delegate. PERSONAL must include purchase and exclude sell; BUSINESS must include at least one of purchase or sell. Append-only thereafter.cert_tiercapabilities / authorized_marketsauthorized_actions includes sell.max_transaction_value / minimum_counterparty_*identity.scope.{
"agent_type": "BUSINESS",
"profile": { "display_name": "Acme Vendor Agent", "description": "Invoicing and delivery agent", "objective": "...",
"catalog_url": "https://agents.acme.example/catalog.jsonld" },
"authorized_actions": ["sell", "delegate"],
"cert_tier": "business",
"capabilities": ["cap.invoice", "cap.deliver"],
"authorized_markets": ["US-USDC"],
"max_transaction_value": 5000,
"minimum_counterparty_cert_tier": "personal",
"minimum_counterparty_ar": 0.8,
"endpoint_url": "https://agents.acme.example/vendor",
"auto_renew": true,
"status": "DRAFT"
}{
"aid": {
"aid_version": 1,
"environment": "sandbox",
"identity": {
"agent_id": "did:aeap:c8f12d34-5678-90ab-cdef-1234567890ab",
"agent_type": "BUSINESS",
"public_key": null,
"principal": { "principal_id": "did:aeap:principal:550e8400-...",
"country": "US", "principal_type": "company" },
"entity_id": null,
"profile": { "display_name": "Acme Vendor Agent",
"description": "Invoicing and delivery agent", "objective": "...",
"catalog_url": "https://agents.acme.example/catalog.jsonld" },
"endpoint_url": "https://agents.acme.example/vendor",
"certificate": { "cert_tier": "business", "verification_attestation": null },
"scope": { "version": 1,
"authorized_markets": ["US-USDC"],
"authorized_actions": ["sell", "delegate"],
"capabilities": ["cap.invoice", "cap.deliver"],
"max_transaction_value": 5000 },
"delegation": { "chain": [] },
"attestations": []
},
"performance": { "agent_rating": 0.75, "performance_record": null },
"escrow": { "liability_profile": { "escrow_state": "FUNDING", "total_balance": 0,
"funding_rate": 0.1, "dispute_window_days": 30 } },
"disputes": {}, "governance": null, "signature": null
},
"next_step": { "activate": "POST /v1/agents/did:aeap:c8f12d34-.../activate",
"note": "Agent is DRAFT — call activate to issue keys + certificate." }
}The AID carries the five pillars by agent type and authorized actions: an agent that does not sell has null escrow and disputes pillars; a business agent carrying sell carries escrow.liability_profile with funding-tier defaults; governance is populated under a governance document. Rejections (400): cert_tier_type_mismatch, authorized_action_type_mismatch, validation_failed_multi; 403 tier_exceeds_principal.
/v1/agents/{did}/activateGenerates the EC P-256 key pair, issues the certificate, signs the AID, and transitions DRAFT → ACTIVE. The private key is returned exactly once and is not recoverable. Activation has side effects beyond a status change, which is why it is a dedicated endpoint rather than a generic status update. No request body.
POST /v1/agents/did:aeap:c8f12d34-.../activate
AEAP-Api-Key: aeap_a3f2c1d4e...
Idempotency-Key: act_c8f12d34_01{
"agent_keys": {
"private_key": "-----BEGIN PRIVATE KEY-----\nMIGHAg...\n-----END PRIVATE KEY-----",
"public_key": "-----BEGIN PUBLIC KEY-----\nMFkwEw...\n-----END PUBLIC KEY-----",
"warning": "Store the private key securely. It will not be shown again."
},
"certificate": {
"cert_tier": "business",
"expires_at": "2027-05-23T18:18:09Z",
"jwt": "eyJhbGciOiJFUzI1NiIsImtpZCI6ImFlYXAtY2EtMjAyNi0wMSJ9..."
},
"aid": { "...": "updated AID — identity.public_key now set, status ACTIVE" }
}/v1/agents/{did}/scope/authorized_marketsRegisters a blockchain payment method for one of the agent's authorized markets: creates the KMS-held escrow wallet and calls registerSeller(...) on the per-network Settlement Contract. The escrow wallet is created by the Operator — do not pass it. Rejected for agents without sell in authorized_actions.
marketUS-USDC.method / networkblockchain and the settlement network, e.g. base-sepolia.token_addressoperational_wallet{
"market": "US-USDC",
"method": "blockchain",
"network": "base-sepolia",
"operational_wallet": "0x755F0B554cE981500F21D2cF4Ac05d1Acb6D2E53",
"token_address": "0x036CbD53842c5426634e7929541eC2318f3dCF7e"
}{
"id": "9b3e7c0d-5f1a-4d83-a8c2-1f2b3c4d5e6f",
"market": "US-USDC",
"network": "base-sepolia",
"escrow_wallet": "0x37b9F62E25b1E5fDbCa20A21bD3C8c87b9F62E25",
"settlement_contract": "0xc25c0943805FADA7704cc4Cc4CfEAdEA2c4DAF0f",
"register_tx": "0x0a4f3e9c2b1d8e7f6a5c4d3b2e1f0a9b...",
"status": "ACTIVE",
"message": "Market config registered. Seller is now on-chain."
}A per-currency escrow row is created in FUNDING (FUNDING → ACTIVE at threshold → DISPUTE_HOLD / CONSTRAINED / RELEASED). Errors: 400 market_not_authorized / unsupported_network; 409 config_exists; 500 kms_wallet_creation_failed / on_chain_registration_failed (retry-safe).
/v1/agents/{did}/aidResolves the full signed Agent Identity Document — the five-pillar credential (identity, performance, escrow, disputes, governance). Returned in DRAFT before activation, signed and public_key-populated after. The AID URL is the stable certificate_ref a counterparty resolves during discovery.
/v1/agents/{did}/statusServes the live, mutable state of an agent, separately from the stable certificate. The standardized fields are fixed by the protocol. AEAP-Requester-DID is optional and improves event-log audit quality.
{
"agent_id": "did:aeap:c8f12d34-5678-90ab-cdef-1234567890ab",
"status": "ACTIVE",
"environment": "production",
"cert_tier": "business",
"agent_rating": 0.97,
"authorized_markets": ["US-USDC"],
"escrow_state": "ACTIVE",
"last_updated": "2026-05-23T18:18:09Z"
}agent_rating is the live Proof-of-Performance rating — prior-initialized at 0.75 and marked provisional below 10 interactions. escrow_state is null for agents that do not sell. status ∈ { DRAFT, ACTIVE, SUSPENDED, REVOKED, TERMINATED }.
Verification
Challenge–response and bound-proof verification, plus the CA key discovery used for offline certificate checks.
/v1/verify/challengeIssues a fresh, single-use nonce for proof of key control (TTL ≈ 120 s). The nonce is the interaction_id linking the subsequent verify events.
{
"nonce": "1df9b6018121b9119f4d24304c883a5d1a371fee5b5422a10a9e838b7073052d",
"expires_in_seconds": 120
}/v1/verify/certificateVerifies a presented certificate against the Operator CA (signature, kid → JWKS, expiry). Offered for parties that do not verify offline; offline verification against the cached JWKS is preferred and needs no round-trip.
{ "certificate": "eyJhbGciOiJFUzI1NiIsImtpZCI6..." }{
"valid": true,
"agent_id": "did:aeap:c8f12d34-5678-90ab-cdef-1234567890ab",
"iss": "https://ca.operator.example",
"cert_tier": "business",
"agent_type": "BUSINESS"
}/v1/verify/proofVerifies a challenge_response (Phase 1) or a bound_proof (Phase 2). The caller is identified by its certificate; the challenge response signs nonce|agent_id|timestamp, the bound proof signs timestamp|caller_id|callee_id. For a bound proof the Operator also enforces a caller/callee environment match.
{
"proof_type": "bound_proof",
"certificate": "eyJhbGciOiJFUzI1NiIsImtpZCI6...",
"callee_did": "did:aeap:c8f12d34-...",
"proof": "MEUCIQ...",
"timestamp": "2026-05-23T18:19:50Z"
}{
"verified": true,
"agent_id": "did:aeap:c8f12d34-5678-90ab-cdef-1234567890ab",
"cert_tier": "business",
"agent_type": "BUSINESS"
}Checks (per protocol): certificate signature vs CA, exp in future, EC signature vs aeap.public_key, timestamp within ≤ 30 s, single-use nonce, callee DID present in the bound message, environment match, and status == ACTIVE. Failure returns 401 with a reason from the rejection set.
/.well-known/aeap-ca-jwksPublishes the Operator CA signing keys as a JWKS document at a fixed well-known path. Because the path is identical across implementations, a counterparty can verify an AEA/P certificate it has never previously contacted. Agents cache on startup and refetch only on an unknown kid.
{
"keys": [{
"kty": "EC", "crv": "P-256", "kid": "aeap-ca-2026-01",
"use": "sig", "alg": "ES256",
"x": "f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU",
"y": "x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0"
}]
}Interaction & settlement
The runtime surface agents call to price, settle, confirm, and refund a transaction, and the on-chain contract that moves the funds.
/v1/payment-addressCalled by the seller before answering 402. Query: market, network (both required); and, when creating an intent, buyer_did, amount (the seller’s quoted price, whole currency units — required with buyer_did), and seller_did (the counterparty, for the minimum-counterparty floors). Returns the settlement target for the market/network; when buyer_did is supplied the Operator always enforces the buyer’s spend scope from its AID (amount vs cap, rolling window, counterparty floors and allowlist), whatever rules the Platform also applies, and, on pass, opens a payment intent adding intent_id + expires_at — otherwise refusing with 403 spend_policy_violation (no intent). Never exposes the seller's operational or escrow wallet.
{
"market": "US-USDC",
"network": "base-sepolia",
"chain_id": 84532,
"contract": "0xc25c0943805FADA7704cc4Cc4CfEAdEA2c4DAF0f",
"token": "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
"currency": "USDC",
"decimals": 6,
"intent_id": "pi_7c1a9f2e3b4d",
"expires_at": "2026-05-23T18:30:00Z"
}/v1/facilitateCalled by the seller after the buyer's on-chain pay(). The Operator reads the Settled event for tx_hash, verifies the split and the seller/buyer id hashes, credits the escrow leg, advances escrow_state, and opens a PoP task. Read-only on-chain — the Operator submits no transaction.
{
"seller_did": "did:aeap:4ad3c2d3-a658-4793-8c5a-75eae395a053",
"buyer_did": "did:aeap:3042b724-821e-4595-a6c7-c804826f292b",
"tx_hash": "0x4ed82d71a3994883bd57293bbda86b7dc365f449ab152f5b6e2cb2cc7cd37733",
"network": "base-sepolia"
}{
"facilitation_id": "fac_9b3e7c0d5f1a",
"tx_hash": "0x4ed82d71...cd37733",
"gross_amt": "10.000000",
"op_credited": "8.000000",
"escrow_credited": "1.000000",
"fee_charged": "1.000000",
"escrow_state": "ACTIVE",
"task_id": "task_5f1a4d83a8c2"
}Same-principal settlements return task_id: null (no PoP credit). 402 settlement_verification_failed carries reason ∈ { no_settled_event, seller_did_mismatch, buyer_did_mismatch }; 404 unknown agent; 409 already facilitated (idempotent).
/v1/agents/{did}/tasksLists the agent's Proof-of-Performance tasks. Query: status, side (SELLER / BUYER), limit (default 20). GET /v1/tasks/{task_id} resolves one task with its signal breakdown (owner-only).
/v1/tasks/{task_id}/confirmThe buyer confirms or rejects delivery within the 72 h window; triggers signal computation and agent-rating recalculation. The principal must own the confirming (buyer) agent.
{
"outcome": "partial", // confirmed | partial | rejected
"score": 0.8, // required when outcome = partial (0-1)
"note": "Delivered late but complete."
}{
"task_id": "task_5f1a4d83a8c2",
"outcome": "partial",
"task_completion": 0.8,
"status": "CONFIRMED",
"agent_rating": 0.96
}Outcome mapping: confirmed → 1.0, partial → score, rejected → 0.0 (may open a dispute). No call within 72 h auto-confirms at 1.0.
/v1/refundsReports a refund the seller has paid back to the original buyer of a settled transaction (Protocol Specification §7.6). The seller pays from its operational wallet — never from escrow — and then reports the transfer. The Operator reads the transfer on-chain (read-only) and checks that it runs from the seller's operational wallet to the original buyer, in the original currency, with cumulative refunds plus any dispute payouts from escrow within the original value. It then records the refund: refunded_value on both parties' entries for the interaction, a lower net value for the AR blend and the escrow threshold, and no change to dispute_free. A refund is allowed while the seller is SUSPENDED and involves no purchase authorization or spend scope. It is not allowed while a dispute on the sale is open: the seller settles within the dispute, during pre-arbitration, paid from escrow (Protocol Specification §7.6, §8.3).
{
"intent_id": "pi_7c1a9f2e3b4d",
"seller_did": "did:aeap:4ad3c2d3-a658-4793-8c5a-75eae395a053",
"amount": { "amount": 2.5, "currency": "USDC" },
"tx_hash": "0x9a1c3f0e...e04f",
"network": "base-sepolia",
"reason": "Partial delivery — 25% of records stale"
}{
"refund_id": "rf_3d8e1b0c7a2f",
"intent_id": "pi_7c1a9f2e3b4d",
"interaction_id": "task_5f1a4d83a8c2",
"seller_id": "did:aeap:4ad3c2d3-...",
"buyer_id": "did:aeap:3042b724-...",
"amount": { "amount": 2.5, "currency": "USDC" },
"settlement_ref": "0x9a1c3f0e...e04f",
"issued_at": "2026-10-10T18:02:11Z",
"refunded_value": "2.500000"
}Rejections: 403 not_original_seller; 409 refund_exceeds_original (cumulative refunds plus dispute payouts above transaction_value); 409 dispute_open (a dispute on the sale is open — settle it through the dispute); 402 settlement_verification_failed when the transfer cannot be read or does not match. Sending the same tx_hash again returns the existing record (200). A later dispute may claim only the value not yet refunded.
AEAPSettlement (per network)A shared per-network contract the Operator deploys and operates. The Operator signs only the seller configuration write (Phase 0a) and the buyer calls pay(...) directly (Phase 3); the contract emits Settled, which the Operator reads (never writes) during facilitation. Settlement is peer-to-contract — funds never transit an Operator-held wallet.
registerSeller(
sellerIdHash, // keccak256 of did:aeap agent id
opWallet, // seller operational wallet
escrowWallet, // KMS-held, created at market-config
escrowBps, // from funding tier
feeBps // from credential tier
)
event SellerRegistered(sellerIdHash, escrowWallet, settlementContract)pay(token, amount, sellerIdHash, buyerIdHash)
// atomic split: opAmt -> opWallet, escrowAmt -> escrowWallet, feeAmt -> feeWallet
event Settled(txHash, sellerIdHash, buyerIdHash, opAmt, escrowAmt, feeAmt)The Platform surface is illustrative — a Platform chooses its own paths, fields, and transport (REST, MCP, A2A) so long as it consumes the Operator wire contract correctly. The shapes below describe the reference first-party Platform.
Discovery
Match a buyer to eligible sellers, then route requests and apply the Platform's own policies at egress.
/v1/discoverMatches a buyer's task + method / currency to eligible sellers and returns each match with its credential reference and runtime endpoint. References, not secrets — the buyer verifies the credential itself (Phase 1). Query: task, method, currency.
{
"matches": [{
"agent_id": "did:aeap:c8f12d34-5678-90ab-cdef-1234567890ab",
"display_name": "Acme Vendor Agent",
"cert_tier": "business",
"agent_rating": 0.97,
"authorized_markets": ["US-USDC"],
"certificate_ref": "https://operator.example/v1/agents/did:aeap:c8f12d34-.../aid",
"endpoint": "https://agents.acme.example/vendor"
}]
}/resourceThe buyer requests the resource directly from the seller, declaring its method / currency. The Platform routes to the seller, receives the seller's 402 (carrying the Operator-issued payment intent), applies the Platform's own policies at egress, and relays the 402 — or blocks it. These rules are the Platform's own, on top of the agent's spend scope that the Operator already enforced when it created the intent; a Platform declares them as policy_ids in its policy.posture attestation.
{
"seller_did": "did:aeap:c8f12d34-5678-90ab-cdef-1234567890ab",
"market": "US-USDC",
"network": "base-sepolia",
"chain_id": 84532,
"settlement_contract": "0xc25c0943805FADA7704cc4Cc4CfEAdEA2c4DAF0f",
"token": "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
"currency": "USDC",
"decimals": 6,
"amount": "1.00",
"intent_id": "intent_9b3e7c0d...",
"expires_at": "2026-05-23T18:30:00Z"
}{
"error": "platform_policy_violation",
"policy_id": "com.acme.spend.category-block",
"reason": "category_not_permitted"
}Management
Principal-facing configuration and the read views the Platform composes over Operator data.
/v1/agents/{did}/overview · /eventsPrincipal-facing read views the Platform composes from Operator data after settlement: GET /v1/agents/{did}/overview (per-agent outcomes and standing) and GET /v1/agents/{did}/events (interaction history). These are Platform conveniences over the authoritative status, aid, and facilitations resources.
Agent lifecycle
An agent moves DRAFT → ACTIVE explicitly via activation; the remaining states are driven by escrow and governance and surfaced on the status endpoint.
DRAFTACTIVESUSPENDEDREVOKEDTERMINATEDEscrow runs its own track: FUNDING → ACTIVE (at threshold) → DISPUTE_HOLD / CONSTRAINED / RELEASED.
Rejection codes
Verification and authorization failures carry one fixed reason:
| Code | Meaning |
|---|---|
invalid_certificate · certificate_expired | Certificate fails CA verification or is past exp. |
invalid_proof · timestamp_expired · nonce_replayed | Signature, freshness, or replay check failed. |
did_mismatch · environment_mismatch | Bound-proof DID or environment does not match. |
agent_suspended · agent_terminated | Counterparty is not in an active state. |
market_not_authorized · escrow_constrained · spend_policy_violation | Market outside the buyer's derived market, escrow coverage exhausted, or the Operator refused the intent under the buyer's spend scope (amount, window, counterparty floor). |
cert_tier_insufficient · rating_below_threshold · action_not_authorized | Counterparty floor or scope gate not met. |
counterparty_not_allowed | The seller is not on the buyer's private counterparty allowlist. |
provisional_cap_exceeded · certificate_required · untrusted_issuer · authorization_required · authorization_invalid | Provisional limit hit, missing certificate, issuer not in the Trust Registry, or a required commitment authorization is missing or invalid. |
Live explorers
Each certified Operator exposes its running API; because the explorer is the deployed system, it never drifts from what is documented here.
As more Operators are certified, each appears here with a link to its own live API explorer.