{
  "openapi": "3.1.0",
  "info": {
    "title": "Ploy Migration Estimate API",
    "version": "1.0.0",
    "description": "Scan a public website and return a directional manual migration estimate plus the recommended Ploy plan and signup URL."
  },
  "servers": [
    {
      "url": "https://ploy.ai"
    }
  ],
  "paths": {
    "/agent-tools/migration-estimate": {
      "get": {
        "operationId": "estimateMigrationCost",
        "summary": "Estimate website migration cost and time",
        "description": "Uses the same live scanner and estimate model as the Ploy migration cost calculator. The upstream scan has a six-second budget. If the full browser scan is still running after page enumeration succeeds, the API returns a marked partial estimate from the evidence already collected. It never produces an estimate when page enumeration returns zero. Estimates are directional, not vendor quotes.",
        "parameters": [
          {
            "name": "url",
            "in": "query",
            "required": true,
            "description": "Public website URL or bare domain to analyze.",
            "schema": {
              "type": "string",
              "examples": [
                "example.com"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Complete or partial estimate returned after no more than six seconds of upstream scanning.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EstimateResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid URL."
          },
          "422": {
            "description": "The scanner could not enumerate any pages, so no estimate was produced."
          },
          "500": {
            "description": "Unexpected API failure."
          },
          "502": {
            "description": "The importer failed or returned no usable site evidence within six seconds."
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "EstimateResponse": {
        "type": "object",
        "required": [
          "version",
          "inputUrl",
          "finalUrl",
          "scannedAt",
          "scan",
          "site",
          "estimate",
          "recommendation",
          "methodology",
          "links"
        ],
        "properties": {
          "version": {
            "type": "string",
            "const": "1.0"
          },
          "inputUrl": {
            "type": "string",
            "format": "uri"
          },
          "finalUrl": {
            "type": "string",
            "format": "uri"
          },
          "scannedAt": {
            "type": "string",
            "format": "date-time"
          },
          "scan": {
            "type": "object",
            "required": [
              "status"
            ],
            "properties": {
              "status": {
                "type": "string",
                "enum": [
                  "complete",
                  "partial"
                ],
                "description": "Complete when the full browser scan finished; partial when the response budget elapsed after useful evidence was collected."
              },
              "warning": {
                "type": "string"
              }
            }
          },
          "site": {
            "type": "object",
            "properties": {
              "platform": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "platformConfidence": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "pageCount": {
                "type": "integer"
              },
              "cmsItems": {
                "type": "integer"
              },
              "redirects": {
                "type": "integer"
              },
              "forms": {
                "type": "integer"
              },
              "locales": {
                "type": "integer"
              }
            }
          },
          "estimate": {
            "type": "object",
            "properties": {
              "currency": {
                "type": "string",
                "const": "USD"
              },
              "agencyCostLow": {
                "type": "number"
              },
              "agencyCostHigh": {
                "type": "number"
              },
              "agencyWeeksLow": {
                "type": "number"
              },
              "agencyWeeksHigh": {
                "type": "number"
              },
              "manualHours": {
                "type": "number"
              },
              "ployMigrationMinutes": {
                "type": "number"
              }
            }
          },
          "recommendation": {
            "type": "object",
            "description": "The same recommendation card content shown in the calculator UI."
          },
          "methodology": {
            "type": "object"
          },
          "links": {
            "type": "object"
          }
        }
      }
    }
  }
}