{
  "openapi": "3.1.0",
  "info": {"title": "Topaz5 correlated agent signup (isolated preview)", "version": "0.1.0", "description": "Executed local HTTP/PostgreSQL/native fixture contract, not production delivery or native-token delegation. Commerce payloads are unwrapped JSON. Human password and email challenge stay off the agent polling interface."},
  "paths": {
    "/api/commerce/v1/agent-intents": {
      "post": {
        "operationId": "beginOrRecoverAgentSignup",
        "description": "Save client proof privately before first dispatch. First-writer proof binds this stable request. Same proof/key/canonical intake recovers original grant, human invitation/origin and fixed expiry after response loss. An ID alone never authenticates recovery. No native identity override accepted.",
        "security": [{"clientProof": []}],
        "parameters": [{"name": "Idempotency-Key", "in": "header", "required": true, "schema": {"type": "string", "pattern": "^[A-Za-z0-9_-]{16,128}$"}}],
        "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Intake"}}}},
        "responses": {
          "202": {"description": "Original polling grant and private fragment invitation", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Grant"}}}},
          "400": {"description": "Invalid exact intake/request identity"},
          "403": {"description": "Missing/wrong client proof, revoked or expired intent"},
          "409": {"description": "Same authenticated request with changed intake"},
          "429": {"description": "Local peer rate bound"},
          "503": {"description": "Mail/handoff transport unavailable; authenticated same-intent recovery only"}
        }
      }
    },
    "/api/commerce/v1/agent-intents/{intent_id}": {
      "parameters": [{"name": "intent_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}, "description": "Canonical lowercase UUID only"}],
      "get": {
        "operationId": "pollAgentSignup",
        "security": [{"pollCapability": []}],
        "description": "This intent only, before or after human verification. No email challenge, password, enrollment capability or native token. GET updates local rate buckets. Fixed 24-hour intent expiry; no renewal. Completed binding remains billing_pending and native-auth pending.",
        "responses": {
          "200": {"description": "Safe progress/native binding hints; not paid readiness", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Status"}}}},
          "403": {"description": "Unknown/foreign/missing/expired/revoked grant, generic refusal"},
          "429": {"description": "Local peer rate bound"}
        }
      }
    },
    "/browser/bind": {
      "post": {
        "operationId": "bindHumanBrowser",
        "description": "Human browser only. Exact configured Origin/Host, safe fetch metadata, HttpOnly SameSite cookie plus CSRF. Fragment invitation is erased before POST. First browser consumes invitation; same-browser recovery only. Does not verify email. Human then uses existing browser verify/enroll forms.",
        "security": [{"browserCookie": [], "csrfHeader": []}],
        "parameters": [{"name": "Origin", "in": "header", "required": true, "schema": {"type": "string"}, "description": "Exact server-configured human origin, not arbitrary request scope"}],
        "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "additionalProperties": false, "required": ["invitation"], "properties": {"invitation": {"type": "string", "pattern": "^[A-Za-z0-9_-]{43}$", "writeOnly": true}}}}}},
        "responses": {"200": {"description": "Cookie bound, human_verification still required"}, "403": {"description": "Foreign origin/Host/cookie, CSRF, wrong/consumed/expired/revoked/cross-flow invitation"}, "429": {"description": "Local rate bound"}}
      }
    }
  },
  "components": {
    "securitySchemes": {
      "clientProof": {"type": "http", "scheme": "bearer", "description": "CLI-generated 256-bit client secret, 43 URL-safe characters; not polling capability"},
      "pollCapability": {"type": "http", "scheme": "bearer", "description": "Distinct original status-only capability; not client proof, human invitation or native auth"},
      "browserCookie": {"type": "apiKey", "in": "cookie", "name": "topaz_enrollment"},
      "csrfHeader": {"type": "apiKey", "in": "header", "name": "X-CSRF-Token"}
    },
    "schemas": {
      "Intake": {"type": "object", "additionalProperties": false, "required": ["company", "email", "country"], "properties": {"company": {"type": "string", "minLength": 2, "maxLength": 120}, "email": {"type": "string", "format": "email", "maxLength": 254}, "country": {"type": "string", "pattern": "^[A-Z]{2}$", "description": "Business field only, not service coverage"}}},
      "Grant": {"type": "object", "additionalProperties": false, "required": ["intent_id", "poll_capability", "human_url", "scope", "expires_at"], "properties": {"intent_id": {"type": "string", "format": "uuid"}, "poll_capability": {"type": "string", "pattern": "^[A-Za-z0-9_-]{43}$", "description": "Access secret; private 0600 workflow only"}, "human_url": {"type": "string", "format": "uri", "description": "Server-owned origin /#invite=secret. Private human access link; never analytics, logs or tracked evidence"}, "scope": {"const": "signup_status_only_not_native_auth"}, "expires_at": {"type": "string", "format": "date-time", "description": "Fixed original expiry, no authenticated-retry extension"}}},
      "Status": {"type": "object", "required": ["intent_id", "state", "scope", "native_auth", "billing", "pstn_activation"], "properties": {"intent_id": {"type": "string", "format": "uuid"}, "state": {"enum": ["human_verification_pending", "verified", "tenant_bound", "admin_bound", "billing_pending", "needs_review"]}, "scope": {"const": "signup_status_only_not_native_auth"}, "native_auth": {"enum": ["human_native_login_required", "pending_explicit_native_login"]}, "billing": {"const": "pending"}, "pstn_activation": {"const": false}, "native_account_id": {"type": "string", "pattern": "^[0-9a-f]{32}$"}, "native_user_id": {"type": "string", "pattern": "^[0-9a-f]{32}$"}, "native_login_required": {"const": true}}}
    }
  }
}
