{
  "openapi": "3.0.3",
  "info": {
    "title": "Spindora SEO Analysis Tool API",
    "version": "1.0.0",
    "description": "Free on-page SEO analysis API. Async: POST /analyze returns task_id, then poll GET /result/{task_id}. Requires X-Spindora-Key header (format: sp_seo_*). Mandatory attribution: Powered by Spindora linking to https://www.spindorai.com. No screenshots in API responses.",
    "contact": {
      "url": "https://www.spindorai.com/developers/seo-analizi-api"
    }
  },
  "servers": [
    {
      "url": "https://www.spindorai.com/api/public-seo-analizi"
    }
  ],
  "security": [
    {
      "SpindoraApiKey": []
    }
  ],
  "components": {
    "securitySchemes": {
      "SpindoraApiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Spindora-Key",
        "description": "API key from https://www.spindorai.com/seo-analizi-api-key (prefix sp_seo_). Alternative: Authorization: Bearer sp_seo_..."
      }
    },
    "schemas": {
      "AnalyzeRequest": {
        "type": "object",
        "required": ["url"],
        "properties": {
          "url": {
            "type": "string",
            "minLength": 3,
            "maxLength": 2048,
            "example": "https://example.com"
          },
          "keywords": {
            "type": "array",
            "maxItems": 3,
            "items": { "type": "string" },
            "default": [],
            "example": ["seo", "analiz"]
          },
          "device": {
            "type": "string",
            "enum": ["desktop", "mobile"],
            "default": "desktop"
          },
          "locale": {
            "type": "string",
            "enum": ["tr", "en"],
            "default": "tr",
            "description": "Language for check messages in response"
          }
        }
      },
      "AnalyzeResponse": {
        "type": "object",
        "properties": {
          "task_id": { "type": "string" },
          "message": { "type": "string" },
          "mode": { "type": "string", "enum": ["api"] },
          "attribution": {
            "type": "object",
            "properties": {
              "text": { "type": "string", "example": "Powered by Spindora" },
              "url": { "type": "string", "example": "https://www.spindorai.com" },
              "required": { "type": "boolean", "example": true },
              "html": { "type": "string" }
            }
          }
        }
      },
      "PendingResponse": {
        "type": "object",
        "properties": {
          "status": { "type": "string", "example": "pending" }
        }
      },
      "SeoResult": {
        "type": "object",
        "properties": {
          "success": { "type": "boolean" },
          "url": { "type": "string" },
          "final_url": { "type": "string" },
          "seo_score": { "type": "integer", "minimum": 0, "maximum": 100 },
          "word_count": { "type": "integer" },
          "title_text": { "type": "string" },
          "meta_description": { "type": "string" },
          "checks": { "type": "array", "items": { "type": "object" } },
          "headings": { "type": "array", "items": { "type": "object" } },
          "keyword_checks": { "type": "array", "items": { "type": "object" } },
          "schema_types": { "type": "array", "items": { "type": "string" } },
          "server": { "type": "object" },
          "screenshots": {
            "type": "array",
            "items": { "type": "string" },
            "description": "Always empty for API mode"
          },
          "attribution": { "type": "object" }
        }
      }
    }
  },
  "paths": {
    "/analyze": {
      "post": {
        "summary": "Queue SEO analysis",
        "operationId": "analyze",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/AnalyzeRequest" }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Analysis queued",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/AnalyzeResponse" }
              }
            }
          },
          "401": { "description": "Invalid or missing API key" },
          "429": { "description": "Daily quota exceeded (30/day per key)" }
        }
      }
    },
    "/result/{task_id}": {
      "get": {
        "summary": "Poll analysis result",
        "operationId": "getResult",
        "parameters": [
          {
            "name": "task_id",
            "in": "path",
            "required": true,
            "schema": { "type": "string" }
          }
        ],
        "responses": {
          "200": {
            "description": "Result ready",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/SeoResult" }
              }
            }
          },
          "202": {
            "description": "Still processing — poll again after ~2 seconds",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/PendingResponse" }
              }
            }
          },
          "401": { "description": "Invalid API key" },
          "422": { "description": "URL unreachable or analysis error" },
          "500": { "description": "Server error" }
        }
      }
    }
  },
  "x-integration-steps": [
    "Create free API key at https://www.spindorai.com/seo-analizi-api-key (login required). Key shown once, format sp_seo_*.",
    "POST https://www.spindorai.com/api/public-seo-analizi/analyze with header X-Spindora-Key and JSON body { url, keywords?, device?, locale? }.",
    "Read task_id from response.",
    "Poll GET https://www.spindorai.com/api/public-seo-analizi/result/{task_id} with same API key every 2 seconds until HTTP 200 (not 202).",
    "Display attribution link near results: <a href=\"https://www.spindorai.com\">Powered by Spindora</a>",
    "Limits: 30 analyses per day per API key, max 3 active keys per user. screenshots[] is always empty via API."
  ]
}
