{
  "openapi": "3.1.0",
  "info": {
    "title": "Paperologia Service Catalog and Quote Intake",
    "version": "1.0.0",
    "description": "Discover services available through Paperologia and submit an asynchronous callback request. Submission does not create a price, eligibility decision or response-time guarantee."
  },
  "servers": [
    { "url": "https://paperologia.com" }
  ],
  "x-paperologia-universal-handoff": {
    "description": "Preferred human-confirmed handoff for agents that can only open or return URLs. Fragment data is processed locally and removed before the user confirms submission.",
    "urlTemplate": "https://paperologia.com/do/{service_code}#phone={phone}&lang={locale}&message={message}",
    "requiredConsent": true,
    "fragmentParameters": {
      "phone": { "required": true, "description": "Spanish 9-digit or international phone number" },
      "lang": { "required": true, "enum": ["uk", "ru"] },
      "message": { "required": false, "maxLength": 500 }
    }
  },
  "paths": {
    "/catalog/v1/services.json": {
      "get": {
        "operationId": "listServices",
        "summary": "List all active service descriptions",
        "responses": {
          "200": {
            "description": "Versioned compact service index",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ServiceIndex" } } }
          }
        }
      }
    },
    "/catalog/v1/services/{serviceCode}.json": {
      "get": {
        "operationId": "getService",
        "summary": "Get one service description",
        "parameters": [
          { "name": "serviceCode", "in": "path", "required": true, "schema": { "type": "string", "pattern": "^[a-z0-9_]+$" } }
        ],
        "responses": {
          "200": { "description": "Service record", "content": { "application/json": { "schema": { "type": "object" } } } },
          "404": { "description": "Unknown service" }
        }
      }
    },
    "/api/v1/quote-requests": {
      "post": {
        "operationId": "createQuoteRequest",
        "summary": "Request an asynchronous callback for one service",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/QuoteRequest" }
            }
          }
        },
        "responses": {
          "202": { "description": "Request accepted", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/QuoteAccepted" } } } },
          "400": { "description": "Invalid request" },
          "415": { "description": "JSON content type required" },
          "429": { "description": "Too many recent requests" },
          "503": { "description": "Intake temporarily unavailable" }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "ServiceIndex": {
        "type": "object",
        "required": ["schema_version", "catalog_version", "effective_from", "services"],
        "properties": {
          "schema_version": { "type": "string" },
          "catalog_version": { "type": "string" },
          "effective_from": { "type": "string", "format": "date" },
          "public_projection_hash": { "type": "string" },
          "services": { "type": "array", "items": { "type": "object" } }
        }
      },
      "QuoteRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": ["serviceCode", "phone", "locale", "sourcePath", "consent", "idempotencyKey"],
        "properties": {
          "serviceCode": { "type": "string", "pattern": "^[a-z0-9_]+$" },
          "phone": { "type": "string", "description": "International phone number beginning with +" },
          "locale": { "type": "string", "enum": ["uk", "ru"] },
          "sourcePath": { "type": "string", "pattern": "^/(uk|ru)/services" },
          "consent": { "type": "boolean", "const": true },
          "idempotencyKey": { "type": "string", "format": "uuid" }
        }
      },
      "QuoteAccepted": {
        "type": "object",
        "required": ["requestId", "status"],
        "properties": {
          "requestId": { "type": "string", "format": "uuid" },
          "status": { "type": "string", "const": "received" }
        }
      }
    }
  }
}
