{
  "openapi": "3.1.0",
  "info": {
    "title": "Реестр российских ИИ-агентов — API",
    "version": "1.0.0",
    "summary": "Поиск агентов по возможностям, карточка агента, проверка по адресу, статистика.",
    "description": "Открытый API реестра a2aregistry.ru. Без ключа, CORS открыт для чтения, лимит 60 запросов в минуту с одного адреса (проверка по адресу — 10 в минуту). Реестр подтверждает только факты на дату проверки: агент заявлен, владелец назван, паспорт проходит валидатор паспорт-агента.рф, карточка A2A соответствует формату, адрес отвечает. Качество и надёжность агента не оцениваются. Данные — CC BY 4.0.",
    "contact": {"name": "ООО «САРМАТЕХ», реестр ИИ-агентов", "email": "registry@a2aprotocol.ru", "url": "https://a2aregistry.ru/o-proekte/"},
    "license": {"name": "CC BY 4.0", "url": "https://creativecommons.org/licenses/by/4.0/"},
    "termsOfService": "https://a2aregistry.ru/o-proekte/"
  },
  "servers": [{"url": "https://a2aregistry.ru/api/v1"}],
  "externalDocs": {"description": "Описание для людей и AGENTS.md", "url": "https://a2aregistry.ru/api/"},
  "paths": {
    "/agents": {
      "get": {
        "operationId": "searchAgents",
        "summary": "Поиск агентов",
        "parameters": [
          {"name": "q", "in": "query", "schema": {"type": "string", "maxLength": 80}, "description": "Текст: имя, описание, владелец, сайт, номер паспорта"},
          {"name": "skill", "in": "query", "schema": {"type": "string", "enum": ["search", "compare", "quote", "order", "pay", "sign", "message", "publish", "answer", "verify", "crawl", "analyze", "generate", "support", "translate", "automate", "finance", "geo", "devtools"]}},
          {"name": "industry", "in": "query", "schema": {"type": "string", "enum": ["it", "retail", "finance", "gov", "media", "logistics", "telecom", "industry", "realty", "health", "hr", "other"]}},
          {"name": "owner", "in": "query", "schema": {"type": "string"}, "description": "slug владельца, см. /owners"},
          {"name": "level", "in": "query", "schema": {"type": "string", "enum": ["K2", "K3"]}, "description": "Уровень паспорта"},
          {"name": "interface", "in": "query", "schema": {"type": "string", "enum": ["api", "mcp", "a2a", "web", "telegram", "crawler"]}},
          {"name": "status", "in": "query", "schema": {"type": "string", "enum": ["active", "unconfirmed", "offline", "revoked"]}},
          {"name": "passport", "in": "query", "schema": {"type": "string", "enum": ["yes", "no"]}},
          {"name": "card", "in": "query", "schema": {"type": "string", "enum": ["yes"]}},
          {"name": "robots", "in": "query", "schema": {"type": "string", "enum": ["no", "only"]}, "description": "no — без роботов оператора реестра"},
          {"name": "limit", "in": "query", "schema": {"type": "integer", "minimum": 1, "maximum": 200, "default": 50}},
          {"name": "offset", "in": "query", "schema": {"type": "integer", "minimum": 0, "default": 0}}
        ],
        "responses": {
          "200": {"description": "Список", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AgentList"}}}},
          "429": {"$ref": "#/components/responses/RateLimited"}
        }
      }
    },
    "/agents/{slug}.json": {
      "get": {
        "operationId": "getAgent",
        "summary": "Запись об агенте",
        "parameters": [{"name": "slug", "in": "path", "required": true, "schema": {"type": "string", "pattern": "^[a-z0-9][a-z0-9-]{1,60}$"}}],
        "responses": {
          "200": {"description": "Запись", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "item": {"$ref": "#/components/schemas/Agent"}}}}}},
          "404": {"description": "Нет записи"},
          "429": {"$ref": "#/components/responses/RateLimited"}
        }
      }
    },
    "/verify": {
      "get": {
        "operationId": "verifyAgent",
        "summary": "Проверка по адресу сайта или карточки A2A",
        "description": "Отвечает ли адрес, валидна ли карточка A2A (name, url, version, skills), есть ли паспорт ИИ-агента (валидатор паспорт-агента.рф), совпадают ли владелец в карточке и в паспорте, есть ли запись в реестре. До 30 секунд. Лимит 10 в минуту.",
        "parameters": [{"name": "url", "in": "query", "required": true, "schema": {"type": "string", "maxLength": 300}, "example": "agentreadyscan.ru"}],
        "responses": {
          "200": {"description": "Результат", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/VerifyResult"}}}},
          "400": {"description": "Нет адреса"},
          "429": {"$ref": "#/components/responses/RateLimited"}
        }
      }
    },
    "/stats": {"get": {"operationId": "getStats", "summary": "Статистика реестра", "responses": {"200": {"description": "Агрегаты", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Stats"}}}}}}},
    "/owners": {"get": {"operationId": "listOwners", "summary": "Владельцы агентов", "responses": {"200": {"description": "Список владельцев", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "items": {"type": "array", "items": {"$ref": "#/components/schemas/Owner"}}}}}}}}}},
    "/agents.json": {"get": {"operationId": "dumpAgents", "summary": "Все записи одним файлом (статическая копия, обновляется при изменении данных)", "responses": {"200": {"description": "Все записи", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AgentList"}}}}}}}
  },
  "components": {
    "responses": {"RateLimited": {"description": "Превышен лимит; заголовок Retry-After", "headers": {"Retry-After": {"schema": {"type": "integer"}}}}},
    "schemas": {
      "AgentList": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "limit": {"type": "integer"}, "offset": {"type": "integer"}, "items": {"type": "array", "items": {"$ref": "#/components/schemas/Agent"}}, "note": {"type": "string"}, "license": {"type": "string"}}},
      "Agent": {
        "type": "object",
        "required": ["slug", "name", "owner", "status", "passport", "card"],
        "properties": {
          "slug": {"type": "string"}, "name": {"type": "string"}, "summary": {"type": "string"}, "url": {"type": "string", "format": "uri"},
          "owner": {"$ref": "#/components/schemas/OwnerRef"},
          "skills": {"type": "array", "items": {"type": "object", "properties": {"code": {"type": "string"}, "name": {"type": "string"}}}},
          "card_skills": {"type": "array", "items": {"type": "string"}, "description": "Навыки из карточки A2A, если она есть"},
          "industry": {"type": "object", "properties": {"code": {"type": "string"}, "name": {"type": "string"}}},
          "interfaces": {"type": "array", "items": {"type": "string", "enum": ["api", "mcp", "a2a", "web", "telegram", "crawler"]}},
          "protocols": {"type": "array", "items": {"type": "string", "enum": ["a2a", "mcp", "http"]}},
          "endpoint": {"type": "string", "description": "Адрес обращения; пусто — машинного адреса нет"},
          "endpoint_kind": {"type": "string", "enum": ["endpoint", "docs", "none"], "description": "docs — указана страница документации, а не сам адрес"},
          "endpoint_status": {"type": "string", "enum": ["online", "offline", "unknown"]},
          "endpoint_checked_at": {"type": ["string", "null"], "format": "date-time"},
          "site": {"type": "string"}, "user_agent": {"type": "string"}, "stop_url": {"type": "string"},
          "passport": {"type": "object", "properties": {"url": {"type": "string"}, "number": {"type": "string", "description": "AP-ГГГГ-NNNNNN или пусто"}, "level": {"type": "string", "enum": ["", "K2", "K3"]}, "status": {"type": "string", "enum": ["none", "published", "confirmed", "unconfirmed", "suspended", "revoked", "invalid", "offline"]}, "status_text": {"type": "string"}, "checked_at": {"type": ["string", "null"]}, "registry_card": {"type": "string"}}},
          "card": {"type": "object", "properties": {"url": {"type": "string"}, "status": {"type": "string", "enum": ["none", "valid", "invalid", "offline", "unknown"]}, "status_text": {"type": "string"}, "checked_at": {"type": ["string", "null"]}, "snapshot": {"type": ["object", "null"], "description": "Слепок карточки A2A: name, description, url, version, protocolVersion, provider, skills, signatures"}}},
          "status": {"type": "string", "enum": ["active", "unconfirmed", "offline", "revoked"]}, "status_text": {"type": "string"},
          "added_by": {"type": "string"}, "source": {"type": "string", "enum": ["owner", "editorial"]}, "source_url": {"type": "string"}, "source_date": {"type": "string"},
          "owner_confirmed": {"type": "boolean"}, "owner_confirmed_at": {"type": ["string", "null"]},
          "operator_robot": {"type": "boolean", "description": "Робот оператора реестра — образец формата, в счётчик внешних паспортов не входит"},
          "added_at": {"type": "string", "format": "date"},
          "history": {"type": "array", "items": {"type": "object", "properties": {"at": {"type": "string"}, "event": {"type": "string"}, "note": {"type": "string"}}}}
        }
      },
      "OwnerRef": {"type": "object", "properties": {"slug": {"type": "string"}, "name": {"type": "string"}, "inn": {"type": "string"}, "site": {"type": "string"}, "url": {"type": "string"}, "is_registry_operator": {"type": "boolean"}}},
      "Owner": {"type": "object", "properties": {"slug": {"type": "string"}, "name": {"type": "string"}, "inn": {"type": "string"}, "site": {"type": "string"}, "industry": {"type": "string"}, "site_level": {"type": "string"}, "is_registry_operator": {"type": "boolean"}, "agents": {"type": "integer"}, "confirmed": {"type": "integer"}, "url": {"type": "string"}}},
      "VerifyResult": {
        "type": "object",
        "properties": {
          "ok": {"type": "boolean"}, "host": {"type": "string"}, "checked_at": {"type": "string"},
          "endpoint": {"type": "object", "properties": {"url": {"type": "string"}, "online": {"type": "boolean"}, "status": {"type": "integer"}, "ms": {"type": "integer"}, "note": {"type": "string"}}},
          "card": {"type": "object", "properties": {"status": {"type": "string", "enum": ["none", "valid", "invalid", "offline"]}, "issues": {"type": "array", "items": {"type": "string"}}, "card": {"type": ["object", "null"]}, "url": {"type": "string"}}},
          "passport": {"type": "object", "properties": {"status": {"type": "string"}, "number": {"type": "string"}, "level": {"type": "string"}, "passport": {"type": ["object", "null"]}, "note": {"type": "string"}, "check_url": {"type": "string"}}},
          "owner_match": {"type": ["boolean", "null"], "description": "null — сравнивать нечего (нет карточки или паспорта)"},
          "registry": {"oneOf": [{"$ref": "#/components/schemas/Agent"}, {"type": "null"}]},
          "note": {"type": "string"}
        }
      },
      "Stats": {"type": "object", "properties": {"ok": {"type": "boolean"}, "agents": {"type": "integer"}, "owners": {"type": "integer"}, "external_passports_confirmed": {"type": "integer"}, "operator_robots": {"type": "integer"}, "passports_published": {"type": "integer"}, "cards_valid": {"type": "integer"}, "with_endpoint": {"type": "integer"}, "by_industry": {"type": "object", "additionalProperties": {"type": "integer"}}, "by_interface": {"type": "object", "additionalProperties": {"type": "integer"}}, "by_status": {"type": "object", "additionalProperties": {"type": "integer"}}, "last_check": {"type": ["string", "null"]}, "generated_at": {"type": "string"}}}
    }
  }
}
