{
  "openapi": "3.1.0",
  "info": {
    "title": "Index-Now.ru REST API",
    "version": "1.3.0",
    "description": "API для проектов, сайтов, передачи URL в подключённые каналы, статусов, Sitemap и технического аудита. Авторизация выполняется отдельным Bearer API-токеном из личного кабинета. Возможности и лимиты проверяются сервером по тарифу."
  },
  "servers": [
    {
      "url": "https://index-now.ru/api/v1"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "paths": {
    "/account": {
      "get": {
        "summary": "Тариф и доступные возможности",
        "operationId": "getAccountCapabilities",
        "responses": {
          "200": {
            "description": "Тариф, месячный лимит URL и серверные признаки доступности функций"
          }
        }
      }
    },
    "/projects": {
      "get": {
        "summary": "Список проектов и сайтов",
        "operationId": "listProjects",
        "responses": {
          "200": {
            "description": "Проекты организации"
          }
        }
      },
      "post": {
        "summary": "Создать проект",
        "operationId": "createProject",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["name"],
                "properties": {
                  "name": { "type": "string", "minLength": 1, "maxLength": 100 }
                }
              }
            }
          }
        },
        "responses": {
          "201": { "description": "Проект создан" }
        }
      }
    },
    "/sites": {
      "get": {
        "summary": "Список сайтов",
        "operationId": "listSites",
        "parameters": [
          {
            "name": "projectId",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Сайты организации"
          }
        }
      },
      "post": {
        "summary": "Добавить сайт и получить IndexNow key-файл",
        "operationId": "createSite",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["projectId", "domain"],
                "properties": {
                  "projectId": { "type": "string", "format": "uuid" },
                  "domain": { "type": "string", "example": "example.com" }
                }
              }
            }
          }
        },
        "responses": {
          "201": { "description": "Сайт создан; ответ содержит indexNowKeyFile" }
        }
      }
    },
    "/sites/{id}/indexnow-key": {
      "get": {
        "summary": "Получить IndexNow key-файл сайта",
        "operationId": "getIndexNowKey",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": { "type": "string", "format": "uuid" }
          }
        ],
        "responses": {
          "200": { "description": "Имя, содержимое, адрес установки и статус key-файла" }
        }
      }
    },
    "/sites/{id}/indexnow/verify": {
      "post": {
        "summary": "Проверить установку IndexNow key-файла",
        "operationId": "verifyIndexNowKey",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": { "type": "string", "format": "uuid" }
          }
        ],
        "responses": {
          "200": { "description": "Результат проверки файла в корне сайта" }
        }
      }
    },
    "/sites/{id}/indexers": {
      "get": {
        "summary": "Получить доступные индексаторы сайта",
        "operationId": "listSiteIndexers",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": { "type": "string", "format": "uuid" }
          }
        ],
        "responses": {
          "200": { "description": "Индексаторы и признаки доступности по текущим подключениям" }
        }
      }
    },
    "/submit": {
      "post": {
        "summary": "Передать URL в подключённые каналы",
        "operationId": "submitUrls",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SubmissionRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "URL приняты"
          }
        }
      }
    },
    "/dashboard": {
      "get": {
        "summary": "Сводная статистика сайта для CMS",
        "operationId": "getCmsDashboard",
        "parameters": [
          {
            "name": "siteId",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Статистика отправок, последние URL и состояние краулинга"
          }
        }
      }
    },
    "/sites/{id}/crawl-audit": {
      "post": {
        "summary": "Запустить платный аудит сайта или выбранной карты сайта",
        "operationId": "startCrawlAudit",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CrawlAuditRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Краулинг поставлен в очередь"
          },
          "403": {
            "description": "Требуется платный тариф"
          },
          "409": {
            "description": "Краулинг уже выполняется"
          },
          "429": {
            "description": "Сработал суточный лимит или интервал между запусками"
          }
        }
      },
      "get": {
        "summary": "Получить состояние и сводку краулинга",
        "operationId": "getCrawlAudit",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "runId",
            "in": "query",
            "required": false,
            "description": "UUID конкретного запуска",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "sitemapId",
            "in": "query",
            "required": false,
            "description": "Последний запуск для конкретной карты сайта",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Состояние запуска и агрегированные результаты"
          }
        }
      }
    },
    "/status/{id}": {
      "get": {
        "summary": "Статус отправки",
        "operationId": "getSubmissionStatus",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Статус отправки"
          }
        }
      }
    },
    "/history": {
      "get": {
        "summary": "История отправок",
        "operationId": "getSubmissionHistory",
        "parameters": [
          {
            "name": "siteId",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 20
            }
          }
        ],
        "responses": {
          "200": {
            "description": "История отправок"
          }
        }
      }
    },
    "/sitemaps": {
      "get": {
        "summary": "Список отслеживаемых Sitemap",
        "operationId": "listSitemaps",
        "responses": {
          "200": {
            "description": "Sitemap аккаунта"
          }
        }
      },
      "post": {
        "summary": "Подключить Sitemap и настроить обход",
        "operationId": "createSitemap",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/SitemapMutation" }
            }
          }
        },
        "responses": {
          "201": { "description": "Sitemap подключён" },
          "400": { "description": "Sitemap недоступен или выбран неподключённый индексатор" },
          "403": { "description": "Sitemap недоступен на тарифе" }
        }
      }
    },
    "/sitemaps/{id}/check": {
      "post": {
        "summary": "Запустить проверку Sitemap",
        "operationId": "checkSitemap",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Проверка поставлена в очередь"
          }
        }
      }
    },
    "/sitemaps/{id}": {
      "patch": {
        "summary": "Изменить параметры обхода и индексаторы Sitemap",
        "operationId": "updateSitemap",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": { "type": "string", "format": "uuid" }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/SitemapMutation" }
            }
          }
        },
        "responses": {
          "200": { "description": "Sitemap обновлён" },
          "403": { "description": "Sitemap недоступен на тарифе" }
        }
      }
    },
    "/tools/page-audit": {
      "post": {
        "summary": "Технический SEO-аудит страницы",
        "operationId": "auditPage",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "url"
                ],
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Результат аудита"
          },
          "403": {
            "description": "Инструмент недоступен на текущем тарифе"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "API token"
      }
    },
    "schemas": {
      "SubmissionRequest": {
        "type": "object",
        "required": [
          "siteId",
          "urls"
        ],
        "properties": {
          "siteId": {
            "type": "string",
            "format": "uuid"
          },
          "urls": {
            "type": "array",
            "minItems": 1,
            "maxItems": 100,
            "items": {
              "type": "string",
              "format": "uri"
            }
          },
          "engines": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "google",
                "indexnow",
                "yandex",
                "indexnow_org",
                "indexnow_bing",
                "yandex_webmaster",
                "bing_webmaster",
                "telegram",
                "ping",
                "ai_fetcher"
              ]
            }
          },
          "submissionMode": {
            "type": "string",
            "enum": [
              "normal",
              "hard",
              "tier",
              "social"
            ],
            "default": "normal"
          }
        }
      },
      "CrawlAuditRequest": {
        "type": "object",
        "properties": {
          "sitemapId": {
            "type": "string",
            "format": "uuid",
            "description": "Если указан, проверяются только URL этой карты сайта"
          },
          "useAiFetcherFallback": {
            "type": "boolean",
            "default": true
          },
          "respectRobots": {
            "type": "boolean",
            "default": true
          },
          "respectNofollow": {
            "type": "boolean",
            "default": true
          },
          "maxDepth": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100,
            "default": 50
          },
          "includePatterns": {
            "type": "array",
            "maxItems": 20,
            "items": {
              "type": "string"
            }
          },
          "excludePatterns": {
            "type": "array",
            "maxItems": 20,
            "items": {
              "type": "string"
            }
          },
          "keepQueryParameters": {
            "type": "boolean",
            "default": false
          }
        }
      },
      "SitemapMutation": {
        "type": "object",
        "properties": {
          "siteId": { "type": "string", "format": "uuid" },
          "url": { "type": "string", "format": "uri" },
          "engines": {
            "type": "array",
            "minItems": 1,
            "items": {
              "type": "string",
              "enum": [
                "google",
                "indexnow_org",
                "indexnow_bing",
                "yandex_webmaster",
                "bing_webmaster",
                "telegram",
                "ping",
                "ai_fetcher"
              ]
            }
          },
          "submitMode": { "type": "string", "enum": ["immediate", "scheduled"] },
          "scheduleIntervalMin": { "type": "integer", "minimum": 5, "maximum": 10080 },
          "submitOnlyNew": { "type": "boolean" },
          "seedOnAdd": { "type": "boolean" },
          "sitemapPingEnabled": { "type": "boolean" },
          "isActive": { "type": "boolean" },
          "notifyOnDown": { "type": "boolean" },
          "note": { "type": ["string", "null"], "maxLength": 100 }
        }
      }
    }
  }
}
