{
  "openapi": "3.1.0",
  "info": {
    "title": "Nova Agent Onboarding API",
    "version": "1.0.0",
    "description": "Account-owner-mediated onboarding for one Self-Managed WordPress site. Polling clients must wait for retry_after_seconds (always at least 5) and back off; receipts expire after 72 hours. Machine-readable product and pricing facts are published at https://nova.host/.well-known/catalog.json; the Self-Managed plan is $49/month for one site with Agent access included in early access."
  },
  "servers": [{ "url": "https://nova.host" }],
  "x-agent-flow": [
    { "step": 1, "method": "POST", "path": "/api/agent-onboarding/register", "action": "Register an account receipt." },
    { "step": 2, "method": "GET", "path": "/api/agent-onboarding/{onboarding_id}", "action": "Ask the owner to verify email and poll for claimed." },
    { "step": 3, "method": "POST", "path": "/api/auth/login", "action": "Sign in after verification." },
    { "step": "optional", "method": "POST", "path": "/api/agent-purchases", "action": "Purchase an eligible self-serve product with an owner-issued agent key and Shared Payment Token.", "optional": true, "preconditions": ["Account owner has issued an agent key with a monthly spending ceiling.", "Only self-serve products may be purchased this way.", "Managed plans with a setup fee require human confirmation and cannot be purchased through this endpoint."] },
    { "step": 4, "method": "POST", "path": "/api/agent-onboarding/checkout", "action": "Create and hand off the owner checkout URL." },
    { "step": 5, "method": "GET", "path": "/api/agent-onboarding/{onboarding_id}", "action": "Poll for webhook-confirmed payment." },
    { "step": 6, "method": "POST", "path": "/api/tenants", "action": "Provision the subscribed site, passing status.subscription.id as subscriptionId." },
    { "step": 7, "method": "POST", "path": "/api/agent-onboarding/{onboarding_id}/finalize", "action": "Finalize and receive MCP credentials once." }
  ],
  "paths": {
    "/api/agent-onboarding/register": {
      "post": {
        "summary": "Register an agent-led onboarding receipt",
        "description": "Uses the signup email policy and existing verification email. Idempotent for normalized email plus idempotency_key. Issues no session or token.",
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RegisterRequest" } } } },
        "responses": {
          "202": { "description": "Verification required", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RegisterAccepted" } } } },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "409": { "description": "Verified account already exists", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ExistingAccount" } } } },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/api/agent-onboarding/{onboarding_id}": {
      "get": {
        "summary": "Poll onboarding state",
        "description": "Before claim, a poll token reveals only awaiting_email or claimed. After login, a JWT reveals the full receipt. Receipts expire 72 hours after creation.",
        "security": [{ "pollToken": [] }, { "bearerJwt": [] }],
        "parameters": [{ "name": "onboarding_id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
        "responses": {
          "200": { "description": "Current state; poll-token responses omit subscription and tenant details", "content": { "application/json": { "schema": { "oneOf": [{ "$ref": "#/components/schemas/PollStatus" }, { "$ref": "#/components/schemas/OnboardingStatus" }] } } } },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "410": { "$ref": "#/components/responses/Expired" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "502": { "description": "A discovered tenant could not be persisted to the receipt; response retains the prior state and provides retry_after_seconds", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
        }
      }
    },
    "/api/auth/login": {
      "post": {
        "summary": "Sign in to a verified account",
        "description": "Existing login endpoint. Unverified email addresses are rejected and no JWT is issued.",
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LoginRequest" } } } },
        "responses": {
          "200": { "description": "Authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LoginResponse" } } } },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "description": "Email is unverified or account is inactive", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/api/agent-onboarding/checkout": {
      "post": {
        "summary": "Create owner-facing checkout",
        "description": "Only plan host is accepted. Checkout uses onboarding_id as the Stripe idempotency key. Payment state changes only after a Stripe-signed webhook records host/active.",
        "security": [{ "bearerJwt": [] }],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CheckoutRequest" } } } },
        "responses": {
          "200": { "description": "Checkout created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CheckoutResponse" } } } },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "410": { "$ref": "#/components/responses/Expired" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/api/tenants": {
      "post": {
        "summary": "Provision a WordPress tenant",
        "description": "Existing endpoint. Requires an active subscription and enforces the host plan's one-site limit.",
        "security": [{ "bearerJwt": [] }],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TenantRequest" } } } },
        "responses": {
          "201": { "description": "Tenant provisioning started", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TenantResponse" } } } },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "description": "Subscription does not permit provisioning", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
          "409": { "description": "Site limit or subdomain conflict", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
        }
      }
    },
    "/api/agent-onboarding/{onboarding_id}/finalize": {
      "post": {
        "summary": "Finalize MCP access",
        "description": "Requires a caller-owned active tenant and a host/active subscription. Acquires a five-minute issuance lease before creating credentials, then records issuance and clears the lease. Enables only content_read, content_write, publish, site_data_read, and operations; destructive remains disabled. The plaintext MCP key is returned only once and stored only as a hash.",
        "security": [{ "bearerJwt": [] }],
        "parameters": [{ "name": "onboarding_id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FinalizeRequest" } } } },
        "responses": {
          "200": { "description": "MCP credentials issued with non-destructive default grants content_read, content_write, publish, site_data_read, and operations enabled; destructive is disabled.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FinalizeResponse" } } } },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "description": "Tenant ownership or subscription precondition failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
          "409": { "description": "MCP credentials were already issued", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AlreadyFinalized" } } } },
          "410": { "$ref": "#/components/responses/Expired" },
          "423": { "description": "Another credential issuance attempt holds the lease; retry after five seconds", "headers": { "Retry-After": { "schema": { "type": "integer", "const": 5 } } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/IssuanceLocked" } } } },
          "502": { "description": "Upstream or receipt persistence failed. If key creation may have completed, Retry-After identifies when the issuance lease expires.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
        }
      }
    },
    "/api/agent-purchases": {
      "post": {
        "summary": "Purchase an eligible self-serve product",
        "description": "Agent-initiated purchases are in early access. Uses an owner-issued agent key, its monthly spending ceiling, and a bounded Shared Payment Token. When agent purchasing is not enabled for an account, the endpoint returns 403 agent_purchases_disabled and the agent should hand the owner the checkout link instead. Managed plans with a setup fee require human confirmation and cannot be purchased through this endpoint.",
        "security": [{ "bearerJwt": [], "agentKey": [] }],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AgentPurchaseRequest" } } } },
        "responses": {
          "200": { "description": "Idempotent replay of a previous purchase state", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AgentPurchaseResponse" } } } },
          "201": { "description": "Purchase processed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AgentPurchaseResponse" } } } },
          "400": { "description": "Agent purchase request was invalid", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AgentPurchaseBadRequestError" } } } },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "402": { "description": "Payment requires action or failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AgentPurchasePaymentError" } } } },
          "403": { "description": "Agent purchasing is disabled (agent_purchases_disabled), or the spending ceiling, key, ownership, or product policy rejected the purchase", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AgentPurchaseForbiddenError" } } } },
          "409": { "description": "An active subscription or idempotency conflict prevents the purchase", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AgentPurchaseConflictError" } } } },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "502": { "description": "Key introspection or fulfilment service failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AgentPurchaseFulfilmentError" } } } }
        }
      },
      "get": {
        "summary": "List agent-initiated purchases for the account owner",
        "security": [{ "bearerJwt": [], "agentKey": [] }],
        "responses": {
          "200": { "description": "Agent purchase history", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AgentPurchaseListResponse" } } } },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "502": { "description": "Billing service unavailable", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
        }
      }
    },
    "/api/agent-purchases/{id}/convert": {
      "post": {
        "summary": "Convert a fulfilled agent purchase to another eligible product",
        "description": "Early-access wrong-product conversion. The caller's bearer token is verified through auth-service /profile and X-Nova-Agent-Key is forwarded to billing. The source must be fulfilled with a PaymentIntent, within the conversion window, and worth at least the target product. Managed-plan purchases require human confirmation.",
        "security": [{ "bearerJwt": [], "agentKey": [] }],
        "parameters": [{ "name": "id", "in": "path", "required": true, "description": "Agent purchase id", "schema": { "type": "string", "minLength": 8, "maxLength": 64, "pattern": "^[A-Za-z0-9-]+$" } }],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "additionalProperties": false, "required": ["to_product_id"], "properties": { "to_product_id": { "type": "string", "enum": ["host", "seo_content"] } } } } } },
        "responses": {
          "200": { "description": "Converted purchase", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AgentPurchaseResponse" } } } },
          "400": { "description": "Invalid purchase id, body, target, or missing agent key (invalid_request)", "content": { "application/json": { "schema": { "type": "object", "required": ["error"], "properties": { "error": { "const": "invalid_request" }, "message": { "type": "string" } } } } } },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "description": "Agent purchasing is disabled or conversion policy rejected the request", "content": { "application/json": { "schema": { "type": "object", "required": ["error"], "properties": { "error": { "type": "string", "enum": ["agent_purchases_disabled", "managed_plan_requires_human", "conversion_window_expired", "conversion_requires_upgrade_payment"] }, "next": { "type": "string" } } } } } },
          "404": { "description": "Purchase not found (purchase_not_found)", "content": { "application/json": { "schema": { "type": "object", "required": ["error"], "properties": { "error": { "const": "purchase_not_found" } } } } } },
          "409": { "description": "Source was already converted or is not fulfilled", "content": { "application/json": { "schema": { "type": "object", "required": ["error"], "properties": { "error": { "type": "string", "enum": ["already_converted", "source_not_fulfilled"] } } } } } },
          "502": { "description": "Auth or billing service unavailable; billing 5xx responses are mapped to billing_service_unavailable", "content": { "application/json": { "schema": { "type": "object", "required": ["error"], "properties": { "error": { "type": "string", "enum": ["auth_service_unavailable", "billing_service_unavailable"] } } } } } }
        }
      }
    },
    "/api/agent-purchases/spend-limit": {
      "get": {
        "summary": "Get the agent key's monthly spending limit",
        "security": [{ "bearerJwt": [], "agentKey": [] }],
        "parameters": [{ "name": "key_id", "in": "query", "required": true, "schema": { "type": "string", "minLength": 1 } }],
        "responses": {
          "200": { "description": "Current monthly ceiling and spend", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AgentSpendLimitResponse" } } } },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "502": { "description": "Billing service unavailable", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerJwt": { "type": "http", "scheme": "bearer", "bearerFormat": "JWT" },
      "pollToken": { "type": "apiKey", "in": "header", "name": "X-Poll-Token" },
      "agentKey": { "type": "apiKey", "in": "header", "name": "X-Nova-Agent-Key" }
    },
    "responses": {
      "BadRequest": { "description": "Invalid request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "Unauthorized": { "description": "Authentication failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "NotFound": { "description": "Receipt not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "Expired": { "description": "Onboarding receipt expired", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "RateLimited": { "description": "Per-IP/day or edge limit exceeded", "headers": { "Retry-After": { "schema": { "type": "integer", "minimum": 5 } } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
    },
    "schemas": {
      "RegisterRequest": { "type": "object", "additionalProperties": false, "required": ["email", "password", "idempotency_key"], "properties": { "email": { "type": "string", "format": "email" }, "password": { "type": "string", "format": "password" }, "company_name": { "type": "string" }, "idempotency_key": { "type": "string", "minLength": 1 } } },
      "RegisterAccepted": { "type": "object", "additionalProperties": false, "required": ["onboarding_id", "state", "poll_token", "claim_expires_at", "next"], "properties": { "onboarding_id": { "type": "string", "format": "uuid" }, "state": { "const": "awaiting_email" }, "poll_token": { "type": "string" }, "claim_expires_at": { "type": "string", "format": "date-time" }, "next": { "type": "string", "pattern": "^Ask the account owner to open the verification email sent to .+, then poll GET /api/agent-onboarding/.+\\.$" } } },
      "ExistingAccount": { "type": "object", "additionalProperties": false, "required": ["state", "next"], "properties": { "state": { "const": "existing_account" }, "next": { "const": "Sign in with POST /api/auth/login" } } },
      "LoginRequest": { "type": "object", "additionalProperties": false, "required": ["email", "password"], "properties": { "email": { "type": "string", "format": "email" }, "password": { "type": "string", "format": "password" } } },
      "LoginResponse": { "type": "object", "required": ["token", "user"], "properties": { "token": { "type": "string", "description": "Bearer JWT" }, "refresh_token": { "type": "string" }, "user": { "type": "object", "required": ["id", "email"], "properties": { "id": { "type": "string" }, "email": { "type": "string", "format": "email" } }, "additionalProperties": true } }, "additionalProperties": true },
      "CheckoutRequest": { "type": "object", "additionalProperties": false, "required": ["onboarding_id", "plan"], "properties": { "onboarding_id": { "type": "string", "format": "uuid" }, "plan": { "const": "host" } } },
      "CheckoutResponse": { "type": "object", "additionalProperties": false, "required": ["checkout_url", "expires_at", "next"], "properties": { "checkout_url": { "type": "string", "format": "uri" }, "expires_at": { "type": "string", "format": "date-time" }, "next": { "const": "Hand checkout_url to the account owner; poll status until state=paid." } } },
      "Subscription": { "type": ["object", "null"], "required": ["id", "plan", "status"], "properties": { "id": { "type": "string", "description": "Pass this value as subscriptionId to POST /api/tenants." }, "plan": { "type": "string" }, "status": { "type": "string" } }, "additionalProperties": false },
      "TenantStatus": { "type": ["object", "null"], "required": ["id", "status", "site_url", "wp_admin_url"], "properties": { "id": { "type": "string" }, "status": { "type": "string" }, "site_url": { "type": "string", "format": "uri" }, "wp_admin_url": { "type": "string", "format": "uri" } }, "additionalProperties": false },
      "PollStatus": { "type": "object", "additionalProperties": false, "required": ["onboarding_id", "state", "next", "retry_after_seconds"], "properties": { "onboarding_id": { "type": "string", "format": "uuid" }, "state": { "type": "string", "enum": ["awaiting_email", "claimed"] }, "next": { "type": "string" }, "retry_after_seconds": { "type": "integer", "minimum": 5 } } },
      "OnboardingStatus": { "type": "object", "additionalProperties": false, "required": ["onboarding_id", "state", "subscription", "tenant", "next", "retry_after_seconds"], "properties": { "onboarding_id": { "type": "string", "format": "uuid" }, "state": { "type": "string", "enum": ["awaiting_email", "claimed", "awaiting_payment", "paid", "provisioning", "site_active", "mcp_ready"] }, "subscription": { "$ref": "#/components/schemas/Subscription" }, "tenant": { "$ref": "#/components/schemas/TenantStatus" }, "next": { "type": "string" }, "retry_after_seconds": { "type": "integer", "minimum": 5 } } },
      "TenantRequest": { "type": "object", "additionalProperties": true, "required": ["subscriptionId", "name", "subdomain", "siteTitle"], "properties": { "subscriptionId": { "type": "string" }, "name": { "type": "string" }, "subdomain": { "type": "string" }, "siteTitle": { "type": "string" }, "domain": { "type": "string" }, "adminEmail": { "type": "string", "format": "email" }, "tagline": { "type": "string" }, "language": { "type": "string" }, "timezone": { "type": "string" }, "plugins": { "type": "array", "items": { "type": "string" } }, "theme": { "type": "string" } } },
      "TenantResponse": { "type": "object", "required": ["id", "status"], "properties": { "id": { "type": "string" }, "status": { "type": "string" }, "site_url": { "type": "string", "format": "uri" }, "wp_admin_url": { "type": "string", "format": "uri" } }, "additionalProperties": true },
      "FinalizeRequest": { "type": "object", "additionalProperties": false, "required": ["tenant_id"], "properties": { "tenant_id": { "type": "string" } } },
      "McpJson": { "type": "object", "additionalProperties": false, "required": ["mcpServers"], "properties": { "mcpServers": { "type": "object", "additionalProperties": false, "required": ["nova"], "properties": { "nova": { "type": "object", "additionalProperties": false, "required": ["type", "url", "headers"], "properties": { "type": { "const": "http" }, "url": { "const": "https://mcp.nova.host/mcp" }, "headers": { "type": "object", "additionalProperties": false, "required": ["Authorization"], "properties": { "Authorization": { "type": "string", "pattern": "^Bearer .+" } } } } } } } } },
      "FinalizeResponse": { "type": "object", "additionalProperties": false, "required": ["mcp_endpoint", "mcp_api_key", "mcp_json", "claude_code_command", "site_url", "wp_admin_url", "tenant_id", "next"], "properties": { "mcp_endpoint": { "const": "https://mcp.nova.host/mcp" }, "mcp_api_key": { "type": "string", "writeOnly": true }, "mcp_json": { "$ref": "#/components/schemas/McpJson" }, "claude_code_command": { "type": "string" }, "site_url": { "type": "string", "format": "uri" }, "wp_admin_url": { "type": "string", "format": "uri" }, "tenant_id": { "type": "string" }, "next": { "const": "Save mcp_api_key now; it is not shown again. Rotate it from the dashboard." } } },
      "AlreadyFinalized": { "type": "object", "additionalProperties": false, "required": ["state"], "properties": { "state": { "const": "mcp_ready" } } },
      "IssuanceLocked": { "type": "object", "additionalProperties": false, "required": ["error", "retry_after_seconds"], "properties": { "error": { "const": "credential_issuance_locked" }, "retry_after_seconds": { "type": "integer", "const": 5 } } },
      "AgentPurchaseRequest": { "type": "object", "additionalProperties": false, "required": ["product_id", "shared_payment_token", "idempotency_key"], "properties": { "product_id": { "type": "string", "enum": ["host", "seo_content"], "description": "An agent-purchasable self-serve product." }, "tenant_id": { "type": "string", "minLength": 1, "description": "Required when product_id is seo_content; omit for host." }, "shared_payment_token": { "type": "string", "minLength": 1, "writeOnly": true, "description": "An owner-authorized payment token bounded by amount and time." }, "idempotency_key": { "type": "string", "minLength": 1 } } },
      "AgentPurchaseResponse": { "type": "object", "additionalProperties": false, "required": ["purchase_id", "status"], "properties": { "purchase_id": { "type": "string" }, "product_id": { "type": "string", "enum": ["host", "seo_content"] }, "status": { "type": "string", "enum": ["reserved", "paid", "requires_action", "failed", "fulfilled", "fulfilment_failed", "refunded", "converted"] }, "amount_cents": { "type": "integer", "minimum": 0 }, "currency": { "type": "string" }, "period_start": { "type": "string" }, "period_end": { "type": "string" }, "receipt_url": { "type": "string", "format": "uri" }, "next": { "type": "string" }, "idempotent": { "type": "boolean" } } },
      "AgentPurchaseBadRequestError": { "type": "object", "additionalProperties": true, "required": ["error"], "properties": { "error": { "type": "string", "enum": ["invalid_request", "user_id_required", "agent_key_required", "token_insufficient"] }, "reason": { "type": "string" } } },
      "AgentPurchasePaymentError": { "type": "object", "additionalProperties": true, "required": ["error"], "properties": { "error": { "type": "string", "enum": ["requires_action", "payment_failed"] }, "next_action": { "type": "object", "additionalProperties": true }, "decline_code": { "type": "string" }, "idempotent": { "type": "boolean" } } },
      "AgentPurchaseForbiddenError": { "type": "object", "additionalProperties": true, "required": ["error"], "properties": { "error": { "type": "string", "enum": ["agent_purchases_disabled", "key_revoked", "key_user_mismatch", "ceiling_not_set", "managed_plan_requires_human", "product_not_agent_purchasable", "tenant_not_owned", "ceiling_exceeded"] }, "ceiling_cents": { "type": "integer", "minimum": 0 }, "spent_cents": { "type": "integer", "minimum": 0 } } },
      "AgentPurchaseConflictError": { "type": "object", "additionalProperties": true, "required": ["error"], "properties": { "error": { "type": "string", "enum": ["subscription_active", "idempotency_conflict"] } } },
      "AgentPurchaseFulfilmentError": { "type": "object", "additionalProperties": true, "required": ["error"], "properties": { "error": { "type": "string", "enum": ["key_introspection_failed", "fulfilment_service_unavailable", "fulfilment_failed"] }, "idempotent": { "type": "boolean" } } },
      "AgentPurchaseListResponse": { "type": "object", "additionalProperties": false, "required": ["purchases"], "properties": { "purchases": { "type": "array", "items": { "$ref": "#/components/schemas/AgentPurchaseResponse" } } } },
      "AgentSpendLimitResponse": { "type": "object", "additionalProperties": false, "required": ["monthly_spend_ceiling_cents", "spent_cents_this_month", "remaining_cents"], "properties": { "monthly_spend_ceiling_cents": { "type": "integer", "minimum": 0 }, "spent_cents_this_month": { "type": "integer", "minimum": 0 }, "remaining_cents": { "type": "integer", "minimum": 0 } } },
      "Error": { "type": "object", "required": ["error"], "properties": { "error": { "type": "string" }, "message": { "type": "string" } }, "additionalProperties": true }
    }
  }
}
