A protocol to onboard and authenticate agents as net-new customers
From an unauthenticated call to authenticated access
A 401 challenge points to the Inspect document. The agent uses a signed, single-use proof to authenticate directly and can request a reusable session credential when the Service offers one.
An unauthenticated call returns a 401 challengeAn agent calls a protected endpoint with no credentials. The service returns 401, and the challenge carries two fields: the Service DID and the address of its Inspect document.

$ curl -v https://api.example.com/v1/orders GET /v1/orders HTTP/1.1 Host: api.example.com < HTTP/1.1 401 Unauthorized WWW-Authenticate: AEP service_did="did:web:api.example.com" inspect="https://api.example.com/.well-known/aep"
The Inspect document lists the requirements before any signatureThe Agent requests the Inspect document at /.well-known/aep without credentials. It specifies the accepted signing algorithms, identity methods, session credential types, and protected-resource authentication methods. Its Service DID must match the one from the challenge.

$ curl -v https://api.example.com/.well-known/aep GET /.well-known/aep HTTP/1.1 Host: api.example.com Accept: application/aep+json HTTP/1.1 200 OK Content-Type: application/aep+json { "aep_version": "1.0", "authentication": { "methods": ["aep-jwt", "oauth-bearer"] }, "bindings": { "supported": ["http"] }, "claims": { "required": ["contact.email"] }, "commands": { "grant_types": ["oauth-bearer"], "grant_types_config": { "oauth-bearer": { "supports_per_credential_revoke": "true" } }, "supported": ["enroll", "grant", "inspect", "revoke", "status"] }, "core": { "signing_algorithms": ["EdDSA", "ES256"] }, "http": { "endpoint_base": "/aep/" }, "identity": { "methods": ["did:web"] }, "service": { "did": "did:web:api.example.com" } }
A signed proof establishes the Agent's identityThe Agent signs a statement with its private key. The Service verifies it against the public key at a web address the Agent controls without transmitting a shared secret. Enrollment then returns the Agent's current lifecycle status.

$ curl -v -X POST https://api.example.com/aep/enroll \ -H 'Authorization: AEP eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9...' \ -H 'Content-Type: application/aep+json' \ -H 'Idempotency-Key: 9f8a4d2e-1c3b-4f5e-8b7a-000000000000' \ -d @enroll.json > POST /aep/enroll HTTP/1.1 Host: api.example.com Content-Type: application/aep+json Idempotency-Key: 9f8a4d2e-1c3b-4f5e-8b7a-000000000000 Authorization: AEP eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9... { "agent_did": "did:web:agent.example.com:agents:123", "claims": { "contact.email": "ops@example.com" } } HTTP/1.1 200 OK Content-Type: application/aep+json { "status": "active" }
Grant can issue a reusable session credentialWhen the Inspect document advertises Grant, the Agent can use another signed proof to request an API key, OAuth token, or HTTP Basic credential. The Agent can then use that credential on protected resources that advertise the corresponding authentication method.

$ curl -v -X POST https://api.example.com/aep/grant \ -H 'Authorization: AEP eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9...' \ -H 'Content-Type: application/aep+json' \ -H 'Idempotency-Key: 5cb95539-251d-46b4-9a36-8de6efd6b771' \ -d @grant.json > POST /aep/grant HTTP/1.1 Host: api.example.com Content-Type: application/aep+json Idempotency-Key: 5cb95539-251d-46b4-9a36-8de6efd6b771 Authorization: AEP eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9... { "grant_type": "oauth-bearer" } HTTP/1.1 200 OK Content-Type: application/aep+json { "access_token": "ya29.example", "credential_id": "tok_01HZY8W7Q2F8J7D3P9G9Z1N6TT", "expires_at": "2026-09-15T22:00:00Z", "token_type": "Bearer" } $ curl -v https://api.example.com/v1/orders GET /v1/orders HTTP/1.1 Host: api.example.com Authorization: Bearer ya29.example HTTP/1.1 200 OK
Enrollment stays checkable, access stays revocableStatus reads the agent's current enrollment state, active or pending, and lists any requirement still outstanding. Revoke invalidates a session credential and requires the same signed proof as Enroll and Grant, never the credential it's cutting off. The enrollment underneath stays intact.

$ curl -v https://api.example.com/aep/status > GET /aep/status HTTP/1.1 Host: api.example.com Authorization: AEP eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9... HTTP/1.1 200 OK { "requirements_pending": ["contact.email"], "status": "pending" }
$ curl -v -X POST https://api.example.com/aep/revoke \ -H 'Authorization: AEP eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9...' \ -H 'Content-Type: application/aep+json' \ -H 'Idempotency-Key: e29c88b1-8f56-421f-89b0-c2882353a36f' \ -d @revoke.json > POST /aep/revoke HTTP/1.1 Host: api.example.com Content-Type: application/aep+json Idempotency-Key: e29c88b1-8f56-421f-89b0-c2882353a36f Authorization: AEP eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9... { "credential_id": "tok_01HZY8W7Q2F8J7D3P9G9Z1N6TT", "grant_type": "oauth-bearer" } HTTP/1.1 200 OK Content-Type: application/aep+json {}
One enrollment turns every visit into recognizable revenue
Signed identity means fewer chargebacks and disputes
Enrollment ties one identity to a private-key signature. That identity backs a chargeback dispute to avoid fraud and deter bad actors.
Seller Policies use enrollment details to enforce access and transaction rules
A seller reads an agent's declared location and its enrollment status to decide: blocked outright, waits for review, or transacts without restriction.
Satisfy Travel Rule's requirements and stay in compliance
Travel Rule needs a verified name, address, and date of birth before a transfer clears. AEP's claim catalog collects that exact shape at enrollment.
Recognized once, remembered on every call after
Every call from a recognized agent adds to one per-agent usage record. A seller reads that record for upsell timing, term changes, or retention signals.

$ curl -v https://api.example.com/odp/offerings/neural-search-api > GET /odp/offerings/neural-search-api HTTP/1.1 Host: api.example.com HTTP/1.1 200 OK Content-Type: application/odp+json { "odp_version": "1.0", "id": "neural-search-api", "name": "Neural Search API", "price": { "amount": "0.003", "currency": "USDC", "type": "fixed" } }
Find what a Service sells, before AEP runsODP is the most agent-compatible, deterministic way for agents to find services. A protected service is routed to AEP for enrollment.

GET /v1/orders HTTP/1.1 Host: api.example.com AEP-Authorization: AEP eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9... HTTP/1.1 402 Payment Required WWW-Authenticate: Payment id="challenge-1", realm="api.example.com", method="inflow" $ inflow mpp pay https://api.example.com/v1/orders GET /v1/orders HTTP/1.1 Host: api.example.com AEP-Authorization: AEP eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9... Authorization: Payment eyJhbW91bnQiOiIwLjAwMyJ9... HTTP/1.1 200 OK Payment-Receipt: eyJzZXR0bGVkIjp0cnVlfQ...
