{
  "openapi": "3.1.0",
  "info": {
    "title": "SOAR AI Agent Playbook API",
    "description": "High-performance edge API delivering executable SOAR playbooks, automated response primitives, and security operational workflows for autonomous security agents.\n\n## Monetization\n\n- **Model:** pay-per-unique-record, post-paid metered billing.\n- **Unit price:** $0.25 USD per UNIQUE record ID - billed the first time a record is served to your account in a calendar month; repeat retrievals of the same ID are FREE.\n- **Enumeration cap:** 1,400 distinct record IDs per account per month (~15% of the corpus). Requests whose new breadth would exceed the cap return HTTP 429 `ENUMERATION_CAP_EXCEEDED` with a usage summary; repeats of already-seen records always remain free. Search matches count toward the same cap.\n- **Search price:** $0.01 USD per keyword/full-text search call (1 Stripe meter unit on event `soar_search_consumption`) - flat regardless of matches returned.\n- **Synthesized answers:** records are never served verbatim. Every `data` entry is a synthesized, grounded playbook (`title`, `summary`, `steps`, `safety_guidance`) plus provenance (`record_id`, `content_hash`, `source_url`) - the raw `payload` is never returned, so no record content is redistributable through this API (EU AI Act Article 13-friendly audit trail for agent consumers).\n- **Metering:** every response to /v1/records/fetch reports `unit_price_usd`, `records_returned`, `newly_billed_records`, `repeat_retrievals`, `total_charge_usd`, and `usage`; every /v1/records/search response reports `search.matches_returned`, `unit_price_usd`, `newly_billed_records`, `total_charge_usd`, and `usage`. For pay_as_you_go customers, usage is reported to Stripe billing meters (events `soar_record_consumption` and `soar_search_consumption`) keyed by `stripe_customer_id`; the record meter value is the number of newly-billed unique record IDs.\n- **Plans:** `pay_as_you_go` (metered, $0.25/unique record and $0.01/search, 1,400 unique records/month cap, 60 RPM default) and `enterprise` (unmetered and uncapped; `unit_price_usd` and `total_charge_usd` are 0.00).\n- **Machine payments (MPP):** agents without a valid key receive HTTP 402 with Stripe MPP headers (`X-Stripe-MPP-Version: 1`, `Www-Authenticate: Stripe-MPP realm=\"soar-api\"`) and a `Payment-Required` link to a dynamically created Stripe Checkout Session (subscription mode) that subscribes them to the metered SOAR plan at $0.01/search - no upfront charge, because Stripe's $0.50 minimum applies to one-time payments only. After checkout completes, Stripe fires `checkout.session.completed` to POST /webhooks/stripe, which provisions a `soar_live_...` API key bound to the paying customer and delivers it via the `X-Stripe-MPP-Credential` response header and GET /v1/payments/session/{id}?token=... credential endpoint. Agents then retry with `Authorization: Bearer soar_live_<key>`. Search usage invoices monthly from `soar_search_consumption` meter events on the subscription.\n\n## Authentication\n\nSend the API key in the `Authorization` header as `Bearer soar_live_<key>`. Missing or invalid keys return HTTP 402 with an MPP payment challenge (payment is authentication). Keys are provisioned per Stripe customer via the admin endpoint or the MPP webhook and are stored only as SHA-256 hashes.",
    "version": "1.3.0",
    "termsOfService": "https://lateos.ai/terms/",
    "contact": {
      "name": "Lateos Partnerships",
      "email": "partnerships@lateos.ai",
      "url": "https://lateos.ai/"
    },
    "license": {
      "name": "Proprietary - see terms of service"
    },
    "x-monetization": {
      "model": "pay_per_unique_record",
      "unit_price_usd": 0.25,
      "currency": "usd",
      "billing_mode": "post_paid",
      "unique_record_cap_per_month": 1400,
      "repeat_retrievals_free": true,
      "meter": {
        "provider": "stripe",
        "event_name": "soar_record_consumption",
        "payload_key": "value"
      },
      "search_meter": {
        "provider": "stripe",
        "event_name": "soar_search_consumption",
        "unit_price_usd": 0.01,
        "payload_key": "value"
      },
      "plans": {
        "pay_as_you_go": {
          "metered": true,
          "unit_price_usd": 0.25,
          "unique_record_cap_per_month": 1400,
          "rate_limit_rpm": 60
        },
        "enterprise": {
          "metered": false,
          "unit_price_usd": 0,
          "unique_record_cap_per_month": null
        }
      }
    },
    "x-mpp": {
      "status": "implemented",
      "version": "1",
      "realm": "soar-api",
      "http_status": 402,
      "request_headers": [],
      "response_headers": [
        "X-Stripe-MPP-Version",
        "Www-Authenticate",
        "Payment-Required",
        "X-Payment-Required",
        "X-Stripe-MPP-Credential"
      ],
      "flow": "402 challenge -> Stripe Checkout Session (subscription: metered plan at $0.01/search, no upfront charge) -> checkout.session.completed webhook -> soar_live_ API key provisioned -> agent retrieves key at /v1/payments/session/{id} and retries with Bearer auth",
      "note": "Implemented: unauthenticated or invalidly keyed requests receive an MPP payment challenge with a dynamic Stripe checkout that subscribes the customer to the metered SOAR plan (metered price price_1U4Bre4vzmziH9mV8MhVmpCH on meter soar_search_consumption). Post-paid search usage is invoiced monthly via the subscription."
    }
  },
  "servers": [
    {
      "url": "https://soar-api.nevada-f99.workers.dev",
      "description": "Production Edge Gateway"
    }
  ],
  "paths": {
    "/v1/records/fetch": {
      "post": {
        "summary": "Fetch SOAR Playbook Records",
        "description": "Queries security operational playbooks filtered by target platform, execution status, and safety profiles. Records are selected at random from the matching set. Responses are SYNTHESIZED ANSWERS: each entry is a grounded playbook (`title`, `summary`, `steps`, `safety_guidance`) plus provenance (`record_id`, `content_hash`, `source_url`) - never the raw payload. Usage is dynamically metered per UNIQUE record ID: pay_as_you_go customers are charged $0.25 USD the first time a record ID is served to their account in a calendar month (repeats are free), capped at 1,400 distinct records per account per month (429 on breach), reported post-paid to a Stripe billing meter (event `soar_record_consumption`). Enterprise customers are unmetered and uncapped.",
        "operationId": "fetchSoarRecords",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "limit": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 100,
                    "default": 10,
                    "description": "Maximum number of records to return (1-100). Cost is $0.25 per NEW unique record ID (repeats are free) up to the 1,400/month cap - request only what you need."
                  },
                  "platform": {
                    "type": ["string", "null"],
                    "description": "Filter playbooks by operational platform: sentinel, splunk_soar, xsoar, google_secops, knowledge_qa."
                  },
                  "has_destructive_step": {
                    "type": ["boolean", "null"],
                    "description": "Filter by playbooks containing non-reversible actions. Never execute such records without human authorization."
                  },
                  "is_executable": {
                    "type": ["boolean", "null"],
                    "description": "Filter by playbooks formatted for direct code/command execution."
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful record query with synthesized playbooks, provenance, and usage summary. `total_charge_usd` covers only newly-billed unique record IDs and is debited to the Stripe billing meter for pay_as_you_go customers.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": ["success"],
                      "example": "success"
                    },
                    "plan_tier": {
                      "type": "string",
                      "enum": ["pay_as_you_go", "enterprise"],
                      "example": "pay_as_you_go"
                    },
                    "records_returned": {
                      "type": "integer",
                      "example": 2
                    },
                    "synthesized": {
                      "type": "boolean",
                      "example": true
                    },
                    "unit_price_usd": {
                      "type": "number",
                      "description": "Price per unique record. 0.25 for pay_as_you_go, 0.00 for enterprise.",
                      "example": 0.25
                    },
                    "newly_billed_records": {
                      "type": "integer",
                      "description": "Unique record IDs served to this account for the first time this month (these are billed). 0 when all records were repeats.",
                      "example": 2
                    },
                    "repeat_retrievals": {
                      "type": "integer",
                      "description": "Records in this response already served to this account this month - free of charge.",
                      "example": 0
                    },
                    "total_charge_usd": {
                      "type": "number",
                      "description": "newly_billed_records * unit_price_usd, rounded to 4 decimal places.",
                      "example": 0.5
                    },
                    "usage": {
                      "$ref": "#/components/schemas/UsageSummary"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/GroundedPlaybook"
                      }
                    }
                  },
                  "required": [
                    "status",
                    "plan_tier",
                    "records_returned",
                    "synthesized",
                    "unit_price_usd",
                    "newly_billed_records",
                    "repeat_retrievals",
                    "total_charge_usd",
                    "usage",
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Malformed JSON request body. Reserved for client-side validation errors."
          },
          "402": {
            "description": "Payment required (MPP challenge). The request carried no valid API key. Contains Stripe MPP headers and a Payment-Required link to a dynamic Stripe Checkout Session (subscription mode) subscribing the caller to the metered SOAR plan at $0.01/search - no upfront charge. Also includes an EIP-3009 X-Payment-Required header with on-chain settlement parameters for autonomous agent payment interception.",
            "headers": {
              "X-Stripe-MPP-Version": {
                "description": "Stripe Machine Payments Protocol version in use.",
                "schema": { "type": "string", "example": "1" }
              },
              "Www-Authenticate": {
                "description": "MPP challenge scheme and realm.",
                "schema": { "type": "string", "example": "Stripe-MPP realm=\"soar-api\"" }
              },
              "Payment-Required": {
                "description": "URI of the Stripe-hosted payment page for this request.",
                "schema": { "type": "string", "example": "https://checkout.stripe.com/c/pay/cs_test_..." }
              },
              "X-Payment-Required": {
                "description": "EIP-3009 / x402 payment specification header for autonomous agent interception. Specifies on-chain settlement parameters: scheme, network, asset contract, amount in micro-units, and pay_to wallet address.",
                "schema": { "type": "string", "example": "scheme=\"EIP-3009\", network=\"base\", asset=\"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\", amount=\"100000\", pay_to=\"0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb\"" }
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/PaymentRequiredError" }
              }
            }
          },
          "429": {
            "description": "Enumeration cap reached: this account has been served its monthly allowance of 1,400 distinct record IDs. New record breadth is rejected; repeats of already-seen records remain free. Body includes a usage summary (unique_records_served_month, cap, remaining).",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "503": {
            "description": "Authentication service (database) or the breadth-metering ledger (`record_served`) is unreachable. Not a payment demand; retry shortly.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Server-side error while processing the query. No charge is recorded for failed requests.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/v1/records/search": {
      "post": {
        "summary": "Search SOAR Playbook Records",
        "description": "Keyword/full-text search across the golden SOAR dataset. The query term is matched against record payload content (Postgres ILIKE plus full-text ranking via ts_rank/plainto_tsquery, so terms like 'quarantine' or 'block ip' find semantically relevant playbooks). Optionally filter by platform and safety flags. Matches are served as SYNTHESIZED playbooks with provenance (`record_id`, `content_hash`, `source_url`) - never raw payload - and count toward the account's monthly 1,400-unique-record enumeration cap shared with /v1/records/fetch. Flat price: $0.01 USD per search call regardless of matches returned - billed as 1 unit on the Stripe meter `soar_search_consumption` for pay_as_you_go customers. Enterprise customers are unmetered. Use this endpoint when you need to FIND records by content; use /v1/records/fetch to sample random records from a filtered set.",
        "operationId": "searchSoarRecords",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["q"],
                "properties": {
                  "q": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200,
                    "description": "Search term (1-200 chars) matched against playbook payload content. Plain words and short phrases work best; punctuation is stripped by full-text ranking."
                  },
                  "platform": {
                    "type": ["string", "null"],
                    "description": "Filter playbooks by operational platform: sentinel, splunk_soar, xsoar, google_secops, knowledge_qa."
                  },
                  "has_destructive_step": {
                    "type": ["boolean", "null"],
                    "description": "Filter by playbooks containing non-reversible actions. Never execute such records without human authorization."
                  },
                  "is_executable": {
                    "type": ["boolean", "null"],
                    "description": "Filter by playbooks formatted for direct code/command execution."
                  },
                  "requires_human_approval": {
                    "type": ["boolean", "null"],
                    "description": "Filter by playbooks flagged as requiring human approval before execution."
                  },
                  "limit": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 50,
                    "default": 10,
                    "description": "Maximum number of matching records to return (1-50). The $0.01 fee does not scale with this value."
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful search with match count, synthesized playbooks, provenance, and usage summary. `total_charge_usd` is 0.01 for pay_as_you_go customers (billed to the soar_search_consumption meter) and 0.00 for enterprise.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": ["success"],
                      "example": "success"
                    },
                    "plan_tier": {
                      "type": "string",
                      "enum": ["pay_as_you_go", "enterprise"],
                      "example": "pay_as_you_go"
                    },
                    "search": {
                      "type": "object",
                      "properties": {
                        "query": { "type": "string", "example": "phishing" },
                        "matches_returned": { "type": "integer", "example": 3 }
                      }
                    },
                    "synthesized": {
                      "type": "boolean",
                      "example": true
                    },
                    "unit_price_usd": {
                      "type": "number",
                      "description": "Flat price per search. 0.01 for pay_as_you_go, 0.00 for enterprise.",
                      "example": 0.01
                    },
                    "newly_billed_records": {
                      "type": "integer",
                      "description": "Unique record IDs served to this account for the first time this month (count toward the monthly cap).",
                      "example": 3
                    },
                    "repeat_retrievals": {
                      "type": "integer",
                      "description": "Matches already served to this account this month - free of charge.",
                      "example": 0
                    },
                    "total_charge_usd": {
                      "type": "number",
                      "description": "unit_price_usd (flat, not scaled by matches).",
                      "example": 0.01
                    },
                    "usage": {
                      "$ref": "#/components/schemas/UsageSummary"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/GroundedPlaybook"
                      }
                    }
                  },
                  "required": [
                    "status",
                    "plan_tier",
                    "search",
                    "synthesized",
                    "unit_price_usd",
                    "newly_billed_records",
                    "repeat_retrievals",
                    "total_charge_usd",
                    "usage",
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Missing or empty q (or over 200 chars), or malformed JSON body.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "402": {
            "description": "Payment required (MPP challenge). The request carried no valid API key. Complete checkout, retrieve the issued key from `credential_endpoint`, then retry with `Authorization: Bearer soar_live_<key>`.",
            "headers": {
              "X-Stripe-MPP-Version": {
                "description": "Stripe Machine Payments Protocol version in use.",
                "schema": { "type": "string", "example": "1" }
              },
              "Www-Authenticate": {
                "description": "MPP challenge scheme and realm.",
                "schema": { "type": "string", "example": "Stripe-MPP realm=\"soar-api\"" }
              },
              "Payment-Required": {
                "description": "URI of the Stripe-hosted payment page for this request.",
                "schema": { "type": "string", "example": "https://checkout.stripe.com/c/pay/cs_test_..." }
              },
              "X-Payment-Required": {
                "description": "EIP-3009 / x402 payment specification header for autonomous agent interception. Specifies on-chain settlement parameters: scheme, network, asset contract, amount in micro-units, and pay_to wallet address.",
                "schema": { "type": "string", "example": "scheme=\"EIP-3009\", network=\"base\", asset=\"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\", amount=\"100000\", pay_to=\"0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb\"" }
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/PaymentRequiredError" }
              }
            }
          },
          "429": {
            "description": "Enumeration cap reached: this account has been served its monthly allowance of 1,400 distinct record IDs. New record breadth is rejected; repeats of already-seen records remain free. Body includes a usage summary (unique_records_served_month, cap, remaining).",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "503": {
            "description": "Authentication service (database) or the breadth-metering ledger (`record_served`) is unreachable. Not a payment demand; retry shortly.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Server-side error while processing the search. No charge is recorded for failed requests.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/v1/payments/session": {
      "post": {
        "summary": "Create an MPP subscription checkout session",
        "description": "Creates a dynamic Stripe Checkout Session (subscription mode) subscribing the caller to the metered SOAR plan at $0.01/search. There is no upfront charge - Stripe's $0.50 minimum applies to one-time payments only, and subscriptions have no session minimum. Returns the hosted checkout URL plus the session tracking values agents need to retrieve their issued API key after subscribing. This is the same session the 402 challenge creates automatically.",
        "operationId": "createMppSubscriptionSession",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {},
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Payment session created.",
            "headers": {
              "X-Stripe-MPP-Version": {
                "schema": { "type": "string", "example": "1" }
              },
              "Www-Authenticate": {
                "schema": { "type": "string", "example": "Stripe-MPP realm=\"soar-api\"" }
              },
              "Payment-Required": {
                "schema": { "type": "string", "example": "https://checkout.stripe.com/c/pay/cs_test_..." }
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/PaymentSession" }
              }
            }
          },
          "503": {
            "description": "Stripe session creation failed (PAYMENT_PROVIDER_UNAVAILABLE)."
          }
        }
      }
    },
    "/v1/payments/session/{session_id}": {
      "get": {
        "summary": "Retrieve MPP credential (issued API key)",
        "description": "After checkout completes and the webhook provisions a key, the paying agent retrieves the raw soar_live_ key here - once. Match is by session_id or client_reference_id; the credential token returned in the 402 challenge is required. The stored key is nulled after first retrieval.",
        "operationId": "retrieveMppCredential",
        "parameters": [
          {
            "name": "session_id",
            "in": "path",
            "required": true,
            "schema": { "type": "string" },
            "description": "Stripe Checkout Session id (cs_...) or client_reference_id."
          },
          {
            "name": "token",
            "in": "query",
            "required": false,
            "schema": { "type": "string" },
            "description": "Credential token returned in the 402 challenge / session creation response."
          }
        ],
        "responses": {
          "200": {
            "description": "Session status; includes api_key when completed and token matches.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": { "type": "string", "enum": ["open", "completed", "expired"] },
                    "api_key": { "type": "string", "example": "soar_live_..." },
                    "key_id": { "type": ["integer", "null"] },
                    "credential_available": { "type": "boolean" },
                    "warning": { "type": "string" }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Invalid credential token."
          },
          "404": {
            "description": "Unknown session."
          },
          "503": {
            "description": "Credential store unreachable (PAYMENT_UNAVAILABLE)."
          }
        }
      }
    },
    "/webhooks/stripe": {
      "post": {
        "summary": "Stripe webhook (MPP key issuance)",
        "description": "Signature-verified Stripe webhook. On checkout.session.completed it provisions a soar_live_ API key for the paying Stripe customer (bound to the session's client_reference_id), records it against the payment session, and delivers it via the X-Stripe-MPP-Credential response header and the credential retrieval endpoint. checkout.session.expired marks sessions expired. Server errors return 500 so Stripe retries with backoff.",
        "operationId": "stripeWebhook",
        "security": [
          {
            "StripeSignature": []
          }
        ],
        "responses": {
          "200": {
            "description": "Event acknowledged; key_issued when checkout.session.completed."
          },
          "401": {
            "description": "Missing or invalid stripe-signature header."
          },
          "500": {
            "description": "Provisioning failed - Stripe will retry the webhook."
          },
          "503": {
            "description": "STRIPE_WEBHOOK_SECRET not configured."
          }
        }
      }
    },
    "/v1/admin/keys/generate": {
      "post": {
        "summary": "Provision an API key for a Stripe customer",
        "description": "Internal/provisioning endpoint. Creates an active API key bound to a Stripe customer. Requires the `X-Admin-Secret` header. The raw key is returned exactly once - store it immediately. Intended for the billing integration (Stripe webhook / dashboard) that provisions keys after payment setup; not for agent-facing use.",
        "operationId": "generateApiKey",
        "security": [
          {
            "AdminSecret": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["stripe_customer_id"],
                "properties": {
                  "stripe_customer_id": {
                    "type": "string",
                    "description": "Stripe customer ID the key will be bound to for metered billing."
                  },
                  "plan_tier": {
                    "type": "string",
                    "enum": ["pay_as_you_go", "enterprise"],
                    "default": "pay_as_you_go"
                  },
                  "rate_limit_rpm": {
                    "type": "integer",
                    "default": 60
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Key created. The raw key appears in `key` and is not retrievable again.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": { "type": "string", "example": "created" },
                    "key_id": { "type": "string" },
                    "created_at": { "type": "string" },
                    "stripe_customer_id": { "type": "string" },
                    "plan_tier": { "type": "string" },
                    "rate_limit_rpm": { "type": "integer" },
                    "key": { "type": "string", "example": "soar_live_..." },
                    "warning": { "type": "string" }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Missing required parameter `stripe_customer_id`."
          },
          "401": {
            "description": "Missing or invalid `X-Admin-Secret` header."
          },
          "500": {
            "description": "Server-side error creating the key."
          }
        }
      }
    },
    "/openapi.json": {
      "get": {
        "summary": "OpenAPI specification",
        "description": "This specification, served in pretty-printed form with a 1-hour public cache.",
        "operationId": "getOpenApiSpec",
        "responses": {
          "200": {
            "description": "OpenAPI 3.1 specification document."
          }
        }
      }
    },
    "/mcp": {
      "get": {
        "summary": "MCP server discovery (GET)",
        "description": "MCP Streamable HTTP transport - server metadata and tool listing via GET. Returns protocol version, server capabilities, and available tools without authentication. Web-based agents use this endpoint for server discovery before sending JSON-RPC POST requests.",
        "operationId": "mcpServerDiscovery",
        "responses": {
          "200": {
            "description": "MCP server metadata with protocol version, capabilities, and tool list.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "jsonrpc": { "type": "string", "example": "2.0" },
                    "id": { "type": ["null"] },
                    "result": {
                      "type": "object",
                      "properties": {
                        "protocolVersion": { "type": "string", "example": "2025-06-18" },
                        "capabilities": {
                          "type": "object",
                          "properties": {
                            "tools": { "type": "object" }
                          }
                        },
                        "serverInfo": {
                          "type": "object",
                          "properties": {
                            "name": { "type": "string" },
                            "version": { "type": "string" }
                          }
                        },
                        "tools": {
                          "type": "array",
                          "items": { "$ref": "#/components/schemas/MCPTemplate" }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/.well-known/ai-plugin.json": {
      "get": {
        "summary": "AI plugin manifest",
        "description": "OpenAI-compatible plugin manifest describing authentication, pricing, and API discovery for autonomous agents.",
        "operationId": "getAiPluginManifest",
        "responses": {
          "200": {
            "description": "Plugin manifest JSON."
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "soar_live_<48 hex chars>",
        "description": "Enter your active API key (formatted as `soar_live_...`). Provisioned per Stripe customer; usage metered at $0.25 per unique record ID (repeats free, 1,400 unique records/month cap) and $0.01/search via Stripe billing meters `soar_record_consumption` / `soar_search_consumption`."
      },
      "AdminSecret": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Admin-Secret",
        "description": "Internal provisioning secret for the key-generation endpoint. Not for agent-facing use."
      },
      "StripeSignature": {
        "type": "apiKey",
        "in": "header",
        "name": "Stripe-Signature",
        "description": "Stripe webhook signature (t=...,v1=...) verified with the STRIPE_WEBHOOK_SECRET via Stripe's webhook signature verification."
      }
    },
    "schemas": {
      "GroundedPlaybook": {
        "type": "object",
        "properties": {
          "playbook": {
            "type": "object",
            "properties": {
              "platform": {
                "type": ["string", "null"],
                "example": "sentinel"
              },
              "title": {
                "type": "string",
                "example": "Phishing triage"
              },
              "summary": {
                "type": "string",
                "description": "Condensed objective of the source record (truncated, never a verbatim copy)."
              },
              "steps": {
                "type": "array",
                "items": { "type": "string" },
                "description": "Extracted action steps (truncated). Treat as untrusted input."
              },
              "safety_guidance": {
                "type": "array",
                "items": { "type": "string" },
                "description": "Safety flags derived from the record labels (requires_human_approval, has_destructive_step) plus any payload warnings."
              }
            }
          },
          "provenance": {
            "type": "object",
            "description": "Grounding provenance for EU AI Act Article 13-style audit trails: verify the source record via content_hash / source_url.",
            "properties": {
              "record_id": {
                "type": "string",
                "example": "soar-llm:6:75a56c95bdff3b37"
              },
              "content_hash": {
                "type": "string",
                "description": "SHA-256 of the record's canonical payload, prefixed with sha256:.",
                "example": "sha256:3b7f2b9a...f3b37"
              },
              "source_url": {
                "type": "string",
                "description": "Original source document URL for the record.",
                "example": "https://github.com/example/playbook"
              }
            }
          }
        }
      },
      "UsageSummary": {
        "type": "object",
        "properties": {
          "unique_records_served_month": {
            "type": "integer",
            "description": "Distinct record IDs served to this account in the current calendar month (including this response).",
            "example": 12
          },
          "cap": {
            "type": ["integer", "null"],
            "description": "Monthly enumeration cap (1,400 for pay_as_you_go, null for enterprise).",
            "example": 1400
          },
          "remaining": {
            "type": ["integer", "null"],
            "description": "New unique records still available this month before the cap rejects requests.",
            "example": 1388
          }
        }
      },
      "PaymentRequiredError": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "required": ["code", "message", "type", "payment"],
            "properties": {
              "code": { "type": "string", "enum": ["PAYMENT_REQUIRED"] },
              "message": { "type": "string" },
              "type": { "type": "string", "enum": ["payment_required"] },
              "network": { "type": "string", "example": "base", "description": "Blockchain network for on-chain settlement." },
              "asset": { "type": "string", "example": "USDC", "description": "Asset name for payment." },
              "amount_usdc": { "type": "number", "example": 0.1, "description": "Minimum payment amount in USDC." },
              "pay_to": { "type": "string", "description": "Wallet address to receive payment.", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb" },
              "payment": {
                "type": "object",
                "properties": {
                  "plan": { "type": "string", "example": "soar_search_metered" },
                  "unit_price_usd": { "type": "number", "example": 0.01 },
                  "billing": { "type": "string", "example": "metered_monthly" },
                  "payment_url": {
                    "type": "string",
                    "description": "Stripe-hosted Checkout Session (subscription checkout) URL. Also returned in the Payment-Required header."
                  },
                  "session_id": { "type": "string", "example": "cs_test_..." },
                  "client_reference_id": { "type": "string" },
                  "credential_token": {
                    "type": "string",
                    "description": "One-time token required to retrieve the issued API key after subscribing."
                  },
                  "credential_endpoint": {
                    "type": "string",
                    "description": "Path to retrieve the issued API key: GET /v1/payments/session/{id}?token=..."
                  }
                }
              }
            }
          }
        }
      },
      "PaymentSession": {
        "type": "object",
        "properties": {
          "status": { "type": "string", "enum": ["payment_required"] },
          "plan": { "type": "string", "example": "soar_search_metered" },
          "unit_price_usd": { "type": "number", "example": 0.01 },
          "billing": { "type": "string", "example": "metered_monthly" },
          "payment_url": { "type": "string" },
          "session_id": { "type": "string", "example": "cs_test_..." },
          "client_reference_id": { "type": "string" },
          "credential_token": { "type": "string" },
          "credential_endpoint": { "type": "string" }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "required": ["code", "message", "type"],
            "properties": {
              "code": {
                "type": "string",
                "enum": ["UNAUTHORIZED", "FORBIDDEN", "BAD_REQUEST", "SERVER_ERROR", "NOT_FOUND", "ENUMERATION_CAP_EXCEEDED"]
              },
              "message": { "type": "string" },
              "type": {
                "type": "string",
                "enum": ["auth_error", "client_error", "api_error", "rate_limit_error"]
              }
            }
          }
        }
      },
      "MCPTemplate": {
        "type": "object",
        "description": "MCP tool definition as returned by the MCP tools/list method.",
        "properties": {
          "name": { "type": "string" },
          "description": { "type": "string" },
          "inputSchema": {
            "type": "object",
            "properties": {
              "type": { "type": "string" },
              "properties": { "type": "object" },
              "required": { "type": "array" },
              "additionalProperties": { "type": "boolean" }
            }
          }
        }
      }
    }
  }
}
