{"title":"Agent-native web entrance — wire contract","version":"1.0.0","status":"normative","human_docs":"/#agent-web","description":"Engineering contract for websites and APIs that accept accountable agents. This is the end-state entrance pattern: identity (AGIN) + account credentials + authorization + receipts. It is not a CAPTCHA bypass guide.","principles":["Agents are first-class clients alongside humans","Verify which agent is calling (AGIN), not only whether traffic looks human","Separate agent identity from customer product credentials","Return structured outcomes and stable error codes","High-risk mutations may require human approval without denying low-risk agent access"],"identity_headers":{"description":"Public presentation of AGIN on HTTP. Values are examples of field names only — not secret material.","headers":[{"name":"x-agentnet-agin-id","required":true,"example":"agin_01HEXAMPLE","meaning":"Public agent identity card id"},{"name":"x-agentnet-agent-principal","required":true,"example":"agent:ops-core","meaning":"Agent principal name for logs and policy"},{"name":"x-agentnet-call-id","required":true,"example":"call_01HEXAMPLE","meaning":"Idempotent call id for this request"},{"name":"x-agentnet-org-id","required":false,"example":"org_01HEXAMPLE","meaning":"Optional owning org context when applicable"}],"mcp_meta":{"path":"params._meta.agentnet","example":{"agin_id":"agin_01HEXAMPLE","agent_principal":"agent:ops-core","call_id":"call_01HEXAMPLE","org_id":"org_01HEXAMPLE"}}},"account_credentials":{"description":"Customer/product account is separate from AGIN. Use whatever the product already uses for humans.","patterns":["Authorization: Bearer <user_or_service_token>","API key header defined by the product","OAuth2 access token for the customer tenant"],"rule":"AGIN answers which agent; account credentials answer which customer."},"error_codes":[{"code":"agent_web.ok","http":200,"meaning":"Success"},{"code":"agent_web.agin_required","http":401,"meaning":"Agent identity missing on an agent entrance route"},{"code":"agent_web.agin_invalid","http":401,"meaning":"Agent identity present but not acceptable"},{"code":"agent_web.account_required","http":401,"meaning":"Customer/product credentials required"},{"code":"agent_web.scope_denied","http":403,"meaning":"Agent or account not allowed for this action"},{"code":"agent_web.approval_required","http":403,"meaning":"Action requires human approval before continue"},{"code":"agent_web.rate_limited","http":429,"meaning":"Rate limit for this AGIN or account"},{"code":"agent_web.invalid_argument","http":400,"meaning":"Request body/query fails schema"},{"code":"agent_web.not_found","http":404,"meaning":"Resource missing"},{"code":"agent_web.conflict","http":409,"meaning":"Idempotency or state conflict"},{"code":"agent_web.anonymous_blocked","http":403,"meaning":"Anonymous automation blocked; use AGIN entrance"}],"error_envelope":{"type":"object","required":["ok","code","message","request_id"],"properties":{"ok":{"type":"boolean"},"code":{"type":"string"},"message":{"type":"string"},"request_id":{"type":"string"},"retryable":{"type":"boolean"},"approval":{"type":"object","properties":{"required":{"type":"boolean"},"reason":{"type":"string"}}}},"example":{"ok":false,"code":"agent_web.agin_required","message":"Present x-agentnet-agin-id on agent entrance routes","request_id":"req_01HEXAMPLE","retryable":false}},"success_envelope":{"example":{"ok":true,"code":"agent_web.ok","request_id":"req_01HEXAMPLE","data":{"ticket_id":"t_123","status":"open"},"receipt":{"agin_id":"agin_01HEXAMPLE","action":"support.create_ticket","outcome":"created","at":"2026-07-11T00:00:00Z"}}},"provider_policy_ladder":[{"tier":"anonymous","policy":"default_deny_or_strict_challenge","example":"No AGIN, no account → 403 agent_web.anonymous_blocked or legacy challenge"},{"tier":"agin_bearing","policy":"allow_by_scope_rate_limit_audit","example":"AGIN present → evaluate scopes; log receipt"},{"tier":"agin_plus_account","policy":"customer_context_enabled","example":"AGIN + Bearer customer token → full product actions under policy"},{"tier":"sensitive_mutation","policy":"stronger_auth_optional_human_approval","example":"Refund/wire → approval_required until human approves"}],"site_capability_design":{"dual_surface":{"human":"HTML/UI flows","agent":"Versioned JSON capabilities (REST and/or MCP tools) with schemas"},"example_capabilities":[{"id":"catalog.search","method":"POST","path":"/agent/v1/catalog/search","input":{"query":"string","limit":"integer"},"output":{"items":"array"}},{"id":"support.create_ticket","method":"POST","path":"/agent/v1/support/tickets","input":{"subject":"string","body":"string"},"output":{"ticket_id":"string","status":"string"},"sensitivity":"operator"},{"id":"billing.refund","method":"POST","path":"/agent/v1/billing/refunds","input":{"invoice_id":"string","amount":"number"},"sensitivity":"approval"}],"example_curl":"curl -sS -X POST https://api.example.com/agent/v1/support/tickets \\\n  -H 'content-type: application/json' \\\n  -H 'authorization: Bearer <customer_token>' \\\n  -H 'x-agentnet-agin-id: agin_01HEXAMPLE' \\\n  -H 'x-agentnet-agent-principal: agent:support' \\\n  -H 'x-agentnet-call-id: call_01HEXAMPLE' \\\n  -d '{\"subject\":\"Cannot login\",\"body\":\"User reports 401 on SSO\"}'"},"conformance_checklist":["Document dual surfaces (human UI + agent capabilities)","Accept AGIN headers or MCP _meta.agentnet on agent routes","Separate customer credentials from AGIN","Emit stable agent_web.* error codes","Emit receipts for mutating actions","Rate-limit by AGIN and by account","Map high-risk actions to approval_required","Do not require human CAPTCHA on AGIN entrance for ordinary in-scope reads when policy allows","Publish OpenAPI or MCP tool list for agent surface"],"non_goals":["Instructions to bypass third-party bot walls","Replacing product auth with AGIN alone","Mandating AgentNet as the only identity issuer for the entire web"]}