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, spend policy) 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 |
| Group | Called by | Purpose |
|---|---|---|
| Onboarding | Builder | Email + KYC/KYB verification on the Platform, ahead of Operator registration |
| Discovery | Consumer agent | Match tasks to providers; route and enforce spend policy 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 providers) market-config agents, and resolve the AID and live status.
/v1/agentsValidates the Platform's Verification Attestation (KYC/KYB for a provider, address verification for a consumer) and the two role 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.
economic_rolePROVIDER or CONSUMER. Immutable once set.display_nameauthorized_actionspurchase, sell, delegate. CONSUMER must include purchase and exclude sell; PROVIDER the inverse. Append-only thereafter.cert_tiercapabilities / authorized_marketsmax_transaction_value / minimum_counterparty_*identity.scope.{
"economic_role": "PROVIDER",
"profile": { "display_name": "Acme Vendor Agent", "description": "Invoicing and delivery agent", "objective": "..." },
"authorized_actions": ["sell", "delegate"],
"cert_tier": "provider",
"capabilities": ["cap.invoice", "cap.deliver"],
"authorized_markets": ["US-USDC"],
"max_transaction_value": 5000,
"minimum_counterparty_cert_tier": "consumer",
"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",
"economic_role": "PROVIDER",
"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": "..." },
"endpoint_url": "https://agents.acme.example/vendor",
"certificate": { "cert_tier": "provider", "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": null, "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 role: a CONSUMER omits the escrow / disputes / governance pillars (null); a PROVIDER carries escrow.liability_profile with funding-tier defaults. Rejections (400): cert_tier_role_mismatch, authorized_action_role_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": "provider",
"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 registerProvider(...) on the per-network Settlement Contract. The escrow wallet is created by the Operator — do not pass it. Rejected for CONSUMER agents, which make outgoing payments only.
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. Provider 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": "provider",
"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; null for sandbox agents or below the 10-interaction threshold. escrow_state is null for CONSUMER agents. 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": "provider",
"economic_role": "PROVIDER"
}/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": "provider",
"economic_role": "PROVIDER"
}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, and confirm a transaction, and the on-chain contract that moves the funds.
/v1/payment-addressCalled by the provider before answering 402. Query: market, network (both required); and, when creating an intent, consumer_did, amount (the provider’s quoted price, whole currency units — required with consumer_did), and provider_did (the counterparty, for the minimum-counterparty floors). Returns the settlement target for the market/network; when consumer_did is supplied the Operator enforces the consumer’s spend policy (amount vs cap, rolling window, counterparty floors) and, on pass, opens a payment intent adding intent_id + expires_at — otherwise refusing with 403 spend_policy_violation (no intent). Never exposes the provider'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 provider after the consumer's on-chain pay(). The Operator reads the Settled event for tx_hash, verifies the split and the provider/consumer id hashes, credits the escrow leg, advances escrow_state, and opens a PoP task. Read-only on-chain — the Operator submits no transaction.
{
"provider_did": "did:aeap:4ad3c2d3-a658-4793-8c5a-75eae395a053",
"consumer_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, provider_did_mismatch, consumer_did_mismatch }; 404 unknown agent; 409 already facilitated (idempotent).
/v1/agents/{did}/tasksLists the agent's Proof-of-Performance tasks. Query: status, role (provider / consumer), limit (default 20). GET /v1/tasks/{task_id} resolves one task with its signal breakdown (owner-only).
/v1/tasks/{task_id}/confirmThe consumer confirms or rejects delivery within the 72 h window; triggers signal computation and agent-rating recalculation. The principal must own the confirming (consumer) 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.
AEAPSettlement (per network)A shared per-network contract the Operator deploys and operates. The Operator signs only the provider configuration write (Phase 0a) and the consumer 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.
registerProvider(
providerIdHash, // keccak256 of did:aeap agent id
opWallet, // provider operational wallet
escrowWallet, // KMS-held, created at market-config
escrowBps, // from funding tier
feeBps // from credential tier
)
event ProviderRegistered(providerIdHash, escrowWallet, settlementContract)pay(token, amount, providerIdHash, consumerIdHash)
// atomic split: opAmt -> opWallet, escrowAmt -> escrowWallet, feeAmt -> feeWallet
event Settled(txHash, providerIdHash, consumerIdHash, 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 consumer to eligible providers, then route and enforce spend policy at egress.
/v1/discoverMatches a consumer's task + method / currency to eligible providers and returns each match with its credential reference and runtime endpoint. References, not secrets — the consumer 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": "provider",
"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 consumer requests the resource directly from the provider, declaring its method / currency. The Platform routes to the provider, receives the provider's 402 (carrying the Operator-issued payment intent), enforces the consumer's spend policy at egress, and relays the 402 — or blocks it.
{
"provider_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": "spend_policy_violation",
"reason": "amount_exceeds_max_transaction_value",
"limit": 5000, "requested": 7200
}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 consumer's derived market, escrow coverage exhausted, or the consumer's spend policy refused the intent (amount, window, or counterparty floor). |
cert_tier_insufficient · rating_below_threshold · action_not_authorized | Counterparty floor or scope gate not met. |
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.